From bb6941af2afd057c3897afb78d034de2c355b8a0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 13:40:10 -0400 Subject: [PATCH 01/17] lavc: move SANE_NB_CHANNELS to internal.h and use it in the PCM decoders --- libavcodec/internal.h | 2 ++ libavcodec/pcm.c | 6 ++---- libavcodec/utils.c | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libavcodec/internal.h b/libavcodec/internal.h index e5b1958596..231d4b6809 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -30,6 +30,8 @@ #include "libavutil/pixfmt.h" #include "avcodec.h" +#define FF_SANE_NB_CHANNELS 128U + typedef struct InternalBuffer { uint8_t *base[AV_NUM_DATA_POINTERS]; uint8_t *data[AV_NUM_DATA_POINTERS]; diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 1f8f22d172..832cb43851 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -31,8 +31,6 @@ #include "mathops.h" #include "pcm_tablegen.h" -#define MAX_CHANNELS 64 - static av_cold int pcm_encode_init(AVCodecContext *avctx) { avctx->frame_size = 0; @@ -210,7 +208,7 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx) PCMDecode *s = avctx->priv_data; int i; - if (avctx->channels <= 0 || avctx->channels > MAX_CHANNELS) { + if (avctx->channels <= 0) { av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n"); return AVERROR(EINVAL); } @@ -340,7 +338,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, break; case AV_CODEC_ID_PCM_S16LE_PLANAR: { - const uint8_t *src2[MAX_CHANNELS]; + const uint8_t *src2[FF_SANE_NB_CHANNELS]; n /= avctx->channels; for (c = 0; c < avctx->channels; c++) src2[c] = &src[c * n * 2]; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 8daacbe8cf..b4e7ed6b6b 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -758,8 +758,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code if (av_codec_is_decoder(codec)) av_freep(&avctx->subtitle_header); -#define SANE_NB_CHANNELS 128U - if (avctx->channels > SANE_NB_CHANNELS) { + if (avctx->channels > FF_SANE_NB_CHANNELS) { ret = AVERROR(EINVAL); goto free_and_end; } From 0366664ef9af85ee052925f9a1a853d14d2f47a7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 00:56:00 -0400 Subject: [PATCH 02/17] lavc: check channel count after decoder init Ensures the decoder did not set channel count to an insanely high value during initialization, which could cause large memory usage when it tries to get a buffer during decoding. --- libavcodec/utils.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index b4e7ed6b6b..58dfe971e1 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -881,6 +881,11 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code avctx->channel_layout = 0; } } + if (avctx->channels && avctx->channels < 0 || + avctx->channels > FF_SANE_NB_CHANNELS) { + ret = AVERROR(EINVAL); + goto free_and_end; + } } end: entangled_thread_counter--; From a4202003b21ee88c82eec909a0ad086b4c328903 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 7 Oct 2012 20:52:35 -0400 Subject: [PATCH 03/17] dca_parser: allow the parser to change the sample rate --- libavcodec/dca_parser.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/dca_parser.c b/libavcodec/dca_parser.c index 7e65d0ba84..ab235cf480 100644 --- a/libavcodec/dca_parser.c +++ b/libavcodec/dca_parser.c @@ -192,8 +192,7 @@ static int dca_parse(AVCodecParserContext * s, /* read the duration and sample rate from the frame header */ if (!dca_parse_params(buf, buf_size, &duration, &sample_rate)) { s->duration = duration; - if (!avctx->sample_rate) - avctx->sample_rate = sample_rate; + avctx->sample_rate = sample_rate; } else s->duration = 0; From b24a4449a5ae84fc73e12c47e35d19c06a8bfdf3 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 7 Oct 2012 21:17:45 -0400 Subject: [PATCH 04/17] amrnbdec: set channels, channel_layout, and sample_rate Only mono 8kHz is supported. --- libavcodec/amrnbdec.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index 2cb06a6ead..21966456a0 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -43,6 +43,7 @@ #include #include +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "dsputil.h" #include "libavutil/common.h" @@ -154,7 +155,15 @@ static av_cold int amrnb_decode_init(AVCodecContext *avctx) AMRContext *p = avctx->priv_data; int i; - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + if (avctx->channels > 1) { + av_log_missing_feature(avctx, "multi-channel AMR", 0); + return AVERROR_PATCHWELCOME; + } + + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_rate = 8000; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; // p->excitation always points to the same position in p->excitation_buf p->excitation = &p->excitation_buf[PITCH_DELAY_MAX + LP_FILTER_ORDER + 1]; From ee0e9678e761e8a41cfffcb163de42967e5a1758 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 7 Oct 2012 21:19:28 -0400 Subject: [PATCH 05/17] amrwbdec: set channels, channel_layout, and sample_rate Only mono 16kHz is supported. --- libavcodec/amrwbdec.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index c9c793fb4a..9b0fe255b4 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -24,6 +24,7 @@ * AMR wideband decoder */ +#include "libavutil/audioconvert.h" #include "libavutil/common.h" #include "libavutil/lfg.h" @@ -90,7 +91,15 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx) AMRWBContext *ctx = avctx->priv_data; int i; - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + if (avctx->channels > 1) { + av_log_missing_feature(avctx, "multi-channel AMR", 0); + return AVERROR_PATCHWELCOME; + } + + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_rate = 16000; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; av_lfg_init(&ctx->prng, 1); From ec2694d25905c217e5815947cda896aa25398388 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 15 Oct 2012 16:40:44 -0400 Subject: [PATCH 06/17] g722dec: set channel layout at initialization instead of validating it --- libavcodec/g722dec.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c index ea06ce0913..3364850b18 100644 --- a/libavcodec/g722dec.c +++ b/libavcodec/g722dec.c @@ -34,6 +34,7 @@ * respectively of each byte are ignored. */ +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "get_bits.h" #include "g722.h" @@ -57,11 +58,9 @@ static av_cold int g722_decode_init(AVCodecContext * avctx) { G722Context *c = avctx->priv_data; - if (avctx->channels != 1) { - av_log(avctx, AV_LOG_ERROR, "Only mono tracks are allowed.\n"); - return AVERROR_INVALIDDATA; - } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; c->band[0].scale_factor = 8; c->band[1].scale_factor = 2; From 4f56f9c48f40db7f84819fc923b79ddaac678ae7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 17 Oct 2012 11:29:04 -0400 Subject: [PATCH 07/17] dsicinaudio: set channels and channel layout --- libavcodec/dsicinav.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 1492717f66..2dcbf745ea 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -24,6 +24,7 @@ * Delphine Software International CIN audio/video decoders */ +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "bytestream.h" #include "mathops.h" @@ -319,14 +320,11 @@ static av_cold int cinaudio_decode_init(AVCodecContext *avctx) { CinAudioContext *cin = avctx->priv_data; - if (avctx->channels != 1) { - av_log_ask_for_sample(avctx, "Number of channels is not supported\n"); - return AVERROR_PATCHWELCOME; - } - cin->initial_decode_frame = 1; - cin->delta = 0; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + cin->delta = 0; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; avcodec_get_frame_defaults(&cin->frame); avctx->coded_frame = &cin->frame; From a38eadf7ed08293667c9f81780f7c081f278f19a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 17 Oct 2012 11:45:49 -0400 Subject: [PATCH 08/17] atrac1: do not keep a copy of channel count in the private context --- libavcodec/atrac1.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 7e78c7321c..b746a54e3b 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -80,7 +80,6 @@ typedef struct { DECLARE_ALIGNED(32, float, high)[512]; float* bands[3]; FFTContext mdct_ctx[3]; - int channels; DSPContext dsp; } AT1Ctx; @@ -280,7 +279,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, GetBitContext gb; - if (buf_size < 212 * q->channels) { + if (buf_size < 212 * avctx->channels) { av_log(avctx, AV_LOG_ERROR, "Not enough data to decode!\n"); return AVERROR_INVALIDDATA; } @@ -292,7 +291,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, return ret; } - for (ch = 0; ch < q->channels; ch++) { + for (ch = 0; ch < avctx->channels; ch++) { AT1SUCtx* su = &q->SUs[ch]; init_get_bits(&gb, &buf[212 * ch], 212 * 8); @@ -343,7 +342,6 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) avctx->channels); return AVERROR(EINVAL); } - q->channels = avctx->channels; /* Init the mdct transforms */ if ((ret = ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15))) || From a3145d0335b04d143c26832c91dcc7242c758206 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 13:48:50 -0400 Subject: [PATCH 09/17] bmvaudio: set channel layout at init() rather than validating it --- libavcodec/bmv.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c index 461111967d..53781e74e6 100644 --- a/libavcodec/bmv.c +++ b/libavcodec/bmv.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "bytestream.h" @@ -304,12 +305,9 @@ static av_cold int bmv_aud_decode_init(AVCodecContext *avctx) { BMVAudioDecContext *c = avctx->priv_data; - if (avctx->channels != 2) { - av_log(avctx, AV_LOG_INFO, "invalid number of channels\n"); - return AVERROR(EINVAL); - } - - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 2; + avctx->channel_layout = AV_CH_LAYOUT_STEREO; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; avcodec_get_frame_defaults(&c->frame); avctx->coded_frame = &c->frame; From 3509eee19c03c23a14c6f226e6cc90072f323025 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 14:24:04 -0400 Subject: [PATCH 10/17] cook: use AVCodecContext.channels instead of keeping a private copy --- libavcodec/cook.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index a45bd80280..8323bbe68f 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -126,7 +126,6 @@ typedef struct cook { AVFrame frame; GetBitContext gb; /* stream data */ - int nb_channels; int bit_rate; int sample_rate; int num_vectors; @@ -1024,7 +1023,7 @@ static void dump_cook_context(COOKContext *q) PRINT("js_vlc_bits", q->subpacket[0].js_vlc_bits); } av_log(q->avctx, AV_LOG_ERROR, "COOKContext\n"); - PRINT("nb_channels", q->nb_channels); + PRINT("nb_channels", q->avctx->channels); PRINT("bit_rate", q->bit_rate); PRINT("sample_rate", q->sample_rate); PRINT("samples_per_channel", q->subpacket[0].samples_per_channel); @@ -1072,9 +1071,8 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) /* Take data from the AVCodecContext (RM container). */ q->sample_rate = avctx->sample_rate; - q->nb_channels = avctx->channels; q->bit_rate = avctx->bit_rate; - if (!q->nb_channels) { + if (!avctx->channels) { av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); return AVERROR_INVALIDDATA; } @@ -1101,7 +1099,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) } /* Initialize extradata related variables. */ - q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame / q->nb_channels; + q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame / avctx->channels; q->subpacket[s].bits_per_subpacket = avctx->block_align * 8; /* Initialize default data states. */ @@ -1116,21 +1114,21 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->subpacket[s].joint_stereo = 0; switch (q->subpacket[s].cookversion) { case MONO: - if (q->nb_channels != 1) { + if (avctx->channels != 1) { av_log_ask_for_sample(avctx, "Container channels != 1.\n"); return AVERROR_PATCHWELCOME; } av_log(avctx, AV_LOG_DEBUG, "MONO\n"); break; case STEREO: - if (q->nb_channels != 1) { + if (avctx->channels != 1) { q->subpacket[s].bits_per_subpdiv = 1; q->subpacket[s].num_channels = 2; } av_log(avctx, AV_LOG_DEBUG, "STEREO\n"); break; case JOINT_STEREO: - if (q->nb_channels != 2) { + if (avctx->channels != 2) { av_log_ask_for_sample(avctx, "Container channels != 2.\n"); return AVERROR_PATCHWELCOME; } From 8aa5b8c5c825a86449774f6023400b4775c25027 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 14:25:18 -0400 Subject: [PATCH 11/17] cook: remove unneeded COOKContext variable, bit_rate --- libavcodec/cook.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 8323bbe68f..7467749a6a 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -126,7 +126,6 @@ typedef struct cook { AVFrame frame; GetBitContext gb; /* stream data */ - int bit_rate; int sample_rate; int num_vectors; int samples_per_channel; @@ -1024,7 +1023,7 @@ static void dump_cook_context(COOKContext *q) } av_log(q->avctx, AV_LOG_ERROR, "COOKContext\n"); PRINT("nb_channels", q->avctx->channels); - PRINT("bit_rate", q->bit_rate); + PRINT("bit_rate", q->avctx->bit_rate); PRINT("sample_rate", q->sample_rate); PRINT("samples_per_channel", q->subpacket[0].samples_per_channel); PRINT("samples_per_frame", q->subpacket[0].samples_per_frame); @@ -1071,7 +1070,6 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) /* Take data from the AVCodecContext (RM container). */ q->sample_rate = avctx->sample_rate; - q->bit_rate = avctx->bit_rate; if (!avctx->channels) { av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); return AVERROR_INVALIDDATA; From 926e9d28f1a85898545706a26b27c24672c9c716 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 14:26:29 -0400 Subject: [PATCH 12/17] cook: remove unneeded COOKContext variable, sample_rate --- libavcodec/cook.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 7467749a6a..f6d2e664ab 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -126,7 +126,6 @@ typedef struct cook { AVFrame frame; GetBitContext gb; /* stream data */ - int sample_rate; int num_vectors; int samples_per_channel; /* states */ @@ -1024,7 +1023,7 @@ static void dump_cook_context(COOKContext *q) av_log(q->avctx, AV_LOG_ERROR, "COOKContext\n"); PRINT("nb_channels", q->avctx->channels); PRINT("bit_rate", q->avctx->bit_rate); - PRINT("sample_rate", q->sample_rate); + PRINT("sample_rate", q->avctx->sample_rate); PRINT("samples_per_channel", q->subpacket[0].samples_per_channel); PRINT("samples_per_frame", q->subpacket[0].samples_per_frame); PRINT("subbands", q->subpacket[0].subbands); @@ -1069,7 +1068,6 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "codecdata_length=%d\n", avctx->extradata_size); /* Take data from the AVCodecContext (RM container). */ - q->sample_rate = avctx->sample_rate; if (!avctx->channels) { av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); return AVERROR_INVALIDDATA; From d21b2e4726822ec1c604e2b9010a1a2cc0d88aec Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 14:33:11 -0400 Subject: [PATCH 13/17] cook: reverse a condition so that the code makes more sense --- libavcodec/cook.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index f6d2e664ab..211fe12d72 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1244,9 +1244,8 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) } /* Try to catch some obviously faulty streams, othervise it might be exploitable */ - if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) - || (q->samples_per_channel == 1024)) { - } else { + if (q->samples_per_channel != 256 && q->samples_per_channel != 512 && + q->samples_per_channel != 1024) { av_log_ask_for_sample(avctx, "unknown amount of samples_per_channel = %d\n", q->samples_per_channel); From 7efbba2e3665285207bf769b8f0d712cedf1bfd9 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 14:36:38 -0400 Subject: [PATCH 14/17] cook: use av_get_channel_layout_nb_channels() instead of cook_count_channels() --- libavcodec/cook.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 211fe12d72..152471947f 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1034,16 +1034,6 @@ static void dump_cook_context(COOKContext *q) } #endif -static av_cold int cook_count_channels(unsigned int mask) -{ - int i; - int channels = 0; - for (i = 0; i < 32; i++) - if (mask & (1 << i)) - ++channels; - return channels; -} - /** * Cook initialization * @@ -1147,7 +1137,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) if (extradata_size >= 4) channel_mask |= q->subpacket[s].channel_mask = bytestream_get_be32(&edata_ptr); - if (cook_count_channels(q->subpacket[s].channel_mask) > 1) { + if (av_get_channel_layout_nb_channels(q->subpacket[s].channel_mask) > 1) { q->subpacket[s].total_subbands = q->subpacket[s].subbands + q->subpacket[s].js_subband_start; q->subpacket[s].joint_stereo = 1; From 8f173ef019d7e8921ab2cb094718f14e8c016a59 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 14:43:02 -0400 Subject: [PATCH 15/17] cook: move samples_per_frame from COOKSubpacket to where it is used --- libavcodec/cook.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 152471947f..ed8eaf391c 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -72,7 +72,6 @@ typedef struct { int size; int num_channels; int cookversion; - int samples_per_frame; int subbands; int js_subband_start; int js_vlc_bits; @@ -1025,7 +1024,6 @@ static void dump_cook_context(COOKContext *q) PRINT("bit_rate", q->avctx->bit_rate); PRINT("sample_rate", q->avctx->sample_rate); PRINT("samples_per_channel", q->subpacket[0].samples_per_channel); - PRINT("samples_per_frame", q->subpacket[0].samples_per_frame); PRINT("subbands", q->subpacket[0].subbands); PRINT("js_subband_start", q->subpacket[0].js_subband_start); PRINT("log2_numvector_size", q->subpacket[0].log2_numvector_size); @@ -1047,6 +1045,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) int extradata_size = avctx->extradata_size; int s = 0; unsigned int channel_mask = 0; + int samples_per_frame; int ret; q->avctx = avctx; @@ -1073,7 +1072,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) Swap to right endianness so we don't need to care later on. */ if (extradata_size >= 8) { q->subpacket[s].cookversion = bytestream_get_be32(&edata_ptr); - q->subpacket[s].samples_per_frame = bytestream_get_be16(&edata_ptr); + samples_per_frame = bytestream_get_be16(&edata_ptr); q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr); extradata_size -= 8; } @@ -1085,7 +1084,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) } /* Initialize extradata related variables. */ - q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame / avctx->channels; + q->subpacket[s].samples_per_channel = samples_per_frame / avctx->channels; q->subpacket[s].bits_per_subpacket = avctx->block_align * 8; /* Initialize default data states. */ @@ -1142,7 +1141,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->subpacket[s].js_subband_start; q->subpacket[s].joint_stereo = 1; q->subpacket[s].num_channels = 2; - q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame >> 1; + q->subpacket[s].samples_per_channel = samples_per_frame >> 1; if (q->subpacket[s].samples_per_channel > 256) { q->subpacket[s].log2_numvector_size = 6; @@ -1151,7 +1150,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->subpacket[s].log2_numvector_size = 7; } } else - q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame; + q->subpacket[s].samples_per_channel = samples_per_frame; break; default: From 93e27f86f161ca5ed811be3570289a4f972862dc Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 14:47:10 -0400 Subject: [PATCH 16/17] cook: use av_dlog() for debug logging instead of av_log() with AV_LOG_ERROR --- libavcodec/cook.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index ed8eaf391c..201b44c2be 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1012,14 +1012,14 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data, static void dump_cook_context(COOKContext *q) { //int i=0; -#define PRINT(a, b) av_log(q->avctx, AV_LOG_ERROR, " %s = %d\n", a, b); - av_log(q->avctx, AV_LOG_ERROR, "COOKextradata\n"); - av_log(q->avctx, AV_LOG_ERROR, "cookversion=%x\n", q->subpacket[0].cookversion); +#define PRINT(a, b) av_dlog(q->avctx, " %s = %d\n", a, b); + av_dlog(q->avctx, "COOKextradata\n"); + av_dlog(q->avctx, "cookversion=%x\n", q->subpacket[0].cookversion); if (q->subpacket[0].cookversion > STEREO) { PRINT("js_subband_start", q->subpacket[0].js_subband_start); PRINT("js_vlc_bits", q->subpacket[0].js_vlc_bits); } - av_log(q->avctx, AV_LOG_ERROR, "COOKContext\n"); + av_dlog(q->avctx, "COOKContext\n"); PRINT("nb_channels", q->avctx->channels); PRINT("bit_rate", q->avctx->bit_rate); PRINT("sample_rate", q->avctx->sample_rate); From 8ac0f6767bf63d3e6b308ee6648ff02598b81e03 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 15:12:36 -0400 Subject: [PATCH 17/17] dcadec: allow the decoder to change the channel layout mid-stream --- libavcodec/dcadec.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c index eb12eb2db9..026c572689 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -317,7 +317,6 @@ typedef struct { /* Primary audio coding header */ int subframes; ///< number of subframes - int is_channels_set; ///< check for if the channel number is already set int total_channels; ///< number of channels including extensions int prim_channels; ///< number of primary audio channels int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count @@ -1831,22 +1830,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode); return AVERROR_INVALIDDATA; } - - - /* There is nothing that prevents a dts frame to change channel configuration - but Libav doesn't support that so only set the channels if it is previously - unset. Ideally during the first probe for channels the crc should be checked - and only set avctx->channels when the crc is ok. Right now the decoder could - set the channels based on a broken first frame.*/ - if (s->is_channels_set == 0) { - s->is_channels_set = 1; - avctx->channels = channels; - } - if (avctx->channels != channels) { - av_log(avctx, AV_LOG_ERROR, "DCA decoder does not support number of " - "channels changing in stream. Skipping frame.\n"); - return AVERROR_PATCHWELCOME; - } + avctx->channels = channels; /* get output buffer */ s->frame.nb_samples = 256 * (s->sample_blocks / 8);