On 10/12/2011 03:38 PM, Janne Grunau wrote:

> 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

ok, i'll fix that.

[...]
>> @@ -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

yes, there is a reason. it probably could be merged with the warning
message, but it needs to be after the data_size check.

nb_samples is the maximum number of samples that could potentially be
output based on the amount of packet data.  it could turn out to be
lower than that for some codecs.  one reason is that the coded sample
count can sometimes define how many samples should be output,
independent of the data size.  another reason is that one codec can
switch between adpcm and uncompressed pcm during decoding.  we can't
rely on the coded sample count when checking allocated data size without
also adding more checks during the decoding process.

-Justin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to