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
