From 268f8ba112570956f1d7be8f4f2f0bea86c61461 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 16:15:34 -0400 Subject: [PATCH 01/24] flacdec: use av_samples_* functions for sample buffer allocation Also, return an error on allocation failure. --- libavcodec/flacdec.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index a1fdc357e0..4ecf5f27aa 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -60,6 +60,8 @@ typedef struct FLACContext { int got_streaminfo; ///< indicates if the STREAMINFO has been read int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples + uint8_t *decoded_buffer; + unsigned int decoded_buffer_size; FLACDSPContext dsp; } FLACContext; @@ -73,7 +75,7 @@ static const int64_t flac_channel_layouts[6] = { AV_CH_LAYOUT_5POINT1 }; -static void allocate_buffers(FLACContext *s); +static int allocate_buffers(FLACContext *s); static void flac_set_bps(FLACContext *s) { @@ -101,6 +103,7 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) { enum FLACExtradataFormat format; uint8_t *streaminfo; + int ret; FLACContext *s = avctx->priv_data; s->avctx = avctx; @@ -114,7 +117,9 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) /* initialize based on the demuxer-supplied streamdata header */ avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); - allocate_buffers(s); + ret = allocate_buffers(s); + if (ret < 0) + return ret; flac_set_bps(s); ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->bps); s->got_streaminfo = 1; @@ -137,15 +142,24 @@ static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s) av_log(avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps); } -static void allocate_buffers(FLACContext *s) +static int allocate_buffers(FLACContext *s) { - int i; + int buf_size; assert(s->max_blocksize); - for (i = 0; i < s->channels; i++) { - s->decoded[i] = av_malloc(sizeof(int32_t)*s->max_blocksize); - } + buf_size = av_samples_get_buffer_size(NULL, s->channels, s->max_blocksize, + AV_SAMPLE_FMT_S32P, 0); + if (buf_size < 0) + return buf_size; + + av_fast_malloc(&s->decoded_buffer, &s->decoded_buffer_size, buf_size); + if (!s->decoded_buffer) + return AVERROR(ENOMEM); + + return av_samples_fill_arrays((uint8_t **)s->decoded, NULL, + s->decoded_buffer, s->channels, + s->max_blocksize, AV_SAMPLE_FMT_S32P, 0); } /** @@ -157,7 +171,7 @@ static void allocate_buffers(FLACContext *s) */ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) { - int metadata_type, metadata_size; + int metadata_type, metadata_size, ret; if (buf_size < FLAC_STREAMINFO_SIZE+8) { /* need more data */ @@ -169,7 +183,9 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) return AVERROR_INVALIDDATA; } avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]); - allocate_buffers(s); + ret = allocate_buffers(s); + if (ret < 0) + return ret; flac_set_bps(s); ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); s->got_streaminfo = 1; @@ -462,7 +478,9 @@ static int decode_frame(FLACContext *s) s->samplerate = s->avctx->sample_rate = fi.samplerate; if (!s->got_streaminfo) { - allocate_buffers(s); + int ret = allocate_buffers(s); + if (ret < 0) + return ret; ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); s->got_streaminfo = 1; dump_headers(s->avctx, (FLACStreaminfo *)s); @@ -552,11 +570,8 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, static av_cold int flac_decode_close(AVCodecContext *avctx) { FLACContext *s = avctx->priv_data; - int i; - for (i = 0; i < s->channels; i++) { - av_freep(&s->decoded[i]); - } + av_freep(&s->decoded_buffer); return 0; } From 90fcac0e95b7d266c148a86506f301a2072d9de3 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 17:02:28 -0400 Subject: [PATCH 02/24] flacdec: allow mid-stream channel layout change Although the libFLAC decoder cannot handle such a change, it is allowed by the spec and could potentially occur with live streams. --- libavcodec/flac.c | 19 +++++++++++++++++++ libavcodec/flac.h | 3 +++ libavcodec/flac_parser.c | 1 + libavcodec/flacdec.c | 27 +++++++++------------------ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/libavcodec/flac.c b/libavcodec/flac.c index d624beb61f..07da702e94 100644 --- a/libavcodec/flac.c +++ b/libavcodec/flac.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/audioconvert.h" #include "libavutil/crc.h" #include "libavutil/log.h" #include "bytestream.h" @@ -28,6 +29,15 @@ static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 }; +static const int64_t flac_channel_layouts[6] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_QUAD, + AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT1 +}; + static int64_t get_utf8(GetBitContext *gb) { int64_t val; @@ -181,6 +191,14 @@ int avpriv_flac_is_extradata_valid(AVCodecContext *avctx, return 1; } +void ff_flac_set_channel_layout(AVCodecContext *avctx) +{ + if (avctx->channels <= FF_ARRAY_ELEMS(flac_channel_layouts)) + avctx->channel_layout = flac_channel_layouts[avctx->channels - 1]; + else + avctx->channel_layout = 0; +} + void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, const uint8_t *buffer) { @@ -205,6 +223,7 @@ void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo * avctx->channels = s->channels; avctx->sample_rate = s->samplerate; avctx->bits_per_raw_sample = s->bps; + ff_flac_set_channel_layout(avctx); s->samples = get_bits_long(&gb, 32) << 4; s->samples |= get_bits(&gb, 4); diff --git a/libavcodec/flac.h b/libavcodec/flac.h index 55bacea9ea..63f41c25a4 100644 --- a/libavcodec/flac.h +++ b/libavcodec/flac.h @@ -137,4 +137,7 @@ int ff_flac_get_max_frame_size(int blocksize, int ch, int bps); */ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, FLACFrameInfo *fi, int log_level_offset); + +void ff_flac_set_channel_layout(AVCodecContext *avctx); + #endif /* AVCODEC_FLAC_H */ diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index 6c8c04675c..f0a37f310e 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -459,6 +459,7 @@ static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf, fpc->avctx->sample_rate = header->fi.samplerate; fpc->avctx->channels = header->fi.channels; + ff_flac_set_channel_layout(fpc->avctx); fpc->pc->duration = header->fi.blocksize; *poutbuf = flac_fifo_read_wrap(fpc, header->offset, *poutbuf_size, &fpc->wrap_buf, diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 4ecf5f27aa..20af820a9d 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -66,15 +66,6 @@ typedef struct FLACContext { FLACDSPContext dsp; } FLACContext; -static const int64_t flac_channel_layouts[6] = { - AV_CH_LAYOUT_MONO, - AV_CH_LAYOUT_STEREO, - AV_CH_LAYOUT_SURROUND, - AV_CH_LAYOUT_QUAD, - AV_CH_LAYOUT_5POINT0, - AV_CH_LAYOUT_5POINT1 -}; - static int allocate_buffers(FLACContext *s); static void flac_set_bps(FLACContext *s) @@ -127,9 +118,6 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) avcodec_get_frame_defaults(&s->frame); avctx->coded_frame = &s->frame; - if (avctx->channels <= FF_ARRAY_ELEMS(flac_channel_layouts)) - avctx->channel_layout = flac_channel_layouts[avctx->channels - 1]; - return 0; } @@ -421,7 +409,7 @@ static inline int decode_subframe(FLACContext *s, int channel) static int decode_frame(FLACContext *s) { - int i; + int i, ret; GetBitContext *gb = &s->gb; FLACFrameInfo fi; @@ -430,12 +418,15 @@ static int decode_frame(FLACContext *s) return -1; } - if (s->channels && fi.channels != s->channels) { - av_log(s->avctx, AV_LOG_ERROR, "switching channel layout mid-stream " - "is not supported\n"); - return -1; + if (s->channels && fi.channels != s->channels && s->got_streaminfo) { + s->channels = s->avctx->channels = fi.channels; + ff_flac_set_channel_layout(s->avctx); + ret = allocate_buffers(s); + if (ret < 0) + return ret; } s->channels = s->avctx->channels = fi.channels; + ff_flac_set_channel_layout(s->avctx); s->ch_mode = fi.ch_mode; if (!s->bps && !fi.bps) { @@ -478,7 +469,7 @@ static int decode_frame(FLACContext *s) s->samplerate = s->avctx->sample_rate = fi.samplerate; if (!s->got_streaminfo) { - int ret = allocate_buffers(s); + ret = allocate_buffers(s); if (ret < 0) return ret; ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); From 99d868635725e3b85a5c549e6bb0e97e10cf5248 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 21 Oct 2012 17:04:58 -0400 Subject: [PATCH 03/24] flacdec: do not warn on sample rate change --- libavcodec/flacdec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 20af820a9d..10e33f22f2 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -460,12 +460,8 @@ static int decode_frame(FLACContext *s) " or frame header\n"); return -1; } - if (fi.samplerate == 0) { + if (fi.samplerate == 0) fi.samplerate = s->samplerate; - } else if (s->samplerate && fi.samplerate != s->samplerate) { - av_log(s->avctx, AV_LOG_WARNING, "sample rate changed from %d to %d\n", - s->samplerate, fi.samplerate); - } s->samplerate = s->avctx->sample_rate = fi.samplerate; if (!s->got_streaminfo) { From e00eb03cd8bfb6993d33c30ccd560947b5f6bad5 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 13:26:14 -0400 Subject: [PATCH 04/24] g726dec: set channel layout at initialization instead of validating it --- libavcodec/g726.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/g726.c b/libavcodec/g726.c index 7fa2be3e99..ed4bd26c70 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -22,6 +22,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include + +#include "libavutil/audioconvert.h" #include "libavutil/avassert.h" #include "libavutil/opt.h" #include "avcodec.h" @@ -428,10 +430,8 @@ static av_cold int g726_decode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - if(avctx->channels != 1){ - av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); - return AVERROR(EINVAL); - } + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; c->code_size = avctx->bits_per_coded_sample; if (c->code_size < 2 || c->code_size > 5) { From a346aaf148dc2ce53da30e2f67223834495c0fd6 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 13:26:46 -0400 Subject: [PATCH 05/24] g726dec: do not validate sample rate For decoding it does not really matter what the sample rate is. --- libavcodec/g726.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/libavcodec/g726.c b/libavcodec/g726.c index ed4bd26c70..91b5e54cef 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -422,14 +422,6 @@ static av_cold int g726_decode_init(AVCodecContext *avctx) { G726Context* c = avctx->priv_data; - if (avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT && - avctx->sample_rate != 8000) { - av_log(avctx, AV_LOG_ERROR, "Only 8kHz sample rate is allowed when " - "the compliance level is strict. Reduce the compliance level " - "if you wish to decode the stream anyway.\n"); - return AVERROR(EINVAL); - } - avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; From c5b8acad731c06389b98df8248b6a536e1b7e58d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 15:43:59 -0400 Subject: [PATCH 06/24] libgsmdec: always set channel layout and sample rate at initialization Only mono 8kHz is supported. --- libavcodec/libgsm.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index e6d435ba05..afed7100a0 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -29,6 +29,7 @@ #include +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "internal.h" #include "gsm.h" @@ -149,19 +150,10 @@ typedef struct LibGSMDecodeContext { static av_cold int libgsm_decode_init(AVCodecContext *avctx) { LibGSMDecodeContext *s = avctx->priv_data; - if (avctx->channels > 1) { - av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n", - avctx->channels); - return -1; - } - - if (!avctx->channels) - avctx->channels = 1; - - if (!avctx->sample_rate) - avctx->sample_rate = 8000; - - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_rate = 8000; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; s->state = gsm_create(); From 32c7769e5c851ff7b47a83113b97a325dde7b442 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 15:45:38 -0400 Subject: [PATCH 07/24] gsmdec: always set channel layout and sample rate at initialization Only mono 8kHz is supported. --- libavcodec/gsmdec.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c index a5e0d7d73a..14b7e03047 100644 --- a/libavcodec/gsmdec.c +++ b/libavcodec/gsmdec.c @@ -24,6 +24,7 @@ * GSM decoder */ +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "get_bits.h" #include "msgsmdec.h" @@ -34,10 +35,10 @@ static av_cold int gsm_init(AVCodecContext *avctx) { GSMContext *s = avctx->priv_data; - avctx->channels = 1; - if (!avctx->sample_rate) - avctx->sample_rate = 8000; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_rate = 8000; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; switch (avctx->codec_id) { case AV_CODEC_ID_GSM: From 1c7a0161538a9e8417086759a5d6d3295337c433 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 15:54:29 -0400 Subject: [PATCH 08/24] imc: set channels to 1 instead of validating it --- libavcodec/imc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 1156e8aac2..4c2d01d025 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -175,8 +175,10 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) IMCContext *q = avctx->priv_data; double r1, r2; - if ((avctx->codec_id == AV_CODEC_ID_IMC && avctx->channels != 1) - || (avctx->codec_id == AV_CODEC_ID_IAC && avctx->channels > 2)) { + if (avctx->codec_id == AV_CODEC_ID_IMC) + avctx->channels = 1; + + if (avctx->channels > 2) { av_log_ask_for_sample(avctx, "Number of channels is not supported\n"); return AVERROR_PATCHWELCOME; } From 0fd1ddf15545a7bac1e8d2622d070fdf4bad95d8 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 16:03:20 -0400 Subject: [PATCH 09/24] dpcm: use AVCodecContext.channels instead of keeping a private copy --- libavcodec/dpcm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index f9aff98417..fb1c7ce6f2 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -44,7 +44,6 @@ typedef struct DPCMContext { AVFrame frame; - int channels; int16_t roq_square_array[256]; int sample[2]; ///< previous sample (for SOL_DPCM) const int8_t *sol_table; ///< delta table for SOL_DPCM @@ -123,7 +122,6 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - s->channels = avctx->channels; s->sample[0] = s->sample[1] = 0; switch(avctx->codec->id) { @@ -179,7 +177,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int out = 0, ret; int predictor[2]; int ch = 0; - int stereo = s->channels - 1; + int stereo = avctx->channels - 1; int16_t *output_samples, *samples_end; GetByteContext gb; @@ -193,10 +191,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, out = buf_size - 8; break; case AV_CODEC_ID_INTERPLAY_DPCM: - out = buf_size - 6 - s->channels; + out = buf_size - 6 - avctx->channels; break; case AV_CODEC_ID_XAN_DPCM: - out = buf_size - 2 * s->channels; + out = buf_size - 2 * avctx->channels; break; case AV_CODEC_ID_SOL_DPCM: if (avctx->codec_tag != 3) @@ -211,7 +209,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, } /* get output buffer */ - s->frame.nb_samples = out / s->channels; + s->frame.nb_samples = out / avctx->channels; if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; @@ -245,7 +243,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, case AV_CODEC_ID_INTERPLAY_DPCM: bytestream2_skipu(&gb, 6); /* skip over the stream mask and stream length */ - for (ch = 0; ch < s->channels; ch++) { + for (ch = 0; ch < avctx->channels; ch++) { predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16); *output_samples++ = predictor[ch]; } @@ -265,7 +263,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, { int shift[2] = { 4, 4 }; - for (ch = 0; ch < s->channels; ch++) + for (ch = 0; ch < avctx->channels; ch++) predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16); ch = 0; From 30f8da29bf609d741bbebd33b2a5003c426ab919 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 17:41:47 -0400 Subject: [PATCH 10/24] libilbc: set channel layout --- libavcodec/libilbc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c index a93285c16f..281206109c 100644 --- a/libavcodec/libilbc.c +++ b/libavcodec/libilbc.c @@ -21,6 +21,7 @@ #include +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "libavutil/common.h" #include "libavutil/opt.h" @@ -68,9 +69,10 @@ static av_cold int ilbc_decode_init(AVCodecContext *avctx) avcodec_get_frame_defaults(&s->frame); avctx->coded_frame = &s->frame; - avctx->channels = 1; - avctx->sample_rate = 8000; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_rate = 8000; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; } From d40dab907aad684885988552a84da76488f298c0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 17:49:59 -0400 Subject: [PATCH 11/24] libopencore-amr: set channel layout for amr-nb or if not set by the user --- libavcodec/libopencore-amr.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c index 9a543b48b2..a754d521a6 100644 --- a/libavcodec/libopencore-amr.c +++ b/libavcodec/libopencore-amr.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 "libavutil/avstring.h" #include "libavutil/common.h" @@ -30,13 +31,16 @@ static void amr_decode_fix_avctx(AVCodecContext *avctx) { const int is_amr_wb = 1 + (avctx->codec_id == AV_CODEC_ID_AMR_WB); - if (!avctx->sample_rate) - avctx->sample_rate = 8000 * is_amr_wb; + avctx->sample_rate = 8000 * is_amr_wb; - if (!avctx->channels) - avctx->channels = 1; + if (avctx->channels > 1) { + av_log_missing_feature(avctx, "multi-channel AMR", 0); + return AVERROR_PATCHWELCOME; + } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; } #if CONFIG_LIBOPENCORE_AMRNB From d26701ce2f3504e2ee341251448db3af6328a69b Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 17:58:24 -0400 Subject: [PATCH 12/24] nellymoserdec: set channels to 1 --- libavcodec/nellymoserdec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index fce184ae16..f17e9fd839 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -129,6 +129,7 @@ static av_cold int decode_init(AVCodecContext * avctx) { if (!ff_sine_128[127]) ff_init_ff_sine_windows(7); + avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; avcodec_get_frame_defaults(&s->frame); From e3d6ab57042ef7b35f24bf154fba39369034a665 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 18:25:46 -0400 Subject: [PATCH 13/24] qcelpdec: set channel layout --- libavcodec/qcelpdec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index edb1d24603..9c2b354cd4 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -29,6 +29,7 @@ #include +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "internal.h" #include "get_bits.h" @@ -89,7 +90,9 @@ static av_cold int qcelp_decode_init(AVCodecContext *avctx) QCELPContext *q = avctx->priv_data; int i; - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; for (i = 0; i < 10; i++) q->prev_lspf[i] = (i + 1) / 11.; From be2ab8b75a634a686a5ced1544c0c9a4ebeab0dc Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 18:53:19 -0400 Subject: [PATCH 14/24] qdm2: make sure channels is not <= 0 and set channel layout --- libavcodec/qdm2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 4d3b3915fb..8e93886f1c 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -36,6 +36,7 @@ #include #define BITSTREAM_READER_LE +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "get_bits.h" #include "dsputil.h" @@ -1768,8 +1769,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata); extradata += 4; - if (s->channels > MPA_MAX_CHANNELS) + if (s->channels <= 0 || s->channels > MPA_MAX_CHANNELS) return AVERROR_INVALIDDATA; + avctx->channel_layout = avctx->channels == 2 ? AV_CH_LAYOUT_STEREO : + AV_CH_LAYOUT_MONO; avctx->sample_rate = AV_RB32(extradata); extradata += 4; From eb38d8fe926bdce8110fa4be4fddf6598a079a20 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 18:54:29 -0400 Subject: [PATCH 15/24] qdm2: remove unneeded checks for channel count --- libavcodec/qdm2.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 8e93886f1c..a094e6c188 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -544,10 +544,6 @@ static void fill_tone_level_array (QDM2Context *q, int flag) int i, sb, ch, sb_used; int tmp, tab; - // This should never happen - if (q->nb_channels <= 0) - return; - for (ch = 0; ch < q->nb_channels; ch++) for (sb = 0; sb < 30; sb++) for (i = 0; i < 8; i++) { @@ -643,10 +639,6 @@ static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_arra int add1, add2, add3, add4; int64_t multres; - // This should never happen - if (nb_channels <= 0) - return; - if (!superblocktype_2_3) { /* This case is untested, no samples available */ SAMPLES_NEEDED From 6159f6436495ed8859fe9d32c4c2c1a2eb4c1e91 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 22 Oct 2012 18:57:39 -0400 Subject: [PATCH 16/24] ra144dec: set channel layout --- libavcodec/ra144dec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index 0cb4f86721..cee3892f79 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -22,6 +22,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/audioconvert.h" #include "libavutil/intmath.h" #include "avcodec.h" #include "get_bits.h" @@ -37,7 +38,9 @@ static av_cold int ra144_decode_init(AVCodecContext * avctx) ractx->lpc_coef[0] = ractx->lpc_tables[0]; ractx->lpc_coef[1] = ractx->lpc_tables[1]; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; avcodec_get_frame_defaults(&ractx->frame); avctx->coded_frame = &ractx->frame; From 4e13e50432bd1c1a89f626f8196b55a0302c8f19 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 00:35:50 -0400 Subject: [PATCH 17/24] ra288dec: set channel layout --- libavcodec/ra288.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index 1d02c7bf41..e080d2beac 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/audioconvert.h" #include "libavutil/float_dsp.h" #include "avcodec.h" #define BITSTREAM_READER_LE @@ -61,7 +62,11 @@ typedef struct { static av_cold int ra288_decode_init(AVCodecContext *avctx) { RA288Context *ractx = avctx->priv_data; - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + avpriv_float_dsp_init(&ractx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); avcodec_get_frame_defaults(&ractx->frame); From 4c53f4aed3edfa58360c7a2a468782eae31d3176 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 00:40:51 -0400 Subject: [PATCH 18/24] shorten: validate that the channel count in the header is not <= 0 --- libavcodec/shorten.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 1664a907ae..be2b8e20e9 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -342,7 +342,7 @@ static int read_header(ShortenContext *s) s->internal_ftype = get_uint(s, TYPESIZE); s->channels = get_uint(s, CHANSIZE); - if (s->channels > MAX_CHANNELS) { + if (s->channels <= 0 || s->channels > MAX_CHANNELS) { av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); return -1; } From 523734eb6a904c43cf73d801f1c885829380f0de Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 00:51:26 -0400 Subject: [PATCH 19/24] sipr: set channel layout --- libavcodec/sipr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index 1e9168a76f..9db09232c1 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -25,6 +25,7 @@ #include #include +#include "libavutil/audioconvert.h" #include "libavutil/mathematics.h" #include "avcodec.h" #define BITSTREAM_READER_LE @@ -509,7 +510,9 @@ static av_cold int sipr_decoder_init(AVCodecContext * avctx) for (i = 0; i < 4; i++) ctx->energy_history[i] = -14; - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; avcodec_get_frame_defaults(&ctx->frame); avctx->coded_frame = &ctx->frame; From cebea00c8abac0817d3ae8bdd9573a603c655b75 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 00:53:16 -0400 Subject: [PATCH 20/24] truespeech: set channel layout --- libavcodec/truespeech.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index bbee146136..efe5f45706 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/audioconvert.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "dsputil.h" @@ -66,7 +67,8 @@ static av_cold int truespeech_decode_init(AVCodecContext * avctx) return AVERROR(EINVAL); } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; ff_dsputil_init(&c->dsp, avctx); From 8cc72ce5a0d8ab6bc88d28cf55cd62674240121d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 13:15:24 -0400 Subject: [PATCH 21/24] twinvq: validate that channels is not <= 0 This could occur due to integer overflow when reading the channel count from the extradata. --- libavcodec/twinvq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index d009196445..50ee6266b3 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -1126,7 +1126,7 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) default: avctx->sample_rate = isampf * 1000; break; } - if (avctx->channels > CHANNELS_MAX) { + if (avctx->channels <= 0 || avctx->channels > CHANNELS_MAX) { av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n", avctx->channels); return -1; From 335826cf5f7169199ed0a8d3a61f697ec0438d30 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 13:17:17 -0400 Subject: [PATCH 22/24] twinvq: set channel layout --- libavcodec/twinvq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 50ee6266b3..3159e498e7 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/audioconvert.h" #include "libavutil/float_dsp.h" #include "avcodec.h" #include "get_bits.h" @@ -1131,6 +1132,9 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) avctx->channels); return -1; } + avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO : + AV_CH_LAYOUT_STEREO; + ibps = avctx->bit_rate / (1000 * avctx->channels); switch ((isampf << 8) + ibps) { From b5f628e227743fc1725a28b5b21f538a40efca82 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 13:17:50 -0400 Subject: [PATCH 23/24] twinvq: validate sample rate code A large invalid value could cause undefined behavior when left-shifted by 8 later in the function. --- libavcodec/twinvq.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 3159e498e7..7af370ee5a 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -1120,6 +1120,11 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) avctx->channels = AV_RB32(avctx->extradata ) + 1; avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000; isampf = AV_RB32(avctx->extradata + 8); + + if (isampf < 8 || isampf > 44) { + av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n"); + return AVERROR_INVALIDDATA; + } switch (isampf) { case 44: avctx->sample_rate = 44100; break; case 22: avctx->sample_rate = 22050; break; From 50a65e7a540ce6747f81d6dbf6a602ad35be77ff Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 23 Oct 2012 15:27:44 -0400 Subject: [PATCH 24/24] vmdaudio: set channel layout --- libavcodec/vmdav.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index 5776d92cd5..6efc9e73fc 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -43,6 +43,7 @@ #include #include +#include "libavutil/audioconvert.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" @@ -508,6 +509,9 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } + avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO : + AV_CH_LAYOUT_STEREO; + if (avctx->bits_per_coded_sample == 16) avctx->sample_fmt = AV_SAMPLE_FMT_S16; else