Skip to content

Commit 1074077

Browse files
allow parameterized streaming
1 parent 417ecbe commit 1074077

2 files changed

Lines changed: 76 additions & 20 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
*pgm
22
build/*
3-
small_bunny_1080p_60fps.mp4
43
bunny_1080p_60fps.mp4
54
bunny_1s_gop.mp4
5+
bunny_1s_gop.mp4.ts
6+
bunny_1s_gop.mp4.webm

3_transcoding.c

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@
1212
typedef struct StreamingParams {
1313
char copy_video;
1414
char copy_audio;
15-
char fragmented_mp4;
15+
char *output_extension;
16+
char *muxer_opt_key;
17+
char *muxer_opt_value;
1618
char *video_codec;
1719
char *audio_codec;
20+
char *codec_priv_key;
21+
char *codec_priv_value;
1822
} StreamingParams;
1923

2024
typedef struct StreamingContext {
@@ -76,20 +80,15 @@ int prepare_decoder(StreamingContext *sc) {
7680
int prepare_video_encoder(StreamingContext *sc, AVCodecContext *decoder_ctx, AVRational input_framerate, StreamingParams sp) {
7781
sc->video_avs = avformat_new_stream(sc->avfc, NULL);
7882

79-
char *codec_name = strcmp(sp.video_codec, "x264") == 0 ? "libx264" : "libx265";
80-
char *x264_opts = "keyint=60:min-keyint=60:scenecut=0:force-cfr=1";
81-
char *x265_opts = "keyint=60:min-keyint=60:scenecut=0";
82-
char *codec_priv_key = strcmp(sp.video_codec, "x264") == 0 ? "x264-params" : "x265-params";
83-
char *codec_priv_value = strcmp(sp.video_codec, "x264") == 0 ? x264_opts : x265_opts;
84-
85-
sc->video_avc = avcodec_find_encoder_by_name(codec_name);
83+
sc->video_avc = avcodec_find_encoder_by_name(sp.video_codec);
8684
if (!sc->video_avc) {logging("could not find the proper codec"); return -1;}
8785

8886
sc->video_avcc = avcodec_alloc_context3(sc->video_avc);
8987
if (!sc->video_avcc) {logging("could not allocated memory for codec context"); return -1;}
9088

9189
av_opt_set(sc->video_avcc->priv_data, "preset", "fast", 0);
92-
av_opt_set(sc->video_avcc->priv_data, codec_priv_key, codec_priv_value, 0);
90+
if (sp.codec_priv_key && sp.codec_priv_value)
91+
av_opt_set(sc->video_avcc->priv_data, sp.codec_priv_key, sp.codec_priv_value, 0);
9392

9493
sc->video_avcc->height = decoder_ctx->height;
9594
sc->video_avcc->width = decoder_ctx->width;
@@ -114,11 +113,7 @@ int prepare_video_encoder(StreamingContext *sc, AVCodecContext *decoder_ctx, AVR
114113
int prepare_audio_encoder(StreamingContext *sc, int sample_rate, StreamingParams sp){
115114
sc->audio_avs = avformat_new_stream(sc->avfc, NULL);
116115

117-
char *codec = "aac";
118-
if (sp.audio_codec)
119-
codec = sp.audio_codec;
120-
121-
sc->audio_avc = avcodec_find_encoder_by_name(codec);
116+
sc->audio_avc = avcodec_find_encoder_by_name(sp.audio_codec);
122117
if (!sc->audio_avc) {logging("could not find the proper codec"); return -1;}
123118

124119
sc->audio_avcc = avcodec_alloc_context3(sc->audio_avc);
@@ -251,19 +246,79 @@ int transcode_video(StreamingContext *decoder, StreamingContext *encoder, AVPack
251246

252247
int main(int argc, char *argv[])
253248
{
249+
/*
250+
* H264 -> H265
251+
* Audio -> remuxed (untouched)
252+
* MP4 - MP4
253+
*/
254254
StreamingParams sp = {0};
255255
sp.copy_audio = 1;
256256
sp.copy_video = 0;
257-
sp.fragmented_mp4 = 0;
258-
sp.video_codec = "x265";
259-
sp.audio_codec = "aac";
257+
sp.video_codec = "libx265";
258+
sp.codec_priv_key = "x265-params";
259+
sp.codec_priv_value = "keyint=60:min-keyint=60:scenecut=0";
260+
261+
/*
262+
* H264 -> H264 (fixed gop)
263+
* Audio -> remuxed (untouched)
264+
* MP4 - MP4
265+
*/
266+
//StreamingParams sp = {0};
267+
//sp.copy_audio = 1;
268+
//sp.copy_video = 0;
269+
//sp.video_codec = "libx264";
270+
//sp.codec_priv_key = "x264-params";
271+
//sp.codec_priv_value = "keyint=60:min-keyint=60:scenecut=0:force-cfr=1";
272+
273+
/*
274+
* H264 -> H264 (fixed gop)
275+
* Audio -> remuxed (untouched)
276+
* MP4 - fragmented MP4
277+
*/
278+
//StreamingParams sp = {0};
279+
//sp.copy_audio = 1;
280+
//sp.copy_video = 0;
281+
//sp.video_codec = "libx264";
282+
//sp.codec_priv_key = "x264-params";
283+
//sp.codec_priv_value = "keyint=60:min-keyint=60:scenecut=0:force-cfr=1";
284+
//sp.muxer_opt_key = "movflags";
285+
//sp.muxer_opt_value = "frag_keyframe+empty_moov+default_base_moof";
286+
287+
/*
288+
* H264 -> H264 (fixed gop)
289+
* Audio -> AAC
290+
* MP4 - MPEG-TS
291+
*/
292+
//StreamingParams sp = {0};
293+
//sp.copy_audio = 0;
294+
//sp.copy_video = 0;
295+
//sp.video_codec = "libx264";
296+
//sp.codec_priv_key = "x264-params";
297+
//sp.codec_priv_value = "keyint=60:min-keyint=60:scenecut=0:force-cfr=1";
298+
//sp.audio_codec = "aac";
299+
//sp.output_extension = ".ts";
300+
301+
/*
302+
* H264 -> VP9
303+
* Audio -> Vorbis
304+
* MP4 - WebM
305+
*/
306+
//StreamingParams sp = {0};
307+
//sp.copy_audio = 0;
308+
//sp.copy_video = 0;
309+
//sp.video_codec = "libvpx-vp9";
310+
//sp.audio_codec = "libvorbis";
311+
//sp.output_extension = ".webm";
260312

261313
StreamingContext *decoder = (StreamingContext*) calloc(1, sizeof(StreamingContext));
262314
decoder->filename = argv[1];
263315

264316
StreamingContext *encoder = (StreamingContext*) calloc(1, sizeof(StreamingContext));
265317
encoder->filename = argv[2];
266318

319+
if (sp.output_extension)
320+
strcat(encoder->filename, sp.output_extension);
321+
267322
if (open_media(decoder->filename, &decoder->avfc)) return -1;
268323
if (prepare_decoder(decoder)) return -1;
269324

@@ -295,8 +350,8 @@ int main(int argc, char *argv[])
295350

296351
AVDictionary* muxer_opts = NULL;
297352

298-
if (sp.fragmented_mp4) {
299-
av_dict_set(&muxer_opts, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
353+
if (sp.muxer_opt_key && sp.muxer_opt_value) {
354+
av_dict_set(&muxer_opts, sp.muxer_opt_key, sp.muxer_opt_value, 0);
300355
}
301356

302357
if (avformat_write_header(encoder->avfc, &muxer_opts) < 0) {logging("an error occurred when opening output file"); return -1;}

0 commit comments

Comments
 (0)