]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
lavu: add thread message API.
[ffmpeg] / ffmpeg.c
index b2e39e8d0eed3604c676cddbe57f65ae8aa8955b..5299f0ef0f08b8e04eaced7d3c377e079418fdbc 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -438,18 +438,20 @@ static void ffmpeg_cleanup(int ret)
     }
 
     for (i = 0; i < nb_filtergraphs; i++) {
-        avfilter_graph_free(&filtergraphs[i]->graph);
-        for (j = 0; j < filtergraphs[i]->nb_inputs; j++) {
-            av_freep(&filtergraphs[i]->inputs[j]->name);
-            av_freep(&filtergraphs[i]->inputs[j]);
-        }
-        av_freep(&filtergraphs[i]->inputs);
-        for (j = 0; j < filtergraphs[i]->nb_outputs; j++) {
-            av_freep(&filtergraphs[i]->outputs[j]->name);
-            av_freep(&filtergraphs[i]->outputs[j]);
-        }
-        av_freep(&filtergraphs[i]->outputs);
-        av_freep(&filtergraphs[i]->graph_desc);
+        FilterGraph *fg = filtergraphs[i];
+        avfilter_graph_free(&fg->graph);
+        for (j = 0; j < fg->nb_inputs; j++) {
+            av_freep(&fg->inputs[j]->name);
+            av_freep(&fg->inputs[j]);
+        }
+        av_freep(&fg->inputs);
+        for (j = 0; j < fg->nb_outputs; j++) {
+            av_freep(&fg->outputs[j]->name);
+            av_freep(&fg->outputs[j]);
+        }
+        av_freep(&fg->outputs);
+        av_freep(&fg->graph_desc);
+
         av_freep(&filtergraphs[i]);
     }
     av_freep(&filtergraphs);
@@ -458,29 +460,33 @@ static void ffmpeg_cleanup(int ret)
 
     /* close files */
     for (i = 0; i < nb_output_files; i++) {
-        AVFormatContext *s = output_files[i]->ctx;
+        OutputFile *of = output_files[i];
+        AVFormatContext *s = of->ctx;
         if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE) && s->pb)
             avio_close(s->pb);
         avformat_free_context(s);
-        av_dict_free(&output_files[i]->opts);
+        av_dict_free(&of->opts);
+
         av_freep(&output_files[i]);
     }
     for (i = 0; i < nb_output_streams; i++) {
-        AVBitStreamFilterContext *bsfc = output_streams[i]->bitstream_filters;
+        OutputStream *ost = output_streams[i];
+        AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
         while (bsfc) {
             AVBitStreamFilterContext *next = bsfc->next;
             av_bitstream_filter_close(bsfc);
             bsfc = next;
         }
-        output_streams[i]->bitstream_filters = NULL;
-        av_frame_free(&output_streams[i]->filtered_frame);
+        ost->bitstream_filters = NULL;
+        av_frame_free(&ost->filtered_frame);
 
-        av_parser_close(output_streams[i]->parser);
+        av_parser_close(ost->parser);
+
+        av_freep(&ost->forced_keyframes);
+        av_expr_free(ost->forced_keyframes_pexpr);
+        av_freep(&ost->avfilter);
+        av_freep(&ost->logfile_prefix);
 
-        av_freep(&output_streams[i]->forced_keyframes);
-        av_expr_free(output_streams[i]->forced_keyframes_pexpr);
-        av_freep(&output_streams[i]->avfilter);
-        av_freep(&output_streams[i]->logfile_prefix);
         av_freep(&output_streams[i]);
     }
 #if HAVE_PTHREADS
@@ -491,13 +497,16 @@ static void ffmpeg_cleanup(int ret)
         av_freep(&input_files[i]);
     }
     for (i = 0; i < nb_input_streams; i++) {
-        av_frame_free(&input_streams[i]->decoded_frame);
-        av_frame_free(&input_streams[i]->filter_frame);
-        av_dict_free(&input_streams[i]->opts);
-        avsubtitle_free(&input_streams[i]->prev_sub.subtitle);
-        av_frame_free(&input_streams[i]->sub2video.frame);
-        av_freep(&input_streams[i]->filters);
-        av_freep(&input_streams[i]->hwaccel_device);
+        InputStream *ist = input_streams[i];
+
+        av_frame_free(&ist->decoded_frame);
+        av_frame_free(&ist->filter_frame);
+        av_dict_free(&ist->decoder_opts);
+        avsubtitle_free(&ist->prev_sub.subtitle);
+        av_frame_free(&ist->sub2video.frame);
+        av_freep(&ist->filters);
+        av_freep(&ist->hwaccel_device);
+
         av_freep(&input_streams[i]);
     }
 
@@ -588,6 +597,9 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
         ost->frame_number++;
     }
 
+    if (bsfc)
+        av_packet_split_side_data(pkt);
+
     while (bsfc) {
         AVPacket new_pkt = *pkt;
         int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
@@ -821,6 +833,7 @@ static void do_subtitle_out(AVFormatContext *s,
             else
                 pkt.pts += 90 * sub->end_display_time;
         }
+        pkt.dts = pkt.pts;
         write_frame(s, &pkt, ost);
     }
 }
@@ -1090,7 +1103,7 @@ static void do_video_stats(OutputStream *ost, int frame_size)
 
         fprintf(vstats_file,"f_size= %6d ", frame_size);
         /* compute pts value */
-        ti1 = ost->st->pts.val * av_q2d(enc->time_base);
+        ti1 = av_stream_get_end_pts(ost->st) * av_q2d(ost->st->time_base);
         if (ti1 < 0.01)
             ti1 = 0.01;
 
@@ -1402,8 +1415,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
             vid = 1;
         }
         /* compute min output value */
-        if (ost->st->pts.val != AV_NOPTS_VALUE)
-            pts = FFMAX(pts, av_rescale_q(ost->st->pts.val,
+        if (av_stream_get_end_pts(ost->st) != AV_NOPTS_VALUE)
+            pts = FFMAX(pts, av_rescale_q(av_stream_get_end_pts(ost->st),
                                           ost->st->time_base, AV_TIME_BASE_Q));
     }
 
@@ -1663,7 +1676,6 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
     }
 
     write_frame(of->ctx, &opkt, ost);
-    ost->st->codec->frame_number++;
 }
 
 int guess_input_channel_layout(InputStream *ist)
@@ -2240,9 +2252,9 @@ static int init_input_stream(int ist_index, char *error, int error_len)
 
         av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0);
 
-        if (!av_dict_get(ist->opts, "threads", NULL, 0))
-            av_dict_set(&ist->opts, "threads", "auto", 0);
-        if ((ret = avcodec_open2(ist->st->codec, codec, &ist->opts)) < 0) {
+        if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0))
+            av_dict_set(&ist->decoder_opts, "threads", "auto", 0);
+        if ((ret = avcodec_open2(ist->st->codec, codec, &ist->decoder_opts)) < 0) {
             if (ret == AVERROR_EXPERIMENTAL)
                 abort_codec_experimental(codec, 0);
 
@@ -2252,7 +2264,7 @@ static int init_input_stream(int ist_index, char *error, int error_len)
                      ist->file_index, ist->st->index, av_err2str(ret));
             return ret;
         }
-        assert_avoptions(ist->opts);
+        assert_avoptions(ist->decoder_opts);
     }
 
     ist->next_pts = AV_NOPTS_VALUE;
@@ -2352,11 +2364,51 @@ static void report_new_stream(int input_index, AVPacket *pkt)
     file->nb_streams_warn = pkt->stream_index + 1;
 }
 
+static void set_encoder_id(OutputFile *of, OutputStream *ost)
+{
+    AVDictionaryEntry *e;
+
+    uint8_t *encoder_string;
+    int encoder_string_len;
+    int format_flags = 0;
+    int codec_flags = 0;
+
+    if (av_dict_get(ost->st->metadata, "encoder",  NULL, 0))
+        return;
+
+    e = av_dict_get(of->opts, "fflags", NULL, 0);
+    if (e) {
+        const AVOption *o = av_opt_find(of->ctx, "fflags", NULL, 0, 0);
+        if (!o)
+            return;
+        av_opt_eval_flags(of->ctx, o, e->value, &format_flags);
+    }
+    e = av_dict_get(ost->encoder_opts, "flags", NULL, 0);
+    if (e) {
+        const AVOption *o = av_opt_find(ost->st->codec, "flags", NULL, 0, 0);
+        if (!o)
+            return;
+        av_opt_eval_flags(ost->st->codec, o, e->value, &codec_flags);
+    }
+
+    encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(ost->enc->name) + 2;
+    encoder_string     = av_mallocz(encoder_string_len);
+    if (!encoder_string)
+        exit_program(1);
+
+    if (!(format_flags & AVFMT_FLAG_BITEXACT) && !(codec_flags & CODEC_FLAG_BITEXACT))
+        av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len);
+    else
+        av_strlcpy(encoder_string, "Lavc ", encoder_string_len);
+    av_strlcat(encoder_string, ost->enc->name, encoder_string_len);
+    av_dict_set(&ost->st->metadata, "encoder",  encoder_string,
+                AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE);
+}
+
 static int transcode_init(void)
 {
     int ret = 0, i, j, k;
     AVFormatContext *oc;
-    AVCodecContext *codec;
     OutputStream *ost;
     InputStream *ist;
     char error[1024];
@@ -2382,7 +2434,7 @@ static int transcode_init(void)
         InputFile *ifile = input_files[i];
         if (ifile->rate_emu)
             for (j = 0; j < ifile->nb_streams; j++)
-                input_streams[j + ifile->ist_index]->start = av_gettime();
+                input_streams[j + ifile->ist_index]->start = av_gettime_relative();
     }
 
     /* output stream init */
@@ -2402,7 +2454,8 @@ static int transcode_init(void)
 
     /* for each output stream, we compute the right encoding parameters */
     for (i = 0; i < nb_output_streams; i++) {
-        AVCodecContext *icodec = NULL;
+        AVCodecContext *enc_ctx;
+        AVCodecContext *dec_ctx = NULL;
         ost = output_streams[i];
         oc  = output_files[ost->file_index]->ctx;
         ist = get_input_stream(ost);
@@ -2410,22 +2463,22 @@ static int transcode_init(void)
         if (ost->attachment_filename)
             continue;
 
-        codec  = ost->st->codec;
+        enc_ctx = ost->st->codec;
 
         if (ist) {
-            icodec = ist->st->codec;
+            dec_ctx = ist->st->codec;
 
             ost->st->disposition          = ist->st->disposition;
-            codec->bits_per_raw_sample    = icodec->bits_per_raw_sample;
-            codec->chroma_sample_location = icodec->chroma_sample_location;
+            enc_ctx->bits_per_raw_sample    = dec_ctx->bits_per_raw_sample;
+            enc_ctx->chroma_sample_location = dec_ctx->chroma_sample_location;
         } else {
             for (j=0; j<oc->nb_streams; j++) {
                 AVStream *st = oc->streams[j];
-                if (st != ost->st && st->codec->codec_type == codec->codec_type)
+                if (st != ost->st && st->codec->codec_type == enc_ctx->codec_type)
                     break;
             }
             if (j == oc->nb_streams)
-                if (codec->codec_type == AVMEDIA_TYPE_AUDIO || codec->codec_type == AVMEDIA_TYPE_VIDEO)
+                if (enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO || enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
                     ost->st->disposition = AV_DISPOSITION_DEFAULT;
         }
 
@@ -2435,37 +2488,37 @@ static int transcode_init(void)
 
             av_assert0(ist && !ost->filter);
 
-            extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
+            extra_size = (uint64_t)dec_ctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
 
             if (extra_size > INT_MAX) {
                 return AVERROR(EINVAL);
             }
 
             /* if stream_copy is selected, no need to decode or encode */
-            codec->codec_id   = icodec->codec_id;
-            codec->codec_type = icodec->codec_type;
+            enc_ctx->codec_id   = dec_ctx->codec_id;
+            enc_ctx->codec_type = dec_ctx->codec_type;
 
-            if (!codec->codec_tag) {
+            if (!enc_ctx->codec_tag) {
                 unsigned int codec_tag;
                 if (!oc->oformat->codec_tag ||
-                     av_codec_get_id (oc->oformat->codec_tag, icodec->codec_tag) == codec->codec_id ||
-                     !av_codec_get_tag2(oc->oformat->codec_tag, icodec->codec_id, &codec_tag))
-                    codec->codec_tag = icodec->codec_tag;
+                     av_codec_get_id (oc->oformat->codec_tag, dec_ctx->codec_tag) == enc_ctx->codec_id ||
+                     !av_codec_get_tag2(oc->oformat->codec_tag, dec_ctx->codec_id, &codec_tag))
+                    enc_ctx->codec_tag = dec_ctx->codec_tag;
             }
 
-            codec->bit_rate       = icodec->bit_rate;
-            codec->rc_max_rate    = icodec->rc_max_rate;
-            codec->rc_buffer_size = icodec->rc_buffer_size;
-            codec->field_order    = icodec->field_order;
-            codec->extradata      = av_mallocz(extra_size);
-            if (!codec->extradata) {
+            enc_ctx->bit_rate       = dec_ctx->bit_rate;
+            enc_ctx->rc_max_rate    = dec_ctx->rc_max_rate;
+            enc_ctx->rc_buffer_size = dec_ctx->rc_buffer_size;
+            enc_ctx->field_order    = dec_ctx->field_order;
+            enc_ctx->extradata      = av_mallocz(extra_size);
+            if (!enc_ctx->extradata) {
                 return AVERROR(ENOMEM);
             }
-            memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
-            codec->extradata_size= icodec->extradata_size;
-            codec->bits_per_coded_sample  = icodec->bits_per_coded_sample;
+            memcpy(enc_ctx->extradata, dec_ctx->extradata, dec_ctx->extradata_size);
+            enc_ctx->extradata_size= dec_ctx->extradata_size;
+            enc_ctx->bits_per_coded_sample  = dec_ctx->bits_per_coded_sample;
 
-            codec->time_base = ist->st->time_base;
+            enc_ctx->time_base = ist->st->time_base;
             /*
              * Avi is a special case here because it supports variable fps but
              * having the fps and timebase differe significantly adds quite some
@@ -2474,90 +2527,90 @@ static int transcode_init(void)
             if(!strcmp(oc->oformat->name, "avi")) {
                 if ( copy_tb<0 && av_q2d(ist->st->r_frame_rate) >= av_q2d(ist->st->avg_frame_rate)
                                && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(ist->st->time_base)
-                               && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(icodec->time_base)
-                               && av_q2d(ist->st->time_base) < 1.0/500 && av_q2d(icodec->time_base) < 1.0/500
+                               && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(dec_ctx->time_base)
+                               && av_q2d(ist->st->time_base) < 1.0/500 && av_q2d(dec_ctx->time_base) < 1.0/500
                      || copy_tb==2){
-                    codec->time_base.num = ist->st->r_frame_rate.den;
-                    codec->time_base.den = 2*ist->st->r_frame_rate.num;
-                    codec->ticks_per_frame = 2;
-                } else if (   copy_tb<0 && av_q2d(icodec->time_base)*icodec->ticks_per_frame > 2*av_q2d(ist->st->time_base)
+                    enc_ctx->time_base.num = ist->st->r_frame_rate.den;
+                    enc_ctx->time_base.den = 2*ist->st->r_frame_rate.num;
+                    enc_ctx->ticks_per_frame = 2;
+                } else if (   copy_tb<0 && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > 2*av_q2d(ist->st->time_base)
                                  && av_q2d(ist->st->time_base) < 1.0/500
                     || copy_tb==0){
-                    codec->time_base = icodec->time_base;
-                    codec->time_base.num *= icodec->ticks_per_frame;
-                    codec->time_base.den *= 2;
-                    codec->ticks_per_frame = 2;
+                    enc_ctx->time_base = dec_ctx->time_base;
+                    enc_ctx->time_base.num *= dec_ctx->ticks_per_frame;
+                    enc_ctx->time_base.den *= 2;
+                    enc_ctx->ticks_per_frame = 2;
                 }
             } else if(!(oc->oformat->flags & AVFMT_VARIABLE_FPS)
                       && strcmp(oc->oformat->name, "mov") && strcmp(oc->oformat->name, "mp4") && strcmp(oc->oformat->name, "3gp")
                       && strcmp(oc->oformat->name, "3g2") && strcmp(oc->oformat->name, "psp") && strcmp(oc->oformat->name, "ipod")
                       && strcmp(oc->oformat->name, "f4v")
             ) {
-                if(   copy_tb<0 && icodec->time_base.den
-                                && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base)
+                if(   copy_tb<0 && dec_ctx->time_base.den
+                                && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > av_q2d(ist->st->time_base)
                                 && av_q2d(ist->st->time_base) < 1.0/500
                    || copy_tb==0){
-                    codec->time_base = icodec->time_base;
-                    codec->time_base.num *= icodec->ticks_per_frame;
+                    enc_ctx->time_base = dec_ctx->time_base;
+                    enc_ctx->time_base.num *= dec_ctx->ticks_per_frame;
                 }
             }
-            if (   codec->codec_tag == AV_RL32("tmcd")
-                && icodec->time_base.num < icodec->time_base.den
-                && icodec->time_base.num > 0
-                && 121LL*icodec->time_base.num > icodec->time_base.den) {
-                codec->time_base = icodec->time_base;
+            if (   enc_ctx->codec_tag == AV_RL32("tmcd")
+                && dec_ctx->time_base.num < dec_ctx->time_base.den
+                && dec_ctx->time_base.num > 0
+                && 121LL*dec_ctx->time_base.num > dec_ctx->time_base.den) {
+                enc_ctx->time_base = dec_ctx->time_base;
             }
 
             if (ist && !ost->frame_rate.num)
                 ost->frame_rate = ist->framerate;
             if(ost->frame_rate.num)
-                codec->time_base = av_inv_q(ost->frame_rate);
+                enc_ctx->time_base = av_inv_q(ost->frame_rate);
 
-            av_reduce(&codec->time_base.num, &codec->time_base.den,
-                        codec->time_base.num, codec->time_base.den, INT_MAX);
+            av_reduce(&enc_ctx->time_base.num, &enc_ctx->time_base.den,
+                        enc_ctx->time_base.num, enc_ctx->time_base.den, INT_MAX);
 
-            ost->parser = av_parser_init(codec->codec_id);
+            ost->parser = av_parser_init(enc_ctx->codec_id);
 
-            switch (codec->codec_type) {
+            switch (enc_ctx->codec_type) {
             case AVMEDIA_TYPE_AUDIO:
                 if (audio_volume != 256) {
                     av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
                     exit_program(1);
                 }
-                codec->channel_layout     = icodec->channel_layout;
-                codec->sample_rate        = icodec->sample_rate;
-                codec->channels           = icodec->channels;
-                codec->frame_size         = icodec->frame_size;
-                codec->audio_service_type = icodec->audio_service_type;
-                codec->block_align        = icodec->block_align;
-                codec->delay              = icodec->delay;
-                if((codec->block_align == 1 || codec->block_align == 1152 || codec->block_align == 576) && codec->codec_id == AV_CODEC_ID_MP3)
-                    codec->block_align= 0;
-                if(codec->codec_id == AV_CODEC_ID_AC3)
-                    codec->block_align= 0;
+                enc_ctx->channel_layout     = dec_ctx->channel_layout;
+                enc_ctx->sample_rate        = dec_ctx->sample_rate;
+                enc_ctx->channels           = dec_ctx->channels;
+                enc_ctx->frame_size         = dec_ctx->frame_size;
+                enc_ctx->audio_service_type = dec_ctx->audio_service_type;
+                enc_ctx->block_align        = dec_ctx->block_align;
+                enc_ctx->delay              = dec_ctx->delay;
+                if((enc_ctx->block_align == 1 || enc_ctx->block_align == 1152 || enc_ctx->block_align == 576) && enc_ctx->codec_id == AV_CODEC_ID_MP3)
+                    enc_ctx->block_align= 0;
+                if(enc_ctx->codec_id == AV_CODEC_ID_AC3)
+                    enc_ctx->block_align= 0;
                 break;
             case AVMEDIA_TYPE_VIDEO:
-                codec->pix_fmt            = icodec->pix_fmt;
-                codec->width              = icodec->width;
-                codec->height             = icodec->height;
-                codec->has_b_frames       = icodec->has_b_frames;
+                enc_ctx->pix_fmt            = dec_ctx->pix_fmt;
+                enc_ctx->width              = dec_ctx->width;
+                enc_ctx->height             = dec_ctx->height;
+                enc_ctx->has_b_frames       = dec_ctx->has_b_frames;
                 if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
                     sar =
                         av_mul_q(ost->frame_aspect_ratio,
-                                 (AVRational){ codec->height, codec->width });
+                                 (AVRational){ enc_ctx->height, enc_ctx->width });
                     av_log(NULL, AV_LOG_WARNING, "Overriding aspect ratio "
                            "with stream copy may produce invalid files\n");
                 }
                 else if (ist->st->sample_aspect_ratio.num)
                     sar = ist->st->sample_aspect_ratio;
                 else
-                    sar = icodec->sample_aspect_ratio;
-                ost->st->sample_aspect_ratio = codec->sample_aspect_ratio = sar;
+                    sar = dec_ctx->sample_aspect_ratio;
+                ost->st->sample_aspect_ratio = enc_ctx->sample_aspect_ratio = sar;
                 ost->st->avg_frame_rate = ist->st->avg_frame_rate;
                 break;
             case AVMEDIA_TYPE_SUBTITLE:
-                codec->width  = icodec->width;
-                codec->height = icodec->height;
+                enc_ctx->width  = dec_ctx->width;
+                enc_ctx->height = dec_ctx->height;
                 break;
             case AVMEDIA_TYPE_DATA:
             case AVMEDIA_TYPE_ATTACHMENT:
@@ -2567,7 +2620,7 @@ static int transcode_init(void)
             }
         } else {
             if (!ost->enc)
-                ost->enc = avcodec_find_encoder(codec->codec_id);
+                ost->enc = avcodec_find_encoder(enc_ctx->codec_id);
             if (!ost->enc) {
                 /* should only happen when a default codec is not present. */
                 snprintf(error, sizeof(error), "Encoder (codec %s) not found for output stream #%d:%d",
@@ -2580,9 +2633,11 @@ static int transcode_init(void)
                 ist->decoding_needed++;
             ost->encoding_needed = 1;
 
+            set_encoder_id(output_files[ost->file_index], ost);
+
             if (!ost->filter &&
-                (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
-                 codec->codec_type == AVMEDIA_TYPE_AUDIO)) {
+                (enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+                 enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO)) {
                     FilterGraph *fg;
                     fg = init_simple_filtergraph(ist, ost);
                     if (configure_filtergraph(fg)) {
@@ -2591,7 +2646,7 @@ static int transcode_init(void)
                     }
             }
 
-            if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+            if (enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
                 if (ost->filter && !ost->frame_rate.num)
                     ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter);
                 if (ist && !ost->frame_rate.num)
@@ -2612,25 +2667,25 @@ static int transcode_init(void)
                     int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
                     ost->frame_rate = ost->enc->supported_framerates[idx];
                 }
-                if (codec->codec_id == AV_CODEC_ID_MPEG4) {
+                if (enc_ctx->codec_id == AV_CODEC_ID_MPEG4) {
                     av_reduce(&ost->frame_rate.num, &ost->frame_rate.den,
                               ost->frame_rate.num, ost->frame_rate.den, 65535);
                 }
             }
 
-            switch (codec->codec_type) {
+            switch (enc_ctx->codec_type) {
             case AVMEDIA_TYPE_AUDIO:
-                codec->sample_fmt     = ost->filter->filter->inputs[0]->format;
-                codec->sample_rate    = ost->filter->filter->inputs[0]->sample_rate;
-                codec->channel_layout = ost->filter->filter->inputs[0]->channel_layout;
-                codec->channels       = avfilter_link_get_channels(ost->filter->filter->inputs[0]);
-                codec->time_base      = (AVRational){ 1, codec->sample_rate };
+                enc_ctx->sample_fmt     = ost->filter->filter->inputs[0]->format;
+                enc_ctx->sample_rate    = ost->filter->filter->inputs[0]->sample_rate;
+                enc_ctx->channel_layout = ost->filter->filter->inputs[0]->channel_layout;
+                enc_ctx->channels       = avfilter_link_get_channels(ost->filter->filter->inputs[0]);
+                enc_ctx->time_base      = (AVRational){ 1, enc_ctx->sample_rate };
                 break;
             case AVMEDIA_TYPE_VIDEO:
-                codec->time_base = av_inv_q(ost->frame_rate);
-                if (ost->filter && !(codec->time_base.num && codec->time_base.den))
-                    codec->time_base = ost->filter->filter->inputs[0]->time_base;
-                if (   av_q2d(codec->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH
+                enc_ctx->time_base = av_inv_q(ost->frame_rate);
+                if (ost->filter && !(enc_ctx->time_base.num && enc_ctx->time_base.den))
+                    enc_ctx->time_base = ost->filter->filter->inputs[0]->time_base;
+                if (   av_q2d(enc_ctx->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH
                    && (video_sync_method == VSYNC_CFR || video_sync_method == VSYNC_VSCFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){
                     av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n"
                                                "Please consider specifying a lower framerate, a different muxer or -vsync 2\n");
@@ -2638,35 +2693,37 @@ static int transcode_init(void)
                 for (j = 0; j < ost->forced_kf_count; j++)
                     ost->forced_kf_pts[j] = av_rescale_q(ost->forced_kf_pts[j],
                                                          AV_TIME_BASE_Q,
-                                                         codec->time_base);
+                                                         enc_ctx->time_base);
 
-                codec->width  = ost->filter->filter->inputs[0]->w;
-                codec->height = ost->filter->filter->inputs[0]->h;
-                codec->sample_aspect_ratio = ost->st->sample_aspect_ratio =
+                enc_ctx->width  = ost->filter->filter->inputs[0]->w;
+                enc_ctx->height = ost->filter->filter->inputs[0]->h;
+                enc_ctx->sample_aspect_ratio = ost->st->sample_aspect_ratio =
                     ost->frame_aspect_ratio.num ? // overridden by the -aspect cli option
-                    av_mul_q(ost->frame_aspect_ratio, (AVRational){ codec->height, codec->width }) :
+                    av_mul_q(ost->frame_aspect_ratio, (AVRational){ enc_ctx->height, enc_ctx->width }) :
                     ost->filter->filter->inputs[0]->sample_aspect_ratio;
                 if (!strncmp(ost->enc->name, "libx264", 7) &&
-                    codec->pix_fmt == AV_PIX_FMT_NONE &&
+                    enc_ctx->pix_fmt == AV_PIX_FMT_NONE &&
                     ost->filter->filter->inputs[0]->format != AV_PIX_FMT_YUV420P)
                     av_log(NULL, AV_LOG_WARNING,
                            "No pixel format specified, %s for H.264 encoding chosen.\n"
                            "Use -pix_fmt yuv420p for compatibility with outdated media players.\n",
                            av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format));
                 if (!strncmp(ost->enc->name, "mpeg2video", 10) &&
-                    codec->pix_fmt == AV_PIX_FMT_NONE &&
+                    enc_ctx->pix_fmt == AV_PIX_FMT_NONE &&
                     ost->filter->filter->inputs[0]->format != AV_PIX_FMT_YUV420P)
                     av_log(NULL, AV_LOG_WARNING,
                            "No pixel format specified, %s for MPEG-2 encoding chosen.\n"
                            "Use -pix_fmt yuv420p for compatibility with outdated media players.\n",
                            av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format));
-                codec->pix_fmt = ost->filter->filter->inputs[0]->format;
+                enc_ctx->pix_fmt = ost->filter->filter->inputs[0]->format;
+
+                ost->st->avg_frame_rate = ost->frame_rate;
 
-                if (!icodec ||
-                    codec->width   != icodec->width  ||
-                    codec->height  != icodec->height ||
-                    codec->pix_fmt != icodec->pix_fmt) {
-                    codec->bits_per_raw_sample = frame_bits_per_raw_sample;
+                if (!dec_ctx ||
+                    enc_ctx->width   != dec_ctx->width  ||
+                    enc_ctx->height  != dec_ctx->height ||
+                    enc_ctx->pix_fmt != dec_ctx->pix_fmt) {
+                    enc_ctx->bits_per_raw_sample = frame_bits_per_raw_sample;
                 }
 
                 if (ost->forced_keyframes) {
@@ -2688,10 +2745,10 @@ static int transcode_init(void)
                 }
                 break;
             case AVMEDIA_TYPE_SUBTITLE:
-                codec->time_base = (AVRational){1, 1000};
-                if (!codec->width) {
-                    codec->width     = input_streams[ost->source_index]->st->codec->width;
-                    codec->height    = input_streams[ost->source_index]->st->codec->height;
+                enc_ctx->time_base = (AVRational){1, 1000};
+                if (!enc_ctx->width) {
+                    enc_ctx->width     = input_streams[ost->source_index]->st->codec->width;
+                    enc_ctx->height    = input_streams[ost->source_index]->st->codec->height;
                 }
                 break;
             default:
@@ -2699,7 +2756,7 @@ static int transcode_init(void)
                 break;
             }
             /* two pass mode */
-            if (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) {
+            if (enc_ctx->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) {
                 char logfilename[1024];
                 FILE *f;
 
@@ -2708,9 +2765,9 @@ static int transcode_init(void)
                                                DEFAULT_PASS_LOGFILENAME_PREFIX,
                          i);
                 if (!strcmp(ost->enc->name, "libx264")) {
-                    av_dict_set(&ost->opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
+                    av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
                 } else {
-                    if (codec->flags & CODEC_FLAG_PASS2) {
+                    if (enc_ctx->flags & CODEC_FLAG_PASS2) {
                         char  *logbuffer;
                         size_t logbuffer_size;
                         if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
@@ -2718,9 +2775,9 @@ static int transcode_init(void)
                                    logfilename);
                             exit_program(1);
                         }
-                        codec->stats_in = logbuffer;
+                        enc_ctx->stats_in = logbuffer;
                     }
-                    if (codec->flags & CODEC_FLAG_PASS1) {
+                    if (enc_ctx->flags & CODEC_FLAG_PASS1) {
                         f = av_fopen_utf8(logfilename, "wb");
                         if (!f) {
                             av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
@@ -2753,9 +2810,9 @@ static int transcode_init(void)
                 memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
                 ost->st->codec->subtitle_header_size = dec->subtitle_header_size;
             }
-            if (!av_dict_get(ost->opts, "threads", NULL, 0))
-                av_dict_set(&ost->opts, "threads", "auto", 0);
-            if ((ret = avcodec_open2(ost->st->codec, codec, &ost->opts)) < 0) {
+            if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
+                av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
+            if ((ret = avcodec_open2(ost->st->codec, codec, &ost->encoder_opts)) < 0) {
                 if (ret == AVERROR_EXPERIMENTAL)
                     abort_codec_experimental(codec, 1);
                 snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height",
@@ -2766,12 +2823,12 @@ static int transcode_init(void)
                 !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
                 av_buffersink_set_frame_size(ost->filter->filter,
                                              ost->st->codec->frame_size);
-            assert_avoptions(ost->opts);
+            assert_avoptions(ost->encoder_opts);
             if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000)
                 av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
                                              " It takes bits/s as argument, not kbits/s\n");
         } else {
-            av_opt_set_dict(ost->st->codec, &ost->opts);
+            av_opt_set_dict(ost->st->codec, &ost->encoder_opts);
         }
     }
 
@@ -3108,7 +3165,7 @@ static void free_input_threads(void)
             av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
             av_free_packet(&pkt);
         }
-        av_fifo_free(f->fifo);
+        av_fifo_freep(&f->fifo);
     }
 }
 
@@ -3122,7 +3179,7 @@ static int init_input_threads(void)
     for (i = 0; i < nb_input_files; i++) {
         InputFile *f = input_files[i];
 
-        if (!(f->fifo = av_fifo_alloc(8*sizeof(AVPacket))))
+        if (!(f->fifo = av_fifo_alloc_array(8, sizeof(AVPacket))))
             return AVERROR(ENOMEM);
 
         if (f->ctx->pb ? !f->ctx->pb->seekable :
@@ -3175,7 +3232,7 @@ static int get_input_packet(InputFile *f, AVPacket *pkt)
         for (i = 0; i < f->nb_streams; i++) {
             InputStream *ist = input_streams[f->ist_index + i];
             int64_t pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
-            int64_t now = av_gettime() - ist->start;
+            int64_t now = av_gettime_relative() - ist->start;
             if (pts > now)
                 return AVERROR(EAGAIN);
         }
@@ -3541,7 +3598,7 @@ static int transcode(void)
         av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
     }
 
-    timer_start = av_gettime();
+    timer_start = av_gettime_relative();
 
 #if HAVE_PTHREADS
     if ((ret = init_input_threads()) < 0)
@@ -3549,7 +3606,7 @@ static int transcode(void)
 #endif
 
     while (!received_sigterm) {
-        int64_t cur_time= av_gettime();
+        int64_t cur_time= av_gettime_relative();
 
         /* if 'q' pressed, exits */
         if (stdin_interaction)
@@ -3596,7 +3653,7 @@ static int transcode(void)
     }
 
     /* dump report by using the first video and audio streams */
-    print_report(1, timer_start, av_gettime());
+    print_report(1, timer_start, av_gettime_relative());
 
     /* close each encoder */
     for (i = 0; i < nb_output_streams; i++) {
@@ -3638,7 +3695,7 @@ static int transcode(void)
                 av_freep(&ost->st->codec->subtitle_header);
                 av_freep(&ost->forced_kf_pts);
                 av_freep(&ost->apad);
-                av_dict_free(&ost->opts);
+                av_dict_free(&ost->encoder_opts);
                 av_dict_free(&ost->swr_opts);
                 av_dict_free(&ost->resample_opts);
             }