On 02/23/2012 09:27 AM, Anton Khirnov wrote:

> 
> On Wed, 22 Feb 2012 19:57:24 -0500, Justin Ruggles <[email protected]> 
> wrote:
>> It is not allowed to change mid-stream like it does currently. Instead we 
>> need
>> to buffer the first 8 frames before returning them as a single packet, then
>> only return single frame packets after that.
>> ---
>>  libavcodec/roqaudioenc.c |   93 
>> ++++++++++++++++++++++++++++++++-------------
>>  1 files changed, 66 insertions(+), 27 deletions(-)
>>
>> diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c
>> index 1562417..091692b 100644
>> --- a/libavcodec/roqaudioenc.c
>> +++ b/libavcodec/roqaudioenc.c
>> @@ -25,9 +25,8 @@
>>  #include "avcodec.h"
>>  #include "bytestream.h"
>>  
>> -#define ROQ_FIRST_FRAME_SIZE     (735*8)
>>  #define ROQ_FRAME_SIZE           735
>> -
>> +#define ROQ_HEADER_SIZE   8
>>  
>>  #define MAX_DPCM (127*127)
>>  
>> @@ -35,11 +34,26 @@
>>  typedef struct
>>  {
>>      short lastSample[2];
>> +    int input_frames;
>> +    int buffered_samples;
>> +    int16_t *frame_buffer;
>>  } ROQDPCMContext;
>>  
>> +
>> +static av_cold int roq_dpcm_encode_close(AVCodecContext *avctx)
>> +{
>> +    ROQDPCMContext *context = avctx->priv_data;
>> +
>> +    av_freep(&avctx->coded_frame);
>> +    av_freep(&context->frame_buffer);
>> +
>> +    return 0;
>> +}
>> +
>>  static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx)
>>  {
>>      ROQDPCMContext *context = avctx->priv_data;
>> +    int ret;
>>  
>>      if (avctx->channels > 2) {
>>          av_log(avctx, AV_LOG_ERROR, "Audio must be mono or stereo\n");
>> @@ -50,15 +64,27 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext 
>> *avctx)
>>          return -1;
>>      }
>>  
>> -    avctx->frame_size = ROQ_FIRST_FRAME_SIZE;
>> +    avctx->frame_size = ROQ_FRAME_SIZE;
>> +
>> +    context->frame_buffer = av_malloc(8 * ROQ_FRAME_SIZE * avctx->channels *
>> +                                      sizeof(*context->frame_buffer));
>> +    if (!context->frame_buffer) {
>> +        ret = AVERROR(ENOMEM);
>> +        goto error;
>> +    }
>>  
>>      context->lastSample[0] = context->lastSample[1] = 0;
>>  
>>      avctx->coded_frame= avcodec_alloc_frame();
>> -    if (!avctx->coded_frame)
>> -        return AVERROR(ENOMEM);
>> +    if (!avctx->coded_frame) {
>> +        ret = AVERROR(ENOMEM);
>> +        goto error;
>> +    }
>>  
>>      return 0;
>> +error:
>> +    roq_dpcm_encode_close(avctx);
>> +    return ret;
>>  }
>>  
>>  static unsigned char dpcm_predict(short *previous, short current)
>> @@ -104,25 +130,45 @@ static unsigned char dpcm_predict(short *previous, 
>> short current)
>>  static int roq_dpcm_encode_frame(AVCodecContext *avctx,
>>                  unsigned char *frame, int buf_size, void *data)
>>  {
>> -    int i, samples, stereo, ch;
>> -    const short *in;
>> -    unsigned char *out;
>> -
>> +    int i, stereo, data_size;
>> +    const int16_t *in = data;
>> +    uint8_t *out = frame;
>>      ROQDPCMContext *context = avctx->priv_data;
>>  
>>      stereo = (avctx->channels == 2);
>>  
>> +    if (!data && context->input_frames >= 8)
>> +        return 0;
>> +
>> +    if (data && context->input_frames < 8) {
>> +        memcpy(&context->frame_buffer[context->buffered_samples * 
>> avctx->channels],
>> +               in, avctx->frame_size * avctx->channels * sizeof(*in));
>> +        context->buffered_samples += avctx->frame_size;
>> +        if (context->input_frames < 7) {
>> +            context->input_frames++;
>> +            return 0;
>> +        }
>> +        in = context->frame_buffer;
>> +    }
>> +
>>      if (stereo) {
>>          context->lastSample[0] &= 0xFF00;
>>          context->lastSample[1] &= 0xFF00;
>>      }
>>  
>> -    out = frame;
>> -    in = data;
>> +    if (context->input_frames == 7 || !data)
>> +        data_size = avctx->channels * context->buffered_samples;
>> +    else
>> +        data_size = avctx->channels * avctx->frame_size;
>>  
>> -    bytestream_put_byte(&out, stereo ? 0x21 : 0x20);
>> +    if (buf_size < ROQ_HEADER_SIZE + data_size) {
>> +        av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
>> +        return AVERROR(EINVAL);
>> +    }
>> +
>> +    bytestream_put_byte(&out, avctx->channels > 1 ? 0x21 : 0x20);
> 
> Why the change from stereo?
> 
> Looks fine otherwise.


Oops, stray change... I'll fix it.

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

Reply via email to