diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index eee56351f5..4bddbaa4aa 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -703,6 +703,11 @@ typedef struct RcOverride{ * encoders */ #define CODEC_CAP_EXPERIMENTAL 0x0200 +/** + * Codec should fill in channel configuration and samplerate instead of container + */ +#define CODEC_CAP_CHANNEL_CONF 0x0400 + //The following defines may change, don't expect compatibility if you use them. #define MB_TYPE_INTRA4x4 0x0001 diff --git a/libavcodec/dca.c b/libavcodec/dca.c index e8627a23d9..afd55bb075 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -1500,4 +1500,5 @@ AVCodec dca_decoder = { .decode = dca_decode_frame, .close = dca_decode_end, .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), + .capabilities = CODEC_CAP_CHANNEL_CONF, }; diff --git a/libavformat/utils.c b/libavformat/utils.c index 24dbd88feb..598551178c 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2167,6 +2167,7 @@ int av_find_stream_info(AVFormatContext *ic) } info[MAX_STREAMS] = {{0}}; for(i=0;inb_streams;i++) { + AVCodec *codec; st = ic->streams[i]; if (st->codec->codec_id == CODEC_ID_AAC) { st->codec->sample_rate = 0; @@ -2187,9 +2188,17 @@ int av_find_stream_info(AVFormatContext *ic) } } assert(!st->codec->codec); + codec = avcodec_find_decoder(st->codec->codec_id); + + /* Force decoding of at least one frame of codec data + * this makes sure the codec initializes the channel configuration + * and does not trust the values from the container. + */ + if (codec && codec->capabilities & CODEC_CAP_CHANNEL_CONF) + st->codec->channels = 0; + //try to just open decoders, in case this is enough to get parameters if(!has_codec_parameters(st->codec)){ - AVCodec *codec = avcodec_find_decoder(st->codec->codec_id); if (codec) avcodec_open(st->codec, codec); }