diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-01-16 01:20:32 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-01-16 01:33:35 +0100 |
commit | 4a4c4278b716b49b9f1653df4ac4f1f026606081 (patch) | |
tree | e1f9e2855fb0dc8a836ff795bd0eb95b48af30bd /libavcodec | |
parent | f94ce3bcab67369b18976f6cf8e69ae132805213 (diff) | |
parent | 2df5f59ad0710a0d85114b73bd6a5094c26d08bc (diff) | |
download | ffmpeg-4a4c4278b716b49b9f1653df4ac4f1f026606081.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
fate: split ADPCM and DPCM test references into separate files.
mov, mxfdec: Employ more meaningful return values.
lavc: Relax API strictness in avcodec_decode_audio3 with a custom get_buffer()
wavpack: fix clipping for 32-bit lossy mode
vb: Use bytestream2 functions
Conflicts:
libavcodec/utils.c
libavcodec/vb.c
libavformat/mxfdec.c
tests/fate/dpcm.mak
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/avcodec.h | 5 | ||||
-rw-r--r-- | libavcodec/utils.c | 6 | ||||
-rw-r--r-- | libavcodec/vb.c | 77 | ||||
-rw-r--r-- | libavcodec/wavpack.c | 27 |
4 files changed, 56 insertions, 59 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 9a8ca81db9..4e55e0e12b 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4188,6 +4188,11 @@ int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that * no overreading happens for damaged MPEG streams. * + * @warning You must not provide a custom get_buffer() when using + * avcodec_decode_audio3(). Doing so will override it with + * avcodec_default_get_buffer. Use avcodec_decode_audio4() instead, + * which does allow the application to provide a custom get_buffer(). + * * @note You might have to align the input buffer avpkt->data and output buffer * samples. The alignment requirements depend on the CPU: On some CPUs it isn't * necessary at all, on others it won't work at all if not aligned and on others diff --git a/libavcodec/utils.c b/libavcodec/utils.c index e25f1dfb41..462288446b 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1057,8 +1057,10 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa int ret, got_frame = 0; if (avctx->get_buffer != avcodec_default_get_buffer) { - av_log(avctx, AV_LOG_ERROR, "Overriding custom get_buffer() for " - "avcodec_decode_audio3()\n"); + av_log(avctx, AV_LOG_ERROR, "Custom get_buffer() for use with" + "avcodec_decode_audio3() detected. Overriding with avcodec_default_get_buffer\n"); + av_log(avctx, AV_LOG_ERROR, "Please port your application to " + "avcodec_decode_audio4()\n"); avctx->get_buffer = avcodec_default_get_buffer; avctx->release_buffer = avcodec_default_release_buffer; } diff --git a/libavcodec/vb.c b/libavcodec/vb.c index 26967db7b2..50e5d0b1a4 100644 --- a/libavcodec/vb.c +++ b/libavcodec/vb.c @@ -44,7 +44,7 @@ typedef struct VBDecContext { uint8_t *frame, *prev_frame; uint32_t pal[AVPALETTE_COUNT]; - const uint8_t *stream; + GetByteContext stream; } VBDecContext; static const uint16_t vb_patterns[64] = { @@ -62,8 +62,8 @@ static void vb_decode_palette(VBDecContext *c, int data_size) { int start, size, i; - start = bytestream_get_byte(&c->stream); - size = (bytestream_get_byte(&c->stream) - 1) & 0xFF; + start = bytestream2_get_byte(&c->stream); + size = (bytestream2_get_byte(&c->stream) - 1) & 0xFF; if(start + size > 255){ av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n"); return; @@ -73,7 +73,7 @@ static void vb_decode_palette(VBDecContext *c, int data_size) return; } for(i = start; i <= start + size; i++) - c->pal[i] = 0xFF << 24 | bytestream_get_be24(&c->stream); + c->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&c->stream); } static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end) @@ -86,10 +86,10 @@ static inline int check_line(uint8_t *buf, uint8_t *start, uint8_t *end) return buf >= start && (buf + 4) <= end; } -static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_size, int offset) +static int vb_decode_framedata(VBDecContext *c, int offset) { + GetByteContext g; uint8_t *prev, *cur; - const uint8_t* data_end = buf + data_size; int blk, blocks, t, blk2; int blocktypes = 0; int x, y, a, b; @@ -98,6 +98,8 @@ static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_siz uint8_t *pstart = c->prev_frame; uint8_t *pend = c->prev_frame + width*c->avctx->height; + g = c->stream; + prev = c->prev_frame + offset; cur = c->frame; @@ -105,11 +107,7 @@ static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_siz blk2 = 0; for(blk = 0; blk < blocks; blk++){ if(!(blk & 3)) { - if(buf >= data_end){ - av_log(c->avctx, AV_LOG_ERROR, "Data pointer out of bounds\n"); - return -1; - } - blocktypes = bytestream_get_byte(&buf); + blocktypes = bytestream2_get_byte(&g); } switch(blocktypes & 0xC0){ case 0x00: //skip @@ -120,15 +118,14 @@ static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_siz memset(cur + y*width, 0, 4); break; case 0x40: - t = bytestream_get_byte(&buf); + t = bytestream2_get_byte(&g); if(!t){ //raw block - if(buf + 16 > data_end){ + if (bytestream2_get_bytes_left(&g) < 16) { av_log(c->avctx, AV_LOG_ERROR, "Insufficient data\n"); return -1; } for(y = 0; y < 4; y++) - memcpy(cur + y*width, buf + y*4, 4); - buf += 16; + bytestream2_get_buffer(&g, cur + y * width, 4); }else{ // motion compensation x = ((t & 0xF)^8) - 8; y = ((t >> 4) ^8) - 8; @@ -141,22 +138,18 @@ static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_siz } break; case 0x80: // fill - t = bytestream_get_byte(&buf); + t = bytestream2_get_byte(&g); for(y = 0; y < 4; y++) memset(cur + y*width, t, 4); break; case 0xC0: // pattern fill - if(buf + 2 > data_end){ - av_log(c->avctx, AV_LOG_ERROR, "Insufficient data\n"); - return -1; - } - t = bytestream_get_byte(&buf); + t = bytestream2_get_byte(&g); pattype = t >> 6; pattern = vb_patterns[t & 0x3F]; switch(pattype){ case 0: - a = bytestream_get_byte(&buf); - b = bytestream_get_byte(&buf); + a = bytestream2_get_byte(&g); + b = bytestream2_get_byte(&g); for(y = 0; y < 4; y++) for(x = 0; x < 4; x++, pattern >>= 1) cur[x + y*width] = (pattern & 1) ? b : a; @@ -164,7 +157,7 @@ static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_siz case 1: pattern = ~pattern; case 2: - a = bytestream_get_byte(&buf); + a = bytestream2_get_byte(&g); for(y = 0; y < 4; y++) for(x = 0; x < 4; x++, pattern >>= 1) if(pattern & 1 && check_pixel(prev + x + y*width, pstart, pend)) @@ -193,16 +186,15 @@ static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_siz static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; VBDecContext * const c = avctx->priv_data; uint8_t *outptr, *srcptr; int i, j; int flags; uint32_t size; - int rest = buf_size; int offset = 0; + bytestream2_init(&c->stream, avpkt->data, avpkt->size); + if(c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); c->pic.reference = 3; @@ -211,38 +203,25 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac return -1; } - c->stream = buf; - flags = bytestream_get_le16(&c->stream); - rest -= 2; + flags = bytestream2_get_le16(&c->stream); if(flags & VB_HAS_GMC){ - i = (int16_t)bytestream_get_le16(&c->stream); - j = (int16_t)bytestream_get_le16(&c->stream); + i = (int16_t)bytestream2_get_le16(&c->stream); + j = (int16_t)bytestream2_get_le16(&c->stream); offset = i + j * avctx->width; - rest -= 4; - } - if(rest < 0){ - av_log(avctx, AV_LOG_ERROR, "not enough data\n"); - return -1; } if(flags & VB_HAS_VIDEO){ - size = bytestream_get_le32(&c->stream); - if(size > rest || size<4){ + size = bytestream2_get_le32(&c->stream); + if(size > bytestream2_get_bytes_left(&c->stream)+4 || size<4){ av_log(avctx, AV_LOG_ERROR, "Frame size invalid\n"); return -1; } - vb_decode_framedata(c, c->stream, size, offset); - c->stream += size - 4; - rest -= size; + vb_decode_framedata(c, offset); + bytestream2_skip(&c->stream, size - 4); } if(flags & VB_HAS_PALETTE){ - size = bytestream_get_le32(&c->stream); - if(size > rest){ - av_log(avctx, AV_LOG_ERROR, "Palette size is too big\n"); - return -1; - } + size = bytestream2_get_le32(&c->stream); vb_decode_palette(c, size); - rest -= size; } memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); @@ -263,7 +242,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ - return buf_size; + return avpkt->size; } static av_cold int decode_init(AVCodecContext *avctx) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 7d358238b2..9adfc968db 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -112,7 +112,8 @@ typedef struct WavpackFrameContext { int extra_bits; int and, or, shift; int post_shift; - int hybrid, hybrid_bitrate, hybrid_maxclip; + int hybrid, hybrid_bitrate; + int hybrid_maxclip, hybrid_minclip; int float_flag; int float_shift; int float_max_exp; @@ -412,12 +413,12 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, } bit = (S & s->and) | s->or; - bit = (((S + bit) << s->shift) - bit) << s->post_shift; + bit = ((S + bit) << s->shift) - bit; if (s->hybrid) - bit = av_clip(bit, -s->hybrid_maxclip - 1, s->hybrid_maxclip); + bit = av_clip(bit, s->hybrid_minclip, s->hybrid_maxclip); - return bit; + return bit << s->post_shift; } static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) @@ -763,7 +764,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, const uint8_t *orig_buf = buf; const uint8_t *buf_end = buf + buf_size; int i, j, id, size, ssize, weights, t; - int bpp, chan, chmask; + int bpp, chan, chmask, orig_bpp; if (buf_size == 0) { *got_frame_ptr = 0; @@ -799,15 +800,16 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->frame_flags = AV_RL32(buf); buf += 4; bpp = av_get_bytes_per_sample(avctx->sample_fmt); samples = (uint8_t*)samples + bpp * wc->ch_offset; + orig_bpp = ((s->frame_flags & 0x03) + 1) << 3; s->stereo = !(s->frame_flags & WV_MONO); s->stereo_in = (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo; s->joint = s->frame_flags & WV_JOINT_STEREO; s->hybrid = s->frame_flags & WV_HYBRID_MODE; s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE; - s->hybrid_maxclip = (1LL << ((((s->frame_flags & 0x03) + 1) << 3) - 1)) - 1; - s->post_shift = 8 * (bpp - 1 - (s->frame_flags & 0x03)) + - ((s->frame_flags >> 13) & 0x1f); + s->post_shift = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f); + s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1) >> s->post_shift; + s->hybrid_minclip = ((-1LL << (orig_bpp - 1))) >> s->post_shift; s->CRC = AV_RL32(buf); buf += 4; if (wc->mkv_mode) buf += 4; //skip block size; @@ -968,6 +970,15 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->and = 1; s->shift = buf[3]; } + /* original WavPack decoder forces 32-bit lossy sound to be treated + * as 24-bit one in order to have proper clipping + */ + if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) { + s->post_shift += 8; + s->shift -= 8; + s->hybrid_maxclip >>= 8; + s->hybrid_minclip >>= 8; + } buf += 4; break; case WP_ID_FLOATINFO: |