1212typedef 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
2024typedef struct StreamingContext {
@@ -76,20 +80,15 @@ int prepare_decoder(StreamingContext *sc) {
7680int 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
114113int 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
252247int 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