On Tue, Oct 04, 2011 at 06:02:07PM -0400, Justin Ruggles wrote:
> This also allows for removing some of the buf_size checks and using the
> sample count for some of the decoding loops.
> ---
> libavcodec/adpcm.c | 352
> +++++++++++++++++++++++++++++++++++-----------------
> 1 files changed, 235 insertions(+), 117 deletions(-)
>
> diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
> index c26c515..c976544 100644
> --- a/libavcodec/adpcm.c
> +++ b/libavcodec/adpcm.c
> @@ -315,6 +315,178 @@ static void xa_decode(short *out, const unsigned char
> *in,
> }
> }
>
> +/**
> + * Get the number of samples that will be decoded from the packet.
> + * In one case, this is actually the maximum number of samples possible to
> + * decode with the given buf_size.
> + *
> + * @param[out] coded_samples set to the number of samples as coded in the
> + * packet, or 0 if the codec does not encode the
> + * number of samples in each frame.
> + */
> +static int get_nb_samples(AVCodecContext *avctx, const uint8_t *buf,
> + int buf_size, int *coded_samples)
> +{
> + ADPCMDecodeContext *s = avctx->priv_data;
> + int nb_samples = 0;
> + int ch = avctx->channels;
> + int has_coded_samples = 0;
> + int header_size;
> +
> + *coded_samples = 0;
> +
> + /* constant, only check buf_size */
> + switch (avctx->codec->id) {
> + case CODEC_ID_ADPCM_EA_XAS:
> + if (buf_size < 76 * avctx->channels)
> + return 0;
> + nb_samples = 128;
> + break;
> + case CODEC_ID_ADPCM_IMA_QT:
> + if (buf_size < 34)
> + return 0;
> + nb_samples = 64;
> + break;
> + }
> + if (nb_samples)
> + return nb_samples;
> +
> + /* simple 4-bit adpcm */
> + switch (avctx->codec->id) {
> + case CODEC_ID_ADPCM_CT:
> + case CODEC_ID_ADPCM_IMA_EA_SEAD:
> + case CODEC_ID_ADPCM_IMA_WS:
> + case CODEC_ID_ADPCM_YAMAHA:
> + nb_samples = buf_size * 2 / ch;
> + break;
> + }
> + if (nb_samples)
> + return nb_samples;
the first two switch blocks should be joined
> +
> + /* simple 4-bit adpcm, with header */
> + header_size = 0;
> + switch (avctx->codec->id) {
> + case CODEC_ID_ADPCM_4XM:
> + case CODEC_ID_ADPCM_IMA_ISS: header_size = 4 * ch; break;
> + case CODEC_ID_ADPCM_IMA_AMV: header_size = 8; break;
> + case CODEC_ID_ADPCM_IMA_SMJPEG: header_size = 4; break;
> + }
> + if (header_size > 0)
> + return (buf_size - header_size) * 2 / ch;
> +
> + /* more complex formats */
> + switch (avctx->codec->id) {
> + case CODEC_ID_ADPCM_EA:
> + has_coded_samples = 1;
> + if (buf_size < 4)
> + return 0;
> + *coded_samples = AV_RL32(buf);
> + *coded_samples -= *coded_samples % 28;
> + nb_samples = (buf_size - 12) / 30 * 28;
> + break;
> + case CODEC_ID_ADPCM_IMA_EA_EACS:
> + has_coded_samples = 1;
> + if (buf_size < 4)
> + return 0;
> + *coded_samples = AV_RL32(buf);
> + nb_samples = (buf_size - (4 + 8 * ch)) * 2 / ch;
> + break;
> + case CODEC_ID_ADPCM_EA_MAXIS_XA:
> + nb_samples = ((buf_size - ch) / (2 * ch)) * 2 * ch;
> + break;
> + case CODEC_ID_ADPCM_EA_R1:
> + case CODEC_ID_ADPCM_EA_R2:
> + case CODEC_ID_ADPCM_EA_R3:
> + /* maximum number of samples */
> + /* has internal offsets and a per-frame switch to signal raw 16-bit
> */
> + has_coded_samples = 1;
> + if (buf_size < 4)
> + return 0;
> + switch (avctx->codec->id) {
> + case CODEC_ID_ADPCM_EA_R1:
> + header_size = 4 + 9 * ch;
> + *coded_samples = AV_RL32(buf);
> + break;
> + case CODEC_ID_ADPCM_EA_R2:
> + header_size = 4 + 5 * ch;
> + *coded_samples = AV_RL32(buf);
> + break;
> + case CODEC_ID_ADPCM_EA_R3:
> + header_size = 4 + 5 * ch;
> + *coded_samples = AV_RB32(buf);
> + break;
> + }
> + *coded_samples -= *coded_samples % 28;
> + nb_samples = (buf_size - header_size) * 2 / ch;
> + nb_samples -= nb_samples % 28;
> + break;
> + case CODEC_ID_ADPCM_IMA_DK3:
> + if (avctx->block_align > 0)
> + buf_size = FFMIN(buf_size, avctx->block_align);
> + nb_samples = ((buf_size - 16) * 8 / 3) / ch;
> + break;
> + case CODEC_ID_ADPCM_IMA_DK4:
> + nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch;
> + break;
> + case CODEC_ID_ADPCM_IMA_WAV:
> + if (avctx->block_align > 0)
> + buf_size = FFMIN(buf_size, avctx->block_align);
> + nb_samples = 1 + (buf_size - 4 * ch) / (4 * ch) * 8;
> + break;
> + case CODEC_ID_ADPCM_MS:
> + if (avctx->block_align > 0)
> + buf_size = FFMIN(buf_size, avctx->block_align);
> + nb_samples = 2 + (buf_size - 7 * ch) * 2 / ch;
> + break;
> + case CODEC_ID_ADPCM_SBPRO_2:
> + case CODEC_ID_ADPCM_SBPRO_3:
> + case CODEC_ID_ADPCM_SBPRO_4:
> + {
> + int samples_per_byte;
> + switch (avctx->codec->id) {
> + case CODEC_ID_ADPCM_SBPRO_2: samples_per_byte = 4; break;
> + case CODEC_ID_ADPCM_SBPRO_3: samples_per_byte = 3; break;
> + case CODEC_ID_ADPCM_SBPRO_4: samples_per_byte = 2; break;
> + }
> + if (!s->status[0].step_index) {
> + nb_samples++;
> + buf_size -= ch;
> + }
> + nb_samples += buf_size * samples_per_byte / ch;
> + break;
> + }
> + case CODEC_ID_ADPCM_SWF:
> + {
> + int buf_bits = buf_size * 8 - 2;
> + int nbits = (buf[0] >> 6) + 2;
> + int block_hdr_size = 22 * ch;
> + int block_size = block_hdr_size + nbits * ch * 4095;
> + int nblocks = buf_bits / block_size;
> + int bits_left = buf_bits - nblocks * block_size;
> + nb_samples = nblocks * 4096;
> + if (bits_left >= block_hdr_size)
> + nb_samples += 1 + (bits_left - block_hdr_size) / (nbits * ch);
> + break;
> + }
> + case CODEC_ID_ADPCM_THP:
> + has_coded_samples = 1;
> + if (buf_size < 8)
> + return 0;
> + *coded_samples = AV_RB32(&buf[4]);
> + *coded_samples -= *coded_samples % 14;
> + nb_samples = (buf_size - 80) / (8 * ch) * 14;
> + break;
> + case CODEC_ID_ADPCM_XA:
> + nb_samples = (buf_size / 128) * 224 / ch;
> + break;
> + }
> +
> + /* validate coded sample count */
> + if (has_coded_samples && (*coded_samples <= 0 || *coded_samples >
> nb_samples))
> + return AVERROR_INVALIDDATA;
> +
> + return nb_samples;
> +}
>
> /* DK3 ADPCM support macro */
> #define DK3_GET_NEXT_NIBBLE() \
> @@ -344,20 +516,33 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> ADPCMChannelStatus *cs;
> int n, m, channel, i;
> short *samples;
> - short *samples_end;
> const uint8_t *src;
> int st; /* stereo */
> - uint32_t samples_in_chunk;
> int count1, count2;
> + int nb_samples, coded_samples, out_bps, out_size;
>
> - //should protect all 4bit ADPCM variants
> - //8 is needed for CODEC_ID_ADPCM_IMA_WAV with 2 channels
> - //
> - if(*data_size/4 < buf_size + 8)
> - return -1;
> + nb_samples = get_nb_samples(avctx, buf, buf_size, &coded_samples);
> + if (nb_samples <= 0) {
> + av_log(avctx, AV_LOG_ERROR, "invalid number of samples in packet\n");
> + return AVERROR_INVALIDDATA;
> + }
> + if (coded_samples && coded_samples != nb_samples)
> + av_log(avctx, AV_LOG_WARNING, "mismatch in coded sample count\n");
> +
> + out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
> + out_size = nb_samples * avctx->channels * out_bps;
> + if (*data_size < out_size) {
> + av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
> + return AVERROR(EINVAL);
> + }
> + /* use coded_samples when applicable */
> + /* it is always <= nb_samples, so the output buffer will be large enough
> */
> + if (coded_samples) {
> + nb_samples = coded_samples;
> + out_size = nb_samples * avctx->channels * out_bps;
> + }
is there a specific why this is set here? merging it with the "mismatch
in coded sample count\n" if () would make sense and would make
the recalculation of out_size unnecessary
>
> samples = data;
> - samples_end= samples + *data_size/2;
> src = buf;
>
> st = avctx->channels == 2 ? 1 : 0;
> @@ -366,10 +551,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> case CODEC_ID_ADPCM_IMA_QT:
> /* In QuickTime, IMA is encoded by chunks of 34 bytes (=64 samples).
> Channel data is interleaved per-chunk. */
> - if (buf_size / 34 < avctx->channels) {
> - av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
> - return AVERROR(EINVAL);
> - }
> for (channel = 0; channel < avctx->channels; channel++) {
> int16_t predictor;
> int step_index;
> @@ -410,15 +591,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> src ++;
> }
> }
> - if (st)
> - samples--;
> break;
> case CODEC_ID_ADPCM_IMA_WAV:
> if (avctx->block_align != 0 && buf_size > avctx->block_align)
> buf_size = avctx->block_align;
>
> -// samples_per_block= (block_align-4*chanels)*8 / (bits_per_sample *
> chanels) + 1;
> -
> for(i=0; i<avctx->channels; i++){
> cs = &(c->status[i]);
> cs->predictor = *samples++ = (int16_t)bytestream_get_le16(&src);
> @@ -431,7 +608,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> if (*src++) av_log(avctx, AV_LOG_ERROR, "unused byte should be
> null but is %d!!\n", src[-1]); /* unused */
> }
>
> - while (src <= buf + buf_size - (avctx->channels * 4)) {
> + for (n = (nb_samples - 1) / 8; n > 0; n--) {
> for (i = 0; i < avctx->channels; i++) {
> cs = &c->status[i];
> for (m = 0; m < 4; m++) {
> @@ -455,20 +632,17 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> c->status[i].step_index = av_clip(c->status[i].step_index, 0,
> 88);
> }
>
> - m= (buf_size - (src - buf))>>st;
> -
> for (i = 0; i < avctx->channels; i++) {
> samples = (short*)data + i;
> cs = &c->status[i];
> - for (n = 0; n < m; n++) {
> - uint8_t v = *src++;
> + for (n = nb_samples >> 1; n > 0; n--, src++) {
> + uint8_t v = *src;
> *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 4);
> samples += avctx->channels;
> *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 4);
> samples += avctx->channels;
> }
> }
> - samples -= (avctx->channels - 1);
> break;
> case CODEC_ID_ADPCM_MS:
> {
> @@ -476,9 +650,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
>
> if (avctx->block_align != 0 && buf_size > avctx->block_align)
> buf_size = avctx->block_align;
> - n = buf_size - 7 * avctx->channels;
> - if (n < 0)
> - return -1;
>
> block_predictor = av_clip(*src++, 0, 6);
> c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];
> @@ -502,10 +673,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> if (st) *samples++ = c->status[1].sample2;
> *samples++ = c->status[0].sample1;
> if (st) *samples++ = c->status[1].sample1;
> - for(;n>0;n--) {
> + for(n = (nb_samples - 2) >> (1 - st); n > 0; n--, src++) {
> *samples++ = adpcm_ms_expand_nibble(&c->status[0 ], src[0] >> 4
> );
> *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] &
> 0x0F);
> - src ++;
> }
> break;
> }
> @@ -513,12 +683,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> if (avctx->block_align != 0 && buf_size > avctx->block_align)
> buf_size = avctx->block_align;
>
> - n = buf_size - 4 * avctx->channels;
> - if (n < 0) {
> - av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
> - return AVERROR(EINVAL);
> - }
> -
> for (channel = 0; channel < avctx->channels; channel++) {
> cs = &c->status[channel];
> cs->predictor = (int16_t)bytestream_get_le16(&src);
> @@ -526,8 +690,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> src++;
> *samples++ = cs->predictor;
> }
> - while (n-- > 0) {
> - uint8_t v = *src++;
> + for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
> + uint8_t v = *src;
> *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4 ,
> 3);
> *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F,
> 3);
> }
> @@ -543,9 +707,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> if (avctx->block_align != 0 && buf_size > avctx->block_align)
> buf_size = avctx->block_align;
>
> - if(buf_size + 16 > (samples_end - samples)*3/8)
> - return -1;
> -
> c->status[0].predictor = (int16_t)AV_RL16(src + 10);
> c->status[1].predictor = (int16_t)AV_RL16(src + 12);
> c->status[0].step_index = src[14];
> @@ -586,12 +747,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> break;
> }
> case CODEC_ID_ADPCM_IMA_ISS:
> - n = buf_size - 4 * avctx->channels;
> - if (n < 0) {
> - av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
> - return AVERROR(EINVAL);
> - }
> -
> for (channel = 0; channel < avctx->channels; channel++) {
> cs = &c->status[channel];
> cs->predictor = (int16_t)bytestream_get_le16(&src);
> @@ -599,9 +754,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> src++;
> }
>
> - while (n-- > 0) {
> + for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
> uint8_t v1, v2;
> - uint8_t v = *src++;
> + uint8_t v = *src;
> /* nibbles are swapped for mono */
> if (st) {
> v1 = v >> 4;
> @@ -631,25 +786,20 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> }
> break;
> case CODEC_ID_ADPCM_IMA_EA_EACS:
> - samples_in_chunk = bytestream_get_le32(&src) >> (1-st);
> -
> - if (samples_in_chunk > buf_size-4-(8<<st)) {
> - src += buf_size - 4;
> - break;
> - }
> + src += 4; // skip sample count (already read)
>
> for (i=0; i<=st; i++)
> c->status[i].step_index = bytestream_get_le32(&src);
> for (i=0; i<=st; i++)
> c->status[i].predictor = bytestream_get_le32(&src);
>
> - for (; samples_in_chunk; samples_in_chunk--, src++) {
> + for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
> *samples++ = adpcm_ima_expand_nibble(&c->status[0], *src>>4,
> 3);
> *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F,
> 3);
> }
> break;
> case CODEC_ID_ADPCM_IMA_EA_SEAD:
> - for (; src < buf+buf_size; src++) {
> + for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
> *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4,
> 6);
> *samples++ = adpcm_ima_expand_nibble(&c->status[st],src[0]&0x0F,
> 6);
> }
> @@ -664,22 +814,15 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
>
> /* Each EA ADPCM frame has a 12-byte header followed by 30-byte
> pieces,
> each coding 28 stereo samples. */
> - if (buf_size < 12) {
> - av_log(avctx, AV_LOG_ERROR, "frame too small\n");
> - return AVERROR(EINVAL);
> - }
> - samples_in_chunk = AV_RL32(src);
> - if (samples_in_chunk / 28 > (buf_size - 12) / 30) {
> - av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
> - return AVERROR(EINVAL);
> - }
> - src += 4;
> +
> + src += 4; // skip sample count (already read)
> +
> current_left_sample = (int16_t)bytestream_get_le16(&src);
> previous_left_sample = (int16_t)bytestream_get_le16(&src);
> current_right_sample = (int16_t)bytestream_get_le16(&src);
> previous_right_sample = (int16_t)bytestream_get_le16(&src);
>
> - for (count1 = 0; count1 < samples_in_chunk/28;count1++) {
> + for (count1 = 0; count1 < nb_samples / 28; count1++) {
> coeff1l = ea_adpcm_table[ *src >> 4 ];
> coeff2l = ea_adpcm_table[(*src >> 4 ) + 4];
> coeff1r = ea_adpcm_table[*src & 0x0F];
> @@ -726,7 +869,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> shift[channel] = (*src & 0x0F) + 8;
> src++;
> }
> - for (count1 = 0; count1 < (buf_size - avctx->channels) /
> avctx->channels; count1++) {
> + for (count1 = 0; count1 < nb_samples / 2; count1++) {
> for(i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL
> LL (mono) */
> for(channel = 0; channel < avctx->channels; channel++) {
> int32_t sample = (int32_t)(((*(src+channel) >> i) &
> 0x0F) << 0x1C) >> shift[channel];
> @@ -740,6 +883,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> }
> src+=avctx->channels;
> }
> + /* consume whole packet */
> + src = buf + buf_size;
> break;
> }
> case CODEC_ID_ADPCM_EA_R1:
> @@ -757,14 +902,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> uint16_t *samplesC;
> const uint8_t *srcC;
> const uint8_t *src_end = buf + buf_size;
> + int count = 0;
>
> - samples_in_chunk = (big_endian ? bytestream_get_be32(&src)
> - : bytestream_get_le32(&src)) / 28;
> - if (samples_in_chunk > UINT32_MAX/(28*avctx->channels) ||
> - 28*samples_in_chunk*avctx->channels > samples_end-samples) {
> - src += buf_size - 4;
> - break;
> - }
> + src += 4; // skip sample count (already read)
>
> for (channel=0; channel<avctx->channels; channel++) {
> int32_t offset = (big_endian ? bytestream_get_be32(&src)
> @@ -783,7 +923,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> previous_sample = c->status[channel].prev_sample;
> }
>
> - for (count1=0; count1<samples_in_chunk; count1++) {
> + for (count1 = 0; count1 < nb_samples / 28; count1++) {
> if (*srcC == 0xEE) { /* only seen in R2 and R3 */
> srcC++;
> if (srcC > src_end - 30*2) break;
> @@ -817,6 +957,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> }
> }
> }
> + if (!count) {
> + count = count1;
> + } else if (count != count1) {
> + av_log(avctx, AV_LOG_WARNING, "per-channel sample count
> mismatch\n");
> + count = FFMAX(count, count1);
> + }
>
> if (avctx->codec->id != CODEC_ID_ADPCM_EA_R1) {
> c->status[channel].predictor = current_sample;
> @@ -824,16 +970,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> }
> }
>
> - src = src + buf_size - (4 + 4*avctx->channels);
> - samples += 28 * samples_in_chunk * avctx->channels;
> + out_size = count * 28 * avctx->channels * out_bps;
> + src = src_end;
> break;
> }
> case CODEC_ID_ADPCM_EA_XAS:
> - if (samples_end-samples < 32*4*avctx->channels
> - || buf_size < (4+15)*4*avctx->channels) {
> - src += buf_size;
> - break;
> - }
> for (channel=0; channel<avctx->channels; channel++) {
> int coeff[2][4], shift[4];
> short *s2, *s = &samples[channel];
> @@ -857,7 +998,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> }
> }
> }
> - samples += 32*4*avctx->channels;
> break;
> case CODEC_ID_ADPCM_IMA_AMV:
> case CODEC_ID_ADPCM_IMA_SMJPEG:
> @@ -867,7 +1007,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV)
> src+=4;
>
> - while (src < buf + buf_size) {
> + for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
> char hi, lo;
> lo = *src & 0x0F;
> hi = *src >> 4;
> @@ -879,12 +1019,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> lo, 3);
> *samples++ = adpcm_ima_expand_nibble(&c->status[0],
> hi, 3);
> - src++;
> }
> break;
> case CODEC_ID_ADPCM_CT:
> - while (src < buf + buf_size) {
> - uint8_t v = *src++;
> + for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
> + uint8_t v = *src;
> *samples++ = adpcm_ct_expand_nibble(&c->status[0 ], v >> 4 );
> *samples++ = adpcm_ct_expand_nibble(&c->status[st], v & 0x0F);
> }
> @@ -898,27 +1037,26 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> if (st)
> *samples++ = 128 * (*src++ - 0x80);
> c->status[0].step_index = 1;
> + nb_samples--;
> }
> if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_4) {
> - while (src < buf + buf_size) {
> + for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
> *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
> src[0] >> 4, 4, 0);
> *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
> src[0] & 0x0F, 4, 0);
> - src++;
> }
> } else if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_3) {
> - while (src < buf + buf_size && samples + 2 < samples_end) {
> + for (n = nb_samples / 3; n > 0; n--, src++) {
> *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
> src[0] >> 5 , 3, 0);
> *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
> (src[0] >> 2) & 0x07, 3, 0);
> *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
> src[0] & 0x03, 2, 0);
> - src++;
> }
> } else {
> - while (src < buf + buf_size && samples + 3 < samples_end) {
> + for (n = nb_samples >> (2 - st); n > 0; n--, src++) {
> *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
> src[0] >> 6 , 2, 2);
> *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
> @@ -927,7 +1065,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> (src[0] >> 2) & 0x03, 2, 2);
> *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
> src[0] & 0x03, 2, 2);
> - src++;
> }
> }
> break;
> @@ -982,10 +1119,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> c->status[i].predictor =
> av_clip_int16(c->status[i].predictor);
>
> *samples++ = c->status[i].predictor;
> - if (samples >= samples_end) {
> - av_log(avctx, AV_LOG_ERROR, "allocated output buffer
> is too small\n");
> - return -1;
> - }
> }
> }
> }
> @@ -993,8 +1126,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> break;
> }
> case CODEC_ID_ADPCM_YAMAHA:
> - while (src < buf + buf_size) {
> - uint8_t v = *src++;
> + for (n = nb_samples >> (1 - st); n > 0; n--, src++) {
> + uint8_t v = *src;
> *samples++ = adpcm_yamaha_expand_nibble(&c->status[0 ], v &
> 0x0F);
> *samples++ = adpcm_yamaha_expand_nibble(&c->status[st], v >> 4
> );
> }
> @@ -1002,17 +1135,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> case CODEC_ID_ADPCM_THP:
> {
> int table[2][16];
> - unsigned int samplecnt;
> int prev[2][2];
> int ch;
>
> - if (buf_size < 80) {
> - av_log(avctx, AV_LOG_ERROR, "frame too small\n");
> - return -1;
> - }
> -
> - src+=4;
> - samplecnt = bytestream_get_be32(&src);
> + src += 4; // skip channel size
> + src += 4; // skip number of samples (already read)
>
> for (i = 0; i < 32; i++)
> table[0][i] = (int16_t)bytestream_get_be16(&src);
> @@ -1021,16 +1148,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> for (i = 0; i < 4; i++)
> prev[0][i] = (int16_t)bytestream_get_be16(&src);
>
> - if (samplecnt >= (samples_end - samples) / (st + 1)) {
> - av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too
> small\n");
> - return -1;
> - }
> -
> for (ch = 0; ch <= st; ch++) {
> samples = (unsigned short *) data + ch;
>
> /* Read in every sample for this channel. */
> - for (i = 0; i < samplecnt / 14; i++) {
> + for (i = 0; i < nb_samples / 14; i++) {
> int index = (*src >> 4) & 7;
> unsigned int exp = 28 - (*src++ & 15);
> int factor1 = table[ch][index * 2];
> @@ -1054,17 +1176,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
> }
> }
> }
> -
> - /* In the previous loop, in case stereo is used, samples is
> - increased exactly one time too often. */
> - samples -= st;
> break;
> }
>
> default:
> return -1;
> }
> - *data_size = (uint8_t *)samples - (uint8_t *)data;
> + *data_size = out_size;
> return src - buf;
> }
>
looks sane otherwise
Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel