From 33cd32b389864f2437c94e6fd7dc109ff5f0ed06 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 29 Dec 2011 09:07:32 -0800 Subject: kgv1: use avctx->get/release_buffer(). Also fixes crashes on corrupt bitstreams. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/kgv1dec.c | 64 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index f3ffd8f09e..ca639b7c5d 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -30,10 +30,17 @@ typedef struct { AVCodecContext *avctx; - AVFrame pic; - uint16_t *prev, *cur; + AVFrame prev, cur; } KgvContext; +static void decode_flush(AVCodecContext *avctx) +{ + KgvContext * const c = avctx->priv_data; + + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); +} + static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; @@ -42,7 +49,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac int offsets[8]; uint16_t *out, *prev; int outcnt = 0, maxcnt; - int w, h, i; + int w, h, i, res; if (avpkt->size < 2) return -1; @@ -59,15 +66,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac maxcnt = w * h; - out = av_realloc(c->cur, w * h * 2); - if (!out) - return -1; - c->cur = out; - - prev = av_realloc(c->prev, w * h * 2); - if (!prev) - return -1; - c->prev = prev; + c->cur.reference = 3; + if ((res = avctx->get_buffer(avctx, &c->cur)) < 0) + return res; + out = (uint16_t *) c->cur.data[0]; + if (c->prev.data[0]) { + prev = (uint16_t *) c->prev.data[0]; + } else { + prev = NULL; + } for (i = 0; i < 8; i++) offsets[i] = -1; @@ -80,6 +87,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac out[outcnt++] = code; // rgb555 pixel coded directly } else { int count; + int inp_off; uint16_t *inp; if ((code & 0x6000) == 0x6000) { @@ -101,7 +109,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (maxcnt - start < count) break; - inp = prev + start; + if (!prev) { + av_log(avctx, AV_LOG_ERROR, + "Frame reference does not exist\n"); + break; + } + + inp = prev; + inp_off = start; } else { // copy from earlier in this frame int offset = (code & 0x1FFF) + 1; @@ -119,27 +134,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (outcnt < offset) break; - inp = out + outcnt - offset; + inp = out; + inp_off = outcnt - offset; } if (maxcnt - outcnt < count) break; - for (i = 0; i < count; i++) + for (i = inp_off; i < count + inp_off; i++) { out[outcnt++] = inp[i]; + } } } if (outcnt - maxcnt) av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt); - c->pic.data[0] = (uint8_t *)c->cur; - c->pic.linesize[0] = w * 2; - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; + *(AVFrame*)data = c->cur; - FFSWAP(uint16_t *, c->cur, c->prev); + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); + FFSWAP(AVFrame, c->cur, c->prev); return avpkt->size; } @@ -150,17 +166,14 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_RGB555; + avctx->flags |= CODEC_FLAG_EMU_EDGE; return 0; } static av_cold int decode_end(AVCodecContext *avctx) { - KgvContext * const c = avctx->priv_data; - - av_freep(&c->cur); - av_freep(&c->prev); - + decode_flush(avctx); return 0; } @@ -172,5 +185,6 @@ AVCodec ff_kgv1_decoder = { .init = decode_init, .close = decode_end, .decode = decode_frame, + .flush = decode_flush, .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"), }; -- cgit v1.2.3 From 87840eeb7115a8949ab589a82f24bc25ee647b78 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 14:48:57 -0800 Subject: avcodec: disallow reget_buffer() if pix_fmt changed. --- libavcodec/utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 67c9e36bba..285be9b72b 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -553,6 +553,8 @@ int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){ return s->get_buffer(s, pic); } + assert(s->pix_fmt == pic->pix_fmt); + /* If internal buffer type return the same buffer */ if(pic->type == FF_BUFFER_TYPE_INTERNAL) { if(s->pkt) pic->pkt_pts= s->pkt->pts; -- cgit v1.2.3 From 830f70442a87a31f7c75565e9380e3caf8333b8a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 24 Feb 2012 14:11:04 -0800 Subject: fraps: release reference buffer on pix_fmt change. Prevents crash when trying to copy from a non-existing plane in e.g. a RGB32 reference image to a YUV420P target image Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/fraps.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 3643325328..e2355d8f2f 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -139,7 +139,7 @@ static int decode_frame(AVCodecContext *avctx, uint32_t *luma1,*luma2,*cb,*cr; uint32_t offs[4]; int i, j, is_chroma, planes; - + enum PixelFormat pix_fmt; header = AV_RL32(buf); version = header & 0xff; @@ -156,12 +156,16 @@ static int decode_frame(AVCodecContext *avctx, if (header_size == 8) buf+=4; + pix_fmt = version & 1 ? PIX_FMT_BGR24 : PIX_FMT_YUVJ420P; + if (avctx->pix_fmt != pix_fmt && f->data[0]) { + avctx->release_buffer(avctx, f); + } + avctx->pix_fmt = pix_fmt; + switch(version) { case 0: default: /* Fraps v0 is a reordered YUV420 */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; - if ( (buf_size != avctx->width*avctx->height*3/2+header_size) && (buf_size != header_size) ) { av_log(avctx, AV_LOG_ERROR, @@ -209,8 +213,6 @@ static int decode_frame(AVCodecContext *avctx, case 1: /* Fraps v1 is an upside-down BGR24 */ - avctx->pix_fmt = PIX_FMT_BGR24; - if ( (buf_size != avctx->width*avctx->height*3+header_size) && (buf_size != header_size) ) { av_log(avctx, AV_LOG_ERROR, @@ -245,7 +247,6 @@ static int decode_frame(AVCodecContext *avctx, * Fraps v2 is Huffman-coded YUV420 planes * Fraps v4 is virtually the same */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; planes = 3; f->reference = 1; f->buffer_hints = FF_BUFFER_HINTS_VALID | @@ -291,7 +292,6 @@ static int decode_frame(AVCodecContext *avctx, case 3: case 5: /* Virtually the same as version 4, but is for RGB24 */ - avctx->pix_fmt = PIX_FMT_BGR24; planes = 3; f->reference = 1; f->buffer_hints = FF_BUFFER_HINTS_VALID | -- cgit v1.2.3 From 19adb0bc2d42ad88d6137efa5420e13696e721d0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 24 Jan 2012 18:10:28 -0500 Subject: vorbisdec: add a flush() function clear MDCT overlap buffer and reset previous window mode when seeking --- libavcodec/vorbisdec.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 11d6d76235..d3f6faff69 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1698,6 +1698,17 @@ static av_cold int vorbis_decode_close(AVCodecContext *avccontext) return 0; } +static av_cold void vorbis_decode_flush(AVCodecContext *avccontext) +{ + vorbis_context *vc = avccontext->priv_data; + + if (vc->saved) { + memset(vc->saved, 0, (vc->blocksize[1] / 4) * vc->audio_channels * + sizeof(*vc->saved)); + } + vc->previous_window = 0; +} + AVCodec ff_vorbis_decoder = { .name = "vorbis", .type = AVMEDIA_TYPE_AUDIO, @@ -1706,6 +1717,7 @@ AVCodec ff_vorbis_decoder = { .init = vorbis_decode_init, .close = vorbis_decode_close, .decode = vorbis_decode_frame, + .flush = vorbis_decode_flush, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), .channel_layouts = ff_vorbis_channel_layouts, -- cgit v1.2.3 From 2bb628f870264455ff2573c6f56580e7c5dc8717 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 24 Feb 2012 15:32:25 -0800 Subject: swscale: fix another integer overflow at large dimensions/rescales. --- libswscale/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/utils.c b/libswscale/utils.c index 796adb60e1..3b488ca44f 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -274,7 +274,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi int j; (*filterPos)[i]= xx; for (j=0; j Date: Tue, 21 Feb 2012 20:41:14 +0000 Subject: cdxl: fix ham6/8 on big endian Signed-off-by: Paul B Mahol Signed-off-by: Justin Ruggles --- libavcodec/cdxl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c index bb9df40122..01ebbccc19 100644 --- a/libavcodec/cdxl.c +++ b/libavcodec/cdxl.c @@ -122,7 +122,7 @@ static void cdxl_decode_ham6(CDXLVideoContext *c) g = index * 0x11 << 8; break; } - AV_WN32(out + x * 3, r | g | b); + AV_WL24(out + x * 3, r | g | b); } out += c->frame.linesize[0]; } @@ -165,7 +165,7 @@ static void cdxl_decode_ham8(CDXLVideoContext *c) g = (index << 10) | (g & (3 << 8)); break; } - AV_WN32(out + x * 3, r | g | b); + AV_WL24(out + x * 3, r | g | b); } out += c->frame.linesize[0]; } -- cgit v1.2.3 From 159a2436b03de541d533a5c331a0be66a8f3fbb5 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 21 Feb 2012 21:44:21 +0000 Subject: fate: add tests for cdxl video Signed-off-by: Paul B Mahol Signed-off-by: Justin Ruggles --- tests/Makefile | 1 + tests/fate/cdxl.mak | 14 +++++++++++++ tests/ref/fate/cdxl-ham6 | 17 +++++++++++++++ tests/ref/fate/cdxl-ham8 | 2 ++ tests/ref/fate/cdxl-pal8 | 12 +++++++++++ tests/ref/fate/cdxl-pal8-small | 47 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+) create mode 100644 tests/fate/cdxl.mak create mode 100644 tests/ref/fate/cdxl-ham6 create mode 100644 tests/ref/fate/cdxl-ham8 create mode 100644 tests/ref/fate/cdxl-pal8 create mode 100644 tests/ref/fate/cdxl-pal8-small diff --git a/tests/Makefile b/tests/Makefile index 85665d9dbc..fcbb55eccf 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -29,6 +29,7 @@ include $(SRC_PATH)/tests/fate/amrnb.mak include $(SRC_PATH)/tests/fate/amrwb.mak include $(SRC_PATH)/tests/fate/atrac.mak include $(SRC_PATH)/tests/fate/audio.mak +include $(SRC_PATH)/tests/fate/cdxl.mak include $(SRC_PATH)/tests/fate/dct.mak include $(SRC_PATH)/tests/fate/demux.mak include $(SRC_PATH)/tests/fate/dfa.mak diff --git a/tests/fate/cdxl.mak b/tests/fate/cdxl.mak new file mode 100644 index 0000000000..82ac27e430 --- /dev/null +++ b/tests/fate/cdxl.mak @@ -0,0 +1,14 @@ +FATE_CDXL += fate-cdxl-ham6 +fate-cdxl-ham6: CMD = framecrc -i $(SAMPLES)/cdxl/cat.cdxl -an -frames:v 16 + +FATE_CDXL += fate-cdxl-ham8 +fate-cdxl-ham8: CMD = framecrc -i $(SAMPLES)/cdxl/mirage.cdxl -an -frames:v 1 + +FATE_CDXL += fate-cdxl-pal8 +fate-cdxl-pal8: CMD = framecrc -i $(SAMPLES)/cdxl/maku.cdxl -pix_fmt rgb24 -frames:v 11 + +FATE_CDXL += fate-cdxl-pal8-small +fate-cdxl-pal8-small: CMD = framecrc -i $(SAMPLES)/cdxl/fruit.cdxl -an -pix_fmt rgb24 -frames:v 46 + +FATE_TESTS += $(FATE_CDXL) +fate-cdxl: $(FATE_CDXL) diff --git a/tests/ref/fate/cdxl-ham6 b/tests/ref/fate/cdxl-ham6 new file mode 100644 index 0000000000..6426d45014 --- /dev/null +++ b/tests/ref/fate/cdxl-ham6 @@ -0,0 +1,17 @@ +#tb 0: 52/525 +0, 0, 0, 1, 57600, 0x87887a7b +0, 1, 1, 1, 57600, 0x10c301d2 +0, 2, 2, 1, 57600, 0xd1a6f910 +0, 3, 3, 1, 57600, 0x20242bb9 +0, 4, 4, 1, 57600, 0xae33cb7f +0, 5, 5, 1, 57600, 0x501b82c8 +0, 6, 6, 1, 57600, 0x84199043 +0, 7, 7, 1, 57600, 0x946a6dbb +0, 8, 8, 1, 57600, 0xeacea671 +0, 9, 9, 1, 57600, 0x77b8723f +0, 10, 10, 1, 57600, 0x371cdb09 +0, 11, 11, 1, 57600, 0xa16ef5ee +0, 12, 12, 1, 57600, 0xcb6abd9e +0, 13, 13, 1, 57600, 0xb73e800f +0, 14, 14, 1, 57600, 0x368bd93e +0, 15, 15, 1, 57600, 0xcde72dc5 diff --git a/tests/ref/fate/cdxl-ham8 b/tests/ref/fate/cdxl-ham8 new file mode 100644 index 0000000000..269f1f30cf --- /dev/null +++ b/tests/ref/fate/cdxl-ham8 @@ -0,0 +1,2 @@ +#tb 0: 3/158 +0, 0, 0, 1, 67584, 0xce0cade5 diff --git a/tests/ref/fate/cdxl-pal8 b/tests/ref/fate/cdxl-pal8 new file mode 100644 index 0000000000..82d4d634c7 --- /dev/null +++ b/tests/ref/fate/cdxl-pal8 @@ -0,0 +1,12 @@ +#tb 0: 12/601 +0, 0, 0, 1, 67584, 0x5eae629b +0, 1, 1, 1, 67584, 0x32591227 +0, 2, 2, 1, 67584, 0x4e4424c7 +0, 3, 3, 1, 67584, 0x70db0134 +0, 4, 4, 1, 67584, 0x3550ed0b +0, 5, 5, 1, 67584, 0x86fe3eef +0, 6, 6, 1, 67584, 0x3414bb33 +0, 7, 7, 1, 67584, 0x667bfb91 +0, 8, 8, 1, 67584, 0x6e1a4ccb +0, 9, 9, 1, 67584, 0xf723f9ae +0, 10, 10, 1, 67584, 0x88481d5d diff --git a/tests/ref/fate/cdxl-pal8-small b/tests/ref/fate/cdxl-pal8-small new file mode 100644 index 0000000000..f7a1a465ab --- /dev/null +++ b/tests/ref/fate/cdxl-pal8-small @@ -0,0 +1,47 @@ +#tb 0: 368/11025 +0, 0, 0, 1, 30720, 0x0d552cfd +0, 1, 1, 1, 30720, 0x3cf93291 +0, 2, 2, 1, 30720, 0xe45b2868 +0, 3, 3, 1, 30720, 0xb5df289b +0, 4, 4, 1, 30720, 0x2562259e +0, 5, 5, 1, 30720, 0xbf171878 +0, 6, 6, 1, 30720, 0x695b1d73 +0, 7, 7, 1, 30720, 0x89ef1614 +0, 8, 8, 1, 30720, 0xe12a1dd9 +0, 9, 9, 1, 30720, 0x49622ffa +0, 10, 10, 1, 30720, 0xd6832703 +0, 11, 11, 1, 30720, 0xec1d0cb7 +0, 12, 12, 1, 30720, 0x8bee0525 +0, 13, 13, 1, 30720, 0x1e0cf0c4 +0, 14, 14, 1, 30720, 0xf83fd9db +0, 15, 15, 1, 30720, 0xffb0d6ab +0, 16, 16, 1, 30720, 0xe37fe239 +0, 17, 17, 1, 30720, 0x74b0f856 +0, 18, 18, 1, 30720, 0x9c88d3e1 +0, 19, 19, 1, 30720, 0x714db368 +0, 20, 20, 1, 30720, 0x6c8e8860 +0, 21, 21, 1, 30720, 0x804968e6 +0, 22, 22, 1, 30720, 0x7ac56ae4 +0, 23, 23, 1, 30720, 0xffd85cbf +0, 24, 24, 1, 30720, 0x1f8455f9 +0, 25, 25, 1, 30720, 0x3ae65296 +0, 26, 26, 1, 30720, 0x9e544ecd +0, 27, 27, 1, 30720, 0x35678e5a +0, 28, 28, 1, 30720, 0x04bae866 +0, 29, 29, 1, 30720, 0xb126ed94 +0, 30, 30, 1, 30720, 0x1720efc5 +0, 31, 31, 1, 30720, 0x4c1b01c2 +0, 32, 32, 1, 30720, 0xd0a1e866 +0, 33, 33, 1, 30720, 0x0d330789 +0, 34, 34, 1, 30720, 0xf5ac08bb +0, 35, 35, 1, 30720, 0x9abe0d83 +0, 36, 36, 1, 30720, 0xa44c02f4 +0, 37, 37, 1, 30720, 0xdc4cc688 +0, 38, 38, 1, 30720, 0x22eef3c1 +0, 39, 39, 1, 30720, 0xcfbc0d1d +0, 40, 40, 1, 30720, 0x7104ea31 +0, 41, 41, 1, 30720, 0x80daecfb +0, 42, 42, 1, 30720, 0xe1bab995 +0, 43, 43, 1, 30720, 0x43f4b896 +0, 44, 44, 1, 30720, 0xa0d2bf5c +0, 45, 45, 1, 30720, 0x3556a114 -- cgit v1.2.3 From 99cff417f381bd489f65d38b300bc0d2f3e78de5 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 24 Feb 2012 04:53:26 +0000 Subject: xwdenc: fix monow encoding Signed-off-by: Paul B Mahol Signed-off-by: Anton Khirnov --- libavcodec/xwdenc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/xwdenc.c b/libavcodec/xwdenc.c index 67fac81619..8c98ef9f5d 100644 --- a/libavcodec/xwdenc.c +++ b/libavcodec/xwdenc.c @@ -44,7 +44,7 @@ static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, { enum PixelFormat pix_fmt = avctx->pix_fmt; uint32_t pixdepth, bpp, bpad, ncolors = 0, lsize, vclass, be = 0; - uint32_t rgb[3] = { 0 }; + uint32_t rgb[3] = { 0 }, bitorder = 0; uint32_t header_size; int i, out_size, ret; uint8_t *ptr, *buf; @@ -133,6 +133,8 @@ static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ncolors = 256; break; case PIX_FMT_MONOWHITE: + be = 1; + bitorder = 1; bpp = 1; bpad = 8; vclass = XWD_STATIC_GRAY; @@ -164,7 +166,7 @@ static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream_put_be32(&buf, 0); // bitmap x offset bytestream_put_be32(&buf, be); // byte order bytestream_put_be32(&buf, 32); // bitmap unit - bytestream_put_be32(&buf, be); // bit-order of image data + bytestream_put_be32(&buf, bitorder); // bit-order of image data bytestream_put_be32(&buf, bpad); // bitmap scan-line pad in bits bytestream_put_be32(&buf, bpp); // bits per pixel bytestream_put_be32(&buf, lsize); // bytes per scan-line -- cgit v1.2.3 From 52953d61ca6b4fb6dd5b8892099e9fb9f795490c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 24 Feb 2012 13:02:05 +0100 Subject: lavc: signal no output when a NULL frame is passed to audio encoder without delay --- libavcodec/utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 285be9b72b..4d07c9c52e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -862,6 +862,8 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, int user_packet = !!avpkt->data; int nb_samples; + *got_packet_ptr = 0; + if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { av_init_packet(avpkt); avpkt->size = 0; @@ -883,7 +885,6 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, } if (avctx->codec->encode2) { - *got_packet_ptr = 0; ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); if (!ret && *got_packet_ptr) { if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) { -- cgit v1.2.3 From d55fa6f9cb1d374065229443fbb717f97df2110c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 24 Feb 2012 13:06:23 +0100 Subject: lavc: factorize setting got_packet_ptr in avcodec_encode_video2() --- libavcodec/utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 4d07c9c52e..47cab4118b 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1093,10 +1093,11 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, int ret; int user_packet = !!avpkt->data; + *got_packet_ptr = 0; + if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { av_init_packet(avpkt); avpkt->size = 0; - *got_packet_ptr = 0; return 0; } @@ -1105,7 +1106,6 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, av_assert0(avctx->codec->encode2); - *got_packet_ptr = 0; ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); if (!ret) { if (!*got_packet_ptr) -- cgit v1.2.3 From 03ca0a5b3000d705aba86ea2184df47303851f65 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 24 Feb 2012 13:07:57 +0100 Subject: lavc: merge two if()s with the same condition. --- libavcodec/utils.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 47cab4118b..e57f7ef130 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1112,10 +1112,9 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, avpkt->size = 0; else if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) avpkt->pts = avpkt->dts = frame->pts; - } - if (!ret) avctx->frame_number++; + } emms_c(); return ret; -- cgit v1.2.3 From cd40c31ee9ad2cca6f3635950b002fd46be07e98 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 24 Feb 2012 16:12:18 -0800 Subject: matroska: don't overwrite string values until read/alloc was succesful. This prevents certain tags with a default value assigned to them (as per the EBML syntax elements) from ever being assigned a NULL value. Other parts of the code rely on these being non-NULL (i.e. they don't check for NULL before e.g. using the string in strcmp() or similar), and thus in effect this prevents crashes when reading of such specific tags fails, either because of low memory or because of targeted file corruption. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavformat/matroskadec.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 4d02488b19..eadf653028 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -639,16 +639,19 @@ static int ebml_read_float(AVIOContext *pb, int size, double *num) */ static int ebml_read_ascii(AVIOContext *pb, int size, char **str) { - av_free(*str); + char *res; + /* EBML strings are usually not 0-terminated, so we allocate one * byte more, read the string and NULL-terminate it ourselves. */ - if (!(*str = av_malloc(size + 1))) + if (!(res = av_malloc(size + 1))) return AVERROR(ENOMEM); - if (avio_read(pb, (uint8_t *) *str, size) != size) { - av_freep(str); + if (avio_read(pb, (uint8_t *) res, size) != size) { + av_free(res); return AVERROR(EIO); } - (*str)[size] = '\0'; + (res)[size] = '\0'; + av_free(*str); + *str = res; return 0; } -- cgit v1.2.3 From 6c4c27adb61b2881a94ce5c7d97ee1c8adadb5fe Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 24 Feb 2012 16:27:53 -0800 Subject: kgv1: release reference picture on size change. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/kgv1dec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index ca639b7c5d..42bbcae530 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -61,8 +61,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (av_image_check_size(w, h, 0, avctx)) return -1; - if (w != avctx->width || h != avctx->height) + if (w != avctx->width || h != avctx->height) { + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); avcodec_set_dimensions(avctx, w, h); + } maxcnt = w * h; -- cgit v1.2.3 From 7600e5c5aa1d48c781f1ed363b754c3a0a631eb7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 20 Feb 2012 16:52:27 -0500 Subject: avcodec: document the use of AVCodecContext.delay for audio encoders --- libavcodec/avcodec.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 7128a83148..d1df5b4168 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1315,8 +1315,20 @@ typedef struct AVCodecContext { int frame_number; ///< audio or video frame number /** - * Number of frames the decoded output will be delayed relative to - * the encoded input. + * Encoder delay. + * + * Video: + * Number of frames the decoded output will be delayed relative to the + * encoded input. + * + * Audio: + * Number of "priming" samples added to the beginning of the stream + * during encoding. The decoded output will be delayed by this many + * samples relative to the input to the encoder. Note that this field is + * purely informational and does not directly affect the pts output by + * the encoder, which should always be based on the actual presentation + * time, including any delay. + * * - encoding: Set by libavcodec. * - decoding: unused */ -- cgit v1.2.3 From ca300d938bae4a35deaf668ef8349e396456fe0f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 9 Feb 2012 21:03:02 -0500 Subject: libspeexenc: export encoder delay through AVCodecContext.delay --- libavcodec/libspeexenc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c index 73a1d4e8c2..99fe2fe8e1 100644 --- a/libavcodec/libspeexenc.c +++ b/libavcodec/libspeexenc.c @@ -81,7 +81,6 @@ typedef struct { int cbr_quality; ///< CBR quality 0 to 10 int abr; ///< flag to enable ABR int pkt_frame_count; ///< frame count for the current packet - int lookahead; ///< encoder delay int64_t next_pts; ///< next pts, in sample_rate time base int pkt_sample_count; ///< sample count in the current packet } LibSpeexEncContext; @@ -200,8 +199,7 @@ static av_cold int encode_init(AVCodecContext *avctx) s->header.frames_per_packet = s->frames_per_packet; /* set encoding delay */ - speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &s->lookahead); - s->next_pts = -s->lookahead; + speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &avctx->delay); /* create header packet bytes from header struct */ /* note: libspeex allocates the memory for header_data, which is freed @@ -257,7 +255,8 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, /* write output if all frames for the packet have been encoded */ if (s->pkt_frame_count == s->frames_per_packet) { s->pkt_frame_count = 0; - avctx->coded_frame->pts = ff_samples_to_time_base(avctx, s->next_pts); + avctx->coded_frame->pts = ff_samples_to_time_base(avctx, s->next_pts - + avctx->delay); s->next_pts += s->pkt_sample_count; s->pkt_sample_count = 0; if (buf_size > speex_bits_nbytes(&s->bits)) { -- cgit v1.2.3 From 8e2555d3b1855374707a4d53bf93d3e07d61e05c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 20 Feb 2012 13:12:37 -0500 Subject: g722enc: check for trellis data allocation error --- libavcodec/g722enc.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c index 1cb0070649..a5ae0a5153 100644 --- a/libavcodec/g722enc.c +++ b/libavcodec/g722enc.c @@ -41,9 +41,22 @@ #define MIN_TRELLIS 0 #define MAX_TRELLIS 16 +static av_cold int g722_encode_close(AVCodecContext *avctx) +{ + G722Context *c = avctx->priv_data; + int i; + for (i = 0; i < 2; i++) { + av_freep(&c->paths[i]); + av_freep(&c->node_buf[i]); + av_freep(&c->nodep_buf[i]); + } + return 0; +} + static av_cold int g722_encode_init(AVCodecContext * avctx) { G722Context *c = avctx->priv_data; + int ret; if (avctx->channels != 1) { av_log(avctx, AV_LOG_ERROR, "Only mono tracks are allowed.\n"); @@ -62,6 +75,10 @@ static av_cold int g722_encode_init(AVCodecContext * avctx) c->paths[i] = av_mallocz(max_paths * sizeof(**c->paths)); c->node_buf[i] = av_mallocz(2 * frontier * sizeof(**c->node_buf)); c->nodep_buf[i] = av_mallocz(2 * frontier * sizeof(**c->nodep_buf)); + if (!c->paths[i] || !c->node_buf[i] || !c->nodep_buf[i]) { + ret = AVERROR(ENOMEM); + goto error; + } } } @@ -100,18 +117,9 @@ static av_cold int g722_encode_init(AVCodecContext * avctx) } return 0; -} - -static av_cold int g722_encode_close(AVCodecContext *avctx) -{ - G722Context *c = avctx->priv_data; - int i; - for (i = 0; i < 2; i++) { - av_freep(&c->paths[i]); - av_freep(&c->node_buf[i]); - av_freep(&c->nodep_buf[i]); - } - return 0; +error: + g722_encode_close(avctx); + return ret; } static const int16_t low_quant[33] = { -- cgit v1.2.3 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/libfaac.c | 1 - libavcodec/libgsm.c | 1 - libavcodec/libvorbis.c | 1 - libavcodec/mpegaudioenc.c | 1 - libavcodec/pcm.c | 1 - libavcodec/roqaudioenc.c | 1 - 6 files changed, 6 deletions(-) diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c index 7ee1f3c3fa..997aa834a4 100644 --- a/libavcodec/libfaac.c +++ b/libavcodec/libfaac.c @@ -90,7 +90,6 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) avctx->frame_size = samples_input / avctx->channels; avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; /* Set decoder specific info */ avctx->extradata_size = 0; diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index 1fa04cf9d9..b917cc374d 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -70,7 +70,6 @@ static av_cold int libgsm_encode_init(AVCodecContext *avctx) { } avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; return 0; } diff --git a/libavcodec/libvorbis.c b/libavcodec/libvorbis.c index 4d58fdc34e..b60b1f0670 100644 --- a/libavcodec/libvorbis.c +++ b/libavcodec/libvorbis.c @@ -156,7 +156,6 @@ static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) avccontext->frame_size = OGGVORBIS_FRAME_SIZE; avccontext->coded_frame = avcodec_alloc_frame(); - avccontext->coded_frame->key_frame = 1; return 0; } diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc.c index 71ea39373e..d2b1e70900 100644 --- a/libavcodec/mpegaudioenc.c +++ b/libavcodec/mpegaudioenc.c @@ -181,7 +181,6 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) } avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; return 0; } diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 594bd444fe..2e0b5ec4b0 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -49,7 +49,6 @@ 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(); - avctx->coded_frame->key_frame= 1; return 0; } 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(+) 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 c9bca801324f03746757aef8549ebd26599adec2 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 24 Feb 2012 23:27:14 -0500 Subject: avutil: add AVERROR_UNKNOWN Useful to return instead of -1 when the cause of the error is unknown, typically from an external library. --- doc/APIchanges | 3 +++ libavutil/avutil.h | 4 ++-- libavutil/error.c | 1 + libavutil/error.h | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 78e2bfc9a3..0cdb3be158 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -12,6 +12,9 @@ libavutil: 2011-04-18 API changes, most recent first: +2012-xx-xx - xxxxxxx - lavu 51.24.0 - error.h + Add AVERROR_UNKNOWN + 2012-xx-xx - xxxxxxx - lavc 54.x.x Add duration field to AVCodecParserContext diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 8d474e4546..c9c71415e9 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -153,8 +153,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 51 -#define LIBAVUTIL_VERSION_MINOR 23 -#define LIBAVUTIL_VERSION_MICRO 1 +#define LIBAVUTIL_VERSION_MINOR 24 +#define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ diff --git a/libavutil/error.c b/libavutil/error.c index a330e9f99c..21b68762d2 100644 --- a/libavutil/error.c +++ b/libavutil/error.c @@ -39,6 +39,7 @@ int av_strerror(int errnum, char *errbuf, size_t errbuf_size) case AVERROR_PROTOCOL_NOT_FOUND:errstr = "Protocol not found" ; break; case AVERROR_STREAM_NOT_FOUND: errstr = "Stream not found" ; break; case AVERROR_BUG: errstr = "Bug detected, please report the issue" ; break; + case AVERROR_UNKNOWN: errstr = "Unknown error occurred" ; break; } if (errstr) { diff --git a/libavutil/error.h b/libavutil/error.h index 2db65cb83f..11bcc5c4c4 100644 --- a/libavutil/error.h +++ b/libavutil/error.h @@ -58,6 +58,7 @@ #define AVERROR_PROTOCOL_NOT_FOUND (-MKTAG(0xF8,'P','R','O')) ///< Protocol not found #define AVERROR_STREAM_NOT_FOUND (-MKTAG(0xF8,'S','T','R')) ///< Stream not found #define AVERROR_BUG (-MKTAG( 'B','U','G',' ')) ///< Bug detected, please report the issue +#define AVERROR_UNKNOWN (-MKTAG( 'U','N','K','N')) ///< Unknown error, typically from an external library /** * Put a description of the AVERROR code errnum in errbuf. -- cgit v1.2.3 From 7a8cbb39f6154fb091597d28deba8d3bec38df64 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 15 Feb 2012 19:06:34 -0500 Subject: libfaac: improve error checking and handling in Faac_encode_init() --- libavcodec/libfaac.c | 55 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c index 997aa834a4..514d2a50f0 100644 --- a/libavcodec/libfaac.c +++ b/libavcodec/libfaac.c @@ -31,28 +31,48 @@ typedef struct FaacAudioContext { faacEncHandle faac_handle; } FaacAudioContext; + +static av_cold int Faac_encode_close(AVCodecContext *avctx) +{ + FaacAudioContext *s = avctx->priv_data; + + av_freep(&avctx->coded_frame); + av_freep(&avctx->extradata); + + if (s->faac_handle) + faacEncClose(s->faac_handle); + return 0; +} + static av_cold int Faac_encode_init(AVCodecContext *avctx) { FaacAudioContext *s = avctx->priv_data; faacEncConfigurationPtr faac_cfg; unsigned long samples_input, max_bytes_output; + int ret; /* number of channels */ if (avctx->channels < 1 || avctx->channels > 6) { av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); - return -1; + ret = AVERROR(EINVAL); + goto error; } s->faac_handle = faacEncOpen(avctx->sample_rate, avctx->channels, &samples_input, &max_bytes_output); + if (!s->faac_handle) { + av_log(avctx, AV_LOG_ERROR, "error in faacEncOpen()\n"); + ret = AVERROR_UNKNOWN; + goto error; + } /* check faac version */ faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle); if (faac_cfg->version != FAAC_CFG_VERSION) { av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version); - faacEncClose(s->faac_handle); - return -1; + ret = AVERROR(EINVAL); + goto error; } /* put the options in the configuration struct */ @@ -72,8 +92,8 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n"); - faacEncClose(s->faac_handle); - return -1; + ret = AVERROR(EINVAL); + goto error; } faac_cfg->mpegVersion = MPEG4; faac_cfg->useTns = 0; @@ -90,6 +110,10 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) avctx->frame_size = samples_input / avctx->channels; avctx->coded_frame= avcodec_alloc_frame(); + if (!avctx->coded_frame) { + ret = AVERROR(ENOMEM); + goto error; + } /* Set decoder specific info */ avctx->extradata_size = 0; @@ -101,6 +125,10 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer, &decoder_specific_info_size)) { avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) { + ret = AVERROR(ENOMEM); + goto error; + } avctx->extradata_size = decoder_specific_info_size; memcpy(avctx->extradata, buffer, avctx->extradata_size); faac_cfg->outputFormat = 0; @@ -112,10 +140,14 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) { av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n"); - return -1; + ret = AVERROR(EINVAL); + goto error; } return 0; +error: + Faac_encode_close(avctx); + return ret; } static int Faac_encode_frame(AVCodecContext *avctx, @@ -134,17 +166,6 @@ static int Faac_encode_frame(AVCodecContext *avctx, return bytes_written; } -static av_cold int Faac_encode_close(AVCodecContext *avctx) -{ - FaacAudioContext *s = avctx->priv_data; - - av_freep(&avctx->coded_frame); - av_freep(&avctx->extradata); - - faacEncClose(s->faac_handle); - return 0; -} - static const AVProfile profiles[] = { { FF_PROFILE_AAC_MAIN, "Main" }, { FF_PROFILE_AAC_LOW, "LC" }, -- cgit v1.2.3 From be60eec6680e51e4bab7599bdf90e34d837a6eae Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 21 Feb 2012 15:27:23 -0500 Subject: mpegaudioenc: return AVERROR codes instead of -1 --- libavcodec/mpegaudioenc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc.c index 455c4b2662..9ee7f2cba4 100644 --- a/libavcodec/mpegaudioenc.c +++ b/libavcodec/mpegaudioenc.c @@ -75,7 +75,7 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) if (channels <= 0 || channels > 2){ av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels); - return -1; + return AVERROR(EINVAL); } bitrate = bitrate / 1000; s->nb_channels = channels; @@ -93,7 +93,7 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) } if (i == 3){ av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq); - return -1; + return AVERROR(EINVAL); } s->freq_index = i; @@ -104,7 +104,7 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx) } if (i == 15){ av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate); - return -1; + return AVERROR(EINVAL); } s->bitrate_index = i; -- cgit v1.2.3 From 6f600ab35424823fb682b5669241edcc66590a8d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 21 Feb 2012 18:40:22 -0500 Subject: libvorbis: improve error checking in oggvorbis_encode_init() --- libavcodec/libvorbis.c | 113 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 37 deletions(-) diff --git a/libavcodec/libvorbis.c b/libavcodec/libvorbis.c index b60b1f0670..3226f86486 100644 --- a/libavcodec/libvorbis.c +++ b/libavcodec/libvorbis.c @@ -61,45 +61,63 @@ static const AVOption options[] = { }; static const AVClass class = { "libvorbis", av_default_item_name, options, LIBAVUTIL_VERSION_INT }; +static int vorbis_error_to_averror(int ov_err) +{ + switch (ov_err) { + case OV_EFAULT: return AVERROR_BUG; + case OV_EINVAL: return AVERROR(EINVAL); + case OV_EIMPL: return AVERROR(EINVAL); + default: return AVERROR_UNKNOWN; + } +} + static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext) { OggVorbisContext *context = avccontext->priv_data; double cfreq; + int ret; if (avccontext->flags & CODEC_FLAG_QSCALE) { /* variable bitrate */ - if (vorbis_encode_setup_vbr(vi, avccontext->channels, - avccontext->sample_rate, - avccontext->global_quality / (float)FF_QP2LAMBDA / 10.0)) - return -1; + float q = avccontext->global_quality / (float)FF_QP2LAMBDA; + if ((ret = vorbis_encode_setup_vbr(vi, avccontext->channels, + avccontext->sample_rate, + q / 10.0))) + goto error; } else { int minrate = avccontext->rc_min_rate > 0 ? avccontext->rc_min_rate : -1; int maxrate = avccontext->rc_min_rate > 0 ? avccontext->rc_max_rate : -1; /* constant bitrate */ - if (vorbis_encode_setup_managed(vi, avccontext->channels, - avccontext->sample_rate, minrate, - avccontext->bit_rate, maxrate)) - return -1; + if ((ret = vorbis_encode_setup_managed(vi, avccontext->channels, + avccontext->sample_rate, minrate, + avccontext->bit_rate, maxrate))) + goto error; /* variable bitrate by estimate, disable slow rate management */ if (minrate == -1 && maxrate == -1) - if (vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL)) - return -1; + if ((ret = vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL))) + goto error; } /* cutoff frequency */ if (avccontext->cutoff > 0) { cfreq = avccontext->cutoff / 1000.0; - if (vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)) - return -1; + if ((ret = vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq))) + goto error; } if (context->iblock) { - vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &context->iblock); + if ((ret = vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &context->iblock))) + goto error; } - return vorbis_encode_setup_init(vi); + if ((ret = vorbis_encode_setup_init(vi))) + goto error; + + return 0; +error: + return vorbis_error_to_averror(ret); } /* How many bytes are needed for a buffer of length 'l' */ @@ -108,32 +126,63 @@ static int xiph_len(int l) return 1 + l / 255 + l; } +static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext) +{ + OggVorbisContext *context = avccontext->priv_data; +/* ogg_packet op ; */ + + vorbis_analysis_wrote(&context->vd, 0); /* notify vorbisenc this is EOF */ + + vorbis_block_clear(&context->vb); + vorbis_dsp_clear(&context->vd); + vorbis_info_clear(&context->vi); + + av_freep(&avccontext->coded_frame); + av_freep(&avccontext->extradata); + + return 0; +} + static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) { OggVorbisContext *context = avccontext->priv_data; ogg_packet header, header_comm, header_code; uint8_t *p; unsigned int offset; + int ret; vorbis_info_init(&context->vi); - if (oggvorbis_init_encoder(&context->vi, avccontext) < 0) { + if ((ret = oggvorbis_init_encoder(&context->vi, avccontext))) { av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed\n"); - return -1; + goto error; + } + if ((ret = vorbis_analysis_init(&context->vd, &context->vi))) { + ret = vorbis_error_to_averror(ret); + goto error; + } + if ((ret = vorbis_block_init(&context->vd, &context->vb))) { + ret = vorbis_error_to_averror(ret); + goto error; } - vorbis_analysis_init(&context->vd, &context->vi); - vorbis_block_init(&context->vd, &context->vb); vorbis_comment_init(&context->vc); vorbis_comment_add_tag(&context->vc, "encoder", LIBAVCODEC_IDENT); - vorbis_analysis_headerout(&context->vd, &context->vc, &header, - &header_comm, &header_code); + if ((ret = vorbis_analysis_headerout(&context->vd, &context->vc, &header, + &header_comm, &header_code))) { + ret = vorbis_error_to_averror(ret); + goto error; + } avccontext->extradata_size = 1 + xiph_len(header.bytes) + xiph_len(header_comm.bytes) + header_code.bytes; p = avccontext->extradata = av_malloc(avccontext->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!p) { + ret = AVERROR(ENOMEM); + goto error; + } p[0] = 2; offset = 1; offset += av_xiphlacing(&p[offset], header.bytes); @@ -156,8 +205,15 @@ static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) avccontext->frame_size = OGGVORBIS_FRAME_SIZE; avccontext->coded_frame = avcodec_alloc_frame(); + if (!avccontext->coded_frame) { + ret = AVERROR(ENOMEM); + goto error; + } return 0; +error: + oggvorbis_encode_close(avccontext); + return ret; } static int oggvorbis_encode_frame(AVCodecContext *avccontext, @@ -233,23 +289,6 @@ static int oggvorbis_encode_frame(AVCodecContext *avccontext, return l; } -static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext) -{ - OggVorbisContext *context = avccontext->priv_data; -/* ogg_packet op ; */ - - vorbis_analysis_wrote(&context->vd, 0); /* notify vorbisenc this is EOF */ - - vorbis_block_clear(&context->vb); - vorbis_dsp_clear(&context->vd); - vorbis_info_clear(&context->vi); - - av_freep(&avccontext->coded_frame); - av_freep(&avccontext->extradata); - - return 0; -} - AVCodec ff_libvorbis_encoder = { .name = "libvorbis", .type = AVMEDIA_TYPE_AUDIO, -- cgit v1.2.3 From 333506c33f21f9cf2d552fe67a8a86b5e3496a5c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 21 Feb 2012 18:42:32 -0500 Subject: nellymoserenc: return AVERROR codes instead of -1 --- libavcodec/nellymoserenc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 104e4079e7..81e1d374a4 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -134,7 +134,7 @@ static av_cold int encode_init(AVCodecContext *avctx) if (avctx->channels != 1) { av_log(avctx, AV_LOG_ERROR, "Nellymoser supports only 1 channel\n"); - return -1; + return AVERROR(EINVAL); } if (avctx->sample_rate != 8000 && avctx->sample_rate != 16000 && @@ -142,7 +142,7 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->sample_rate != 22050 && avctx->sample_rate != 44100 && avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) { av_log(avctx, AV_LOG_ERROR, "Nellymoser works only with 8000, 16000, 11025, 22050 and 44100 sample rate\n"); - return -1; + return AVERROR(EINVAL); } avctx->frame_size = NELLY_SAMPLES; -- cgit v1.2.3 From 370b44cda2230cf839f7c3849a3b881650fe1bd8 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 21 Feb 2012 18:46:00 -0500 Subject: nellymoserenc: improve error checking in encode_init() --- libavcodec/nellymoserenc.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 81e1d374a4..4f351dabe4 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -127,10 +127,24 @@ static void apply_mdct(NellyMoserEncodeContext *s) s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN); } +static av_cold int encode_end(AVCodecContext *avctx) +{ + NellyMoserEncodeContext *s = avctx->priv_data; + + ff_mdct_end(&s->mdct_ctx); + + if (s->avctx->trellis) { + av_free(s->opt); + av_free(s->path); + } + + return 0; +} + static av_cold int encode_init(AVCodecContext *avctx) { NellyMoserEncodeContext *s = avctx->priv_data; - int i; + int i, ret; if (avctx->channels != 1) { av_log(avctx, AV_LOG_ERROR, "Nellymoser supports only 1 channel\n"); @@ -147,7 +161,8 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->frame_size = NELLY_SAMPLES; s->avctx = avctx; - ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0); + if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0) + goto error; ff_dsputil_init(&s->dsp, avctx); /* Generate overlap window */ @@ -158,23 +173,16 @@ static av_cold int encode_init(AVCodecContext *avctx) if (s->avctx->trellis) { s->opt = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(float )); s->path = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(uint8_t)); + if (!s->opt || !s->path) { + ret = AVERROR(ENOMEM); + goto error; + } } return 0; -} - -static av_cold int encode_end(AVCodecContext *avctx) -{ - NellyMoserEncodeContext *s = avctx->priv_data; - - ff_mdct_end(&s->mdct_ctx); - - if (s->avctx->trellis) { - av_free(s->opt); - av_free(s->path); - } - - return 0; +error: + encode_end(avctx); + return ret; } #define find_best(val, table, LUT, LUT_add, LUT_size) \ -- cgit v1.2.3 From 928672f1f193167a5876cd5e00c904d4f6b52b4a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 21 Feb 2012 18:47:50 -0500 Subject: nellymoserenc: set AVCodecContext.coded_frame --- libavcodec/nellymoserenc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 4f351dabe4..e60b0b5afa 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -137,6 +137,7 @@ static av_cold int encode_end(AVCodecContext *avctx) av_free(s->opt); av_free(s->path); } + av_freep(&avctx->coded_frame); return 0; } @@ -179,6 +180,12 @@ static av_cold int encode_init(AVCodecContext *avctx) } } + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) { + ret = AVERROR(ENOMEM); + goto error; + } + return 0; error: encode_end(avctx); -- cgit v1.2.3 From a65f7c96fce257966ca7e224cbc1ff91af81e91c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 22 Feb 2012 13:10:38 -0500 Subject: ra144enc: remove unneeded sample_fmt check --- libavcodec/ra144enc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c index c8a09a2ed2..302f66b410 100644 --- a/libavcodec/ra144enc.c +++ b/libavcodec/ra144enc.c @@ -38,10 +38,6 @@ static av_cold int ra144_encode_init(AVCodecContext * avctx) RA144Context *ractx; int ret; - if (avctx->sample_fmt != AV_SAMPLE_FMT_S16) { - av_log(avctx, AV_LOG_ERROR, "invalid sample format\n"); - return -1; - } if (avctx->channels != 1) { av_log(avctx, AV_LOG_ERROR, "invalid number of channels: %d\n", avctx->channels); -- cgit v1.2.3 From 03359ebcf99d2949f44069836224273d383b1638 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 22 Feb 2012 13:29:09 -0500 Subject: ra144enc: set AVCodecContext.coded_frame --- libavcodec/ra144enc.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c index 302f66b410..5977928362 100644 --- a/libavcodec/ra144enc.c +++ b/libavcodec/ra144enc.c @@ -33,6 +33,15 @@ #include "ra144.h" +static av_cold int ra144_encode_close(AVCodecContext *avctx) +{ + RA144Context *ractx = avctx->priv_data; + ff_lpc_end(&ractx->lpc_ctx); + av_freep(&avctx->coded_frame); + return 0; +} + + static av_cold int ra144_encode_init(AVCodecContext * avctx) { RA144Context *ractx; @@ -51,15 +60,19 @@ static av_cold int ra144_encode_init(AVCodecContext * avctx) ractx->avctx = avctx; ret = ff_lpc_init(&ractx->lpc_ctx, avctx->frame_size, LPC_ORDER, FF_LPC_TYPE_LEVINSON); - return ret; -} + if (ret < 0) + goto error; + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) { + ret = AVERROR(ENOMEM); + goto error; + } -static av_cold int ra144_encode_close(AVCodecContext *avctx) -{ - RA144Context *ractx = avctx->priv_data; - ff_lpc_end(&ractx->lpc_ctx); return 0; +error: + ra144_encode_close(avctx); + return ret; } -- cgit v1.2.3 From 4b7f8838e865bb2f803310ac2b27f9166309e4a0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 22 Feb 2012 13:35:38 -0500 Subject: ra144enc: use int16_t* for input samples rather than void* --- libavcodec/ra144enc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c index 5977928362..ff8316912f 100644 --- a/libavcodec/ra144enc.c +++ b/libavcodec/ra144enc.c @@ -441,6 +441,7 @@ static int ra144_encode_frame(AVCodecContext *avctx, uint8_t *frame, int16_t block_coefs[NBLOCKS][LPC_ORDER]; int lpc_refl[LPC_ORDER]; /**< reflection coefficients of the frame */ unsigned int refl_rms[NBLOCKS]; /**< RMS of the reflection coefficients */ + const int16_t *samples = data; int energy = 0; int i, idx; @@ -515,7 +516,7 @@ static int ra144_encode_frame(AVCodecContext *avctx, uint8_t *frame, ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0]; FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]); for (i = 0; i < NBLOCKS * BLOCKSIZE; i++) - ractx->curr_block[i] = *((int16_t *)data + i) >> 2; + ractx->curr_block[i] = samples[i] >> 2; return FRAMESIZE; } -- 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(-) 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(-) 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(+) 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(-) 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 From be8d812c9635f31f69c30dff9ebf565a07a7dab7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 22 Feb 2012 19:23:18 -0500 Subject: vorbisenc: check all allocations for failure --- libavcodec/vorbisenc.c | 127 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 92 insertions(+), 35 deletions(-) diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index 00fe402d3e..9257333c1c 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -155,7 +155,7 @@ static int cb_lookup_vals(int lookup, int dimentions, int entries) return 0; } -static void ready_codebook(vorbis_enc_codebook *cb) +static int ready_codebook(vorbis_enc_codebook *cb) { int i; @@ -167,6 +167,8 @@ static void ready_codebook(vorbis_enc_codebook *cb) int vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); cb->dimentions = av_malloc(sizeof(float) * cb->nentries * cb->ndimentions); cb->pow2 = av_mallocz(sizeof(float) * cb->nentries); + if (!cb->dimentions || !cb->pow2) + return AVERROR(ENOMEM); for (i = 0; i < cb->nentries; i++) { float last = 0; int j; @@ -187,13 +189,16 @@ static void ready_codebook(vorbis_enc_codebook *cb) cb->pow2[i] /= 2.; } } + return 0; } -static void ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) +static int ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) { int i; assert(rc->type == 2); rc->maxes = av_mallocz(sizeof(float[2]) * rc->classifications); + if (!rc->maxes) + return AVERROR(ENOMEM); for (i = 0; i < rc->classifications; i++) { int j; vorbis_enc_codebook * cb; @@ -223,15 +228,16 @@ static void ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) rc->maxes[i][0] += 0.8; rc->maxes[i][1] += 0.8; } + return 0; } -static void create_vorbis_context(vorbis_enc_context *venc, - AVCodecContext *avccontext) +static int create_vorbis_context(vorbis_enc_context *venc, + AVCodecContext *avccontext) { vorbis_enc_floor *fc; vorbis_enc_residue *rc; vorbis_enc_mapping *mc; - int i, book; + int i, book, ret; venc->channels = avccontext->channels; venc->sample_rate = avccontext->sample_rate; @@ -239,6 +245,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->ncodebooks = FF_ARRAY_ELEMS(cvectors); venc->codebooks = av_malloc(sizeof(vorbis_enc_codebook) * venc->ncodebooks); + if (!venc->codebooks) + return AVERROR(ENOMEM); // codebook 0..14 - floor1 book, values 0..255 // codebook 15 residue masterbook @@ -255,27 +263,36 @@ static void create_vorbis_context(vorbis_enc_context *venc, cb->lens = av_malloc(sizeof(uint8_t) * cb->nentries); cb->codewords = av_malloc(sizeof(uint32_t) * cb->nentries); + if (!cb->lens || !cb->codewords) + return AVERROR(ENOMEM); memcpy(cb->lens, cvectors[book].clens, cvectors[book].len); memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len); if (cb->lookup) { vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); cb->quantlist = av_malloc(sizeof(int) * vals); + if (!cb->quantlist) + return AVERROR(ENOMEM); for (i = 0; i < vals; i++) cb->quantlist[i] = cvectors[book].quant[i]; } else { cb->quantlist = NULL; } - ready_codebook(cb); + if ((ret = ready_codebook(cb)) < 0) + return ret; } venc->nfloors = 1; venc->floors = av_malloc(sizeof(vorbis_enc_floor) * venc->nfloors); + if (!venc->floors) + return AVERROR(ENOMEM); // just 1 floor fc = &venc->floors[0]; fc->partitions = NUM_FLOOR_PARTITIONS; fc->partition_to_class = av_malloc(sizeof(int) * fc->partitions); + if (!fc->partition_to_class) + return AVERROR(ENOMEM); fc->nclasses = 0; for (i = 0; i < fc->partitions; i++) { static const int a[] = {0, 1, 2, 2, 3, 3, 4, 4}; @@ -284,6 +301,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, } fc->nclasses++; fc->classes = av_malloc(sizeof(vorbis_enc_floor_class) * fc->nclasses); + if (!fc->classes) + return AVERROR(ENOMEM); for (i = 0; i < fc->nclasses; i++) { vorbis_enc_floor_class * c = &fc->classes[i]; int j, books; @@ -292,6 +311,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, c->masterbook = floor_classes[i].masterbook; books = (1 << c->subclass); c->books = av_malloc(sizeof(int) * books); + if (!c->books) + return AVERROR(ENOMEM); for (j = 0; j < books; j++) c->books[j] = floor_classes[i].nbooks[j]; } @@ -303,6 +324,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, fc->values += fc->classes[fc->partition_to_class[i]].dim; fc->list = av_malloc(sizeof(vorbis_floor1_entry) * fc->values); + if (!fc->list) + return AVERROR(ENOMEM); fc->list[0].x = 0; fc->list[1].x = 1 << fc->rangebits; for (i = 2; i < fc->values; i++) { @@ -317,6 +340,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->nresidues = 1; venc->residues = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues); + if (!venc->residues) + return AVERROR(ENOMEM); // single residue rc = &venc->residues[0]; @@ -327,6 +352,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, rc->classifications = 10; rc->classbook = 15; rc->books = av_malloc(sizeof(*rc->books) * rc->classifications); + if (!rc->books) + return AVERROR(ENOMEM); { static const int8_t a[10][8] = { { -1, -1, -1, -1, -1, -1, -1, -1, }, @@ -342,19 +369,26 @@ static void create_vorbis_context(vorbis_enc_context *venc, }; memcpy(rc->books, a, sizeof a); } - ready_residue(rc, venc); + if ((ret = ready_residue(rc, venc)) < 0) + return ret; venc->nmappings = 1; venc->mappings = av_malloc(sizeof(vorbis_enc_mapping) * venc->nmappings); + if (!venc->mappings) + return AVERROR(ENOMEM); // single mapping mc = &venc->mappings[0]; mc->submaps = 1; mc->mux = av_malloc(sizeof(int) * venc->channels); + if (!mc->mux) + return AVERROR(ENOMEM); for (i = 0; i < venc->channels; i++) mc->mux[i] = 0; mc->floor = av_malloc(sizeof(int) * mc->submaps); mc->residue = av_malloc(sizeof(int) * mc->submaps); + if (!mc->floor || !mc->residue) + return AVERROR(ENOMEM); for (i = 0; i < mc->submaps; i++) { mc->floor[i] = 0; mc->residue[i] = 0; @@ -362,6 +396,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, mc->coupling_steps = venc->channels == 2 ? 1 : 0; mc->magnitude = av_malloc(sizeof(int) * mc->coupling_steps); mc->angle = av_malloc(sizeof(int) * mc->coupling_steps); + if (!mc->magnitude || !mc->angle) + return AVERROR(ENOMEM); if (mc->coupling_steps) { mc->magnitude[0] = 0; mc->angle[0] = 1; @@ -369,6 +405,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->nmodes = 1; venc->modes = av_malloc(sizeof(vorbis_enc_mode) * venc->nmodes); + if (!venc->modes) + return AVERROR(ENOMEM); // single mode venc->modes[0].blockflag = 0; @@ -379,12 +417,18 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->samples = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1])); venc->floor = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); venc->coeffs = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); + if (!venc->saved || !venc->samples || !venc->floor || !venc->coeffs) + return AVERROR(ENOMEM); venc->win[0] = ff_vorbis_vwin[venc->log2_blocksize[0] - 6]; venc->win[1] = ff_vorbis_vwin[venc->log2_blocksize[1] - 6]; - ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0); - ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0); + if ((ret = ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0)) < 0) + return ret; + if ((ret = ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0)) < 0) + return ret; + + return 0; } static void put_float(PutBitContext *pb, float f) @@ -647,6 +691,8 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out) len = hlens[0] + hlens[1] + hlens[2]; p = *out = av_mallocz(64 + len + len/255); + if (!p) + return AVERROR(ENOMEM); *p++ = 2; p += av_xiphlacing(p, hlens[0]); @@ -952,32 +998,6 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *a return 1; } -static av_cold int vorbis_encode_init(AVCodecContext *avccontext) -{ - vorbis_enc_context *venc = avccontext->priv_data; - - if (avccontext->channels != 2) { - av_log(avccontext, AV_LOG_ERROR, "Current Libav Vorbis encoder only supports 2 channels.\n"); - return -1; - } - - create_vorbis_context(venc, avccontext); - - if (avccontext->flags & CODEC_FLAG_QSCALE) - venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA / 10.; - else - venc->quality = 0.03; - venc->quality *= venc->quality; - - avccontext->extradata_size = put_main_header(venc, (uint8_t**)&avccontext->extradata); - - avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1); - - avccontext->coded_frame = avcodec_alloc_frame(); - avccontext->coded_frame->key_frame = 1; - - return 0; -} static int vorbis_encode_frame(AVCodecContext *avccontext, unsigned char *packets, @@ -1102,6 +1122,43 @@ static av_cold int vorbis_encode_close(AVCodecContext *avccontext) return 0 ; } +static av_cold int vorbis_encode_init(AVCodecContext *avccontext) +{ + vorbis_enc_context *venc = avccontext->priv_data; + int ret; + + if (avccontext->channels != 2) { + av_log(avccontext, AV_LOG_ERROR, "Current Libav Vorbis encoder only supports 2 channels.\n"); + return -1; + } + + if ((ret = create_vorbis_context(venc, avccontext)) < 0) + goto error; + + if (avccontext->flags & CODEC_FLAG_QSCALE) + venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA / 10.; + else + venc->quality = 0.03; + venc->quality *= venc->quality; + + if ((ret = put_main_header(venc, (uint8_t**)&avccontext->extradata)) < 0) + goto error; + avccontext->extradata_size = ret; + + avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1); + + avccontext->coded_frame = avcodec_alloc_frame(); + if (!avccontext->coded_frame) { + ret = AVERROR(ENOMEM); + goto error; + } + + return 0; +error: + vorbis_encode_close(avccontext); + return ret; +} + AVCodec ff_vorbis_encoder = { .name = "vorbis", .type = AVMEDIA_TYPE_AUDIO, -- cgit v1.2.3 From 0a9efe4c6eb48bf863e2e630b3ad907a198961c5 Mon Sep 17 00:00:00 2001 From: Tim Walker Date: Sat, 25 Feb 2012 22:33:48 +0100 Subject: mlp_parser: fix the channel mask value used for the top surround channel Signed-off-by: Justin Ruggles --- libavcodec/mlp_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c index 3bf38c7f35..1879e0044f 100644 --- a/libavcodec/mlp_parser.c +++ b/libavcodec/mlp_parser.c @@ -82,7 +82,7 @@ static const uint64_t thd_layout[13] = { AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, // LRc AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, // LRrs AV_CH_BACK_CENTER, // Cs - AV_CH_TOP_BACK_CENTER, // Ts + AV_CH_TOP_CENTER, // Ts AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, // LRsd AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT, // LRw AV_CH_TOP_FRONT_CENTER, // Cvh -- cgit v1.2.3