diff mbox

[FFmpeg-devel] ffmpeg: switch to codecpar

Message ID 20160920212048.19749-1-u@pkh.me
State Accepted
Headers show

Commit Message

Clément Bœsch Sept. 20, 2016, 9:20 p.m. UTC
From: Clément Bœsch <clement@stupeflix.com>

This commit is largely based on commit 15e84ed3 from Anton Khirnov
<anton@khirnov.net> which was previously skipped in bbf5ef9d.

There are still a bunch of things raising codecpar related warnings that
need fixing, such as:
- the use of codec->debug in the interactive debug mode
- read_ffserver_streams(): it's probably broken now but there is no test
- lowres stuff
- codec copy apparently required by bitstream filters

The matroska references are updated because they now properly forward
the field_order (previously unknown, now progressive).

Thanks to James Almer for fixing a bunch of FATE issues in this commit.

Signed-off-by: Clément Bœsch <clement@stupeflix.com>
Signed-off-by: James Almer <jamrial@gmail.com>
---
Changes since previous patch:
- restore the usage of avctx instead of ost->enc_ctx in the extradata stuff
  (which is going away in later commits)
- unconditionnally set pkt_timebase (as suggested by nevcairiel) with a new
  simpler comment
- restored the frame_size copy which i discarded by mistake
---
 cmdutils.c               |   4 +-
 ffmpeg.c                 | 234 +++++++++++++++++++++++++----------------------
 ffmpeg.h                 |   1 +
 ffmpeg_filter.c          |  24 ++---
 ffmpeg_opt.c             | 140 ++++++++++++++++------------
 libavformat/utils.c      |   2 +-
 tests/ref/fate/rgb24-mkv |   2 +-
 tests/ref/lavf/mkv       |   4 +-
 8 files changed, 226 insertions(+), 185 deletions(-)

Comments

Michael Niedermayer Sept. 21, 2016, 10:26 a.m. UTC | #1
On Tue, Sep 20, 2016 at 11:20:48PM +0200, Clément Bœsch wrote:
> From: Clément Bœsch <clement@stupeflix.com>
> 
> This commit is largely based on commit 15e84ed3 from Anton Khirnov
> <anton@khirnov.net> which was previously skipped in bbf5ef9d.
> 
> There are still a bunch of things raising codecpar related warnings that
> need fixing, such as:
> - the use of codec->debug in the interactive debug mode
> - read_ffserver_streams(): it's probably broken now but there is no test
> - lowres stuff
> - codec copy apparently required by bitstream filters
> 
> The matroska references are updated because they now properly forward
> the field_order (previously unknown, now progressive).
> 
> Thanks to James Almer for fixing a bunch of FATE issues in this commit.
> 
> Signed-off-by: Clément Bœsch <clement@stupeflix.com>
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> Changes since previous patch:
> - restore the usage of avctx instead of ost->enc_ctx in the extradata stuff
>   (which is going away in later commits)
> - unconditionnally set pkt_timebase (as suggested by nevcairiel) with a new
>   simpler comment
> - restored the frame_size copy which i discarded by mistake
> ---
>  cmdutils.c               |   4 +-
>  ffmpeg.c                 | 234 +++++++++++++++++++++++++----------------------
>  ffmpeg.h                 |   1 +
>  ffmpeg_filter.c          |  24 ++---
>  ffmpeg_opt.c             | 140 ++++++++++++++++------------

>  libavformat/utils.c      |   2 +-

This should go in a seperate patch possibly with a version bump
so ffmpeg.c can properly "depend" on that avformat version


[...]
> @@ -708,22 +709,30 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
>              exit_program(1);
>          }
>  
> -        ret = avcodec_copy_context(ist->dec_ctx, dec);
> +        ret = avcodec_parameters_to_context(ist->dec_ctx, par);
>          if (ret < 0) {
>              av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
>              exit_program(1);
>          }
>  
> -        switch (dec->codec_type) {
> +        switch (par->codec_type) {
>          case AVMEDIA_TYPE_VIDEO:
>              if(!ist->dec)
> -                ist->dec = avcodec_find_decoder(dec->codec_id);
> +                ist->dec = avcodec_find_decoder(par->codec_id);
>  #if FF_API_EMU_EDGE
> -            if (av_codec_get_lowres(dec)) {
> -                dec->flags |= CODEC_FLAG_EMU_EDGE;
> +            if (av_codec_get_lowres(st->codec)) {

> +                ist->dec_ctx->lowres = av_codec_get_lowres(st->codec);

av_codec_set_lowres()

[...]
Clément Bœsch Sept. 21, 2016, 10:45 a.m. UTC | #2
On Wed, Sep 21, 2016 at 12:26:48PM +0200, Michael Niedermayer wrote:
> On Tue, Sep 20, 2016 at 11:20:48PM +0200, Clément Bœsch wrote:
> > From: Clément Bœsch <clement@stupeflix.com>
> > 
> > This commit is largely based on commit 15e84ed3 from Anton Khirnov
> > <anton@khirnov.net> which was previously skipped in bbf5ef9d.
> > 
> > There are still a bunch of things raising codecpar related warnings that
> > need fixing, such as:
> > - the use of codec->debug in the interactive debug mode
> > - read_ffserver_streams(): it's probably broken now but there is no test
> > - lowres stuff
> > - codec copy apparently required by bitstream filters
> > 
> > The matroska references are updated because they now properly forward
> > the field_order (previously unknown, now progressive).
> > 
> > Thanks to James Almer for fixing a bunch of FATE issues in this commit.
> > 
> > Signed-off-by: Clément Bœsch <clement@stupeflix.com>
> > Signed-off-by: James Almer <jamrial@gmail.com>
> > ---
> > Changes since previous patch:
> > - restore the usage of avctx instead of ost->enc_ctx in the extradata stuff
> >   (which is going away in later commits)
> > - unconditionnally set pkt_timebase (as suggested by nevcairiel) with a new
> >   simpler comment
> > - restored the frame_size copy which i discarded by mistake
> > ---
> >  cmdutils.c               |   4 +-
> >  ffmpeg.c                 | 234 +++++++++++++++++++++++++----------------------
> >  ffmpeg.h                 |   1 +
> >  ffmpeg_filter.c          |  24 ++---
> >  ffmpeg_opt.c             | 140 ++++++++++++++++------------
> 
> >  libavformat/utils.c      |   2 +-
> 
> This should go in a seperate patch possibly with a version bump
> so ffmpeg.c can properly "depend" on that avformat version
> 

would it be OK to replace that condition with
(ost->codecpar->codec_tag == AV_RL32("tmcd") || enc_ctx->codec_tag == AV_RL32("tmcd"))
within that commit?
Michael Niedermayer Sept. 21, 2016, 12:20 p.m. UTC | #3
On Wed, Sep 21, 2016 at 12:45:40PM +0200, Clément Bœsch wrote:
> On Wed, Sep 21, 2016 at 12:26:48PM +0200, Michael Niedermayer wrote:
> > On Tue, Sep 20, 2016 at 11:20:48PM +0200, Clément Bœsch wrote:
> > > From: Clément Bœsch <clement@stupeflix.com>
> > > 
> > > This commit is largely based on commit 15e84ed3 from Anton Khirnov
> > > <anton@khirnov.net> which was previously skipped in bbf5ef9d.
> > > 
> > > There are still a bunch of things raising codecpar related warnings that
> > > need fixing, such as:
> > > - the use of codec->debug in the interactive debug mode
> > > - read_ffserver_streams(): it's probably broken now but there is no test
> > > - lowres stuff
> > > - codec copy apparently required by bitstream filters
> > > 
> > > The matroska references are updated because they now properly forward
> > > the field_order (previously unknown, now progressive).
> > > 
> > > Thanks to James Almer for fixing a bunch of FATE issues in this commit.
> > > 
> > > Signed-off-by: Clément Bœsch <clement@stupeflix.com>
> > > Signed-off-by: James Almer <jamrial@gmail.com>
> > > ---
> > > Changes since previous patch:
> > > - restore the usage of avctx instead of ost->enc_ctx in the extradata stuff
> > >   (which is going away in later commits)
> > > - unconditionnally set pkt_timebase (as suggested by nevcairiel) with a new
> > >   simpler comment
> > > - restored the frame_size copy which i discarded by mistake
> > > ---
> > >  cmdutils.c               |   4 +-
> > >  ffmpeg.c                 | 234 +++++++++++++++++++++++++----------------------
> > >  ffmpeg.h                 |   1 +
> > >  ffmpeg_filter.c          |  24 ++---
> > >  ffmpeg_opt.c             | 140 ++++++++++++++++------------
> > 
> > >  libavformat/utils.c      |   2 +-
> > 
> > This should go in a seperate patch possibly with a version bump
> > so ffmpeg.c can properly "depend" on that avformat version
> > 
> 
> would it be OK to replace that condition with
> (ost->codecpar->codec_tag == AV_RL32("tmcd") || enc_ctx->codec_tag == AV_RL32("tmcd"))
> within that commit?

ok

[...]
Clément Bœsch Sept. 21, 2016, 1:43 p.m. UTC | #4
On Wed, Sep 21, 2016 at 02:20:03PM +0200, Michael Niedermayer wrote:
> On Wed, Sep 21, 2016 at 12:45:40PM +0200, Clément Bœsch wrote:
> > On Wed, Sep 21, 2016 at 12:26:48PM +0200, Michael Niedermayer wrote:
> > > On Tue, Sep 20, 2016 at 11:20:48PM +0200, Clément Bœsch wrote:
> > > > From: Clément Bœsch <clement@stupeflix.com>
> > > > 
> > > > This commit is largely based on commit 15e84ed3 from Anton Khirnov
> > > > <anton@khirnov.net> which was previously skipped in bbf5ef9d.
> > > > 
> > > > There are still a bunch of things raising codecpar related warnings that
> > > > need fixing, such as:
> > > > - the use of codec->debug in the interactive debug mode
> > > > - read_ffserver_streams(): it's probably broken now but there is no test
> > > > - lowres stuff
> > > > - codec copy apparently required by bitstream filters
> > > > 
> > > > The matroska references are updated because they now properly forward
> > > > the field_order (previously unknown, now progressive).
> > > > 
> > > > Thanks to James Almer for fixing a bunch of FATE issues in this commit.
> > > > 
> > > > Signed-off-by: Clément Bœsch <clement@stupeflix.com>
> > > > Signed-off-by: James Almer <jamrial@gmail.com>
> > > > ---
> > > > Changes since previous patch:
> > > > - restore the usage of avctx instead of ost->enc_ctx in the extradata stuff
> > > >   (which is going away in later commits)
> > > > - unconditionnally set pkt_timebase (as suggested by nevcairiel) with a new
> > > >   simpler comment
> > > > - restored the frame_size copy which i discarded by mistake
> > > > ---
> > > >  cmdutils.c               |   4 +-
> > > >  ffmpeg.c                 | 234 +++++++++++++++++++++++++----------------------
> > > >  ffmpeg.h                 |   1 +
> > > >  ffmpeg_filter.c          |  24 ++---
> > > >  ffmpeg_opt.c             | 140 ++++++++++++++++------------
> > > 
> > > >  libavformat/utils.c      |   2 +-
> > > 
> > > This should go in a seperate patch possibly with a version bump
> > > so ffmpeg.c can properly "depend" on that avformat version
> > > 
> > 
> > would it be OK to replace that condition with
> > (ost->codecpar->codec_tag == AV_RL32("tmcd") || enc_ctx->codec_tag == AV_RL32("tmcd"))
> > within that commit?
> 
> ok
> 

Applied, thanks
diff mbox

Patch

diff --git a/cmdutils.c b/cmdutils.c
index 44f44cd..68deed9 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -1993,7 +1993,7 @@  AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
         codec            = s->oformat ? avcodec_find_encoder(codec_id)
                                       : avcodec_find_decoder(codec_id);
 
-    switch (st->codec->codec_type) {
+    switch (st->codecpar->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
         prefix  = 'v';
         flags  |= AV_OPT_FLAG_VIDEO_PARAM;
@@ -2051,7 +2051,7 @@  AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
         return NULL;
     }
     for (i = 0; i < s->nb_streams; i++)
-        opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id,
+        opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
                                     s, s->streams[i], NULL);
     return opts;
 }
diff --git a/ffmpeg.c b/ffmpeg.c
index 5d7d32a..5535b40 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -530,6 +530,7 @@  static void ffmpeg_cleanup(int ret)
         av_dict_free(&ost->sws_dict);
 
         avcodec_free_context(&ost->enc_ctx);
+        avcodec_parameters_free(&ost->ref_par);
 
         av_freep(&output_streams[i]);
     }
@@ -634,20 +635,13 @@  static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream,
 
 static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
 {
+    AVStream *st = ost->st;
     AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
     AVCodecContext          *avctx = ost->encoding_needed ? ost->enc_ctx : ost->st->codec;
     int ret;
 
-    if (!ost->st->codec->extradata_size && ost->enc_ctx->extradata_size) {
-        ost->st->codec->extradata = av_mallocz(ost->enc_ctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
-        if (ost->st->codec->extradata) {
-            memcpy(ost->st->codec->extradata, ost->enc_ctx->extradata, ost->enc_ctx->extradata_size);
-            ost->st->codec->extradata_size = ost->enc_ctx->extradata_size;
-        }
-    }
-
-    if ((avctx->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) ||
-        (avctx->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
+    if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) ||
+        (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
         pkt->pts = pkt->dts = AV_NOPTS_VALUE;
 
     /*
@@ -657,14 +651,14 @@  static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
      * Counting encoded video frames needs to be done separately because of
      * reordering, see do_video_out()
      */
-    if (!(avctx->codec_type == AVMEDIA_TYPE_VIDEO && avctx->codec)) {
+    if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed)) {
         if (ost->frame_number >= ost->max_frames) {
             av_packet_unref(pkt);
             return;
         }
         ost->frame_number++;
     }
-    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+    if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
         int i;
         uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
                                               NULL);
@@ -696,14 +690,14 @@  static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
     }
     if (pkt->size == 0 && pkt->side_data_elems == 0)
         return;
-    if (!ost->st->codecpar->extradata && avctx->extradata) {
-        ost->st->codecpar->extradata = av_malloc(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
-        if (!ost->st->codecpar->extradata) {
+    if (!st->codecpar->extradata_size && avctx->extradata_size) {
+        st->codecpar->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+        if (!st->codecpar->extradata) {
             av_log(NULL, AV_LOG_ERROR, "Could not allocate extradata buffer to copy parser data.\n");
             exit_program(1);
         }
-        ost->st->codecpar->extradata_size = avctx->extradata_size;
-        memcpy(ost->st->codecpar->extradata, avctx->extradata, avctx->extradata_size);
+        st->codecpar->extradata_size = avctx->extradata_size;
+        memcpy(st->codecpar->extradata, avctx->extradata, avctx->extradata_size);
     }
 
     if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
@@ -718,13 +712,13 @@  static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
                      - FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
                      - FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
         }
-        if ((avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) &&
+        if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
             pkt->dts != AV_NOPTS_VALUE &&
-            !(avctx->codec_id == AV_CODEC_ID_VP9 && ost->stream_copy) &&
+            !(st->codecpar->codec_id == AV_CODEC_ID_VP9 && ost->stream_copy) &&
             ost->last_mux_dts != AV_NOPTS_VALUE) {
             int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
             if (pkt->dts < max) {
-                int loglevel = max - pkt->dts > 2 || avctx->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
+                int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
                 av_log(s, loglevel, "Non-monotonous DTS in output stream "
                        "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
                        ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
@@ -932,7 +926,7 @@  static void do_video_out(AVFormatContext *s,
     int ret, format_video_sync;
     AVPacket pkt;
     AVCodecContext *enc = ost->enc_ctx;
-    AVCodecContext *mux_enc = ost->st->codec;
+    AVCodecParameters *mux_par = ost->st->codecpar;
     int nb_frames, nb0_frames, i;
     double delta, delta0;
     double duration = 0;
@@ -1093,9 +1087,9 @@  static void do_video_out(AVFormatContext *s,
            avoid any copies. We support temporarily the older
            method. */
         if (in_picture->interlaced_frame)
-            mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
+            mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
         else
-            mux_enc->field_order = AV_FIELD_PROGRESSIVE;
+            mux_par->field_order = AV_FIELD_PROGRESSIVE;
         pkt.data   = (uint8_t *)in_picture;
         pkt.size   =  sizeof(AVPicture);
         pkt.pts    = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base);
@@ -1114,11 +1108,11 @@  static void do_video_out(AVFormatContext *s,
 
         if (in_picture->interlaced_frame) {
             if (enc->codec->id == AV_CODEC_ID_MJPEG)
-                mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB;
+                mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB;
             else
-                mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
+                mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
         } else
-            mux_enc->field_order = AV_FIELD_PROGRESSIVE;
+            mux_par->field_order = AV_FIELD_PROGRESSIVE;
 
         in_picture->quality = enc->global_quality;
         in_picture->pict_type = 0;
@@ -1850,7 +1844,7 @@  static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
         opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
     opkt.dts -= ost_tb_start_time;
 
-    if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->dts != AV_NOPTS_VALUE) {
+    if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && pkt->dts != AV_NOPTS_VALUE) {
         int duration = av_get_audio_frame_duration(ist->dec_ctx, pkt->size);
         if(!duration)
             duration = ist->dec_ctx->frame_size;
@@ -1862,10 +1856,10 @@  static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
     opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
     opkt.flags    = pkt->flags;
     // FIXME remove the following 2 lines they shall be replaced by the bitstream filters
-    if (  ost->st->codec->codec_id != AV_CODEC_ID_H264
-       && ost->st->codec->codec_id != AV_CODEC_ID_MPEG1VIDEO
-       && ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
-       && ost->st->codec->codec_id != AV_CODEC_ID_VC1
+    if (  ost->st->codecpar->codec_id != AV_CODEC_ID_H264
+       && ost->st->codecpar->codec_id != AV_CODEC_ID_MPEG1VIDEO
+       && ost->st->codecpar->codec_id != AV_CODEC_ID_MPEG2VIDEO
+       && ost->st->codecpar->codec_id != AV_CODEC_ID_VC1
        ) {
         int ret = av_parser_change(ost->parser, ost->st->codec,
                              &opkt.data, &opkt.size,
@@ -1888,11 +1882,11 @@  static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
     av_copy_packet_side_data(&opkt, pkt);
 
 #if FF_API_LAVF_FMT_RAWPICTURE
-    if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-        ost->st->codec->codec_id == AV_CODEC_ID_RAWVIDEO &&
+    if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+        ost->st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO &&
         (of->ctx->oformat->flags & AVFMT_RAWPICTURE)) {
         /* store AVPicture in AVPacket, as expected by the output format */
-        int ret = avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height);
+        int ret = avpicture_fill(&pict, opkt.data, ost->st->codecpar->format, ost->st->codecpar->width, ost->st->codecpar->height);
         if (ret < 0) {
             av_log(NULL, AV_LOG_FATAL, "avpicture_fill failed: %s\n",
                    av_err2str(ret));
@@ -2089,17 +2083,17 @@  static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
 
     // The following line may be required in some cases where there is no parser
     // or the parser does not has_b_frames correctly
-    if (ist->st->codec->has_b_frames < ist->dec_ctx->has_b_frames) {
+    if (ist->st->codecpar->video_delay < ist->dec_ctx->has_b_frames) {
         if (ist->dec_ctx->codec_id == AV_CODEC_ID_H264) {
-            ist->st->codec->has_b_frames = ist->dec_ctx->has_b_frames;
+            ist->st->codecpar->video_delay = ist->dec_ctx->has_b_frames;
         } else
             av_log(ist->dec_ctx, AV_LOG_WARNING,
-                   "has_b_frames is larger in decoder than demuxer %d > %d.\n"
+                   "video_delay is larger in decoder than demuxer %d > %d.\n"
                    "If you want to help, upload a sample "
                    "of this file to ftp://upload.ffmpeg.org/incoming/ "
                    "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)",
                    ist->dec_ctx->has_b_frames,
-                   ist->st->codec->has_b_frames);
+                   ist->st->codecpar->video_delay);
     }
 
     check_decode_result(ist, got_output, ret);
@@ -2560,6 +2554,10 @@  static int init_input_stream(int ist_index, char *error, int error_len)
 
         av_dict_set(&ist->decoder_opts, "sub_text_format", "ass", AV_DICT_DONT_OVERWRITE);
 
+        /* Useful for subtitles retiming by lavf (FIXME), skipping samples in
+         * audio, and video decoders such as cuvid or mediacodec */
+        av_codec_set_pkt_timebase(ist->dec_ctx, ist->st->time_base);
+
         if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0))
             av_dict_set(&ist->decoder_opts, "threads", "auto", 0);
         if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) {
@@ -2644,12 +2642,20 @@  static int init_output_stream(OutputStream *ost, char *error, int error_len)
             av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
                                          " It takes bits/s as argument, not kbits/s\n");
 
-        ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx);
+        ret = avcodec_parameters_from_context(ost->st->codecpar, ost->enc_ctx);
         if (ret < 0) {
             av_log(NULL, AV_LOG_FATAL,
                    "Error initializing the output stream codec context.\n");
             exit_program(1);
         }
+        /*
+         * FIXME: this is only so that the bitstream filters and parsers (that still
+         * work with a codec context) get the parameter values.
+         * This should go away with the new BSF/parser API.
+         */
+        ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx);
+        if (ret < 0)
+            return ret;
 
         if (ost->enc_ctx->nb_coded_side_data) {
             int i;
@@ -2677,14 +2683,17 @@  static int init_output_stream(OutputStream *ost, char *error, int error_len)
         ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1});
         ost->st->codec->codec= ost->enc_ctx->codec;
     } else if (ost->stream_copy) {
-        ret = av_opt_set_dict(ost->st->codec, &ost->encoder_opts);
-        if (ret < 0) {
-           av_log(NULL, AV_LOG_FATAL,
-                  "Error setting up codec context options.\n");
-           return ret;
-        }
         // copy timebase while removing common factors
         ost->st->time_base = av_add_q(ost->st->codec->time_base, (AVRational){0, 1});
+
+        /*
+         * FIXME: this is only so that the bitstream filters and parsers (that still
+         * work with a codec context) get the parameter values.
+         * This should go away with the new BSF/parser API.
+         */
+        ret = avcodec_parameters_to_context(ost->st->codec, ost->st->codecpar);
+        if (ret < 0)
+            return ret;
     }
 
     return ret;
@@ -2762,7 +2771,7 @@  static void report_new_stream(int input_index, AVPacket *pkt)
         return;
     av_log(file->ctx, AV_LOG_WARNING,
            "New %s stream %d:%d at pos:%"PRId64" and DTS:%ss\n",
-           av_get_media_type_string(st->codec->codec_type),
+           av_get_media_type_string(st->codecpar->codec_type),
            input_index, pkt->stream_index,
            pkt->pos, av_ts2timestr(pkt->dts, &st->time_base));
     file->nb_streams_warn = pkt->stream_index + 1;
@@ -2843,8 +2852,6 @@  static int transcode_init(void)
 
     /* for each output stream, we compute the right encoding parameters */
     for (i = 0; i < nb_output_streams; i++) {
-        AVCodecContext *enc_ctx;
-        AVCodecContext *dec_ctx = NULL;
         ost = output_streams[i];
         oc  = output_files[ost->file_index]->ctx;
         ist = get_input_stream(ost);
@@ -2852,67 +2859,75 @@  static int transcode_init(void)
         if (ost->attachment_filename)
             continue;
 
-        enc_ctx = ost->stream_copy ? ost->st->codec : ost->enc_ctx;
-
         if (ist) {
-            dec_ctx = ist->dec_ctx;
-
             ost->st->disposition          = ist->st->disposition;
-            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 == enc_ctx->codec_type)
+                if (st != ost->st && st->codecpar->codec_type == ost->st->codecpar->codec_type)
                     break;
             }
             if (j == oc->nb_streams)
-                if (enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO || enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
+                if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ||
+                    ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
                     ost->st->disposition = AV_DISPOSITION_DEFAULT;
         }
 
         if (ost->stream_copy) {
+            AVCodecParameters *par_dst = ost->st->codecpar;
+            AVCodecParameters *par_src = ost->ref_par;
             AVRational sar;
             uint64_t extra_size;
 
             av_assert0(ist && !ost->filter);
 
-            extra_size = (uint64_t)dec_ctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE;
+            avcodec_parameters_to_context(ost->enc_ctx, ist->st->codecpar);
+            ret = av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts);
+            if (ret < 0) {
+                av_log(NULL, AV_LOG_FATAL,
+                       "Error setting up codec context options.\n");
+                return ret;
+            }
+            avcodec_parameters_from_context(par_src, ost->enc_ctx);
+
+            extra_size = (uint64_t)par_src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE;
 
             if (extra_size > INT_MAX) {
                 return AVERROR(EINVAL);
             }
 
             /* if stream_copy is selected, no need to decode or encode */
-            enc_ctx->codec_id   = dec_ctx->codec_id;
-            enc_ctx->codec_type = dec_ctx->codec_type;
+            par_dst->codec_id   = par_src->codec_id;
+            par_dst->codec_type = par_src->codec_type;
 
-            if (!enc_ctx->codec_tag) {
+            if (!par_dst->codec_tag) {
                 unsigned int codec_tag;
                 if (!oc->oformat->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;
+                     av_codec_get_id (oc->oformat->codec_tag, par_src->codec_tag) == par_dst->codec_id ||
+                     !av_codec_get_tag2(oc->oformat->codec_tag, par_src->codec_id, &codec_tag))
+                    par_dst->codec_tag = par_src->codec_tag;
             }
 
-            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;
-            if (dec_ctx->extradata_size) {
-                enc_ctx->extradata      = av_mallocz(extra_size);
-                if (!enc_ctx->extradata) {
+            par_dst->bit_rate        = par_src->bit_rate;
+            par_dst->field_order     = par_src->field_order;
+            par_dst->chroma_location = par_src->chroma_location;
+            if (par_src->extradata_size) {
+                par_dst->extradata      = av_mallocz(extra_size);
+                if (!par_dst->extradata) {
                     return AVERROR(ENOMEM);
                 }
-                memcpy(enc_ctx->extradata, dec_ctx->extradata, dec_ctx->extradata_size);
+                memcpy(par_dst->extradata, par_src->extradata, par_src->extradata_size);
             }
-            enc_ctx->extradata_size= dec_ctx->extradata_size;
-            enc_ctx->bits_per_coded_sample  = dec_ctx->bits_per_coded_sample;
-            enc_ctx->bits_per_raw_sample    = dec_ctx->bits_per_raw_sample;
+            par_dst->extradata_size= par_src->extradata_size;
+            par_dst->bits_per_coded_sample  = par_src->bits_per_coded_sample;
+            par_dst->bits_per_raw_sample    = par_src->bits_per_raw_sample;
 
             if (!ost->frame_rate.num)
                 ost->frame_rate = ist->framerate;
             ost->st->avg_frame_rate = ost->frame_rate;
 
+            ost->st->time_base = ist->st->time_base;
+
             ret = avformat_transfer_internal_stream_timing_info(oc->oformat, ost->st, ist->st, copy_tb);
             if (ret < 0)
                 return ret;
@@ -2941,59 +2956,55 @@  static int transcode_init(void)
                 }
             }
 
-            ost->parser = av_parser_init(enc_ctx->codec_id);
+            ost->parser = av_parser_init(par_dst->codec_id);
 
-            switch (enc_ctx->codec_type) {
+            switch (par_dst->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);
                 }
-                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->initial_padding    = dec_ctx->delay;
-                enc_ctx->trailing_padding   = dec_ctx->trailing_padding;
-                enc_ctx->profile            = dec_ctx->profile;
-#if FF_API_AUDIOENC_DELAY
-                enc_ctx->delay              = dec_ctx->delay;
-#endif
-                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;
+                par_dst->channel_layout     = par_src->channel_layout;
+                par_dst->sample_rate        = par_src->sample_rate;
+                par_dst->channels           = par_src->channels;
+                par_dst->frame_size         = par_src->frame_size;
+                par_dst->block_align        = par_src->block_align;
+                par_dst->initial_padding    = par_src->initial_padding;
+                par_dst->trailing_padding   = par_src->trailing_padding;
+                par_dst->profile            = par_src->profile;
+                if((par_dst->block_align == 1 || par_dst->block_align == 1152 || par_dst->block_align == 576) && par_dst->codec_id == AV_CODEC_ID_MP3)
+                    par_dst->block_align= 0;
+                if(par_dst->codec_id == AV_CODEC_ID_AC3)
+                    par_dst->block_align= 0;
                 break;
             case AVMEDIA_TYPE_VIDEO:
-                enc_ctx->pix_fmt            = dec_ctx->pix_fmt;
-                enc_ctx->colorspace         = dec_ctx->colorspace;
-                enc_ctx->color_range        = dec_ctx->color_range;
-                enc_ctx->color_primaries    = dec_ctx->color_primaries;
-                enc_ctx->color_trc          = dec_ctx->color_trc;
-                enc_ctx->width              = dec_ctx->width;
-                enc_ctx->height             = dec_ctx->height;
-                enc_ctx->has_b_frames       = dec_ctx->has_b_frames;
-                enc_ctx->profile            = dec_ctx->profile;
+                par_dst->format             = par_src->format;
+                par_dst->color_space        = par_src->color_space;
+                par_dst->color_range        = par_src->color_range;
+                par_dst->color_primaries    = par_src->color_primaries;
+                par_dst->color_trc          = par_src->color_trc;
+                par_dst->width              = par_src->width;
+                par_dst->height             = par_src->height;
+                par_dst->video_delay        = par_src->video_delay;
+                par_dst->profile            = par_src->profile;
                 if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
                     sar =
                         av_mul_q(ost->frame_aspect_ratio,
-                                 (AVRational){ enc_ctx->height, enc_ctx->width });
+                                 (AVRational){ par_dst->height, par_dst->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 = dec_ctx->sample_aspect_ratio;
-                ost->st->sample_aspect_ratio = enc_ctx->sample_aspect_ratio = sar;
+                    sar = par_src->sample_aspect_ratio;
+                ost->st->sample_aspect_ratio = par_dst->sample_aspect_ratio = sar;
                 ost->st->avg_frame_rate = ist->st->avg_frame_rate;
                 ost->st->r_frame_rate = ist->st->r_frame_rate;
                 break;
             case AVMEDIA_TYPE_SUBTITLE:
-                enc_ctx->width  = dec_ctx->width;
-                enc_ctx->height = dec_ctx->height;
+                par_dst->width  = par_src->width;
+                par_dst->height = par_src->height;
                 break;
             case AVMEDIA_TYPE_UNKNOWN:
             case AVMEDIA_TYPE_DATA:
@@ -3003,8 +3014,17 @@  static int transcode_init(void)
                 abort();
             }
         } else {
+            AVCodecContext *enc_ctx = ost->enc_ctx;
+            AVCodecContext *dec_ctx = NULL;
+
             set_encoder_id(output_files[ost->file_index], ost);
 
+            if (ist) {
+                dec_ctx = ist->dec_ctx;
+
+                enc_ctx->chroma_sample_location = dec_ctx->chroma_sample_location;
+            }
+
 #if CONFIG_LIBMFX
             if (qsv_transcode_init(ost))
                 exit_program(1);
@@ -3136,8 +3156,8 @@  static int transcode_init(void)
             case AVMEDIA_TYPE_SUBTITLE:
                 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;
+                    enc_ctx->width     = input_streams[ost->source_index]->st->codecpar->width;
+                    enc_ctx->height    = input_streams[ost->source_index]->st->codecpar->height;
                 }
                 break;
             case AVMEDIA_TYPE_DATA:
diff --git a/ffmpeg.h b/ffmpeg.h
index 49d65d8..5caf584 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -418,6 +418,7 @@  typedef struct OutputStream {
     int64_t last_mux_dts;
     AVBitStreamFilterContext *bitstream_filters;
     AVCodecContext *enc_ctx;
+    AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */
     AVCodec *enc;
     int64_t max_frames;
     AVFrame *filtered_frame;
diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c
index 76030cf..27aeca0 100644
--- a/ffmpeg_filter.c
+++ b/ffmpeg_filter.c
@@ -94,19 +94,19 @@  void choose_sample_fmt(AVStream *st, AVCodec *codec)
     if (codec && codec->sample_fmts) {
         const enum AVSampleFormat *p = codec->sample_fmts;
         for (; *p != -1; p++) {
-            if (*p == st->codec->sample_fmt)
+            if (*p == st->codecpar->format)
                 break;
         }
         if (*p == -1) {
-            if((codec->capabilities & AV_CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0]))
+            if((codec->capabilities & AV_CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codecpar->format) > av_get_sample_fmt_name(codec->sample_fmts[0]))
                 av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
-            if(av_get_sample_fmt_name(st->codec->sample_fmt))
+            if(av_get_sample_fmt_name(st->codecpar->format))
             av_log(NULL, AV_LOG_WARNING,
                    "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
-                   av_get_sample_fmt_name(st->codec->sample_fmt),
+                   av_get_sample_fmt_name(st->codecpar->format),
                    codec->name,
                    av_get_sample_fmt_name(codec->sample_fmts[0]));
-            st->codec->sample_fmt = codec->sample_fmts[0];
+            st->codecpar->format = codec->sample_fmts[0];
         }
     }
 }
@@ -251,7 +251,7 @@  static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
         s = input_files[file_idx]->ctx;
 
         for (i = 0; i < s->nb_streams; i++) {
-            enum AVMediaType stream_type = s->streams[i]->codec->codec_type;
+            enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type;
             if (stream_type != type &&
                 !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
                   type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
@@ -611,7 +611,7 @@  static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
         int i;
 
         for (i=0; i<of->ctx->nb_streams; i++)
-            if (of->ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+            if (of->ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
                 break;
 
         if (i<of->ctx->nb_streams) {
@@ -673,15 +673,15 @@  static int sub2video_prepare(InputStream *ist)
     int i, w, h;
 
     /* Compute the size of the canvas for the subtitles stream.
-       If the subtitles codec has set a size, use it. Otherwise use the
+       If the subtitles codecpar has set a size, use it. Otherwise use the
        maximum dimensions of the video streams in the same file. */
     w = ist->dec_ctx->width;
     h = ist->dec_ctx->height;
     if (!(w && h)) {
         for (i = 0; i < avf->nb_streams; i++) {
-            if (avf->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-                w = FFMAX(w, avf->streams[i]->codec->width);
-                h = FFMAX(h, avf->streams[i]->codec->height);
+            if (avf->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+                w = FFMAX(w, avf->streams[i]->codecpar->width);
+                h = FFMAX(h, avf->streams[i]->codecpar->height);
             }
         }
         if (!(w && h)) {
@@ -1081,7 +1081,7 @@  int configure_filtergraph(FilterGraph *fg)
             /* identical to the same check in ffmpeg.c, needed because
                complex filter graphs are initialized earlier */
             av_log(NULL, AV_LOG_ERROR, "Encoder (codec %s) not found for output stream #%d:%d\n",
-                     avcodec_get_name(ost->st->codec->codec_id), ost->file_index, ost->index);
+                     avcodec_get_name(ost->st->codecpar->codec_id), ost->file_index, ost->index);
             return AVERROR(EINVAL);
         }
         if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 0c0d3a6..81e3979 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -429,12 +429,12 @@  static int opt_map_channel(void *optctx, const char *opt, const char *arg)
         exit_program(1);
     }
     st = input_files[m->file_idx]->ctx->streams[m->stream_idx];
-    if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+    if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
         av_log(NULL, AV_LOG_FATAL, "mapchan: stream #%d.%d is not an audio stream.\n",
                m->file_idx, m->stream_idx);
         exit_program(1);
     }
-    if (m->channel_idx < 0 || m->channel_idx >= st->codec->channels) {
+    if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->channels) {
         av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n",
                m->file_idx, m->stream_idx, m->channel_idx);
         exit_program(1);
@@ -634,11 +634,11 @@  static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *
 
     MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
     if (codec_name) {
-        AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
-        st->codec->codec_id = codec->id;
+        AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0);
+        st->codecpar->codec_id = codec->id;
         return codec;
     } else
-        return avcodec_find_decoder(st->codec->codec_id);
+        return avcodec_find_decoder(st->codecpar->codec_id);
 }
 
 /* Add all the streams from the given input file to the global
@@ -649,14 +649,15 @@  static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
 
     for (i = 0; i < ic->nb_streams; i++) {
         AVStream *st = ic->streams[i];
-        AVCodecContext *dec = st->codec;
+        AVCodecParameters *par = st->codecpar;
         InputStream *ist = av_mallocz(sizeof(*ist));
         char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
         char *hwaccel_output_format = NULL;
         char *codec_tag = NULL;
         char *next;
         char *discard_str = NULL;
-        const AVOption *discard_opt = av_opt_find(dec, "skip_frame", NULL, 0, 0);
+        const AVClass *cc = avcodec_get_class();
+        const AVOption *discard_opt = av_opt_find(&cc, "skip_frame", NULL, 0, 0);
 
         if (!ist)
             exit_program(1);
@@ -683,18 +684,18 @@  static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
             uint32_t tag = strtol(codec_tag, &next, 0);
             if (*next)
                 tag = AV_RL32(codec_tag);
-            st->codec->codec_tag = tag;
+            st->codecpar->codec_tag = tag;
         }
 
         ist->dec = choose_decoder(o, ic, st);
-        ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec);
+        ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, ic, st, ist->dec);
 
         ist->reinit_filters = -1;
         MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st);
 
         MATCH_PER_STREAM_OPT(discard, str, discard_str, ic, st);
         ist->user_set_discard = AVDISCARD_NONE;
-        if (discard_str && av_opt_eval_int(dec, discard_opt, discard_str, &ist->user_set_discard) < 0) {
+        if (discard_str && av_opt_eval_int(&cc, discard_opt, discard_str, &ist->user_set_discard) < 0) {
             av_log(NULL, AV_LOG_ERROR, "Error parsing discard %s.\n",
                     discard_str);
             exit_program(1);
@@ -708,22 +709,30 @@  static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
             exit_program(1);
         }
 
-        ret = avcodec_copy_context(ist->dec_ctx, dec);
+        ret = avcodec_parameters_to_context(ist->dec_ctx, par);
         if (ret < 0) {
             av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
             exit_program(1);
         }
 
-        switch (dec->codec_type) {
+        switch (par->codec_type) {
         case AVMEDIA_TYPE_VIDEO:
             if(!ist->dec)
-                ist->dec = avcodec_find_decoder(dec->codec_id);
+                ist->dec = avcodec_find_decoder(par->codec_id);
 #if FF_API_EMU_EDGE
-            if (av_codec_get_lowres(dec)) {
-                dec->flags |= CODEC_FLAG_EMU_EDGE;
+            if (av_codec_get_lowres(st->codec)) {
+                ist->dec_ctx->lowres = av_codec_get_lowres(st->codec);
+                ist->dec_ctx->width  = st->codec->width;
+                ist->dec_ctx->height = st->codec->height;
+                ist->dec_ctx->coded_width  = st->codec->coded_width;
+                ist->dec_ctx->coded_height = st->codec->coded_height;
+                ist->dec_ctx->flags |= CODEC_FLAG_EMU_EDGE;
             }
 #endif
 
+            // avformat_find_stream_info() doesn't set this for us anymore.
+            ist->dec_ctx->framerate = st->avg_frame_rate;
+
             ist->resample_height  = ist->dec_ctx->height;
             ist->resample_width   = ist->dec_ctx->width;
             ist->resample_pix_fmt = ist->dec_ctx->pix_fmt;
@@ -803,7 +812,7 @@  static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
         case AVMEDIA_TYPE_SUBTITLE: {
             char *canvas_size = NULL;
             if(!ist->dec)
-                ist->dec = avcodec_find_decoder(dec->codec_id);
+                ist->dec = avcodec_find_decoder(par->codec_id);
             MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
             MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st);
             if (canvas_size &&
@@ -819,6 +828,12 @@  static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
         default:
             abort();
         }
+
+        ret = avcodec_parameters_from_context(par, ist->dec_ctx);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
+            exit_program(1);
+        }
     }
 }
 
@@ -857,7 +872,7 @@  static void dump_attachment(AVStream *st, const char *filename)
     AVIOContext *out = NULL;
     AVDictionaryEntry *e;
 
-    if (!st->codec->extradata_size) {
+    if (!st->codecpar->extradata_size) {
         av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
                nb_input_files - 1, st->index);
         return;
@@ -878,7 +893,7 @@  static void dump_attachment(AVStream *st, const char *filename)
         exit_program(1);
     }
 
-    avio_write(out, st->codec->extradata, st->codec->extradata_size);
+    avio_write(out, st->codecpar->extradata, st->codecpar->extradata_size);
     avio_flush(out);
     avio_close(out);
 }
@@ -1028,8 +1043,8 @@  static int open_input_file(OptionsContext *o, const char *filename)
         if (!(ic->iformat->flags & AVFMT_SEEK_TO_PTS)) {
             int dts_heuristic = 0;
             for (i=0; i<ic->nb_streams; i++) {
-                AVCodecContext *avctx = ic->streams[i]->codec;
-                if (avctx->has_b_frames)
+                const AVCodecParameters *par = ic->streams[i]->codecpar;
+                if (par->video_delay)
                     dts_heuristic = 1;
             }
             if (dts_heuristic) {
@@ -1176,28 +1191,28 @@  static int get_preset_file_2(const char *preset_name, const char *codec_name, AV
 
 static int choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
 {
-    enum AVMediaType type = ost->st->codec->codec_type;
+    enum AVMediaType type = ost->st->codecpar->codec_type;
     char *codec_name = NULL;
 
     if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) {
         MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
         if (!codec_name) {
-            ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
-                                                      NULL, ost->st->codec->codec_type);
-            ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
+            ost->st->codecpar->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
+                                                         NULL, ost->st->codecpar->codec_type);
+            ost->enc = avcodec_find_encoder(ost->st->codecpar->codec_id);
             if (!ost->enc) {
                 av_log(NULL, AV_LOG_FATAL, "Automatic encoder selection failed for "
                        "output stream #%d:%d. Default encoder for format %s (codec %s) is "
                        "probably disabled. Please choose an encoder manually.\n",
                        ost->file_index, ost->index, s->oformat->name,
-                       avcodec_get_name(ost->st->codec->codec_id));
+                       avcodec_get_name(ost->st->codecpar->codec_id));
                 return AVERROR_ENCODER_NOT_FOUND;
             }
         } else if (!strcmp(codec_name, "copy"))
             ost->stream_copy = 1;
         else {
-            ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
-            ost->st->codec->codec_id = ost->enc->id;
+            ost->enc = find_codec_or_die(codec_name, ost->st->codecpar->codec_type, 1);
+            ost->st->codecpar->codec_id = ost->enc->id;
         }
         ost->encoding_needed = !ost->stream_copy;
     } else {
@@ -1235,7 +1250,7 @@  static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
     ost->file_index = nb_output_files - 1;
     ost->index      = idx;
     ost->st         = st;
-    st->codec->codec_type = type;
+    st->codecpar->codec_type = type;
 
     ret = choose_encoder(o, oc, ost);
     if (ret < 0) {
@@ -1251,6 +1266,12 @@  static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
     }
     ost->enc_ctx->codec_type = type;
 
+    ost->ref_par = avcodec_parameters_alloc();
+    if (!ost->ref_par) {
+        av_log(NULL, AV_LOG_ERROR, "Error allocating the encoding parameters.\n");
+        exit_program(1);
+    }
+
     if (ost->enc) {
         AVIOContext *s = NULL;
         char *buf = NULL, *arg = NULL, *preset = NULL;
@@ -1328,7 +1349,7 @@  static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
         uint32_t tag = strtol(codec_tag, &next, 0);
         if (*next)
             tag = AV_RL32(codec_tag);
-        ost->st->codec->codec_tag =
+        ost->st->codecpar->codec_tag =
         ost->enc_ctx->codec_tag = tag;
     }
 
@@ -1425,7 +1446,7 @@  static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
     else if (ost->filters)
         return av_strdup(ost->filters);
 
-    return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
+    return av_strdup(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ?
                      "null" : "anull");
 }
 
@@ -1857,9 +1878,9 @@  static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
         AVCodec *codec;
         const char *enc_config;
 
-        codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
+        codec = avcodec_find_encoder(ic->streams[i]->codecpar->codec_id);
         if (!codec) {
-            av_log(s, AV_LOG_ERROR, "no encoder found for codec id %i\n", ic->streams[i]->codec->codec_id);
+            av_log(s, AV_LOG_ERROR, "no encoder found for codec id %i\n", ic->streams[i]->codecpar->codec_id);
             return AVERROR(EINVAL);
         }
         if (codec->type == AVMEDIA_TYPE_AUDIO)
@@ -1878,10 +1899,10 @@  static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
             av_dict_free(&opts);
         }
 
-        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
+        if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
             choose_sample_fmt(st, codec);
-        else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
-            choose_pixel_fmt(st, st->codec, codec, st->codec->pix_fmt);
+        else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
+            choose_pixel_fmt(st, st->codec, codec, st->codecpar->format);
         avcodec_copy_context(ost->enc_ctx, st->codec);
         if (enc_config)
             av_dict_parse_string(&ost->encoder_opts, enc_config, "=", ",", 0);
@@ -2053,18 +2074,18 @@  static int open_output_file(OptionsContext *o, const char *filename)
             ost = output_streams[j];
             for (i = 0; i < nb_input_streams; i++) {
                 ist = input_streams[i];
-                if(ist->st->codec->codec_type == ost->st->codec->codec_type){
+                if(ist->st->codecpar->codec_type == ost->st->codecpar->codec_type){
                     ost->sync_ist= ist;
                     ost->source_index= i;
-                    if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) ost->avfilter = av_strdup("anull");
-                    if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ost->avfilter = av_strdup("null");
+                    if(ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ost->avfilter = av_strdup("anull");
+                    if(ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ost->avfilter = av_strdup("null");
                     ist->discard = 0;
                     ist->st->discard = ist->user_set_discard;
                     break;
                 }
             }
             if(!ost->sync_ist){
-                av_log(NULL, AV_LOG_FATAL, "Missing %s stream which is required by this ffm\n", av_get_media_type_string(ost->st->codec->codec_type));
+                av_log(NULL, AV_LOG_FATAL, "Missing %s stream which is required by this ffm\n", av_get_media_type_string(ost->st->codecpar->codec_type));
                 exit_program(1);
             }
         }
@@ -2079,10 +2100,10 @@  static int open_output_file(OptionsContext *o, const char *filename)
             for (i = 0; i < nb_input_streams; i++) {
                 int new_area;
                 ist = input_streams[i];
-                new_area = ist->st->codec->width * ist->st->codec->height + 100000000*!!ist->st->codec_info_nb_frames;
+                new_area = ist->st->codecpar->width * ist->st->codecpar->height + 100000000*!!ist->st->codec_info_nb_frames;
                 if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
                     new_area = 1;
-                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+                if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
                     new_area > area) {
                     if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
                         continue;
@@ -2100,8 +2121,8 @@  static int open_output_file(OptionsContext *o, const char *filename)
             for (i = 0; i < nb_input_streams; i++) {
                 int score;
                 ist = input_streams[i];
-                score = ist->st->codec->channels + 100000000*!!ist->st->codec_info_nb_frames;
-                if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                score = ist->st->codecpar->channels + 100000000*!!ist->st->codec_info_nb_frames;
+                if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
                     score > best_score) {
                     best_score = score;
                     idx = i;
@@ -2115,9 +2136,9 @@  static int open_output_file(OptionsContext *o, const char *filename)
         MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
         if (!o->subtitle_disable && (avcodec_find_encoder(oc->oformat->subtitle_codec) || subtitle_codec_name)) {
             for (i = 0; i < nb_input_streams; i++)
-                if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+                if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
                     AVCodecDescriptor const *input_descriptor =
-                        avcodec_descriptor_get(input_streams[i]->st->codec->codec_id);
+                        avcodec_descriptor_get(input_streams[i]->st->codecpar->codec_id);
                     AVCodecDescriptor const *output_descriptor = NULL;
                     AVCodec const *output_codec =
                         avcodec_find_encoder(oc->oformat->subtitle_codec);
@@ -2143,8 +2164,8 @@  static int open_output_file(OptionsContext *o, const char *filename)
         if (!o->data_disable ) {
             enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_DATA);
             for (i = 0; codec_id != AV_CODEC_ID_NONE && i < nb_input_streams; i++) {
-                if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_DATA
-                    && input_streams[i]->st->codec->codec_id == codec_id )
+                if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_DATA
+                    && input_streams[i]->st->codecpar->codec_id == codec_id )
                     new_data_stream(o, oc, i);
             }
         }
@@ -2181,17 +2202,17 @@  loop_end:
                 int src_idx = input_files[map->file_index]->ist_index + map->stream_index;
 
                 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
-                if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
+                if(o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
                     continue;
-                if(o->   audio_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+                if(o->   audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
                     continue;
-                if(o->   video_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+                if(o->   video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
                     continue;
-                if(o->    data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)
+                if(o->    data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
                     continue;
 
                 ost = NULL;
-                switch (ist->st->codec->codec_type) {
+                switch (ist->st->codecpar->codec_type) {
                 case AVMEDIA_TYPE_VIDEO:      ost = new_video_stream     (o, oc, src_idx); break;
                 case AVMEDIA_TYPE_AUDIO:      ost = new_audio_stream     (o, oc, src_idx); break;
                 case AVMEDIA_TYPE_SUBTITLE:   ost = new_subtitle_stream  (o, oc, src_idx); break;
@@ -2247,8 +2268,8 @@  loop_end:
 
         ost = new_attachment_stream(o, oc, -1);
         ost->attachment_filename       = o->attachments[i];
-        ost->st->codec->extradata      = attachment;
-        ost->st->codec->extradata_size = len;
+        ost->st->codecpar->extradata      = attachment;
+        ost->st->codecpar->extradata_size = len;
 
         p = strrchr(o->attachments[i], '/');
         av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
@@ -2322,8 +2343,8 @@  loop_end:
             InputStream *ist = input_streams[ost->source_index];
             ist->decoding_needed |= DECODING_FOR_OST;
 
-            if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
-                ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
+                ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
                 err = init_simple_filtergraph(ist, ost);
                 if (err < 0) {
                     av_log(NULL, AV_LOG_ERROR,
@@ -2570,11 +2591,10 @@  static int opt_target(void *optctx, const char *opt, const char *arg)
             int i, j, fr;
             for (j = 0; j < nb_input_files; j++) {
                 for (i = 0; i < input_files[j]->nb_streams; i++) {
-                    AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
-                    if (c->codec_type != AVMEDIA_TYPE_VIDEO ||
-                        !c->time_base.num)
+                    AVStream *st = input_files[j]->ctx->streams[i];
+                    if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
                         continue;
-                    fr = c->time_base.den * 1000 / c->time_base.num;
+                    fr = st->time_base.den * 1000 / st->time_base.num;
                     if (fr == 25000) {
                         norm = PAL;
                         break;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index f043bae..b439273 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -5339,7 +5339,7 @@  int avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt,
         }
     }
 
-    if (enc_ctx->codec_tag == AV_RL32("tmcd")
+    if (ost->codecpar->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) {
diff --git a/tests/ref/fate/rgb24-mkv b/tests/ref/fate/rgb24-mkv
index 8f4b03d..69584f5 100644
--- a/tests/ref/fate/rgb24-mkv
+++ b/tests/ref/fate/rgb24-mkv
@@ -1,4 +1,4 @@ 
-4765774ab65412c9b7565b1b4da82998 *tests/data/fate/rgb24-mkv.matroska
+0d081c8e151a922435830f95000d3c71 *tests/data/fate/rgb24-mkv.matroska
 58321 tests/data/fate/rgb24-mkv.matroska
 #tb 0: 1/10
 #media_type 0: video
diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv
index 72fc291..5b0d386 100644
--- a/tests/ref/lavf/mkv
+++ b/tests/ref/lavf/mkv
@@ -1,6 +1,6 @@ 
-c081514c38735524ab09dbd2a498b7b3 *./tests/data/lavf/lavf.mkv
+5b982c8dfbadc71f51b206cbd10b9a71 *./tests/data/lavf/lavf.mkv
 472875 ./tests/data/lavf/lavf.mkv
 ./tests/data/lavf/lavf.mkv CRC=0xec6c3c68
-d1fc3a31150d00aebbd674862640f701 *./tests/data/lavf/lavf.mkv
+b4a295bae8e6cf536563cb840386f3a4 *./tests/data/lavf/lavf.mkv
 320551 ./tests/data/lavf/lavf.mkv
 ./tests/data/lavf/lavf.mkv CRC=0xec6c3c68