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.

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

Reply via email to