From 255ad8881db0fa937e3632c4937f23d29d0e423d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 15 Feb 2012 19:11:06 -0500 Subject: audio encoders: do not set coded_frame->key_frame. it is already set in avcodec_alloc_frame() --- libavcodec/roqaudioenc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'libavcodec/roqaudioenc.c') diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index e540e14c24..e2d0f3896e 100644 --- a/libavcodec/roqaudioenc.c +++ b/libavcodec/roqaudioenc.c @@ -59,7 +59,6 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) context->lastSample[0] = context->lastSample[1] = 0; avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; return 0; } -- cgit v1.2.3 From a8bdf2405c6027f45a899eaaa6ba74e97c1c2701 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 15 Feb 2012 19:26:09 -0500 Subject: check for coded_frame allocation failure in several audio encoders --- libavcodec/libgsm.c | 4 ++++ libavcodec/libopencore-amr.c | 3 +++ libavcodec/libvo-aacenc.c | 2 ++ libavcodec/libvo-amrwbenc.c | 2 ++ libavcodec/mpegaudioenc.c | 2 ++ libavcodec/pcm.c | 2 ++ libavcodec/roqaudioenc.c | 2 ++ 7 files changed, 17 insertions(+) (limited to 'libavcodec/roqaudioenc.c') diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index b917cc374d..fb7b196022 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -70,6 +70,10 @@ static av_cold int libgsm_encode_init(AVCodecContext *avctx) { } avctx->coded_frame= avcodec_alloc_frame(); + if (!avctx->coded_frame) { + gsm_destroy(avctx->priv_data); + return AVERROR(ENOMEM); + } return 0; } diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c index ded92179d3..ebbc0d90d7 100644 --- a/libavcodec/libopencore-amr.c +++ b/libavcodec/libopencore-amr.c @@ -196,10 +196,13 @@ static av_cold int amr_nb_encode_init(AVCodecContext *avctx) avctx->frame_size = 160; avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); s->enc_state = Encoder_Interface_init(s->enc_dtx); if (!s->enc_state) { av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n"); + av_freep(&avctx->coded_frame); return -1; } diff --git a/libavcodec/libvo-aacenc.c b/libavcodec/libvo-aacenc.c index 280ba27ef9..0a4a270eda 100644 --- a/libavcodec/libvo-aacenc.c +++ b/libavcodec/libvo-aacenc.c @@ -39,6 +39,8 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) int index; avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); avctx->frame_size = 1024; voGetAACEncAPI(&s->codec_api); diff --git a/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c index 5214ee6d2e..7e8721015b 100644 --- a/libavcodec/libvo-amrwbenc.c +++ b/libavcodec/libvo-amrwbenc.c @@ -87,6 +87,8 @@ static av_cold int amr_wb_encode_init(AVCodecContext *avctx) avctx->frame_size = 320; avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); s->state = E_IF_init(); diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc.c index d2b1e70900..455c4b2662 100644 --- a/libavcodec/mpegaudioenc.c +++ b/libavcodec/mpegaudioenc.c @@ -181,6 +181,8 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) } avctx->coded_frame= avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 2e0b5ec4b0..d0407453de 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -49,6 +49,8 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx) avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); avctx->block_align = avctx->channels * avctx->bits_per_coded_sample/8; avctx->coded_frame= avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index e2d0f3896e..3747f18c1b 100644 --- a/libavcodec/roqaudioenc.c +++ b/libavcodec/roqaudioenc.c @@ -59,6 +59,8 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) context->lastSample[0] = context->lastSample[1] = 0; avctx->coded_frame= avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } -- cgit v1.2.3 From 56279f1d6155a7af52526b9852ee28831d0232a6 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 22 Feb 2012 13:40:03 -0500 Subject: roqaudioenc: remove unneeded sample_fmt check --- libavcodec/roqaudioenc.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'libavcodec/roqaudioenc.c') diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index 3747f18c1b..1562417a7e 100644 --- a/libavcodec/roqaudioenc.c +++ b/libavcodec/roqaudioenc.c @@ -49,10 +49,6 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Audio must be 22050 Hz\n"); return -1; } - if (avctx->sample_fmt != AV_SAMPLE_FMT_S16) { - av_log(avctx, AV_LOG_ERROR, "Audio must be signed 16-bit\n"); - return -1; - } avctx->frame_size = ROQ_FIRST_FRAME_SIZE; -- cgit v1.2.3 From cf57c78b774a71e8379d73e892880a2df1bf93ad Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 22 Feb 2012 16:20:49 -0500 Subject: roqaudioenc: use AVCodecContext.frame_size correctly. 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 | 91 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 26 deletions(-) (limited to 'libavcodec/roqaudioenc.c') diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index 1562417a7e..9137b02035 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; + + 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, stereo ? 0x21 : 0x20); bytestream_put_byte(&out, 0x10); - bytestream_put_le32(&out, avctx->frame_size*avctx->channels); + bytestream_put_le32(&out, data_size); if (stereo) { bytestream_put_byte(&out, (context->lastSample[1])>>8); @@ -131,23 +177,15 @@ static int roq_dpcm_encode_frame(AVCodecContext *avctx, bytestream_put_le16(&out, context->lastSample[0]); /* Write the actual samples */ - samples = avctx->frame_size; - for (i=0; ichannels; ch++) - *out++ = dpcm_predict(&context->lastSample[ch], *in++); + for (i = 0; i < data_size; i++) + *out++ = dpcm_predict(&context->lastSample[i & 1], *in++); - /* Use smaller frames from now on */ - avctx->frame_size = ROQ_FRAME_SIZE; + context->input_frames++; + if (!data) + context->input_frames = FFMAX(context->input_frames, 8); /* Return the result size */ - return out - frame; -} - -static av_cold int roq_dpcm_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - - return 0; + return ROQ_HEADER_SIZE + data_size; } AVCodec ff_roq_dpcm_encoder = { @@ -158,6 +196,7 @@ AVCodec ff_roq_dpcm_encoder = { .init = roq_dpcm_encode_init, .encode = roq_dpcm_encode_frame, .close = roq_dpcm_encode_close, + .capabilities = CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("id RoQ DPCM"), }; -- cgit v1.2.3 From 3fa9a999c1fe44a1592c9b4c01956ff509b86f8a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 22 Feb 2012 18:32:19 -0500 Subject: roqaudioenc: set correct bit rate --- libavcodec/roqaudioenc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libavcodec/roqaudioenc.c') diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index 9137b02035..6f36965c8b 100644 --- a/libavcodec/roqaudioenc.c +++ b/libavcodec/roqaudioenc.c @@ -65,6 +65,8 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) } avctx->frame_size = ROQ_FRAME_SIZE; + avctx->bit_rate = (ROQ_HEADER_SIZE + ROQ_FRAME_SIZE * avctx->channels) * + (22050 / ROQ_FRAME_SIZE) * 8; context->frame_buffer = av_malloc(8 * ROQ_FRAME_SIZE * avctx->channels * sizeof(*context->frame_buffer)); -- cgit v1.2.3 From f7a2e12f2a050d9c97c63c3d60c04439aa3ef103 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 22 Feb 2012 18:33:39 -0500 Subject: roqaudioenc: return AVERROR codes instead of -1 --- libavcodec/roqaudioenc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libavcodec/roqaudioenc.c') diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index 6f36965c8b..cebc53cce5 100644 --- a/libavcodec/roqaudioenc.c +++ b/libavcodec/roqaudioenc.c @@ -57,11 +57,11 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) if (avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "Audio must be mono or stereo\n"); - return -1; + return AVERROR(EINVAL); } if (avctx->sample_rate != 22050) { av_log(avctx, AV_LOG_ERROR, "Audio must be 22050 Hz\n"); - return -1; + return AVERROR(EINVAL); } avctx->frame_size = ROQ_FRAME_SIZE; -- cgit v1.2.3