diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index c5e6b09cd4..8a6bb4061b 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -131,8 +131,7 @@ static int init(struct dec_audio *da, const char *decoder) // demux_mkv mp_lavc_set_extradata(lavc_context, c->extradata, c->extradata_size); - if (c->lav_headers) - mp_copy_lav_codec_headers(lavc_context, c->lav_headers); + mp_set_lav_codec_headers(lavc_context, c); mp_set_avcodec_threads(da->log, lavc_context, opts->threads); diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index 7298d9e7d7..eb2e2bb0a9 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -171,7 +171,11 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt) if (!stream) goto fail; +#if HAVE_AVCODEC_HAS_CODECPAR + stream->codecpar->codec_id = spdif_ctx->codec_id; +#else stream->codec->codec_id = spdif_ctx->codec_id; +#endif AVDictionary *format_opts = NULL; diff --git a/common/av_common.c b/common/av_common.c index 6efa1803fd..e40c751e9f 100644 --- a/common/av_common.c +++ b/common/av_common.c @@ -25,9 +25,12 @@ #include #include +#include "config.h" + #include "common/common.h" #include "common/msg.h" #include "demux/packet.h" +#include "demux/stheader.h" #include "av_common.h" #include "codecs.h" @@ -68,6 +71,19 @@ void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st) avctx->has_b_frames = st->has_b_frames; } +// This only copies ffmpeg-native codec parameters. Parameters produced by +// other demuxers must be handled manually. +void mp_set_lav_codec_headers(AVCodecContext *avctx, struct mp_codec_params *c) +{ +#if HAVE_AVCODEC_HAS_CODECPAR + if (c->lav_codecpar) + avcodec_parameters_to_context(avctx, c->lav_codecpar); +#else + if (c->lav_headers) + mp_copy_lav_codec_headers(avctx, c->lav_headers); +#endif +} + // We merely pass-through our PTS/DTS as an int64_t; libavcodec won't use it. union pts { int64_t i; double d; }; diff --git a/common/av_common.h b/common/av_common.h index 1478adf8fb..e2b86bfe40 100644 --- a/common/av_common.h +++ b/common/av_common.h @@ -26,11 +26,13 @@ struct mp_decoder_list; struct demux_packet; +struct mp_codec_params; struct AVDictionary; struct mp_log; int mp_lavc_set_extradata(AVCodecContext *avctx, void *ptr, int size); void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st); +void mp_set_lav_codec_headers(AVCodecContext *avctx, struct mp_codec_params *c); void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb); int64_t mp_pts_to_av(double mp_pts, AVRational *tb); double mp_pts_from_av(int64_t av_pts, AVRational *tb); diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 1c5d0fc05a..e4ad5881ca 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -550,8 +550,14 @@ static void handle_new_stream(demuxer_t *demuxer, int i) lavf_priv_t *priv = demuxer->priv; AVFormatContext *avfc = priv->avfc; AVStream *st = avfc->streams[i]; - AVCodecContext *codec = st->codec; struct sh_stream *sh = NULL; +#if HAVE_AVCODEC_HAS_CODECPAR + AVCodecParameters *codec = st->codecpar; + int lavc_delay = codec->initial_padding; +#else + AVCodecContext *codec = st->codec; + int lavc_delay = codec->delay; +#endif switch (codec->codec_type) { case AVMEDIA_TYPE_AUDIO: { @@ -566,7 +572,7 @@ static void handle_new_stream(demuxer_t *demuxer, int i) double delay = 0; if (codec->sample_rate > 0) - delay = codec->delay / (double)codec->sample_rate; + delay = lavc_delay / (double)codec->sample_rate; priv->seek_delay = MPMAX(priv->seek_delay, delay); export_replaygain(demuxer, sh->codec, st); @@ -647,9 +653,17 @@ static void handle_new_stream(demuxer_t *demuxer, int i) sh->ff_index = st->index; sh->codec->codec = mp_codec_from_av_codec_id(codec->codec_id); sh->codec->codec_tag = codec->codec_tag; +#if HAVE_AVCODEC_HAS_CODECPAR + sh->codec->lav_codecpar = avcodec_parameters_alloc(); + if (sh->codec->lav_codecpar) + avcodec_parameters_copy(sh->codec->lav_codecpar, codec); +#else + sh->codec->codec = mp_codec_from_av_codec_id(codec->codec_id); + sh->codec->codec_tag = codec->codec_tag; sh->codec->lav_headers = avcodec_alloc_context3(NULL); if (sh->codec->lav_headers) mp_copy_lav_codec_headers(sh->codec->lav_headers, codec); +#endif if (st->disposition & AV_DISPOSITION_DEFAULT) sh->default_track = true; diff --git a/demux/stheader.h b/demux/stheader.h index 35be20885a..77d0eb1da3 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -68,7 +68,9 @@ struct mp_codec_params { int extradata_size; // Codec specific header data (set by demux_lavf.c only) + // Which one is in use depends on HAVE_AVCODEC_HAS_CODECPAR. struct AVCodecContext *lav_headers; + struct AVCodecParameters *lav_codecpar; // STREAM_AUDIO int samplerate; diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 478c6d56da..677d406989 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -444,8 +444,7 @@ static void init_avctx(struct dec_video *vd, const char *decoder, mp_imgfmt_to_name(c->codec_tag)); } - if (c->lav_headers) - mp_copy_lav_codec_headers(avctx, c->lav_headers); + mp_set_lav_codec_headers(avctx, c); /* open it */ if (avcodec_open2(avctx, lavc_codec, NULL) < 0) diff --git a/wscript b/wscript index f98656a0fa..c1254f2372 100644 --- a/wscript +++ b/wscript @@ -486,10 +486,16 @@ FFmpeg/Libav libraries. You need at least {0}. Aborting.".format(libav_versions_ use='libav'), }, { 'name': 'avcodec-new-codec-api', - 'desc': 'new libavcodec decode/encode API', + 'desc': 'libavcodec decode/encode API', 'func': check_statement('libavcodec/avcodec.h', 'avcodec_send_packet(0,0)', use='libav'), + }, { + 'name': 'avcodec-has-codecpar', + 'desc': 'libavcodec AVCodecParameters API', + 'func': check_statement('libavcodec/avcodec.h', + 'AVCodecParameters *p = NULL', + use='libav'), }, ]