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
