From 488eec10443c4a498a926fa4f57f74be892c461a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 18 Nov 2011 11:16:23 +0100 Subject: lavc: update doxy to use nondeprecated API. --- libavcodec/avcodec.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 8005af4fd5..43abcd82be 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1199,7 +1199,7 @@ struct AVCodecInternal; typedef struct AVCodecContext { /** * information on struct for av_log - * - set by avcodec_alloc_context + * - set by avcodec_alloc_context3 */ const AVClass *av_class; /** @@ -2897,8 +2897,8 @@ typedef struct AVCodecContext { * For SUBTITLE_ASS subtitle type, it should contain the whole ASS * [Script Info] and [V4+ Styles] section, plus the [Events] line and * the Format line following. It shouldn't include any Dialogue line. - * - encoding: Set/allocated/freed by user (before avcodec_open()) - * - decoding: Set/allocated/freed by libavcodec (by avcodec_open()) + * - encoding: Set/allocated/freed by user (before avcodec_open2()) + * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2()) */ uint8_t *subtitle_header; int subtitle_header_size; @@ -3725,7 +3725,7 @@ AVCodecContext *avcodec_alloc_context2(enum AVMediaType); * resulting struct can be deallocated by simply calling av_free(). * * @param codec if non-NULL, allocate private data and initialize defaults - * for the given codec. It is illegal to then call avcodec_open() + * for the given codec. It is illegal to then call avcodec_open2() * with a different codec. * * @return An AVCodecContext filled with default values or NULL on failure. @@ -3736,7 +3736,7 @@ AVCodecContext *avcodec_alloc_context3(AVCodec *codec); /** * Copy the settings of the source AVCodecContext into the destination * AVCodecContext. The resulting destination codec context will be - * unopened, i.e. you are required to call avcodec_open() before you + * unopened, i.e. you are required to call avcodec_open2() before you * can use this AVCodecContext to decode/encode video/audio data. * * @param dest target codec context, should be initialized with @@ -3800,7 +3800,7 @@ enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum #if FF_API_THREAD_INIT /** - * @deprecated Set s->thread_count before calling avcodec_open() instead of calling this. + * @deprecated Set s->thread_count before calling avcodec_open2() instead of calling this. */ attribute_deprecated int avcodec_thread_init(AVCodecContext *s, int thread_count); @@ -3846,7 +3846,7 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); /** * Initialize the AVCodecContext to use the given AVCodec. Prior to using this - * function the context has to be allocated with avcodec_alloc_context(). + * function the context has to be allocated with avcodec_alloc_context3(). * * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for @@ -3861,9 +3861,9 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); * if (!codec) * exit(1); * - * context = avcodec_alloc_context(); + * context = avcodec_alloc_context3(codec); * - * if (avcodec_open(context, codec, opts) < 0) + * if (avcodec_open2(context, codec, opts) < 0) * exit(1); * @endcode * -- cgit v1.2.3 From 51f316a997d7a9d3f7571f89392ad5767665b11f Mon Sep 17 00:00:00 2001 From: "K.Y.H" Date: Fri, 11 Nov 2011 00:30:39 +0100 Subject: cook: fix apparent typo in extradata parsing Signed-off-by: Anton Khirnov --- libavcodec/cook.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 5a3822d4c7..186c3e70dd 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1075,7 +1075,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr); extradata_size -= 8; } - if (avctx->extradata_size >= 8){ + if (extradata_size >= 8) { bytestream_get_be32(&edata_ptr); //Unknown unused q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr); q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr); -- cgit v1.2.3 From 5ace144fe0b7519c389d3ddcdcf7082b4e89b0df Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 9 Nov 2011 19:40:59 +0100 Subject: fraps: check for overread. Signed-off-by: Anton Khirnov --- libavcodec/fraps.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index ed33c3eabf..1444eda979 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -111,6 +111,10 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, */ if(j) dst[i] += dst[i - stride]; else if(Uoff) dst[i] += 0x80; + if (get_bits_left(&gb) < 0) { + free_vlc(&vlc); + return AVERROR_INVALIDDATA; + } } dst += stride; } -- cgit v1.2.3 From 1484b5dec5e05c11a2e8619d8838b3d276984cb7 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 9 Nov 2011 14:04:22 +0100 Subject: flicvideo: check extradata_size before accessing extradata. Signed-off-by: Anton Khirnov --- libavcodec/flicvideo.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index a78fe5e077..8e8a813258 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -81,6 +81,12 @@ static av_cold int flic_decode_init(AVCodecContext *avctx) unsigned char *fli_header = (unsigned char *)avctx->extradata; int depth; + if (avctx->extradata_size != 12 && + avctx->extradata_size != 128) { + av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n"); + return AVERROR_INVALIDDATA; + } + s->avctx = avctx; s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */ @@ -90,9 +96,6 @@ static av_cold int flic_decode_init(AVCodecContext *avctx) /* special case for magic carpet FLIs */ s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE; depth = 8; - } else if (s->avctx->extradata_size != 128) { - av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n"); - return -1; } else { depth = AV_RL16(&fli_header[12]); } -- cgit v1.2.3 From 785baa738a7c6b5bfc6ade2a7c6fade3056eeb26 Mon Sep 17 00:00:00 2001 From: Reimar Döffinger Date: Sat, 5 Nov 2011 21:11:37 +0100 Subject: nuv: use FFALIGN. Signed-off-by: Anton Khirnov --- libavcodec/nuv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index 73aec433f3..7bace2ec40 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -107,8 +107,8 @@ static void get_quant_quality(NuvContext *c, int quality) { static int codec_reinit(AVCodecContext *avctx, int width, int height, int quality) { NuvContext *c = avctx->priv_data; - width = (width + 1) & ~1; - height = (height + 1) & ~1; + width = FFALIGN(width, 2); + height = FFALIGN(height, 2); if (quality >= 0) get_quant_quality(c, quality); if (width != c->width || height != c->height) { -- cgit v1.2.3 From f6afacdb3b708720c9fb85984b4f7fdbca2b2036 Mon Sep 17 00:00:00 2001 From: Reimar Döffinger Date: Sat, 5 Nov 2011 23:13:07 +0100 Subject: nuv: check per-frame header for validity. Since it contains dimensions parsing an invalid one has rather annoying effects. Signed-off-by: Anton Khirnov --- libavcodec/nuv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index 7bace2ec40..94962b5843 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -184,9 +184,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, } if (c->codec_frameheader) { int w, h, q; - if (buf_size < 12) { - av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n"); - return -1; + if (buf[0] != 'V' || buf_size < 12) { + av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame (wrong codec_tag?)\n"); + return AVERROR_INVALIDDATA; } w = AV_RL16(&buf[6]); h = AV_RL16(&buf[8]); -- cgit v1.2.3 From 7a62ddb6895f29ff56f65429fdda0bdde4e30265 Mon Sep 17 00:00:00 2001 From: Reimar Döffinger Date: Sat, 5 Nov 2011 22:26:42 +0100 Subject: rtjpeg: check get_block return value for error. This avoids crashes due to reading out-of-bounds. Signed-off-by: Anton Khirnov --- libavcodec/rtjpeg.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c index 8d1f28a436..dac7993955 100644 --- a/libavcodec/rtjpeg.c +++ b/libavcodec/rtjpeg.c @@ -114,24 +114,25 @@ int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, init_get_bits(&gb, buf, buf_size * 8); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { +#define BLOCK(quant, dst, stride) do { \ + int res = get_block(&gb, block, c->scan, quant); \ + if (res < 0) \ + return res; \ + if (res > 0) \ + c->dsp->idct_put(dst, stride, block); \ +} while (0) DCTELEM *block = c->block; - if (get_block(&gb, block, c->scan, c->lquant) > 0) - c->dsp->idct_put(y1, f->linesize[0], block); + BLOCK(c->lquant, y1, f->linesize[0]); y1 += 8; - if (get_block(&gb, block, c->scan, c->lquant) > 0) - c->dsp->idct_put(y1, f->linesize[0], block); + BLOCK(c->lquant, y1, f->linesize[0]); y1 += 8; - if (get_block(&gb, block, c->scan, c->lquant) > 0) - c->dsp->idct_put(y2, f->linesize[0], block); + BLOCK(c->lquant, y2, f->linesize[0]); y2 += 8; - if (get_block(&gb, block, c->scan, c->lquant) > 0) - c->dsp->idct_put(y2, f->linesize[0], block); + BLOCK(c->lquant, y2, f->linesize[0]); y2 += 8; - if (get_block(&gb, block, c->scan, c->cquant) > 0) - c->dsp->idct_put(u, f->linesize[1], block); + BLOCK(c->cquant, u, f->linesize[1]); u += 8; - if (get_block(&gb, block, c->scan, c->cquant) > 0) - c->dsp->idct_put(v, f->linesize[2], block); + BLOCK(c->cquant, v, f->linesize[2]); v += 8; } y1 += 2 * 8 * (f->linesize[0] - w); -- cgit v1.2.3 From 7fb55e0b02385ae0905af73a52c3db87d08777da Mon Sep 17 00:00:00 2001 From: Reimar Döffinger Date: Sat, 5 Nov 2011 22:07:22 +0100 Subject: rtjpeg: simplify get_block() by using get_bits_left. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Reimar Döffinger Signed-off-by: Anton Khirnov --- libavcodec/rtjpeg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c index dac7993955..35ab090cb2 100644 --- a/libavcodec/rtjpeg.c +++ b/libavcodec/rtjpeg.c @@ -56,7 +56,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc // number of non-zero coefficients coeff = get_bits(gb, 6); - if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits) + if (get_bits_left(gb) < (coeff << 1)) return -1; // normally we would only need to clear the (63 - coeff) last values, @@ -73,7 +73,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc // 4 bits per coefficient ALIGN(4); - if (get_bits_count(gb) + (coeff << 2) >= gb->size_in_bits) + if (get_bits_left(gb) < (coeff << 2)) return -1; while (coeff) { ac = get_sbits(gb, 4); @@ -84,7 +84,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc // 8 bits per coefficient ALIGN(8); - if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits) + if (get_bits_left(gb) < (coeff << 3)) return -1; while (coeff) { ac = get_sbits(gb, 8); -- cgit v1.2.3 From 3bd1162a52cafc1bb758b25636e857c94fd3999c Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 25 Nov 2011 17:51:10 +0000 Subject: gif: fix invalid signed shifts Signed-off-by: Mans Rullgard --- libavcodec/gifdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index bf40da183d..9bac254c59 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -96,11 +96,11 @@ static int gif_read_image(GifState *s) n = (1 << bits_per_pixel); spal = palette; for(i = 0; i < n; i++) { - s->image_palette[i] = (0xff << 24) | AV_RB24(spal); + s->image_palette[i] = (0xffu << 24) | AV_RB24(spal); spal += 3; } for(; i < 256; i++) - s->image_palette[i] = (0xff << 24); + s->image_palette[i] = (0xffu << 24); /* handle transparency */ if (s->transparent_color_index >= 0) s->image_palette[s->transparent_color_index] = 0; -- cgit v1.2.3 From 93c286e54f5f695c9352d0034f5a417b79aecc2f Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 25 Nov 2011 18:16:44 +0000 Subject: qtrle: simplify 32-bit decode using intreadwrite macros Signed-off-by: Mans Rullgard --- libavcodec/qtrle.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index 8854fb2b96..0c74798226 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -328,7 +328,6 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int int rle_code; int pixel_ptr; int row_inc = s->frame.linesize[0]; - unsigned char a, r, g, b; unsigned int argb; unsigned char *rgb = s->frame.data[0]; int pixel_limit = s->frame.linesize[0] * s->avctx->height; @@ -347,16 +346,13 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int /* decode the run length code */ rle_code = -rle_code; CHECK_STREAM_PTR(4); - a = s->buf[stream_ptr++]; - r = s->buf[stream_ptr++]; - g = s->buf[stream_ptr++]; - b = s->buf[stream_ptr++]; - argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); + argb = AV_RB32(s->buf + stream_ptr); + stream_ptr += 4; CHECK_PIXEL_PTR(rle_code * 4); while (rle_code--) { - *(unsigned int *)(&rgb[pixel_ptr]) = argb; + AV_WN32A(rgb + pixel_ptr, argb); pixel_ptr += 4; } } else { @@ -365,13 +361,10 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int /* copy pixels directly to output */ while (rle_code--) { - a = s->buf[stream_ptr++]; - r = s->buf[stream_ptr++]; - g = s->buf[stream_ptr++]; - b = s->buf[stream_ptr++]; - argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); - *(unsigned int *)(&rgb[pixel_ptr]) = argb; - pixel_ptr += 4; + argb = AV_RB32(s->buf + stream_ptr); + AV_WN32A(rgb + pixel_ptr, argb); + stream_ptr += 4; + pixel_ptr += 4; } } } -- cgit v1.2.3 From 644bff6c9bf15b5ed723a893236dbc8c29579c93 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 25 Nov 2011 18:46:35 +0000 Subject: apedec: fix signed integer overflows This bit manipulation is equivalent but avoids undefined shifts and overflows. Signed-off-by: Mans Rullgard --- libavcodec/apedec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 6c3d29e3bb..7702b291c8 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -690,7 +690,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, /* Update the adaption coefficients */ absres = FFABS(res); if (absres) - *f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> + *f->adaptcoeffs = ((res & (-1<<31)) ^ (-1<<30)) >> (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3)); else *f->adaptcoeffs = 0; -- cgit v1.2.3 From b7581b5c839d1e293bb9dc34352a76df9d3158a9 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 25 Nov 2011 20:43:05 +0000 Subject: cook: use a table for xor key rotation This is simpler and avoids an invalid shift by 32 in the aligned case. Signed-off-by: Mans Rullgard --- libavcodec/cook.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 186c3e70dd..8b0a351495 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -273,6 +273,10 @@ static av_cold void init_cplscales_table (COOKContext *q) { */ static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ + static const uint32_t tab[4] = { + AV_BE2NE32C(0x37c511f2), AV_BE2NE32C(0xf237c511), + AV_BE2NE32C(0x11f237c5), AV_BE2NE32C(0xc511f237), + }; int i, off; uint32_t c; const uint32_t* buf; @@ -285,7 +289,7 @@ static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes) off = (intptr_t)inbuffer & 3; buf = (const uint32_t*) (inbuffer - off); - c = av_be2ne32((0x37c511f2 >> (off*8)) | (0x37c511f2 << (32-(off*8)))); + c = tab[off]; bytes += 3 + off; for (i = 0; i < bytes/4; i++) obuf[i] = c ^ buf[i]; -- cgit v1.2.3 From 3d1af11df49c9bd27f6677ec2fa327b379144e11 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 00:22:28 +0000 Subject: sol: use AV_RL32 instead of raw pointer cast Signed-off-by: Mans Rullgard --- libavformat/sol.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavformat/sol.c b/libavformat/sol.c index 55accc2473..0fd4259651 100644 --- a/libavformat/sol.c +++ b/libavformat/sol.c @@ -23,7 +23,7 @@ * Based on documents from Game Audio Player and own research */ -#include "libavutil/bswap.h" +#include "libavutil/intreadwrite.h" #include "avformat.h" #include "pcm.h" @@ -33,8 +33,7 @@ static int sol_probe(AVProbeData *p) { /* check file header */ - uint16_t magic; - magic=av_le2ne16(*((uint16_t*)p->buf)); + uint16_t magic = AV_RL32(p->buf); if ((magic == 0x0B8D || magic == 0x0C0D || magic == 0x0C8D) && p->buf[2] == 'S' && p->buf[3] == 'O' && p->buf[4] == 'L' && p->buf[5] == 0) -- cgit v1.2.3 From e524eadbf8ac568fcab7fa8f9520fad013beb91a Mon Sep 17 00:00:00 2001 From: Cheng Sun Date: Sat, 26 Nov 2011 10:45:36 -0800 Subject: [PATCH] Fix crash when initializing multi-threaded decoding for corrupted file. Signed-off-by: Ronald S. Bultje --- libavcodec/pthread.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 3364376a66..dae28e6f5e 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -651,7 +651,8 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count) pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); - pthread_join(p->thread, NULL); + if (p->thread) + pthread_join(p->thread, NULL); if (codec->close) codec->close(p->avctx); -- cgit v1.2.3 From 171ec812235a5d22fa421242351ee2da5a96c3ba Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 14:50:23 +0000 Subject: rv34: fix signed multiplication overflow Multiply by unsigned 0x01010101 to replicate bytes into 32-bit word. Signed-off-by: Mans Rullgard --- libavcodec/rv34.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 091d49fdb5..098f7b5a24 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -933,7 +933,7 @@ static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN; } if(!right && up){ - topleft = dst[-stride + 3] * 0x01010101; + topleft = dst[-stride + 3] * 0x01010101u; prev = (uint8_t*)&topleft; } r->h.pred4x4[itype](dst, prev, stride); -- cgit v1.2.3 From e4faa31a0a68dbff320b419a3a73d6b028d770d5 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 15:16:29 +0000 Subject: svq1dec: use sign_extend() Signed-off-by: Mans Rullgard --- libavcodec/svq1dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index a604f1dc96..8569615aa9 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -317,9 +317,9 @@ static int svq1_decode_motion_vector (GetBitContext *bitbuf, svq1_pmv *mv, svq1_ /* add median of motion vector predictors and clip result */ if (i == 1) - mv->y = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; + mv->y = sign_extend(diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y), 6); else - mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; + mv->x = sign_extend(diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x), 6); } return 0; -- cgit v1.2.3 From f7f892e4d5bded48b08e7b776a5fb7c350496f2b Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 16:50:51 +0000 Subject: svq1enc: fix signed multiplication overflow This multiplication can overflow the signed range but not the unsigned. After right-shifting it will thus fit in the signed range again. Signed-off-by: Mans Rullgard --- libavcodec/svq1enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index 79aaa6cb26..01d8b315b8 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -160,7 +160,7 @@ static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *dec } best_count=0; - best_score -= ((block_sum[0]*block_sum[0])>>(level+3)); + best_score -= (int)(((unsigned)block_sum[0]*block_sum[0])>>(level+3)); best_mean= (block_sum[0] + (size>>1)) >> (level+3); if(level<4){ -- cgit v1.2.3 From b02aa3a8eaa5673f36cfd944fe23dc3ea02b38f6 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 16:51:44 +0000 Subject: s3tc: fix shift overflow by using unsigned constant Signed-off-by: Mans Rullgard --- libavcodec/s3tc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/s3tc.c b/libavcodec/s3tc.c index e8ca688270..d0c4eb80e1 100644 --- a/libavcodec/s3tc.c +++ b/libavcodec/s3tc.c @@ -28,7 +28,7 @@ static inline void dxt1_decode_pixels(const uint8_t *s, uint32_t *d, unsigned int qstride, unsigned int flag, uint64_t alpha) { - unsigned int x, y, c0, c1, a = (!flag * 255) << 24; + unsigned int x, y, c0, c1, a = (!flag * 255u) << 24; unsigned int rb0, rb1, rb2, rb3, g0, g1, g2, g3; uint32_t colors[4], pixels; -- cgit v1.2.3 From b6ae0866821df5f3b83f6b7f5c281d9a3e36b7ee Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 18:48:16 +0000 Subject: dv: simplify bitstream splicing in dv_decode_ac() This is simpler and fixes some overflow checker warnings. Signed-off-by: Mans Rullgard --- libavcodec/dv.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/dv.c b/libavcodec/dv.c index f16ed624e7..6c50f77d3f 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -364,7 +364,7 @@ typedef struct BlockInfo { uint8_t pos; /* position in block */ void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block); uint8_t partial_bit_count; - uint16_t partial_bit_buffer; + uint32_t partial_bit_buffer; int shift_offset; } BlockInfo; @@ -392,8 +392,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) /* if we must parse a partial VLC, we do it here */ if (partial_bit_count > 0) { - re_cache = ((unsigned)re_cache >> partial_bit_count) | - (mb->partial_bit_buffer << (sizeof(re_cache) * 8 - partial_bit_count)); + re_cache = re_cache >> partial_bit_count | mb->partial_bit_buffer; re_index -= partial_bit_count; mb->partial_bit_count = 0; } @@ -416,7 +415,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) if (re_index + vlc_len > last_index) { /* should be < 16 bits otherwise a codeword could have been parsed */ mb->partial_bit_count = last_index - re_index; - mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count); + mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count); re_index = last_index; break; } -- cgit v1.2.3 From 3a83b2461e4ce9d48ad6ab037eb14569d0e53506 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 20:11:12 +0000 Subject: dnxhdenc: fix signed overflows Signed-off-by: Mans Rullgard --- libavcodec/dnxhdenc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 89e5c085ab..d1ab597d1d 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -682,7 +682,8 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) int qscale = 1; int mb = y*ctx->m.mb_width+x; for (q = 1; q < avctx->qmax; q++) { - unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<mb_rc[q][mb].bits*lambda+ + ((unsigned)ctx->mb_rc[q][mb].ssd<>1; else lambda -= down_step; - down_step *= 5; // XXX tune ? + down_step = FFMIN((int64_t)down_step*5, INT_MAX); up_step = 1< Date: Sat, 19 Nov 2011 17:05:44 -0500 Subject: adx: rename struct PREV to ADXChannelState --- libavcodec/adx.h | 4 ++-- libavcodec/adxdec.c | 6 ++++-- libavcodec/adxenc.c | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libavcodec/adx.h b/libavcodec/adx.h index c4206963d5..bba09aed8b 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -33,10 +33,10 @@ typedef struct { int s1,s2; -} PREV; +} ADXChannelState; typedef struct { - PREV prev[2]; + ADXChannelState prev[2]; int header_parsed; unsigned char dec_temp[18*2]; int in_temp; diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 79fcf13c31..0a9e60118e 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -40,7 +40,8 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) /* 18 bytes <-> 32 samples */ -static void adx_decode(short *out,const unsigned char *in,PREV *prev) +static void adx_decode(short *out,const unsigned char *in, + ADXChannelState *prev) { int scale = AV_RB16(in); int i; @@ -73,7 +74,8 @@ static void adx_decode(short *out,const unsigned char *in,PREV *prev) } -static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev) +static void adx_decode_stereo(short *out,const unsigned char *in, + ADXChannelState *prev) { short tmp[32*2]; int i; diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c index 61ba07a35d..fde0b8239e 100644 --- a/libavcodec/adxenc.c +++ b/libavcodec/adxenc.c @@ -34,7 +34,8 @@ /* 18 bytes <-> 32 samples */ -static void adx_encode(unsigned char *adx,const short *wav,PREV *prev) +static void adx_encode(unsigned char *adx,const short *wav, + ADXChannelState *prev) { int scale; int i; -- cgit v1.2.3 From e0722d7fb7595bac12feaae138340af6be358acc Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 19 Nov 2011 17:06:45 -0500 Subject: adx: change short to int16_t --- libavcodec/adxdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 0a9e60118e..dbc42feaa7 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -40,7 +40,7 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) /* 18 bytes <-> 32 samples */ -static void adx_decode(short *out,const unsigned char *in, +static void adx_decode(int16_t *out,const unsigned char *in, ADXChannelState *prev) { int scale = AV_RB16(in); @@ -74,7 +74,7 @@ static void adx_decode(short *out,const unsigned char *in, } -static void adx_decode_stereo(short *out,const unsigned char *in, +static void adx_decode_stereo(int16_t *out,const unsigned char *in, ADXChannelState *prev) { short tmp[32*2]; @@ -111,7 +111,7 @@ static int adx_decode_frame(AVCodecContext *avctx, const uint8_t *buf0 = avpkt->data; int buf_size = avpkt->size; ADXContext *c = avctx->priv_data; - short *samples = data; + int16_t *samples = data; const uint8_t *buf = buf0; int rest = buf_size; -- cgit v1.2.3 From fbc79a9101b9674327beba9c2a454163ead1e7a5 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 19 Nov 2011 17:07:46 -0500 Subject: adx: remove useless comments --- libavcodec/adxdec.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index dbc42feaa7..642d31dd66 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -47,14 +47,11 @@ static void adx_decode(int16_t *out,const unsigned char *in, int i; int s0,s1,s2,d; -// printf("%x ",scale); - in+=2; s1 = prev->s1; s2 = prev->s2; for(i=0;i<16;i++) { d = in[i]; - // d>>=4; if (d&8) d-=16; d = ((signed char)d >> 4); s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; s2 = s1; @@ -62,7 +59,6 @@ static void adx_decode(int16_t *out,const unsigned char *in, *out++=s1; d = in[i]; - //d&=15; if (d&8) d-=16; d = ((signed char)(d<<4) >> 4); s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; s2 = s1; @@ -141,7 +137,7 @@ static int adx_decode_frame(AVCodecContext *avctx, samples += 32*2; } } - // + if (avctx->channels==1) { while(rest>=18) { adx_decode(samples,buf,c->prev); @@ -157,14 +153,13 @@ static int adx_decode_frame(AVCodecContext *avctx, samples+=32*2; } } - // + c->in_temp = rest; if (rest) { memcpy(c->dec_temp,buf,rest); buf+=rest; } *data_size = (uint8_t*)samples - (uint8_t*)data; -// printf("%d:%d ",buf-buf0,*data_size); fflush(stdout); return buf-buf0; } -- cgit v1.2.3 From 8db67610c016d1aa8ed09643b1ee9b96f7b18c01 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 19 Nov 2011 17:46:15 -0500 Subject: adx: cosmetics: general pretty-printing and comment clean-up --- libavcodec/adxdec.c | 134 ++++++++++++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 61 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 642d31dd66..7d06d27a75 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -38,82 +38,95 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) return 0; } -/* 18 bytes <-> 32 samples */ - -static void adx_decode(int16_t *out,const unsigned char *in, - ADXChannelState *prev) +/** + * Decode 32 samples from 18 bytes. + * + * A 16-bit scalar value is applied to 32 residuals, which then have a + * 2nd-order LPC filter applied to it to form the output signal for a single + * channel. + */ +static void adx_decode(int16_t *out, const uint8_t *in, ADXChannelState *prev) { int scale = AV_RB16(in); int i; - int s0,s1,s2,d; + int s0, s1, s2, d; - in+=2; + in += 2; s1 = prev->s1; s2 = prev->s2; - for(i=0;i<16;i++) { - d = in[i]; - d = ((signed char)d >> 4); - s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; + for (i = 0; i < 16; i++) { + d = in[i]; + d = (signed char)d >> 4; + s0 = (BASEVOL * d * scale + SCALE1 * s1 - SCALE2 * s2) >> 14; s2 = s1; s1 = av_clip_int16(s0); - *out++=s1; + *out++ = s1; - d = in[i]; - d = ((signed char)(d<<4) >> 4); - s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; + d = in[i]; + d = (signed char)(d << 4) >> 4; + s0 = (BASEVOL * d * scale + SCALE1 * s1 - SCALE2 * s2) >> 14; s2 = s1; s1 = av_clip_int16(s0); - *out++=s1; + *out++ = s1; } prev->s1 = s1; prev->s2 = s2; - } -static void adx_decode_stereo(int16_t *out,const unsigned char *in, +static void adx_decode_stereo(int16_t *out,const uint8_t *in, ADXChannelState *prev) { short tmp[32*2]; int i; - adx_decode(tmp ,in ,prev); - adx_decode(tmp+32,in+18,prev+1); - for(i=0;i<32;i++) { - out[i*2] = tmp[i]; + adx_decode(tmp, in, prev); + adx_decode(tmp+32, in+18, prev+1); + for (i = 0; i < 32; i++) { + out[i*2 ] = tmp[i ]; out[i*2+1] = tmp[i+32]; } } -/* return data offset or 0 */ -static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize) +/** + * Decode stream header. + * + * @param avctx codec context + * @param buf packet data + * @param bufsize packet size + * @return data offset or 0 if header is invalid + */ +static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, + int bufsize) { int offset; - if (buf[0]!=0x80) return 0; - offset = (AV_RB32(buf)^0x80000000)+4; - if (bufsizechannels = buf[7]; - avctx->sample_rate = AV_RB32(buf+8); - avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; + avctx->sample_rate = AV_RB32(buf + 8); + avctx->bit_rate = avctx->sample_rate * avctx->channels * 18 * 8 / 32; return offset; } -static int adx_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) +static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + AVPacket *avpkt) { const uint8_t *buf0 = avpkt->data; - int buf_size = avpkt->size; - ADXContext *c = avctx->priv_data; - int16_t *samples = data; - const uint8_t *buf = buf0; - int rest = buf_size; + int buf_size = avpkt->size; + ADXContext *c = avctx->priv_data; + int16_t *samples = data; + const uint8_t *buf = buf0; + int rest = buf_size; if (!c->header_parsed) { - int hdrsize = adx_decode_header(avctx,buf,rest); - if (hdrsize==0) return -1; + int hdrsize = adx_decode_header(avctx, buf, rest); + if (!hdrsize) + return -1; c->header_parsed = 1; buf += hdrsize; rest -= hdrsize; @@ -121,46 +134,46 @@ static int adx_decode_frame(AVCodecContext *avctx, /* 18 bytes of data are expanded into 32*2 bytes of audio, so guard against buffer overflows */ - if(rest/18 > *data_size/64) - rest = (*data_size/64) * 18; + if (rest / 18 > *data_size / 64) + rest = (*data_size / 64) * 18; if (c->in_temp) { - int copysize = 18*avctx->channels - c->in_temp; - memcpy(c->dec_temp+c->in_temp,buf,copysize); + int copysize = 18 * avctx->channels - c->in_temp; + memcpy(c->dec_temp + c->in_temp, buf, copysize); rest -= copysize; buf += copysize; - if (avctx->channels==1) { - adx_decode(samples,c->dec_temp,c->prev); + if (avctx->channels == 1) { + adx_decode(samples, c->dec_temp, c->prev); samples += 32; } else { - adx_decode_stereo(samples,c->dec_temp,c->prev); + adx_decode_stereo(samples, c->dec_temp, c->prev); samples += 32*2; } } - if (avctx->channels==1) { - while(rest>=18) { - adx_decode(samples,buf,c->prev); - rest-=18; - buf+=18; - samples+=32; + if (avctx->channels == 1) { + while (rest >= 18) { + adx_decode(samples, buf, c->prev); + rest -= 18; + buf += 18; + samples += 32; } } else { - while(rest>=18*2) { - adx_decode_stereo(samples,buf,c->prev); - rest-=18*2; - buf+=18*2; - samples+=32*2; + while (rest >= 18 * 2) { + adx_decode_stereo(samples, buf, c->prev); + rest -= 18 * 2; + buf += 18 * 2; + samples += 32 * 2; } } c->in_temp = rest; if (rest) { - memcpy(c->dec_temp,buf,rest); - buf+=rest; + memcpy(c->dec_temp, buf, rest); + buf += rest; } *data_size = (uint8_t*)samples - (uint8_t*)data; - return buf-buf0; + return buf - buf0; } AVCodec ff_adpcm_adx_decoder = { @@ -170,6 +183,5 @@ AVCodec ff_adpcm_adx_decoder = { .priv_data_size = sizeof(ADXContext), .init = adx_decode_init, .decode = adx_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), + .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), }; - -- cgit v1.2.3 From e2d1eace00a80c4b53998397d38ea4e08c5d47f0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 19 Nov 2011 17:51:36 -0500 Subject: adx: validate header values --- libavcodec/adxdec.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 7d06d27a75..887c6d1404 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -93,7 +93,7 @@ static void adx_decode_stereo(int16_t *out,const uint8_t *in, * @param avctx codec context * @param buf packet data * @param bufsize packet size - * @return data offset or 0 if header is invalid + * @return data offset or negative error code if header is invalid */ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize) @@ -101,13 +101,18 @@ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int offset; if (buf[0] != 0x80) - return 0; + return AVERROR_INVALIDDATA; offset = (AV_RB32(buf) ^ 0x80000000) + 4; if (bufsize < offset || memcmp(buf + offset - 6, "(c)CRI", 6)) - return 0; + return AVERROR_INVALIDDATA; avctx->channels = buf[7]; + if (avctx->channels > 2) + return AVERROR_INVALIDDATA; avctx->sample_rate = AV_RB32(buf + 8); + if (avctx->sample_rate < 1 || + avctx->sample_rate > INT_MAX / (avctx->channels * 18 * 8)) + return AVERROR_INVALIDDATA; avctx->bit_rate = avctx->sample_rate * avctx->channels * 18 * 8 / 32; return offset; @@ -125,8 +130,10 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (!c->header_parsed) { int hdrsize = adx_decode_header(avctx, buf, rest); - if (!hdrsize) - return -1; + if (hdrsize < 0) { + av_log(avctx, AV_LOG_ERROR, "invalid stream header\n"); + return hdrsize; + } c->header_parsed = 1; buf += hdrsize; rest -= hdrsize; -- cgit v1.2.3 From 837bbd19ebd7a77411462bd505b2f50ce1c9c9bf Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 12:46:41 -0500 Subject: adx: remove unneeded post-decode channel interleaving instead interleave channels while decoding --- libavcodec/adx.h | 1 + libavcodec/adxdec.c | 58 ++++++++++++++++++----------------------------------- 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/libavcodec/adx.h b/libavcodec/adx.h index bba09aed8b..a329afb4c4 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -36,6 +36,7 @@ typedef struct { } ADXChannelState; typedef struct { + int channels; ADXChannelState prev[2]; int header_parsed; unsigned char dec_temp[18*2]; diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 887c6d1404..1801c47ac8 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -45,8 +45,9 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) * 2nd-order LPC filter applied to it to form the output signal for a single * channel. */ -static void adx_decode(int16_t *out, const uint8_t *in, ADXChannelState *prev) +static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) { + ADXChannelState *prev = &c->prev[ch]; int scale = AV_RB16(in); int i; int s0, s1, s2, d; @@ -60,33 +61,21 @@ static void adx_decode(int16_t *out, const uint8_t *in, ADXChannelState *prev) s0 = (BASEVOL * d * scale + SCALE1 * s1 - SCALE2 * s2) >> 14; s2 = s1; s1 = av_clip_int16(s0); - *out++ = s1; + *out = s1; + out += c->channels; d = in[i]; d = (signed char)(d << 4) >> 4; s0 = (BASEVOL * d * scale + SCALE1 * s1 - SCALE2 * s2) >> 14; s2 = s1; s1 = av_clip_int16(s0); - *out++ = s1; + *out = s1; + out += c->channels; } prev->s1 = s1; prev->s2 = s2; } -static void adx_decode_stereo(int16_t *out,const uint8_t *in, - ADXChannelState *prev) -{ - short tmp[32*2]; - int i; - - adx_decode(tmp, in, prev); - adx_decode(tmp+32, in+18, prev+1); - for (i = 0; i < 32; i++) { - out[i*2 ] = tmp[i ]; - out[i*2+1] = tmp[i+32]; - } -} - /** * Decode stream header. * @@ -98,6 +87,7 @@ static void adx_decode_stereo(int16_t *out,const uint8_t *in, static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize) { + ADXContext *c = avctx->priv_data; int offset; if (buf[0] != 0x80) @@ -106,7 +96,7 @@ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, if (bufsize < offset || memcmp(buf + offset - 6, "(c)CRI", 6)) return AVERROR_INVALIDDATA; - avctx->channels = buf[7]; + c->channels = avctx->channels = buf[7]; if (avctx->channels > 2) return AVERROR_INVALIDDATA; avctx->sample_rate = AV_RB32(buf + 8); @@ -149,29 +139,19 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, memcpy(c->dec_temp + c->in_temp, buf, copysize); rest -= copysize; buf += copysize; - if (avctx->channels == 1) { - adx_decode(samples, c->dec_temp, c->prev); - samples += 32; - } else { - adx_decode_stereo(samples, c->dec_temp, c->prev); - samples += 32*2; - } + adx_decode(c, samples, c->dec_temp, 0); + if (avctx->channels == 2) + adx_decode(c, samples + 1, c->dec_temp + 18, 1); + samples += 32 * c->channels; } - if (avctx->channels == 1) { - while (rest >= 18) { - adx_decode(samples, buf, c->prev); - rest -= 18; - buf += 18; - samples += 32; - } - } else { - while (rest >= 18 * 2) { - adx_decode_stereo(samples, buf, c->prev); - rest -= 18 * 2; - buf += 18 * 2; - samples += 32 * 2; - } + while (rest >= 18 * c->channels) { + adx_decode(c, samples, buf, 0); + if (c->channels == 2) + adx_decode(c, samples + 1, buf + 18, 1); + rest -= 18 * c->channels; + buf += 18 * c->channels; + samples += 32 * c->channels; } c->in_temp = rest; -- cgit v1.2.3 From ca9e4727baf0458d4dd7038987e060c6415eca09 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 12:57:21 -0500 Subject: adx: fix the data offset parsing in adx_decode_header() first 2 bytes are 0x80, 0x00. offset is only 16-bit. this is according to format descriptions on multimedia wiki and wikipedia. --- libavcodec/adxdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 1801c47ac8..c5a30b2b4e 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -90,9 +90,9 @@ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, ADXContext *c = avctx->priv_data; int offset; - if (buf[0] != 0x80) + if (AV_RB16(buf) != 0x8000) return AVERROR_INVALIDDATA; - offset = (AV_RB32(buf) ^ 0x80000000) + 4; + offset = AV_RB16(buf + 2) + 4; if (bufsize < offset || memcmp(buf + offset - 6, "(c)CRI", 6)) return AVERROR_INVALIDDATA; -- cgit v1.2.3 From c52ddc60241229af198ac03c8d86d219e7d5942a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 13:06:32 -0500 Subject: adx: simplify adx_decode() by using get_sbits() to read residual samples --- libavcodec/adxdec.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index c5a30b2b4e..39223c2e4f 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -22,6 +22,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "adx.h" +#include "get_bits.h" /** * @file @@ -48,24 +49,16 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) { ADXChannelState *prev = &c->prev[ch]; + GetBitContext gb; int scale = AV_RB16(in); int i; int s0, s1, s2, d; - in += 2; + init_get_bits(&gb, in + 2, (18 - 2) * 8); s1 = prev->s1; s2 = prev->s2; - for (i = 0; i < 16; i++) { - d = in[i]; - d = (signed char)d >> 4; - s0 = (BASEVOL * d * scale + SCALE1 * s1 - SCALE2 * s2) >> 14; - s2 = s1; - s1 = av_clip_int16(s0); - *out = s1; - out += c->channels; - - d = in[i]; - d = (signed char)(d << 4) >> 4; + for (i = 0; i < 32; i++) { + d = get_sbits(&gb, 4); s0 = (BASEVOL * d * scale + SCALE1 * s1 - SCALE2 * s2) >> 14; s2 = s1; s1 = av_clip_int16(s0); -- cgit v1.2.3 From 954d94dd5e13ba7a5e9e049d0f980bddced9644c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 14:03:21 -0500 Subject: adx: use 12-bit coefficients instead of 14-bit to avoid integer overflow --- libavcodec/adx.h | 6 +++--- libavcodec/adxdec.c | 2 +- libavcodec/adxenc.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/adx.h b/libavcodec/adx.h index a329afb4c4..ae5eb6a434 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -43,8 +43,8 @@ typedef struct { int in_temp; } ADXContext; -#define BASEVOL 0x4000 -#define SCALE1 0x7298 -#define SCALE2 0x3350 +#define COEFF_BITS 12 +#define COEFF1 0x1CA6 +#define COEFF2 0x0CD4 #endif /* AVCODEC_ADX_H */ diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 39223c2e4f..93bbc6b51b 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -59,7 +59,7 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) s2 = prev->s2; for (i = 0; i < 32; i++) { d = get_sbits(&gb, 4); - s0 = (BASEVOL * d * scale + SCALE1 * s1 - SCALE2 * s2) >> 14; + s0 = ((d << COEFF_BITS) * scale + COEFF1 * s1 - COEFF2 * s2) >> COEFF_BITS; s2 = s1; s1 = av_clip_int16(s0); *out = s1; diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c index fde0b8239e..7225c3159d 100644 --- a/libavcodec/adxenc.c +++ b/libavcodec/adxenc.c @@ -48,7 +48,7 @@ static void adx_encode(unsigned char *adx,const short *wav, s2 = prev->s2; for(i=0;i<32;i++) { s0 = wav[i]; - d = ((s0<<14) - SCALE1*s1 + SCALE2*s2)/BASEVOL; + d = ((s0 << COEFF_BITS) - COEFF1 * s1 + COEFF2 * s2) >> COEFF_BITS; data[i]=d; if (maxd) min=d; -- cgit v1.2.3 From b237248e297760648307356efa5fcbfe16844829 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 14:21:32 -0500 Subject: adx: calculate correct LPC coeffs Instead of using fixed coefficients, the correct way is to calculate the coefficients using the highpass cutoff frequency from the ADX stream header and the sample rate. --- libavcodec/Makefile | 2 +- libavcodec/adx.c | 34 ++++++++++++++++++++++++++++++++++ libavcodec/adx.h | 14 ++++++++++++-- libavcodec/adxdec.c | 7 +++++-- libavcodec/adxenc.c | 27 ++++++++++++++++++--------- 5 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 libavcodec/adx.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 37aa8ee331..2cdcca2cfc 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -489,7 +489,7 @@ OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_ZORK_DECODER) += pcm.o OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o adpcm_data.o -OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o +OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o adx.o OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o diff --git a/libavcodec/adx.c b/libavcodec/adx.c new file mode 100644 index 0000000000..bc3e8825ca --- /dev/null +++ b/libavcodec/adx.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/mathematics.h" +#include "adx.h" + +void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff) +{ + double a, b, c; + + a = M_SQRT2 - cos(2.0 * M_PI * cutoff / sample_rate); + b = M_SQRT2 - 1.0; + c = (a - sqrt((a + b) * (a - b))) / b; + + coeff[0] = lrintf(c * 2.0 * (1 << bits)); + coeff[1] = lrintf(-(c * c) * (1 << bits)); +} diff --git a/libavcodec/adx.h b/libavcodec/adx.h index ae5eb6a434..cd8c45bf6d 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -41,10 +41,20 @@ typedef struct { int header_parsed; unsigned char dec_temp[18*2]; int in_temp; + int cutoff; + int coeff[2]; } ADXContext; #define COEFF_BITS 12 -#define COEFF1 0x1CA6 -#define COEFF2 0x0CD4 + +/** + * Calculate LPC coefficients based on cutoff frequency and sample rate. + * + * @param cutoff cutoff frequency + * @param sample_rate sample rate + * @param bits number of bits used to quantize coefficients + * @param[out] coeff 2 quantized LPC coefficients + */ +void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff); #endif /* AVCODEC_ADX_H */ diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 93bbc6b51b..f9f17cde95 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -59,7 +59,7 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) s2 = prev->s2; for (i = 0; i < 32; i++) { d = get_sbits(&gb, 4); - s0 = ((d << COEFF_BITS) * scale + COEFF1 * s1 - COEFF2 * s2) >> COEFF_BITS; + s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS; s2 = s1; s1 = av_clip_int16(s0); *out = s1; @@ -81,7 +81,7 @@ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize) { ADXContext *c = avctx->priv_data; - int offset; + int offset, cutoff; if (AV_RB16(buf) != 0x8000) return AVERROR_INVALIDDATA; @@ -98,6 +98,9 @@ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, return AVERROR_INVALIDDATA; avctx->bit_rate = avctx->sample_rate * avctx->channels * 18 * 8 / 32; + cutoff = AV_RB16(buf + 16); + ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, c->coeff); + return offset; } diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c index 7225c3159d..b85a70d7b2 100644 --- a/libavcodec/adxenc.c +++ b/libavcodec/adxenc.c @@ -34,7 +34,7 @@ /* 18 bytes <-> 32 samples */ -static void adx_encode(unsigned char *adx,const short *wav, +static void adx_encode(ADXContext *c, unsigned char *adx, const short *wav, ADXChannelState *prev) { int scale; @@ -48,7 +48,7 @@ static void adx_encode(unsigned char *adx,const short *wav, s2 = prev->s2; for(i=0;i<32;i++) { s0 = wav[i]; - d = ((s0 << COEFF_BITS) - COEFF1 * s1 + COEFF2 * s2) >> COEFF_BITS; + d = ((s0 << COEFF_BITS) - c->coeff[0] * s1 - c->coeff[1] * s2) >> COEFF_BITS; data[i]=d; if (maxd) min=d; @@ -102,19 +102,24 @@ static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t buf } adxhdr; /* big endian */ /* offset-6 "(c)CRI" */ #endif + ADXContext *c = avctx->priv_data; + AV_WB32(buf+0x00,0x80000000|0x20); AV_WB32(buf+0x04,0x03120400|avctx->channels); AV_WB32(buf+0x08,avctx->sample_rate); AV_WB32(buf+0x0c,0); /* FIXME: set after */ - AV_WB32(buf+0x10,0x01040300); - AV_WB32(buf+0x14,0x00000000); - AV_WB32(buf+0x18,0x00000000); - memcpy(buf+0x1c,"\0\0(c)CRI",8); + AV_WB16(buf + 0x10, c->cutoff); + AV_WB32(buf + 0x12, 0x03000000); + AV_WB32(buf + 0x16, 0x00000000); + AV_WB32(buf + 0x1a, 0x00000000); + memcpy (buf + 0x1e, "(c)CRI", 6); return 0x20+4; } static av_cold int adx_encode_init(AVCodecContext *avctx) { + ADXContext *c = avctx->priv_data; + if (avctx->channels > 2) return -1; /* only stereo or mono =) */ avctx->frame_size = 32; @@ -124,6 +129,10 @@ static av_cold int adx_encode_init(AVCodecContext *avctx) // avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; + /* the cutoff can be adjusted, but this seems to work pretty well */ + c->cutoff = 500; + ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff); + av_log(avctx, AV_LOG_DEBUG, "adx encode init\n"); return 0; @@ -159,7 +168,7 @@ static int adx_encode_frame(AVCodecContext *avctx, if (avctx->channels==1) { while(rest>=32) { - adx_encode(dst,samples,c->prev); + adx_encode(c, dst, samples, c->prev); dst+=18; samples+=32; rest-=32; @@ -174,8 +183,8 @@ static int adx_encode_frame(AVCodecContext *avctx, tmpbuf[i+32] = samples[i*2+1]; } - adx_encode(dst,tmpbuf,c->prev); - adx_encode(dst+18,tmpbuf+32,c->prev+1); + adx_encode(c, dst, tmpbuf, c->prev); + adx_encode(c, dst + 18, tmpbuf + 32, c->prev + 1); dst+=18*2; samples+=32*2; rest-=32*2; -- cgit v1.2.3 From 994238536a8ec8b970a16d153bee72c96ede0cc3 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 16:49:13 -0500 Subject: adx: simplify encoding by using put_sbits() --- libavcodec/adxenc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c index b85a70d7b2..ae4b9f7da2 100644 --- a/libavcodec/adxenc.c +++ b/libavcodec/adxenc.c @@ -22,6 +22,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" #include "adx.h" +#include "put_bits.h" /** * @file @@ -37,6 +38,7 @@ static void adx_encode(ADXContext *c, unsigned char *adx, const short *wav, ADXChannelState *prev) { + PutBitContext pb; int scale; int i; int s0,s1,s2,d; @@ -72,9 +74,10 @@ static void adx_encode(ADXContext *c, unsigned char *adx, const short *wav, AV_WB16(adx, scale); - for(i=0;i<16;i++) { - adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf); - } + init_put_bits(&pb, adx + 2, 16); + for (i = 0; i < 32; i++) + put_sbits(&pb, 4, av_clip(data[i]/scale, -8, 7)); + flush_put_bits(&pb); } static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize) -- cgit v1.2.3 From d1745619dbd794aaf0e7aa51d14af5f99869ec93 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 17:07:59 -0500 Subject: adx: check for unsupported ADX formats --- libavcodec/adxdec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index f9f17cde95..ee1f1b01f7 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -89,6 +89,12 @@ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, if (bufsize < offset || memcmp(buf + offset - 6, "(c)CRI", 6)) return AVERROR_INVALIDDATA; + /* check for encoding=3 block_size=18, sample_size=4 */ + if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) { + av_log_ask_for_sample(avctx, "unsupported ADX format\n"); + return AVERROR_PATCHWELCOME; + } + c->channels = avctx->channels = buf[7]; if (avctx->channels > 2) return AVERROR_INVALIDDATA; -- cgit v1.2.3 From 05c1f11b56a76d04bb77fb0a31e783ac1d435ad0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 17:50:46 -0500 Subject: adx: define and use 2 new macro constants BLOCK_SIZE and BLOCK_SAMPLES --- libavcodec/adxdec.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index ee1f1b01f7..5989233e30 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -33,6 +33,9 @@ * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ */ +#define BLOCK_SIZE 18 +#define BLOCK_SAMPLES 32 + static av_cold int adx_decode_init(AVCodecContext *avctx) { avctx->sample_fmt = AV_SAMPLE_FMT_S16; @@ -54,10 +57,10 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) int i; int s0, s1, s2, d; - init_get_bits(&gb, in + 2, (18 - 2) * 8); + init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8); s1 = prev->s1; s2 = prev->s2; - for (i = 0; i < 32; i++) { + for (i = 0; i < BLOCK_SAMPLES; i++) { d = get_sbits(&gb, 4); s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS; s2 = s1; @@ -100,9 +103,9 @@ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, return AVERROR_INVALIDDATA; avctx->sample_rate = AV_RB32(buf + 8); if (avctx->sample_rate < 1 || - avctx->sample_rate > INT_MAX / (avctx->channels * 18 * 8)) + avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8)) return AVERROR_INVALIDDATA; - avctx->bit_rate = avctx->sample_rate * avctx->channels * 18 * 8 / 32; + avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES; cutoff = AV_RB16(buf + 16); ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, c->coeff); @@ -133,27 +136,27 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, /* 18 bytes of data are expanded into 32*2 bytes of audio, so guard against buffer overflows */ - if (rest / 18 > *data_size / 64) - rest = (*data_size / 64) * 18; + if (rest / (BLOCK_SIZE * c->channels) > *data_size / (BLOCK_SAMPLES * c->channels)) + rest = (*data_size / (BLOCK_SAMPLES * c->channels)) * BLOCK_SIZE; if (c->in_temp) { - int copysize = 18 * avctx->channels - c->in_temp; + int copysize = BLOCK_SIZE * avctx->channels - c->in_temp; memcpy(c->dec_temp + c->in_temp, buf, copysize); rest -= copysize; buf += copysize; adx_decode(c, samples, c->dec_temp, 0); if (avctx->channels == 2) - adx_decode(c, samples + 1, c->dec_temp + 18, 1); - samples += 32 * c->channels; + adx_decode(c, samples + 1, c->dec_temp + BLOCK_SIZE, 1); + samples += BLOCK_SAMPLES * c->channels; } - while (rest >= 18 * c->channels) { + while (rest >= BLOCK_SIZE * c->channels) { adx_decode(c, samples, buf, 0); if (c->channels == 2) - adx_decode(c, samples + 1, buf + 18, 1); - rest -= 18 * c->channels; - buf += 18 * c->channels; - samples += 32 * c->channels; + adx_decode(c, samples + 1, buf + BLOCK_SIZE, 1); + rest -= BLOCK_SIZE * c->channels; + buf += BLOCK_SIZE * c->channels; + samples += BLOCK_SAMPLES * c->channels; } c->in_temp = rest; -- cgit v1.2.3 From 7ff55d9bdbdd9df004bb45055049499380d0ae68 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 17:53:43 -0500 Subject: adx: calculate the number of blocks in a packet --- libavcodec/adxdec.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 5989233e30..e9226b2bd9 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -122,6 +122,7 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, int16_t *samples = data; const uint8_t *buf = buf0; int rest = buf_size; + int num_blocks; if (!c->header_parsed) { int hdrsize = adx_decode_header(avctx, buf, rest); @@ -136,8 +137,15 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, /* 18 bytes of data are expanded into 32*2 bytes of audio, so guard against buffer overflows */ - if (rest / (BLOCK_SIZE * c->channels) > *data_size / (BLOCK_SAMPLES * c->channels)) + num_blocks = (rest + c->in_temp) / (BLOCK_SIZE * c->channels); + if (num_blocks > *data_size / (BLOCK_SAMPLES * c->channels)) { rest = (*data_size / (BLOCK_SAMPLES * c->channels)) * BLOCK_SIZE; + num_blocks = (rest + c->in_temp) / (BLOCK_SIZE * c->channels); + } + if (!num_blocks) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR_INVALIDDATA; + } if (c->in_temp) { int copysize = BLOCK_SIZE * avctx->channels - c->in_temp; @@ -148,9 +156,10 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (avctx->channels == 2) adx_decode(c, samples + 1, c->dec_temp + BLOCK_SIZE, 1); samples += BLOCK_SAMPLES * c->channels; + num_blocks--; } - while (rest >= BLOCK_SIZE * c->channels) { + while (num_blocks--) { adx_decode(c, samples, buf, 0); if (c->channels == 2) adx_decode(c, samples + 1, buf + BLOCK_SIZE, 1); -- cgit v1.2.3 From d8cec2d7fc1c2c5b6f82b8743b3cfd04cd4bb8cc Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 20 Nov 2011 20:16:05 -0500 Subject: adx: move header decoding to ADX common code --- libavcodec/adx.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/adx.h | 21 +++++++++++++++++++++ libavcodec/adxdec.c | 42 ++++++------------------------------------ 3 files changed, 74 insertions(+), 36 deletions(-) diff --git a/libavcodec/adx.c b/libavcodec/adx.c index bc3e8825ca..9f03e930be 100644 --- a/libavcodec/adx.c +++ b/libavcodec/adx.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" #include "adx.h" @@ -32,3 +33,49 @@ void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff) coeff[0] = lrintf(c * 2.0 * (1 << bits)); coeff[1] = lrintf(-(c * c) * (1 << bits)); } + +int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize, + int *header_size, int *coeff) +{ + int offset, cutoff; + + if (bufsize < 24) + return AVERROR_INVALIDDATA; + + if (AV_RB16(buf) != 0x8000) + return AVERROR_INVALIDDATA; + offset = AV_RB16(buf + 2) + 4; + + /* if copyright string is within the provided data, validate it */ + if (bufsize >= offset && memcmp(buf + offset - 6, "(c)CRI", 6)) + return AVERROR_INVALIDDATA; + + /* check for encoding=3 block_size=18, sample_size=4 */ + if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) { + av_log_ask_for_sample(avctx, "unsupported ADX format\n"); + return AVERROR_PATCHWELCOME; + } + + /* channels */ + avctx->channels = buf[7]; + if (avctx->channels > 2) + return AVERROR_INVALIDDATA; + + /* sample rate */ + avctx->sample_rate = AV_RB32(buf + 8); + if (avctx->sample_rate < 1 || + avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8)) + return AVERROR_INVALIDDATA; + + /* bit rate */ + avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES; + + /* LPC coefficients */ + if (coeff) { + cutoff = AV_RB16(buf + 16); + ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff); + } + + *header_size = offset; + return 0; +} diff --git a/libavcodec/adx.h b/libavcodec/adx.h index cd8c45bf6d..f68a3cb793 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -31,6 +31,10 @@ #ifndef AVCODEC_ADX_H #define AVCODEC_ADX_H +#include + +#include "avcodec.h" + typedef struct { int s1,s2; } ADXChannelState; @@ -47,6 +51,9 @@ typedef struct { #define COEFF_BITS 12 +#define BLOCK_SIZE 18 +#define BLOCK_SAMPLES 32 + /** * Calculate LPC coefficients based on cutoff frequency and sample rate. * @@ -57,4 +64,18 @@ typedef struct { */ void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff); +/** + * Decode ADX stream header. + * Sets avctx->channels and avctx->sample_rate. + * + * @param avctx codec context + * @param buf header data + * @param bufsize data size, should be at least 24 bytes + * @param[out] header_size size of ADX header + * @param[out] coeff 2 LPC coefficients, can be NULL + * @return data offset or negative error code if header is invalid + */ +int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize, + int *header_size, int *coeff); + #endif /* AVCODEC_ADX_H */ diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index e9226b2bd9..0b0eac262c 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -33,9 +33,6 @@ * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ */ -#define BLOCK_SIZE 18 -#define BLOCK_SAMPLES 32 - static av_cold int adx_decode_init(AVCodecContext *avctx) { avctx->sample_fmt = AV_SAMPLE_FMT_S16; @@ -72,45 +69,18 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) prev->s2 = s2; } -/** - * Decode stream header. - * - * @param avctx codec context - * @param buf packet data - * @param bufsize packet size - * @return data offset or negative error code if header is invalid - */ static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize) { ADXContext *c = avctx->priv_data; - int offset, cutoff; - - if (AV_RB16(buf) != 0x8000) - return AVERROR_INVALIDDATA; - offset = AV_RB16(buf + 2) + 4; - if (bufsize < offset || memcmp(buf + offset - 6, "(c)CRI", 6)) - return AVERROR_INVALIDDATA; - - /* check for encoding=3 block_size=18, sample_size=4 */ - if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) { - av_log_ask_for_sample(avctx, "unsupported ADX format\n"); - return AVERROR_PATCHWELCOME; - } - - c->channels = avctx->channels = buf[7]; - if (avctx->channels > 2) - return AVERROR_INVALIDDATA; - avctx->sample_rate = AV_RB32(buf + 8); - if (avctx->sample_rate < 1 || - avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8)) - return AVERROR_INVALIDDATA; - avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES; + int ret, header_size; - cutoff = AV_RB16(buf + 16); - ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, c->coeff); + if ((ret = ff_adx_decode_header(avctx, buf, bufsize, &header_size, + c->coeff)) < 0) + return ret; - return offset; + c->channels = avctx->channels; + return header_size; } static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, -- cgit v1.2.3 From 27360ccc5edcaa1a37dec39127e87c461ce668b6 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 21 Nov 2011 01:49:37 -0500 Subject: adx: add an ADX parser. This simplifies the decoder so it doesn't have to process an in-packet header or handle arbitrary-sized packets. It also fixes decoding of files with large headers. --- libavcodec/Makefile | 1 + libavcodec/adx.h | 3 +- libavcodec/adx_parser.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/adxdec.c | 100 ++++++++++++++++++++-------------------------- libavcodec/allcodecs.c | 1 + libavcodec/version.h | 4 +- libavformat/segafilm.c | 1 + 7 files changed, 154 insertions(+), 60 deletions(-) create mode 100644 libavcodec/adx_parser.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 2cdcca2cfc..926056f42a 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -595,6 +595,7 @@ OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \ aacadtsdec.o mpeg4audio.o OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \ aac_ac3_parser.o +OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o diff --git a/libavcodec/adx.h b/libavcodec/adx.h index f68a3cb793..93d547dcb2 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -43,8 +43,7 @@ typedef struct { int channels; ADXChannelState prev[2]; int header_parsed; - unsigned char dec_temp[18*2]; - int in_temp; + int eof; int cutoff; int coeff[2]; } ADXContext; diff --git a/libavcodec/adx_parser.c b/libavcodec/adx_parser.c new file mode 100644 index 0000000000..6de5ad48d1 --- /dev/null +++ b/libavcodec/adx_parser.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * ADX audio parser + * + * Reads header to extradata and splits packets into individual blocks. + */ + +#include "libavutil/intreadwrite.h" +#include "parser.h" +#include "adx.h" + +typedef struct ADXParseContext { + ParseContext pc; + int header_size; + int block_size; + int buf_pos; +} ADXParseContext; + +#define MIN_HEADER_SIZE 24 + +static int adx_parse(AVCodecParserContext *s1, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ADXParseContext *s = s1->priv_data; + ParseContext *pc = &s->pc; + int next = END_NOT_FOUND; + + if (!avctx->extradata_size) { + int ret; + + ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size); + + if (!s->header_size && pc->index >= MIN_HEADER_SIZE) { + if (ret = ff_adx_decode_header(avctx, pc->buffer, pc->index, + &s->header_size, NULL)) + return AVERROR_INVALIDDATA; + s->block_size = BLOCK_SIZE * avctx->channels; + } + if (s->header_size && s->header_size <= pc->index) { + avctx->extradata = av_mallocz(s->header_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + avctx->extradata_size = s->header_size; + memcpy(avctx->extradata, pc->buffer, s->header_size); + memmove(pc->buffer, pc->buffer + s->header_size, s->header_size); + pc->index -= s->header_size; + } + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + if (pc->index - s->buf_pos >= s->block_size) { + *poutbuf = &pc->buffer[s->buf_pos]; + *poutbuf_size = s->block_size; + s->buf_pos += s->block_size; + return 0; + } + if (pc->index && s->buf_pos) { + memmove(pc->buffer, &pc->buffer[s->buf_pos], pc->index - s->buf_pos); + pc->index -= s->buf_pos; + s->buf_pos = 0; + } + if (buf_size + pc->index >= s->block_size) + next = s->block_size - pc->index; + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser ff_adx_parser = { + .codec_ids = { CODEC_ID_ADPCM_ADX }, + .priv_data_size = sizeof(ADXParseContext), + .parser_parse = adx_parse, + .parser_close = ff_parse_close, +}; diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 0b0eac262c..ca96a904d6 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -35,6 +35,19 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) { + ADXContext *c = avctx->priv_data; + int ret, header_size; + + if (avctx->extradata_size < 24) + return AVERROR_INVALIDDATA; + + if ((ret = ff_adx_decode_header(avctx, avctx->extradata, avctx->extradata_size, + &header_size, c->coeff)) < 0) { + av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n"); + return AVERROR_INVALIDDATA; + } + c->channels = avctx->channels; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; } @@ -46,7 +59,7 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) * 2nd-order LPC filter applied to it to form the output signal for a single * channel. */ -static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) +static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) { ADXChannelState *prev = &c->prev[ch]; GetBitContext gb; @@ -54,6 +67,10 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) int i; int s0, s1, s2, d; + /* check if this is an EOF packet */ + if (scale & 0x8000) + return -1; + init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8); s1 = prev->s1; s2 = prev->s2; @@ -67,84 +84,55 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) } prev->s1 = s1; prev->s2 = s2; -} - -static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, - int bufsize) -{ - ADXContext *c = avctx->priv_data; - int ret, header_size; - if ((ret = ff_adx_decode_header(avctx, buf, bufsize, &header_size, - c->coeff)) < 0) - return ret; - - c->channels = avctx->channels; - return header_size; + return 0; } static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf0 = avpkt->data; int buf_size = avpkt->size; ADXContext *c = avctx->priv_data; int16_t *samples = data; - const uint8_t *buf = buf0; - int rest = buf_size; - int num_blocks; - - if (!c->header_parsed) { - int hdrsize = adx_decode_header(avctx, buf, rest); - if (hdrsize < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid stream header\n"); - return hdrsize; - } - c->header_parsed = 1; - buf += hdrsize; - rest -= hdrsize; + const uint8_t *buf = avpkt->data; + int num_blocks, ch; + + if (c->eof) { + *data_size = 0; + return buf_size; } /* 18 bytes of data are expanded into 32*2 bytes of audio, so guard against buffer overflows */ - num_blocks = (rest + c->in_temp) / (BLOCK_SIZE * c->channels); + num_blocks = buf_size / (BLOCK_SIZE * c->channels); if (num_blocks > *data_size / (BLOCK_SAMPLES * c->channels)) { - rest = (*data_size / (BLOCK_SAMPLES * c->channels)) * BLOCK_SIZE; - num_blocks = (rest + c->in_temp) / (BLOCK_SIZE * c->channels); + buf_size = (*data_size / (BLOCK_SAMPLES * c->channels)) * BLOCK_SIZE; + num_blocks = buf_size / (BLOCK_SIZE * c->channels); } - if (!num_blocks) { - av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + if (!buf_size || buf_size % (BLOCK_SIZE * avctx->channels)) { + if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) { + c->eof = 1; + *data_size = 0; + return avpkt->size; + } return AVERROR_INVALIDDATA; } - if (c->in_temp) { - int copysize = BLOCK_SIZE * avctx->channels - c->in_temp; - memcpy(c->dec_temp + c->in_temp, buf, copysize); - rest -= copysize; - buf += copysize; - adx_decode(c, samples, c->dec_temp, 0); - if (avctx->channels == 2) - adx_decode(c, samples + 1, c->dec_temp + BLOCK_SIZE, 1); - samples += BLOCK_SAMPLES * c->channels; - num_blocks--; - } - while (num_blocks--) { - adx_decode(c, samples, buf, 0); - if (c->channels == 2) - adx_decode(c, samples + 1, buf + BLOCK_SIZE, 1); - rest -= BLOCK_SIZE * c->channels; - buf += BLOCK_SIZE * c->channels; + for (ch = 0; ch < c->channels; ch++) { + if (adx_decode(c, samples + ch, buf, ch)) { + c->eof = 1; + buf = avpkt->data + avpkt->size; + break; + } + buf_size -= BLOCK_SIZE; + buf += BLOCK_SIZE; + } samples += BLOCK_SAMPLES * c->channels; } - c->in_temp = rest; - if (rest) { - memcpy(c->dec_temp, buf, rest); - buf += rest; - } *data_size = (uint8_t*)samples - (uint8_t*)data; - return buf - buf0; + return buf - avpkt->data; } AVCodec ff_adpcm_adx_decoder = { diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index db213a1ae0..82023ff230 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -388,6 +388,7 @@ void avcodec_register_all(void) REGISTER_PARSER (AAC, aac); REGISTER_PARSER (AAC_LATM, aac_latm); REGISTER_PARSER (AC3, ac3); + REGISTER_PARSER (ADX, adx); REGISTER_PARSER (CAVSVIDEO, cavsvideo); REGISTER_PARSER (DCA, dca); REGISTER_PARSER (DIRAC, dirac); diff --git a/libavcodec/version.h b/libavcodec/version.h index 2313fae021..0bd17817ec 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,8 +21,8 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 22 -#define LIBAVCODEC_VERSION_MICRO 1 +#define LIBAVCODEC_VERSION_MINOR 23 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index b75c8774ce..9bf81d30d4 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -172,6 +172,7 @@ static int film_read_header(AVFormatContext *s, if (film->audio_type == CODEC_ID_ADPCM_ADX) { st->codec->bits_per_coded_sample = 18 * 8 / 32; st->codec->block_align = st->codec->channels * 18; + st->need_parsing = AVSTREAM_PARSE_FULL; } else { st->codec->bits_per_coded_sample = film->audio_bits; st->codec->block_align = st->codec->channels * -- cgit v1.2.3 From a17c3c7d15a841ce330e142966b9420fb64cf299 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 21 Nov 2011 02:34:18 -0500 Subject: avformat: add CRI ADX format demuxer --- Changelog | 1 + doc/general.texi | 2 + libavcodec/Makefile | 1 + libavformat/Makefile | 1 + libavformat/adxdec.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++ libavformat/allformats.c | 1 + libavformat/version.h | 2 +- 7 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 libavformat/adxdec.c diff --git a/Changelog b/Changelog index b9b5f26ae8..e5c4993dbe 100644 --- a/Changelog +++ b/Changelog @@ -102,6 +102,7 @@ easier to use. The changes are: - Discworld II BMV decoding support - VBLE Decoder - OS X Video Decoder Acceleration (VDA) support +- CRI ADX audio format demuxer version 0.7: diff --git a/doc/general.texi b/doc/general.texi index d2747c052c..9a5c405f85 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -67,6 +67,8 @@ library: @item Brute Force & Ignorance @tab @tab X @tab Used in the game Flash Traffic: City of Angels. @item BWF @tab X @tab X +@item CRI ADX @tab @tab X + @tab Audio-only format used in console video games. @item Discworld II BMV @tab @tab X @item Interplay C93 @tab @tab X @tab Used in the game Cyberia from Interplay. diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 926056f42a..a78cd8171e 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -528,6 +528,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o # libavformat dependencies OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o +OBJS-$(CONFIG_ADX_DEMUXER) += adx.o OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_DV_DEMUXER) += dvdata.o OBJS-$(CONFIG_DV_MUXER) += dvdata.o diff --git a/libavformat/Makefile b/libavformat/Makefile index 2b7588f1ad..3419148b56 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -21,6 +21,7 @@ OBJS-$(CONFIG_A64_MUXER) += a64.o OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o rawdec.o OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o +OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c new file mode 100644 index 0000000000..76b3728b1e --- /dev/null +++ b/libavformat/adxdec.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * CRI ADX demuxer + */ + +#include "libavutil/intreadwrite.h" +#include "libavcodec/adx.h" +#include "avformat.h" + +#define BLOCK_SIZE 18 +#define BLOCK_SAMPLES 32 + +typedef struct ADXDemuxerContext { + int header_size; +} ADXDemuxerContext; + +static int adx_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + ADXDemuxerContext *c = s->priv_data; + AVCodecContext *avctx = s->streams[0]->codec; + int ret, size; + + size = BLOCK_SIZE * avctx->channels; + + pkt->pos = avio_tell(s->pb); + pkt->stream_index = 0; + + ret = av_get_packet(s->pb, pkt, size); + if (ret != size) { + av_free_packet(pkt); + return ret < 0 ? ret : AVERROR(EIO); + } + if (AV_RB16(pkt->data) & 0x8000) { + av_free_packet(pkt); + return AVERROR_EOF; + } + pkt->size = size; + pkt->duration = 1; + pkt->pts = (pkt->pos - c->header_size) / size; + + return 0; +} + +static int adx_read_header(AVFormatContext *s, AVFormatParameters *ap) +{ + ADXDemuxerContext *c = s->priv_data; + AVCodecContext *avctx; + int ret; + + AVStream *st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + avctx = s->streams[0]->codec; + + if (avio_rb16(s->pb) != 0x8000) + return AVERROR_INVALIDDATA; + c->header_size = avio_rb16(s->pb) + 4; + avio_seek(s->pb, -4, SEEK_CUR); + + avctx->extradata = av_mallocz(c->header_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + if (avio_read(s->pb, avctx->extradata, c->header_size) < c->header_size) { + av_freep(&avctx->extradata); + return AVERROR(EIO); + } + avctx->extradata_size = c->header_size; + + ret = ff_adx_decode_header(avctx, avctx->extradata, avctx->extradata_size, + &c->header_size, NULL); + if (ret) + return ret; + + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = s->iformat->value; + + av_set_pts_info(st, 64, BLOCK_SAMPLES, avctx->sample_rate); + + return 0; +} + +AVInputFormat ff_adx_demuxer = { + .name = "adx", + .long_name = NULL_IF_CONFIG_SMALL("CRI ADX"), + .priv_data_size = sizeof(ADXDemuxerContext), + .read_header = adx_read_header, + .read_packet = adx_read_packet, + .extensions = "adx", + .value = CODEC_ID_ADPCM_ADX, +}; diff --git a/libavformat/allformats.c b/libavformat/allformats.c index bee2f5f11f..573b714d33 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -52,6 +52,7 @@ void av_register_all(void) REGISTER_DEMUXER (AAC, aac); REGISTER_MUXDEMUX (AC3, ac3); REGISTER_MUXER (ADTS, adts); + REGISTER_DEMUXER (ADX, adx); REGISTER_DEMUXER (AEA, aea); REGISTER_MUXDEMUX (AIFF, aiff); REGISTER_MUXDEMUX (AMR, amr); diff --git a/libavformat/version.h b/libavformat/version.h index d56bdb7c87..37c3d5bc88 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,7 +24,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 15 +#define LIBAVFORMAT_VERSION_MINOR 16 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ -- cgit v1.2.3 From 9d2dd356c2eb1ac403f05e7975e3a904e844aa17 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 26 Nov 2011 17:00:00 -0500 Subject: adx: rename ff_adx_decode_header() to avpriv_adx_decode_header() It is used by the ADX decoder, and therefore needs to be exported in order to work with shared libs. --- libavcodec/adx.c | 4 ++-- libavcodec/adx.h | 4 ++-- libavcodec/adx_parser.c | 4 ++-- libavcodec/adxdec.c | 5 +++-- libavformat/adxdec.c | 5 +++-- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/libavcodec/adx.c b/libavcodec/adx.c index 9f03e930be..aa90fd89c3 100644 --- a/libavcodec/adx.c +++ b/libavcodec/adx.c @@ -34,8 +34,8 @@ void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff) coeff[1] = lrintf(-(c * c) * (1 << bits)); } -int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize, - int *header_size, int *coeff) +int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, + int bufsize, int *header_size, int *coeff) { int offset, cutoff; diff --git a/libavcodec/adx.h b/libavcodec/adx.h index 93d547dcb2..da40eec929 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -74,7 +74,7 @@ void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff); * @param[out] coeff 2 LPC coefficients, can be NULL * @return data offset or negative error code if header is invalid */ -int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize, - int *header_size, int *coeff); +int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, + int bufsize, int *header_size, int *coeff); #endif /* AVCODEC_ADX_H */ diff --git a/libavcodec/adx_parser.c b/libavcodec/adx_parser.c index 6de5ad48d1..ebcb1370e5 100644 --- a/libavcodec/adx_parser.c +++ b/libavcodec/adx_parser.c @@ -53,8 +53,8 @@ static int adx_parse(AVCodecParserContext *s1, ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size); if (!s->header_size && pc->index >= MIN_HEADER_SIZE) { - if (ret = ff_adx_decode_header(avctx, pc->buffer, pc->index, - &s->header_size, NULL)) + if (ret = avpriv_adx_decode_header(avctx, pc->buffer, pc->index, + &s->header_size, NULL)) return AVERROR_INVALIDDATA; s->block_size = BLOCK_SIZE * avctx->channels; } diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index ca96a904d6..4558060781 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -41,8 +41,9 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) if (avctx->extradata_size < 24) return AVERROR_INVALIDDATA; - if ((ret = ff_adx_decode_header(avctx, avctx->extradata, avctx->extradata_size, - &header_size, c->coeff)) < 0) { + if ((ret = avpriv_adx_decode_header(avctx, avctx->extradata, + avctx->extradata_size, &header_size, + c->coeff)) < 0) { av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n"); return AVERROR_INVALIDDATA; } diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c index 76b3728b1e..eff26982ea 100644 --- a/libavformat/adxdec.c +++ b/libavformat/adxdec.c @@ -86,8 +86,9 @@ static int adx_read_header(AVFormatContext *s, AVFormatParameters *ap) } avctx->extradata_size = c->header_size; - ret = ff_adx_decode_header(avctx, avctx->extradata, avctx->extradata_size, - &c->header_size, NULL); + ret = avpriv_adx_decode_header(avctx, avctx->extradata, + avctx->extradata_size, &c->header_size, + NULL); if (ret) return ret; -- cgit v1.2.3 From ff6d9cc558d5cc8a4647e123a714603ed5e82628 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 20:42:07 +0000 Subject: snow: fix signed overflow in byte to 32-bit replication Signed-off-by: Mans Rullgard --- libavcodec/snow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/snow.c b/libavcodec/snow.c index a2903583fb..447289aa74 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -290,8 +290,8 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){ if(block->type & BLOCK_INTRA){ int x, y; - const int color = block->color[plane_index]; - const int color4= color*0x01010101; + const unsigned color = block->color[plane_index]; + const unsigned color4 = color*0x01010101; if(b_w==32){ for(y=0; y < b_h; y++){ *(uint32_t*)&dst[0 + y*stride]= color4; -- cgit v1.2.3 From 0e55edcb57bc3104e704e55c8267c72426358c36 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 20:44:37 +0000 Subject: svq1enc: remove stale altivec-related hack altivec.h is no longer (indirectly) included, so this hack is not needed. Signed-off-by: Mans Rullgard --- libavcodec/svq1enc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index 01d8b315b8..80bae3cc85 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -113,10 +113,6 @@ static void svq1_write_header(SVQ1Context *s, int frame_type) #define QUALITY_THRESHOLD 100 #define THRESHOLD_MULTIPLIER 0.6 -#if HAVE_ALTIVEC -#undef vector -#endif - static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){ int count, y, x, i, j, split, best_mean, best_score, best_count; int best_vector[6]; -- cgit v1.2.3 From 8540dcfd7af14da4080770dfbfa997cffdd0878b Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 26 Nov 2011 20:59:17 +0000 Subject: snow: fix integer overflows The way these values are used, they should have an unsigned type. A similar change was made for mpegvideo in cb66847. Signed-off-by: Mans Rullgard --- libavcodec/snow.h | 4 ++-- libavcodec/snowenc.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libavcodec/snow.h b/libavcodec/snow.h index f43deb1d72..bd54994b5b 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -154,8 +154,8 @@ typedef struct SnowContext{ Plane plane[MAX_PLANES]; BlockNode *block; #define ME_CACHE_SIZE 1024 - int me_cache[ME_CACHE_SIZE]; - int me_cache_generation; + unsigned me_cache[ME_CACHE_SIZE]; + unsigned me_cache_generation; slice_buffer sb; int memc_only; diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 4926eef5d2..cd60c3a512 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -958,7 +958,8 @@ static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int const int b_stride= s->b_width << s->block_max_depth; BlockNode *block= &s->block[mb_x + mb_y * b_stride]; BlockNode backup= *block; - int rd, index, value; + unsigned value; + int rd, index; assert(mb_x>=0 && mb_y>=0); assert(mb_xb_width << s->block_max_depth; BlockNode *block= &s->block[mb_x + mb_y * b_stride]; BlockNode backup[4]= {block[0], block[1], block[b_stride], block[b_stride+1]}; - int rd, index, value; + unsigned value; + int rd, index; assert(mb_x>=0 && mb_y>=0); assert(mb_x Date: Sat, 26 Nov 2011 21:53:00 +0000 Subject: swscale: fix signed overflow in yuv2mono_X_c_template As old bits are shifted out of the accumulator, they cause signed overflows when they reach the end. Making the variable unsigned fixes this. Signed-off-by: Mans Rullgard --- libswscale/swscale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 98daf22cbd..975a0bdf1f 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -510,7 +510,7 @@ yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter, const uint8_t * const d128=dither_8x8_220[y&7]; uint8_t *g = c->table_gU[128] + c->table_gV[128]; int i; - int acc = 0; + unsigned acc = 0; for (i = 0; i < dstW - 1; i += 2) { int j; -- cgit v1.2.3