From fe21f78d2bf1ac5b5400570a8a4031be3493aa7d Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 28 Sep 2011 15:43:24 -0700 Subject: [PATCH 01/34] mpeg probe: check the 2/4-bit synchronization value found after a pack_start_code. --- libavformat/mpeg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index f797da7e27..ef683b1a05 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -49,6 +49,10 @@ static int check_pes(uint8_t *p, uint8_t *end){ return pes1||pes2; } +static int check_pack_header(const uint8_t *buf) { + return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20; +} + static int mpegps_probe(AVProbeData *p) { uint32_t code= -1; @@ -61,9 +65,10 @@ static int mpegps_probe(AVProbeData *p) if ((code & 0xffffff00) == 0x100) { int len= p->buf[i+1] << 8 | p->buf[i+2]; int pes= check_pes(p->buf+i, p->buf+p->buf_size); + int pack = check_pack_header(p->buf+i); if(code == SYSTEM_HEADER_START_CODE) sys++; - else if(code == PACK_START_CODE) pspack++; + else if(code == PACK_START_CODE && pack) pspack++; else if((code & 0xf0) == VIDEO_ID && pes) vid++; // skip pes payload to avoid start code emulation for private // and audio streams From fcbe421cee55e06c62d1d5d1f3cc7c522e7210a4 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 28 Sep 2011 17:50:51 -0700 Subject: [PATCH 02/34] prores: Handle 0 or fewer bits left show_bits() is undefined when the number of bits is less than or equal to zero. --- libavcodec/proresdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c index 759c10b6e5..c70d145345 100644 --- a/libavcodec/proresdec.c +++ b/libavcodec/proresdec.c @@ -427,13 +427,13 @@ static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out, lev_cb_index = lev_to_cb_index[FFMIN(level, 9)]; bits_left = get_bits_left(gb); - if (bits_left <= 8 && !show_bits(gb, bits_left)) + if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left))) return; run = decode_vlc_codeword(gb, ac_codebook[run_cb_index]); bits_left = get_bits_left(gb); - if (bits_left <= 8 && !show_bits(gb, bits_left)) + if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left))) return; level = decode_vlc_codeword(gb, ac_codebook[lev_cb_index]) + 1; From 5a9ed7c110d78ddcced94525b5181a2463dc009f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 7 Sep 2011 23:08:57 -0400 Subject: [PATCH 03/34] adpcm: pretty-print tables --- libavcodec/adpcm.c | 17 ++++++++++------- libavcodec/adpcm_data.c | 26 +++++++++++++------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 5e83e4b37a..25432f6160 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -57,16 +57,19 @@ /* These are for CD-ROM XA ADPCM */ static const int xa_adpcm_table[5][2] = { - { 0, 0 }, - { 60, 0 }, - { 115, -52 }, - { 98, -55 }, - { 122, -60 } + { 0, 0 }, + { 60, 0 }, + { 115, -52 }, + { 98, -55 }, + { 122, -60 } }; static const int ea_adpcm_table[] = { - 0, 240, 460, 392, 0, 0, -208, -220, 0, 1, - 3, 4, 7, 8, 10, 11, 0, -1, -3, -4 + 0, 240, 460, 392, + 0, 0, -208, -220, + 0, 1, 3, 4, + 7, 8, 10, 11, + 0, -1, -3, -4 }; // padded to zero where table size is less then 16 diff --git a/libavcodec/adpcm_data.c b/libavcodec/adpcm_data.c index 9dc5670bfc..3bc5de23b3 100644 --- a/libavcodec/adpcm_data.c +++ b/libavcodec/adpcm_data.c @@ -38,14 +38,14 @@ const int8_t ff_adpcm_index_table[16] = { * this table, but such deviations are negligible: */ const int16_t ff_adpcm_step_table[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; @@ -53,18 +53,18 @@ const int16_t ff_adpcm_step_table[89] = { /* ff_adpcm_AdaptationTable[], ff_adpcm_AdaptCoeff1[], and ff_adpcm_AdaptCoeff2[] are from libsndfile */ const int16_t ff_adpcm_AdaptationTable[] = { - 230, 230, 230, 230, 307, 409, 512, 614, - 768, 614, 512, 409, 307, 230, 230, 230 + 230, 230, 230, 230, 307, 409, 512, 614, + 768, 614, 512, 409, 307, 230, 230, 230 }; /** Divided by 4 to fit in 8-bit integers */ const uint8_t ff_adpcm_AdaptCoeff1[] = { - 64, 128, 0, 48, 60, 115, 98 + 64, 128, 0, 48, 60, 115, 98 }; /** Divided by 4 to fit in 8-bit integers */ const int8_t ff_adpcm_AdaptCoeff2[] = { - 0, -64, 0, 16, 0, -52, -58 + 0, -64, 0, 16, 0, -52, -58 }; const int16_t ff_adpcm_yamaha_indexscale[] = { @@ -73,6 +73,6 @@ const int16_t ff_adpcm_yamaha_indexscale[] = { }; const int8_t ff_adpcm_yamaha_difflookup[] = { - 1, 3, 5, 7, 9, 11, 13, 15, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15 }; From de0b586a87c510685bd9a32ca832007c422d7cd8 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 8 Sep 2011 16:03:44 -0400 Subject: [PATCH 04/34] adpcm: simplify and speed up several ADPCM decoders. --- libavcodec/adpcm.c | 86 +++++++++++----------------------------------- 1 file changed, 21 insertions(+), 65 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 25432f6160..c6b0aaa399 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -527,21 +527,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, *samples++ = c->status[1].predictor; } while (src < buf + buf_size) { - - /* take care of the top nibble (always left or mono channel) */ - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] >> 4, 3); - - /* take care of the bottom nibble, which is right sample for - * stereo, or another mono sample */ - if (st) - *samples++ = adpcm_ima_expand_nibble(&c->status[1], - src[0] & 0x0F, 3); - else - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] & 0x0F, 3); - - src++; + uint8_t v = *src++; + *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4 , 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); } break; case CODEC_ID_ADPCM_IMA_DK3: @@ -600,39 +588,25 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } while (src < buf + buf_size) { - + uint8_t v1, v2; + uint8_t v = *src++; + /* nibbles are swapped for mono */ if (st) { - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] >> 4 , 3); - *samples++ = adpcm_ima_expand_nibble(&c->status[1], - src[0] & 0x0F, 3); + v1 = v >> 4; + v2 = v & 0x0F; } else { - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] & 0x0F, 3); - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] >> 4 , 3); + v2 = v >> 4; + v1 = v & 0x0F; } - - src++; + *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v1, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3); } break; case CODEC_ID_ADPCM_IMA_WS: - /* no per-block initialization; just start decoding the data */ while (src < buf + buf_size) { - - if (st) { - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] >> 4 , 3); - *samples++ = adpcm_ima_expand_nibble(&c->status[1], - src[0] & 0x0F, 3); - } else { - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] >> 4 , 3); - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] & 0x0F, 3); - } - - src++; + uint8_t v = *src++; + *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4 , 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); } break; case CODEC_ID_ADPCM_XA: @@ -886,18 +860,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, break; case CODEC_ID_ADPCM_CT: while (src < buf + buf_size) { - if (st) { - *samples++ = adpcm_ct_expand_nibble(&c->status[0], - src[0] >> 4); - *samples++ = adpcm_ct_expand_nibble(&c->status[1], - src[0] & 0x0F); - } else { - *samples++ = adpcm_ct_expand_nibble(&c->status[0], - src[0] >> 4); - *samples++ = adpcm_ct_expand_nibble(&c->status[0], - src[0] & 0x0F); - } - src++; + uint8_t v = *src++; + *samples++ = adpcm_ct_expand_nibble(&c->status[0 ], v >> 4 ); + *samples++ = adpcm_ct_expand_nibble(&c->status[st], v & 0x0F); } break; case CODEC_ID_ADPCM_SBPRO_4: @@ -1005,18 +970,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } case CODEC_ID_ADPCM_YAMAHA: while (src < buf + buf_size) { - if (st) { - *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], - src[0] & 0x0F); - *samples++ = adpcm_yamaha_expand_nibble(&c->status[1], - src[0] >> 4 ); - } else { - *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], - src[0] & 0x0F); - *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], - src[0] >> 4 ); - } - src++; + uint8_t v = *src++; + *samples++ = adpcm_yamaha_expand_nibble(&c->status[0 ], v & 0x0F); + *samples++ = adpcm_yamaha_expand_nibble(&c->status[st], v >> 4 ); } break; case CODEC_ID_ADPCM_THP: From ac94b8bcc6cdba000ada0c84b4c287f7f37f2384 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 8 Sep 2011 18:57:56 -0400 Subject: [PATCH 05/34] adpcm: simplify packet size bounds checking in the ADPCM IMA QT decoder. This is easier to understand. It also avoids returning existing samples mixed with new samples when the packet is too small. --- libavcodec/adpcm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index c6b0aaa399..ae3f99ba0d 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -379,7 +379,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, switch(avctx->codec->id) { case CODEC_ID_ADPCM_IMA_QT: - n = buf_size - 2*avctx->channels; + /* In QuickTime, IMA is encoded by chunks of 34 bytes (=64 samples). + Channel data is interleaved per-chunk. */ + if (buf_size / 34 < avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } for (channel = 0; channel < avctx->channels; channel++) { int16_t predictor; int step_index; @@ -412,7 +417,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, samples = (short*)data + channel; - for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */ + for (m = 0; m < 32; m++) { *samples = adpcm_ima_qt_expand_nibble(cs, src[0] & 0x0F, 3); samples += avctx->channels; *samples = adpcm_ima_qt_expand_nibble(cs, src[0] >> 4 , 3); From 7c287b18a01df4ace16593f43160aaf16c04070e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 9 Sep 2011 14:57:36 -0400 Subject: [PATCH 06/34] adpcm: update reference links Add Multimedia Wiki link. Mark dead links with [dead]. Some can still be accessed through archive.org. Update URLs for pages which have moved. Replace duplicated links in adpcmenc.c with a note to see the ADPCM decoder reference documents. --- libavcodec/adpcm.c | 17 +++++++++-------- libavcodec/adpcmenc.c | 8 +------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index ae3f99ba0d..df316fb646 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -42,16 +42,17 @@ * Features and limitations: * * Reference documents: - * http://www.pcisys.net/~melanson/codecs/simpleaudio.html - * http://www.geocities.com/SiliconValley/8682/aud3.txt - * http://openquicktime.sourceforge.net/plugins.htm - * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html - * http://www.cs.ucla.edu/~leec/mediabench/applications.html - * SoX source code http://home.sprynet.com/~cbagwell/sox.html + * http://wiki.multimedia.cx/index.php?title=Category:ADPCM_Audio_Codecs + * http://www.pcisys.net/~melanson/codecs/simpleaudio.html [dead] + * http://www.geocities.com/SiliconValley/8682/aud3.txt [dead] + * http://openquicktime.sourceforge.net/ + * XAnim sources (xa_codec.c) http://xanim.polter.net/ + * http://www.cs.ucla.edu/~leec/mediabench/applications.html [dead] + * SoX source code http://sox.sourceforge.net/ * * CD-ROM XA: - * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html - * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html + * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html [dead] + * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html [dead] * readstr http://www.geocities.co.jp/Playtown/2004/ */ diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index d46a8c98b6..7027e373dc 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -32,13 +32,7 @@ * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood) * by Mike Melanson (melanson@pcisys.net) * - * Reference documents: - * http://www.pcisys.net/~melanson/codecs/simpleaudio.html - * http://www.geocities.com/SiliconValley/8682/aud3.txt - * http://openquicktime.sourceforge.net/plugins.htm - * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html - * http://www.cs.ucla.edu/~leec/mediabench/applications.html - * SoX source code http://home.sprynet.com/~cbagwell/sox.html + * See ADPCM decoder reference documents for codec information. */ typedef struct TrellisPath { From 119974b164dd2d09031c61c87c8c59a1819f3a90 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 9 Sep 2011 16:26:11 -0400 Subject: [PATCH 07/34] adpcm_ima_wav: process channel-interleaved blocks sequentially rather than simultaneously. Speeds up the ADPCM IMA WAV decoder by 15-20% overall. --- libavcodec/adpcm.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index df316fb646..80e36e536f 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -448,14 +448,18 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } while(src < buf + buf_size){ - for(m=0; m<4; m++){ - for(i=0; i<=st; i++) - *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] & 0x0F, 3); - for(i=0; i<=st; i++) - *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] >> 4 , 3); - src++; + for (i = 0; i < avctx->channels; i++) { + cs = &c->status[i]; + for (m = 0; m < 4; m++) { + uint8_t v = *src++; + *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 3); + samples += avctx->channels; + *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 3); + samples += avctx->channels; + } + samples -= 8 * avctx->channels - 1; } - src += 4*st; + samples += 7 * avctx->channels; } break; case CODEC_ID_ADPCM_4XM: From 943f4db5520c741ccc8f991374a608fc14735e14 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 9 Sep 2011 18:43:19 -0400 Subject: [PATCH 08/34] adpcm_4xm: process planar packets sequentially rather than simultaneously. Also properly clip the right channel step_index. --- libavcodec/adpcm.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 80e36e536f..57f83a7d61 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -463,30 +463,28 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_ADPCM_4XM: - cs = &(c->status[0]); - c->status[0].predictor= (int16_t)bytestream_get_le16(&src); - if(st){ - c->status[1].predictor= (int16_t)bytestream_get_le16(&src); + for (i = 0; i < avctx->channels; i++) + c->status[i].predictor= (int16_t)bytestream_get_le16(&src); + + for (i = 0; i < avctx->channels; i++) { + c->status[i].step_index= (int16_t)bytestream_get_le16(&src); + c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88); } - c->status[0].step_index= (int16_t)bytestream_get_le16(&src); - if(st){ - c->status[1].step_index= (int16_t)bytestream_get_le16(&src); - } - if (cs->step_index < 0) cs->step_index = 0; - if (cs->step_index > 88) cs->step_index = 88; m= (buf_size - (src - buf))>>st; - for(i=0; istatus[0], src[i] & 0x0F, 4); - if (st) - *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] & 0x0F, 4); - *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] >> 4, 4); - if (st) - *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] >> 4, 4); + + for (i = 0; i < avctx->channels; i++) { + samples = (short*)data + i; + cs = &c->status[i]; + for (n = 0; n < m; n++) { + uint8_t v = *src++; + *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 4); + samples += avctx->channels; + *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 4); + samples += avctx->channels; + } } - - src += m<channels - 1); break; case CODEC_ID_ADPCM_MS: if (avctx->block_align != 0 && buf_size > avctx->block_align) From 8114f94ac92404a8ccbf3737c577e508f70f11bd Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 9 Sep 2011 23:18:03 -0400 Subject: [PATCH 09/34] adpcm_ms: clean up reading of predictor coefficients --- libavcodec/adpcm.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 57f83a7d61..d46ec4aabd 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -340,7 +340,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, ADPCMDecodeContext *c = avctx->priv_data; ADPCMChannelStatus *cs; int n, m, channel, i; - int block_predictor[2]; short *samples; short *samples_end; const uint8_t *src; @@ -487,23 +486,27 @@ static int adpcm_decode_frame(AVCodecContext *avctx, samples -= (avctx->channels - 1); break; case CODEC_ID_ADPCM_MS: + { + int block_predictor; + if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; n = buf_size - 7 * avctx->channels; if (n < 0) return -1; - block_predictor[0] = av_clip(*src++, 0, 6); - block_predictor[1] = 0; - if (st) - block_predictor[1] = av_clip(*src++, 0, 6); + + block_predictor = av_clip(*src++, 0, 6); + c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor]; + c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor]; + if (st) { + block_predictor = av_clip(*src++, 0, 6); + c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor]; + c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor]; + } c->status[0].idelta = (int16_t)bytestream_get_le16(&src); if (st){ c->status[1].idelta = (int16_t)bytestream_get_le16(&src); } - c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[0]]; - c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[0]]; - c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[1]]; - c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[1]]; c->status[0].sample1 = bytestream_get_le16(&src); if (st) c->status[1].sample1 = bytestream_get_le16(&src); @@ -520,6 +523,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src ++; } break; + } case CODEC_ID_ADPCM_IMA_DK4: if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; From a57ea1a87e6b65194718968fe0b778e843d4d4b0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 10 Sep 2011 13:52:33 -0400 Subject: [PATCH 10/34] adpcm: simplify reading of IMA DK4 frame header. --- libavcodec/adpcm.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index d46ec4aabd..be10f88de8 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -528,15 +528,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; - c->status[0].predictor = (int16_t)bytestream_get_le16(&src); - c->status[0].step_index = *src++; - src++; - *samples++ = c->status[0].predictor; - if (st) { - c->status[1].predictor = (int16_t)bytestream_get_le16(&src); - c->status[1].step_index = *src++; + for (channel = 0; channel < avctx->channels; channel++) { + cs = &c->status[channel]; + cs->predictor = (int16_t)bytestream_get_le16(&src); + cs->step_index = *src++; src++; - *samples++ = c->status[1].predictor; + *samples++ = cs->predictor; } while (src < buf + buf_size) { uint8_t v = *src++; From 5c9eb4fabbefd4ebb02620a0a3a6e10032ec069d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 10 Sep 2011 13:54:02 -0400 Subject: [PATCH 11/34] adpcm: check buffer size in IMA DK4 decoder before reading header. Also use the post-header data size to control termination of the main decoding loop. --- libavcodec/adpcm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index be10f88de8..80dc7ca1d8 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -528,6 +528,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; + n = buf_size - 4 * avctx->channels; + if (n < 0) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } + for (channel = 0; channel < avctx->channels; channel++) { cs = &c->status[channel]; cs->predictor = (int16_t)bytestream_get_le16(&src); @@ -535,7 +541,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src++; *samples++ = cs->predictor; } - while (src < buf + buf_size) { + while (n-- > 0) { uint8_t v = *src++; *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4 , 3); *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); From ba5d2890d735961f1e4e8484082287a552cad699 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 10 Sep 2011 14:21:39 -0400 Subject: [PATCH 12/34] adpcm: simplify reading of Funcom ISS frame header. --- libavcodec/adpcm.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 80dc7ca1d8..e4e0627542 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -593,13 +593,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_ADPCM_IMA_ISS: - c->status[0].predictor = (int16_t)AV_RL16(src + 0); - c->status[0].step_index = src[2]; - src += 4; - if(st) { - c->status[1].predictor = (int16_t)AV_RL16(src + 0); - c->status[1].step_index = src[2]; - src += 4; + for (channel = 0; channel < avctx->channels; channel++) { + cs = &c->status[channel]; + cs->predictor = (int16_t)bytestream_get_le16(&src); + cs->step_index = *src++; + src++; } while (src < buf + buf_size) { From 9662539c103d54cacf9adbf1345013e011c08d4f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 10 Sep 2011 14:24:00 -0400 Subject: [PATCH 13/34] adpcm: check buffer size in Funcom ISS decoder before reading header. Also use the post-header data size to control termination of the main decoding loop. --- libavcodec/adpcm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index e4e0627542..75d32633be 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -593,6 +593,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_ADPCM_IMA_ISS: + n = buf_size - 4 * avctx->channels; + if (n < 0) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } + for (channel = 0; channel < avctx->channels; channel++) { cs = &c->status[channel]; cs->predictor = (int16_t)bytestream_get_le16(&src); @@ -600,7 +606,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src++; } - while (src < buf + buf_size) { + while (n-- > 0) { uint8_t v1, v2; uint8_t v = *src++; /* nibbles are swapped for mono */ From e562fbd0032eea1a984b7b2521ae58d7b589238c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 10 Sep 2011 14:37:09 -0400 Subject: [PATCH 14/34] adpcm: move codec-specific variable declarations to the sections for the corresponding codecs. --- libavcodec/adpcm.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 75d32633be..fadafafa3f 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -344,22 +344,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, short *samples_end; const uint8_t *src; int st; /* stereo */ - - /* DK3 ADPCM accounting variables */ - unsigned char last_byte = 0; - unsigned char nibble; - int decode_top_nibble_next = 0; - int diff_channel; - - /* EA ADPCM state variables */ uint32_t samples_in_chunk; - int32_t previous_left_sample, previous_right_sample; - int32_t current_left_sample, current_right_sample; - int32_t next_left_sample, next_right_sample; - int32_t coeff1l, coeff2l, coeff1r, coeff2r; - uint8_t shift_left, shift_right; int count1, count2; - int coeff[2][2], shift[2];//used in EA MAXIS ADPCM if (!buf_size) return 0; @@ -548,6 +534,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_ADPCM_IMA_DK3: + { + unsigned char last_byte = 0; + unsigned char nibble; + int decode_top_nibble_next = 0; + int diff_channel; + if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; @@ -592,6 +584,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, *samples++ = c->status[0].predictor - c->status[1].predictor; } break; + } case CODEC_ID_ADPCM_IMA_ISS: n = buf_size - 4 * avctx->channels; if (n < 0) { @@ -662,6 +655,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_ADPCM_EA: + { + int32_t previous_left_sample, previous_right_sample; + int32_t current_left_sample, current_right_sample; + int32_t next_left_sample, next_right_sample; + int32_t coeff1l, coeff2l, coeff1r, coeff2r; + uint8_t shift_left, shift_right; + /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces, each coding 28 stereo samples. */ if (buf_size < 12) { @@ -715,7 +715,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src += 2; // Skip terminating 0x0000 break; + } case CODEC_ID_ADPCM_EA_MAXIS_XA: + { + int coeff[2][2], shift[2]; + for(channel = 0; channel < avctx->channels; channel++) { for (i=0; i<2; i++) coeff[channel][i] = ea_adpcm_table[(*src >> 4) + 4*i]; @@ -737,6 +741,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src+=avctx->channels; } break; + } case CODEC_ID_ADPCM_EA_R1: case CODEC_ID_ADPCM_EA_R2: case CODEC_ID_ADPCM_EA_R3: { From d4a544cbc46fd3550e4d21a9871eeb315e036156 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Fri, 23 Sep 2011 10:51:07 -0500 Subject: [PATCH 15/34] latmenc: Set latmBufferFullness to largest value to indicate it is not used Signed-off-by: Janne Grunau --- libavformat/latmenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c index 707c6031c2..1cdfc1e791 100644 --- a/libavformat/latmenc.c +++ b/libavformat/latmenc.c @@ -116,7 +116,7 @@ static int latm_write_frame_header(AVFormatContext *s, PutBitContext *bs) } put_bits(bs, 3, 0); /* frameLengthType */ - put_bits(bs, 8, 0); /* latmBufferFullness */ + put_bits(bs, 8, 0xff); /* latmBufferFullness */ put_bits(bs, 1, 0); /* otherDataPresent */ put_bits(bs, 1, 0); /* crcCheckPresent */ From dcce09d64bd13ab13b86307f5a268e5c1e50c7e2 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Tue, 5 Jul 2011 00:18:32 +0200 Subject: [PATCH 16/34] dxva: Add ability to enable workaround for older ATI cards The workaround needs to be enabled per PCI ID which cannot be detected inside libavcodec. So add a flag to manually enable the alternate behavior. Signed-off-by: Janne Grunau --- libavcodec/dxva2.h | 2 ++ libavcodec/dxva2_h264.c | 31 ++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h index 5db5d0bc9f..53a00fff17 100644 --- a/libavcodec/dxva2.h +++ b/libavcodec/dxva2.h @@ -27,6 +27,8 @@ #include +#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards + /** * This structure is used to provides the necessary configurations and data * to the DXVA2 Libav HWAccel implementation. diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index 690d4ad9bd..090bce632d 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -113,7 +113,10 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context pp->bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8; pp->bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8; - pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */ + if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) + pp->Reserved16Bits = 0; + else + pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */ pp->StatusReportFeedbackNumber = 1 + ctx->report_id++; pp->CurrFieldOrderCnt[0] = 0; if ((s->picture_structure & PICT_TOP_FIELD) && @@ -150,17 +153,27 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context //pp->SliceGroupMap[810]; /* XXX not implemented by Libav */ } -static void fill_scaling_lists(const H264Context *h, DXVA_Qmatrix_H264 *qm) +static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm) { unsigned i, j; memset(qm, 0, sizeof(*qm)); - for (i = 0; i < 6; i++) - for (j = 0; j < 16; j++) - qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]]; + if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) { + for (i = 0; i < 6; i++) + for (j = 0; j < 16; j++) + qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j]; - for (i = 0; i < 2; i++) - for (j = 0; j < 64; j++) - qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]]; + for (i = 0; i < 2; i++) + for (j = 0; j < 64; j++) + qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][j]; + } else { + for (i = 0; i < 6; i++) + for (j = 0; j < 16; j++) + qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]]; + + for (i = 0; i < 2; i++) + for (j = 0; j < 64; j++) + qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]]; + } } static int is_slice_short(struct dxva_context *ctx) @@ -370,7 +383,7 @@ static int start_frame(AVCodecContext *avctx, fill_picture_parameters(ctx, h, &ctx_pic->pp); /* Fill up DXVA_Qmatrix_H264 */ - fill_scaling_lists(h, &ctx_pic->qm); + fill_scaling_lists(ctx, h, &ctx_pic->qm); ctx_pic->slice_count = 0; ctx_pic->bitstream_size = 0; From 6326afd5e90cfed9df08b652a1cd6f6a948c239a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 23 Sep 2011 21:54:44 -0400 Subject: [PATCH 17/34] avcodec: reject audio packets with NULL data and non-zero size There is no valid reason the user should ever send such packets in the first place, but the documentation for CODEC_CAP_DELAY states that the codec is guaranteed not to get a NULL packet unless that capability is set. That isn't true without preventing this case. --- libavcodec/utils.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 8459e5f870..b598942354 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -747,6 +747,11 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa avctx->pkt = avpkt; + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){ //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){ From bf5d46d8e6de1f3035adb63b50924f474fabb578 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 28 Sep 2011 21:53:03 +0100 Subject: [PATCH 18/34] dca: NEON optimised high freq VQ decoding Signed-off-by: Mans Rullgard --- libavcodec/arm/dca.h | 49 ++++++++++++++++++++++++++++++++++++++++++++ libavcodec/dca.c | 27 ++++++++++++++++-------- libavcodec/dcadata.h | 2 +- 3 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 libavcodec/arm/dca.h diff --git a/libavcodec/arm/dca.h b/libavcodec/arm/dca.h new file mode 100644 index 0000000000..c4c024a36a --- /dev/null +++ b/libavcodec/arm/dca.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Mans Rullgard + * + * 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 + */ + +#ifndef AVCODEC_ARM_DCA_H +#define AVCODEC_ARM_DCA_H + +#include +#include "config.h" + +#if HAVE_NEON && HAVE_INLINE_ASM + +#define int8x8_fmul_int32 int8x8_fmul_int32 +static inline void int8x8_fmul_int32(float *dst, const int8_t *src, int scale) +{ + __asm__ ("vcvt.f32.s32 %2, %2, #4 \n" + "vld1.8 {d0}, [%1,:64] \n" + "vmovl.s8 q0, d0 \n" + "vmovl.s16 q1, d1 \n" + "vmovl.s16 q0, d0 \n" + "vcvt.f32.s32 q0, q0 \n" + "vcvt.f32.s32 q1, q1 \n" + "vmul.f32 q0, q0, %y2 \n" + "vmul.f32 q1, q1, %y2 \n" + "vst1.32 {q0-q1}, [%m0,:128] \n" + : "=Um"(*(float (*)[8])dst) + : "r"(src), "x"(scale) + : "d0", "d1", "d2", "d3"); +} + +#endif + +#endif /* AVCODEC_ARM_DCA_H */ diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 735d7ba9da..e963fe0eb4 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -42,6 +42,10 @@ #include "dcadsp.h" #include "fmtconvert.h" +#if ARCH_ARM +# include "arm/dca.h" +#endif + //#define TRACE #define DCA_PRIM_CHANNELS_MAX (7) @@ -320,7 +324,7 @@ typedef struct { int lfe_scale_factor; /* Subband samples history (for ADPCM) */ - float subband_samples_hist[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4]; + DECLARE_ALIGNED(16, float, subband_samples_hist)[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4]; DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512]; DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32]; int hist_index[DCA_PRIM_CHANNELS_MAX]; @@ -1057,6 +1061,16 @@ static int decode_blockcode(int code, int levels, int *values) static const uint8_t abits_sizes[7] = { 7, 10, 12, 13, 15, 17, 19 }; static const uint8_t abits_levels[7] = { 3, 5, 7, 9, 13, 17, 25 }; +#ifndef int8x8_fmul_int32 +static inline void int8x8_fmul_int32(float *dst, const int8_t *src, int scale) +{ + float fscale = scale / 16.0; + int i; + for (i = 0; i < 8; i++) + dst[i] = src[i] * fscale; +} +#endif + static int dca_subsubframe(DCAContext * s, int base_channel, int block_index) { int k, l; @@ -1161,19 +1175,16 @@ static int dca_subsubframe(DCAContext * s, int base_channel, int block_index) for (l = s->vq_start_subband[k]; l < s->subband_activity[k]; l++) { /* 1 vector -> 32 samples but we only need the 8 samples * for this subsubframe. */ - int m; + int hfvq = s->high_freq_vq[k][l]; if (!s->debug_flag & 0x01) { av_log(s->avctx, AV_LOG_DEBUG, "Stream with high frequencies VQ coding\n"); s->debug_flag |= 0x01; } - for (m = 0; m < 8; m++) { - subband_samples[k][l][m] = - high_freq_vq[s->high_freq_vq[k][l]][subsubframe * 8 + - m] - * (float) s->scale_factor[k][l][0] / 16.0; - } + int8x8_fmul_int32(subband_samples[k][l], + &high_freq_vq[hfvq][subsubframe * 8], + s->scale_factor[k][l][0]); } } diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h index ed3ec4ee52..0a83cdfae7 100644 --- a/libavcodec/dcadata.h +++ b/libavcodec/dcadata.h @@ -4224,7 +4224,7 @@ static const float lossless_quant_d[32] = { /* Vector quantization tables */ -static const int8_t high_freq_vq[1024][32] = +DECLARE_ALIGNED(8, static const int8_t, high_freq_vq)[1024][32] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, From bcb15554894e13d1575d5f6e7ff833812a315004 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Wed, 21 Sep 2011 20:42:48 +0000 Subject: [PATCH 19/34] dxva2_h264: pass the correct 8x8 scaling lists Copy the Inter 8x8 scaling list as second 8x8 matrix into DXVA2's quantization matrix data structure instead of a potentially unset Intra chroma scaling matrix. Fix dxva2 decoding for some H264 samples. Signed-off-by: Janne Grunau --- libavcodec/dxva2_h264.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index 090bce632d..ea51958c62 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -162,17 +162,19 @@ static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, D for (j = 0; j < 16; j++) qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j]; - for (i = 0; i < 2; i++) - for (j = 0; j < 64; j++) - qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][j]; + for (i = 0; i < 64; i++) { + qm->bScalingLists8x8[0][i] = h->pps.scaling_matrix8[0][i]; + qm->bScalingLists8x8[1][i] = h->pps.scaling_matrix8[3][i]; + } } else { for (i = 0; i < 6; i++) for (j = 0; j < 16; j++) qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]]; - for (i = 0; i < 2; i++) - for (j = 0; j < 64; j++) - qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]]; + for (i = 0; i < 64; i++) { + qm->bScalingLists8x8[0][i] = h->pps.scaling_matrix8[0][ff_zigzag_direct[i]]; + qm->bScalingLists8x8[1][i] = h->pps.scaling_matrix8[3][ff_zigzag_direct[i]]; + } } } From e81e5e8ad2bb5746df0c343c396019aca165cf66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 30 Sep 2011 20:30:35 +0300 Subject: [PATCH 20/34] lavf: Avoid using av_malloc(0) in av_dump_format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On OS X, av_malloc(0) returns pointers that cause crashes when freed. Signed-off-by: Martin Storsjö --- libavformat/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index d0ad3589b6..0ba6fc3cd9 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3333,7 +3333,7 @@ void av_dump_format(AVFormatContext *ic, int is_output) { int i; - uint8_t *printed = av_mallocz(ic->nb_streams); + uint8_t *printed = ic->nb_streams ? av_mallocz(ic->nb_streams) : NULL; if (ic->nb_streams && !printed) return; From f5e717f3c735af5c941b458d42615c97028aa916 Mon Sep 17 00:00:00 2001 From: Nathan Caldwell Date: Tue, 27 Sep 2011 18:48:43 -0600 Subject: [PATCH 21/34] avserver: Fix a bug where the socket is IPv4, but IPv6 is autoselected for the loopback address. This fixes bind(8080): Address family not supported by protocol. Signed-off-by: Anton Khirnov --- avserver.c | 1 + 1 file changed, 1 insertion(+) diff --git a/avserver.c b/avserver.c index d0a14aa565..7b8bf1397a 100644 --- a/avserver.c +++ b/avserver.c @@ -522,6 +522,7 @@ static int socket_open_listen(struct sockaddr_in *my_addr) tmp = 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); + my_addr->sin_family = AF_INET; if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) { char bindmsg[32]; snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port)); From b09c7eefb77263b2b1292faa65c292e74c04ff43 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 11:13:04 -0400 Subject: [PATCH 22/34] dpcm: cosmetics: rename channel_number to ch Make the code easier to read. --- libavcodec/dpcm.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 34c739a790..1c80522a00 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -168,7 +168,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, DPCMContext *s = avctx->priv_data; int in, out = 0; int predictor[2]; - int channel_number = 0; + int ch = 0; short *output_samples = data; int shift[2]; unsigned char byte; @@ -195,12 +195,12 @@ static int dpcm_decode_frame(AVCodecContext *avctx, /* decode the samples */ for (in = 8, out = 0; in < buf_size; in++, out++) { - predictor[channel_number] += s->roq_square_array[buf[in]]; - predictor[channel_number] = av_clip_int16(predictor[channel_number]); - output_samples[out] = predictor[channel_number]; + predictor[ch] += s->roq_square_array[buf[in]]; + predictor[ch] = av_clip_int16(predictor[ch]); + output_samples[out] = predictor[ch]; /* toggle channel */ - channel_number ^= s->channels - 1; + ch ^= s->channels - 1; } break; @@ -218,12 +218,12 @@ static int dpcm_decode_frame(AVCodecContext *avctx, } while (in < buf_size) { - predictor[channel_number] += interplay_delta_table[buf[in++]]; - predictor[channel_number] = av_clip_int16(predictor[channel_number]); - output_samples[out++] = predictor[channel_number]; + predictor[ch] += interplay_delta_table[buf[in++]]; + predictor[ch] = av_clip_int16(predictor[ch]); + output_samples[out++] = predictor[ch]; /* toggle channel */ - channel_number ^= s->channels - 1; + ch ^= s->channels - 1; } break; @@ -244,21 +244,21 @@ static int dpcm_decode_frame(AVCodecContext *avctx, byte = buf[in++]; diff = (byte & 0xFC) << 8; if ((byte & 0x03) == 3) - shift[channel_number]++; + shift[ch]++; else - shift[channel_number] -= (2 * (byte & 3)); + shift[ch] -= (2 * (byte & 3)); /* saturate the shifter to a lower limit of 0 */ - if (shift[channel_number] < 0) - shift[channel_number] = 0; + if (shift[ch] < 0) + shift[ch] = 0; - diff >>= shift[channel_number]; - predictor[channel_number] += diff; + diff >>= shift[ch]; + predictor[ch] += diff; - predictor[channel_number] = av_clip_int16(predictor[channel_number]); - output_samples[out++] = predictor[channel_number]; + predictor[ch] = av_clip_int16(predictor[ch]); + output_samples[out++] = predictor[ch]; /* toggle channel */ - channel_number ^= s->channels - 1; + ch ^= s->channels - 1; } break; case CODEC_ID_SOL_DPCM: @@ -283,12 +283,12 @@ static int dpcm_decode_frame(AVCodecContext *avctx, while (in < buf_size) { int n; n = buf[in++]; - if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F]; - else s->sample[channel_number] += s->sol_table[n & 0x7F]; - s->sample[channel_number] = av_clip_int16(s->sample[channel_number]); - output_samples[out++] = s->sample[channel_number]; + if (n & 0x80) s->sample[ch] -= s->sol_table[n & 0x7F]; + else s->sample[ch] += s->sol_table[n & 0x7F]; + s->sample[ch] = av_clip_int16(s->sample[ch]); + output_samples[out++] = s->sample[ch]; /* toggle channel */ - channel_number ^= s->channels - 1; + ch ^= s->channels - 1; } } break; From 3db8db406ff213bf177cc23c44f6cbc8778b1bea Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 11:19:00 -0400 Subject: [PATCH 23/34] dpcm: factor out the stereo flag calculation --- libavcodec/dpcm.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 1c80522a00..185d04e0b2 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -169,6 +169,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, int in, out = 0; int predictor[2]; int ch = 0; + int stereo = s->channels - 1; short *output_samples = data; int shift[2]; unsigned char byte; @@ -184,11 +185,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx, switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: - if (s->channels == 1) - predictor[0] = AV_RL16(&buf[6]); - else { + if (stereo) { predictor[0] = buf[7] << 8; predictor[1] = buf[6] << 8; + } else { + predictor[0] = AV_RL16(&buf[6]); } SE_16BIT(predictor[0]); SE_16BIT(predictor[1]); @@ -200,7 +201,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, output_samples[out] = predictor[ch]; /* toggle channel */ - ch ^= s->channels - 1; + ch ^= stereo; } break; @@ -210,7 +211,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, in += 2; SE_16BIT(predictor[0]) output_samples[out++] = predictor[0]; - if (s->channels == 2) { + if (stereo) { predictor[1] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[1]) @@ -223,7 +224,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, output_samples[out++] = predictor[ch]; /* toggle channel */ - ch ^= s->channels - 1; + ch ^= stereo; } break; @@ -234,7 +235,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, predictor[0] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[0]); - if (s->channels == 2) { + if (stereo) { predictor[1] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[1]); @@ -258,7 +259,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, output_samples[out++] = predictor[ch]; /* toggle channel */ - ch ^= s->channels - 1; + ch ^= stereo; } break; case CODEC_ID_SOL_DPCM: @@ -271,13 +272,13 @@ static int dpcm_decode_frame(AVCodecContext *avctx, n1 = (buf[in] >> 4) & 0xF; n2 = buf[in++] & 0xF; s->sample[0] += s->sol_table[n1]; - if (s->sample[0] < 0) s->sample[0] = 0; + if (s->sample[0] < 0) s->sample[0] = 0; if (s->sample[0] > 255) s->sample[0] = 255; output_samples[out++] = (s->sample[0] - 128) << 8; - s->sample[s->channels - 1] += s->sol_table[n2]; - if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0; - if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255; - output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8; + s->sample[stereo] += s->sol_table[n2]; + if (s->sample[stereo] < 0) s->sample[stereo] = 0; + if (s->sample[stereo] > 255) s->sample[stereo] = 255; + output_samples[out++] = (s->sample[stereo] - 128) << 8; } } else { while (in < buf_size) { @@ -288,7 +289,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, s->sample[ch] = av_clip_int16(s->sample[ch]); output_samples[out++] = s->sample[ch]; /* toggle channel */ - ch ^= s->channels - 1; + ch ^= stereo; } } break; From 76db17dc7d4f19f9a03bdd6de79c2ea37b76888f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 11:51:08 -0400 Subject: [PATCH 24/34] dpcm: calculate and check actual output data size prior to decoding. --- libavcodec/dpcm.c | 50 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 185d04e0b2..3f3b422d96 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -178,9 +178,30 @@ static int dpcm_decode_frame(AVCodecContext *avctx, if (!buf_size) return 0; - // almost every DPCM variant expands one byte of data into two - if(*data_size/2 < buf_size) - return -1; + /* calculate output size */ + switch(avctx->codec->id) { + case CODEC_ID_ROQ_DPCM: + out = buf_size - 8; + break; + case CODEC_ID_INTERPLAY_DPCM: + out = buf_size - 6 - s->channels; + break; + case CODEC_ID_XAN_DPCM: + out = buf_size - 2 * s->channels; + break; + case CODEC_ID_SOL_DPCM: + if (avctx->codec_tag != 3) + out = buf_size * 2; + else + out = buf_size; + break; + } + out *= av_get_bytes_per_sample(avctx->sample_fmt); + + if (*data_size < out) { + av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n"); + return AVERROR(EINVAL); + } switch(avctx->codec->id) { @@ -195,10 +216,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, SE_16BIT(predictor[1]); /* decode the samples */ - for (in = 8, out = 0; in < buf_size; in++, out++) { + for (in = 8; in < buf_size; in++) { predictor[ch] += s->roq_square_array[buf[in]]; predictor[ch] = av_clip_int16(predictor[ch]); - output_samples[out] = predictor[ch]; + *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; @@ -210,23 +231,22 @@ static int dpcm_decode_frame(AVCodecContext *avctx, predictor[0] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[0]) - output_samples[out++] = predictor[0]; + *output_samples++ = predictor[0]; if (stereo) { predictor[1] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[1]) - output_samples[out++] = predictor[1]; + *output_samples++ = predictor[1]; } while (in < buf_size) { predictor[ch] += interplay_delta_table[buf[in++]]; predictor[ch] = av_clip_int16(predictor[ch]); - output_samples[out++] = predictor[ch]; + *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; } - break; case CODEC_ID_XAN_DPCM: @@ -256,7 +276,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, predictor[ch] += diff; predictor[ch] = av_clip_int16(predictor[ch]); - output_samples[out++] = predictor[ch]; + *output_samples++ = predictor[ch]; /* toggle channel */ ch ^= stereo; @@ -265,8 +285,6 @@ static int dpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_SOL_DPCM: in = 0; if (avctx->codec_tag != 3) { - if(*data_size/4 < buf_size) - return -1; while (in < buf_size) { int n1, n2; n1 = (buf[in] >> 4) & 0xF; @@ -274,11 +292,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx, s->sample[0] += s->sol_table[n1]; if (s->sample[0] < 0) s->sample[0] = 0; if (s->sample[0] > 255) s->sample[0] = 255; - output_samples[out++] = (s->sample[0] - 128) << 8; + *output_samples++ = (s->sample[0] - 128) << 8; s->sample[stereo] += s->sol_table[n2]; if (s->sample[stereo] < 0) s->sample[stereo] = 0; if (s->sample[stereo] > 255) s->sample[stereo] = 255; - output_samples[out++] = (s->sample[stereo] - 128) << 8; + *output_samples++ = (s->sample[stereo] - 128) << 8; } } else { while (in < buf_size) { @@ -287,7 +305,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, if (n & 0x80) s->sample[ch] -= s->sol_table[n & 0x7F]; else s->sample[ch] += s->sol_table[n & 0x7F]; s->sample[ch] = av_clip_int16(s->sample[ch]); - output_samples[out++] = s->sample[ch]; + *output_samples++ = s->sample[ch]; /* toggle channel */ ch ^= stereo; } @@ -295,7 +313,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, break; } - *data_size = out * sizeof(short); + *data_size = out; return buf_size; } From 04b24cf94b3582f94a94e28506368d3ee54daad7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:04:46 -0400 Subject: [PATCH 25/34] dpcm: output AV_SAMPLE_FMT_U8 for Sol DPCM subcodecs 1 and 2. Uses the native sample format for the codec instead of left-shifting all samples by 8. --- libavcodec/dpcm.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 3f3b422d96..ef90ab30e1 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -43,7 +43,7 @@ typedef struct DPCMContext { int channels; short roq_square_array[256]; - long sample[2];//for SOL_DPCM + int sample[2]; ///< previous sample (for SOL_DPCM) const int *sol_table;//for SOL_DPCM } DPCMContext; @@ -155,7 +155,11 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) break; } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + if (avctx->codec->id == CODEC_ID_SOL_DPCM && avctx->codec_tag != 3) + avctx->sample_fmt = AV_SAMPLE_FMT_U8; + else + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + return 0; } @@ -285,18 +289,17 @@ static int dpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_SOL_DPCM: in = 0; if (avctx->codec_tag != 3) { + uint8_t *output_samples_u8 = data; while (in < buf_size) { - int n1, n2; - n1 = (buf[in] >> 4) & 0xF; - n2 = buf[in++] & 0xF; - s->sample[0] += s->sol_table[n1]; - if (s->sample[0] < 0) s->sample[0] = 0; - if (s->sample[0] > 255) s->sample[0] = 255; - *output_samples++ = (s->sample[0] - 128) << 8; - s->sample[stereo] += s->sol_table[n2]; - if (s->sample[stereo] < 0) s->sample[stereo] = 0; - if (s->sample[stereo] > 255) s->sample[stereo] = 255; - *output_samples++ = (s->sample[stereo] - 128) << 8; + uint8_t n = buf[in++]; + + s->sample[0] += s->sol_table[n >> 4]; + s->sample[0] = av_clip_uint8(s->sample[0]); + *output_samples_u8++ = s->sample[0]; + + s->sample[stereo] += s->sol_table[n & 0x0F]; + s->sample[stereo] = av_clip_uint8(s->sample[stereo]); + *output_samples_u8++ = s->sample[stereo]; } } else { while (in < buf_size) { From 989bb7bd0477ef467f374dd8464a88d039f86ebe Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:08:38 -0400 Subject: [PATCH 26/34] dpcm: consistently use the variable name 'n' for the next input byte. --- libavcodec/dpcm.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index ef90ab30e1..a024671fa2 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -176,7 +176,6 @@ static int dpcm_decode_frame(AVCodecContext *avctx, int stereo = s->channels - 1; short *output_samples = data; int shift[2]; - unsigned char byte; short diff; if (!buf_size) @@ -266,12 +265,12 @@ static int dpcm_decode_frame(AVCodecContext *avctx, } while (in < buf_size) { - byte = buf[in++]; - diff = (byte & 0xFC) << 8; - if ((byte & 0x03) == 3) + uint8_t n = buf[in++]; + diff = (n & 0xFC) << 8; + if ((n & 0x03) == 3) shift[ch]++; else - shift[ch] -= (2 * (byte & 3)); + shift[ch] -= (2 * (n & 3)); /* saturate the shifter to a lower limit of 0 */ if (shift[ch] < 0) shift[ch] = 0; @@ -303,8 +302,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, } } else { while (in < buf_size) { - int n; - n = buf[in++]; + uint8_t n = buf[in++]; if (n & 0x80) s->sample[ch] -= s->sol_table[n & 0x7F]; else s->sample[ch] += s->sol_table[n & 0x7F]; s->sample[ch] = av_clip_int16(s->sample[ch]); From fc6faee0d1d8bfea642be462c7fd6dcc964f6110 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:13:13 -0400 Subject: [PATCH 27/34] dpcm: move codec-specific variable declarations to their corresponding decoding blocks. --- libavcodec/dpcm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index a024671fa2..02267d7641 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -175,8 +175,6 @@ static int dpcm_decode_frame(AVCodecContext *avctx, int ch = 0; int stereo = s->channels - 1; short *output_samples = data; - int shift[2]; - short diff; if (!buf_size) return 0; @@ -253,8 +251,9 @@ static int dpcm_decode_frame(AVCodecContext *avctx, break; case CODEC_ID_XAN_DPCM: + { + int shift[2] = { 4, 4 }; in = 0; - shift[0] = shift[1] = 4; predictor[0] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[0]); @@ -266,7 +265,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, while (in < buf_size) { uint8_t n = buf[in++]; - diff = (n & 0xFC) << 8; + int16_t diff = (n & 0xFC) << 8; if ((n & 0x03) == 3) shift[ch]++; else @@ -285,6 +284,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, ch ^= stereo; } break; + } case CODEC_ID_SOL_DPCM: in = 0; if (avctx->codec_tag != 3) { From 1de8401c569b55abc86b2a06f35c5b3fc72c98ed Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:24:03 -0400 Subject: [PATCH 28/34] dpcm: remove unnecessary variable by using bytestream functions. Uses 'buf' directly instead of a separate iterator variable 'in'. --- libavcodec/dpcm.c | 66 ++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 02267d7641..57201fd1c0 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -39,6 +39,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bytestream.h" typedef struct DPCMContext { int channels; @@ -47,8 +48,6 @@ typedef struct DPCMContext { const int *sol_table;//for SOL_DPCM } DPCMContext; -#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; - static const int interplay_delta_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -169,8 +168,9 @@ static int dpcm_decode_frame(AVCodecContext *avctx, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + const uint8_t *buf_end = buf + buf_size; DPCMContext *s = avctx->priv_data; - int in, out = 0; + int out = 0; int predictor[2]; int ch = 0; int stereo = s->channels - 1; @@ -207,18 +207,18 @@ static int dpcm_decode_frame(AVCodecContext *avctx, switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: + buf += 6; + if (stereo) { - predictor[0] = buf[7] << 8; - predictor[1] = buf[6] << 8; + predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8); + predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8); } else { - predictor[0] = AV_RL16(&buf[6]); + predictor[0] = (int16_t)bytestream_get_le16(&buf); } - SE_16BIT(predictor[0]); - SE_16BIT(predictor[1]); /* decode the samples */ - for (in = 8; in < buf_size; in++) { - predictor[ch] += s->roq_square_array[buf[in]]; + while (buf < buf_end) { + predictor[ch] += s->roq_square_array[*buf++]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; @@ -228,20 +228,16 @@ static int dpcm_decode_frame(AVCodecContext *avctx, break; case CODEC_ID_INTERPLAY_DPCM: - in = 6; /* skip over the stream mask and stream length */ - predictor[0] = AV_RL16(&buf[in]); - in += 2; - SE_16BIT(predictor[0]) - *output_samples++ = predictor[0]; - if (stereo) { - predictor[1] = AV_RL16(&buf[in]); - in += 2; - SE_16BIT(predictor[1]) - *output_samples++ = predictor[1]; + buf += 6; /* skip over the stream mask and stream length */ + + for (ch = 0; ch < s->channels; ch++) { + predictor[ch] = (int16_t)bytestream_get_le16(&buf); + *output_samples++ = predictor[ch]; } - while (in < buf_size) { - predictor[ch] += interplay_delta_table[buf[in++]]; + ch = 0; + while (buf < buf_end) { + predictor[ch] += interplay_delta_table[*buf++]; predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; @@ -253,18 +249,13 @@ static int dpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_XAN_DPCM: { int shift[2] = { 4, 4 }; - in = 0; - predictor[0] = AV_RL16(&buf[in]); - in += 2; - SE_16BIT(predictor[0]); - if (stereo) { - predictor[1] = AV_RL16(&buf[in]); - in += 2; - SE_16BIT(predictor[1]); - } - while (in < buf_size) { - uint8_t n = buf[in++]; + for (ch = 0; ch < s->channels; ch++) + predictor[ch] = (int16_t)bytestream_get_le16(&buf); + + ch = 0; + while (buf < buf_end) { + uint8_t n = *buf++; int16_t diff = (n & 0xFC) << 8; if ((n & 0x03) == 3) shift[ch]++; @@ -286,11 +277,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, break; } case CODEC_ID_SOL_DPCM: - in = 0; if (avctx->codec_tag != 3) { uint8_t *output_samples_u8 = data; - while (in < buf_size) { - uint8_t n = buf[in++]; + while (buf < buf_end) { + uint8_t n = *buf++; s->sample[0] += s->sol_table[n >> 4]; s->sample[0] = av_clip_uint8(s->sample[0]); @@ -301,8 +291,8 @@ static int dpcm_decode_frame(AVCodecContext *avctx, *output_samples_u8++ = s->sample[stereo]; } } else { - while (in < buf_size) { - uint8_t n = buf[in++]; + while (buf < buf_end) { + uint8_t n = *buf++; if (n & 0x80) s->sample[ch] -= s->sol_table[n & 0x7F]; else s->sample[ch] += s->sol_table[n & 0x7F]; s->sample[ch] = av_clip_int16(s->sample[ch]); From 4bad464e7f5731e2f554ea673f54e8d770bc109e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:37:17 -0400 Subject: [PATCH 29/34] dpcm: misc pretty-printing --- libavcodec/dpcm.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 57201fd1c0..cb128affed 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -84,13 +84,15 @@ static const int interplay_delta_table[] = { }; -static const int sol_table_old[16] = - { 0x0, 0x1, 0x2 , 0x3, 0x6, 0xA, 0xF, 0x15, - -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0}; +static const int sol_table_old[16] = { + 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15, + -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0 +}; -static const int sol_table_new[16] = - { 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15, - 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15}; +static const int sol_table_new[16] = { + 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15, + 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15 +}; static const int sol_table_16[128] = { 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, @@ -109,7 +111,6 @@ static const int sol_table_16[128] = { }; - static av_cold int dpcm_decode_init(AVCodecContext *avctx) { DPCMContext *s = avctx->priv_data; @@ -125,24 +126,23 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) /* initialize square table */ for (i = 0; i < 128; i++) { square = i * i; - s->roq_square_array[i] = square; + s->roq_square_array[i ] = square; s->roq_square_array[i + 128] = -square; } break; - case CODEC_ID_SOL_DPCM: switch(avctx->codec_tag){ case 1: - s->sol_table=sol_table_old; + s->sol_table = sol_table_old; s->sample[0] = s->sample[1] = 0x80; break; case 2: - s->sol_table=sol_table_new; + s->sol_table = sol_table_new; s->sample[0] = s->sample[1] = 0x80; break; case 3: - s->sol_table=sol_table_16; + s->sol_table = sol_table_16; break; default: av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n"); @@ -162,8 +162,8 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) return 0; } -static int dpcm_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, + +static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; @@ -219,7 +219,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, /* decode the samples */ while (buf < buf_end) { predictor[ch] += s->roq_square_array[*buf++]; - predictor[ch] = av_clip_int16(predictor[ch]); + predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ @@ -238,7 +238,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, ch = 0; while (buf < buf_end) { predictor[ch] += interplay_delta_table[*buf++]; - predictor[ch] = av_clip_int16(predictor[ch]); + predictor[ch] = av_clip_int16(predictor[ch]); *output_samples++ = predictor[ch]; /* toggle channel */ @@ -294,7 +294,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, while (buf < buf_end) { uint8_t n = *buf++; if (n & 0x80) s->sample[ch] -= s->sol_table[n & 0x7F]; - else s->sample[ch] += s->sol_table[n & 0x7F]; + else s->sample[ch] += s->sol_table[n & 0x7F]; s->sample[ch] = av_clip_int16(s->sample[ch]); *output_samples++ = s->sample[ch]; /* toggle channel */ @@ -320,6 +320,6 @@ AVCodec ff_ ## name_ ## _decoder = { \ } DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay"); -DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ"); -DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol"); -DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan"); +DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ"); +DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol"); +DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan"); From 8d77d12a2be10e8564599ccbfcdd804ff432d885 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:40:40 -0400 Subject: [PATCH 30/34] dpcm: check to make sure channels is 1 or 2. --- libavcodec/dpcm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index cb128affed..fc38abdb7a 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -117,6 +117,11 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) int i; short square; + if (avctx->channels < 1 || avctx->channels > 2) { + av_log(avctx, AV_LOG_INFO, "invalid number of channels\n"); + return AVERROR(EINVAL); + } + s->channels = avctx->channels; s->sample[0] = s->sample[1] = 0; From f47f7efd14fa57e298886a20920b7679c975afc1 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:41:48 -0400 Subject: [PATCH 31/34] dpcm: replace short with int16_t --- libavcodec/dpcm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index fc38abdb7a..3ddc676a72 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -43,7 +43,7 @@ typedef struct DPCMContext { int channels; - short roq_square_array[256]; + int16_t roq_square_array[256]; int sample[2]; ///< previous sample (for SOL_DPCM) const int *sol_table;//for SOL_DPCM } DPCMContext; @@ -115,7 +115,6 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) { DPCMContext *s = avctx->priv_data; int i; - short square; if (avctx->channels < 1 || avctx->channels > 2) { av_log(avctx, AV_LOG_INFO, "invalid number of channels\n"); @@ -130,7 +129,7 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) case CODEC_ID_ROQ_DPCM: /* initialize square table */ for (i = 0; i < 128; i++) { - square = i * i; + int16_t square = i * i; s->roq_square_array[i ] = square; s->roq_square_array[i + 128] = -square; } @@ -179,7 +178,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, int predictor[2]; int ch = 0; int stereo = s->channels - 1; - short *output_samples = data; + int16_t *output_samples = data; if (!buf_size) return 0; From 5a54d5101780421cdcb71c018eea157e3d4d3c8f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:43:03 -0400 Subject: [PATCH 32/34] dpcm: use sol_table_16 directly instead of through the DPCMContext. --- libavcodec/dpcm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 3ddc676a72..2491292984 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -146,7 +146,6 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) s->sample[0] = s->sample[1] = 0x80; break; case 3: - s->sol_table = sol_table_16; break; default: av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n"); @@ -297,8 +296,8 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } else { while (buf < buf_end) { uint8_t n = *buf++; - if (n & 0x80) s->sample[ch] -= s->sol_table[n & 0x7F]; - else s->sample[ch] += s->sol_table[n & 0x7F]; + if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F]; + else s->sample[ch] += sol_table_16[n & 0x7F]; s->sample[ch] = av_clip_int16(s->sample[ch]); *output_samples++ = s->sample[ch]; /* toggle channel */ From 0354fb7ebe177773e44b889ba7672e4336ee377f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 12:46:06 -0400 Subject: [PATCH 33/34] dpcm: use smaller data types for static tables --- libavcodec/dpcm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 2491292984..d4cf806b82 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -45,10 +45,10 @@ typedef struct DPCMContext { int channels; int16_t roq_square_array[256]; int sample[2]; ///< previous sample (for SOL_DPCM) - const int *sol_table;//for SOL_DPCM + const int8_t *sol_table; ///< delta table for SOL_DPCM } DPCMContext; -static const int interplay_delta_table[] = { +static const int16_t interplay_delta_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -84,17 +84,17 @@ static const int interplay_delta_table[] = { }; -static const int sol_table_old[16] = { +static const int8_t sol_table_old[16] = { 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15, -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0 }; -static const int sol_table_new[16] = { +static const int8_t sol_table_new[16] = { 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15, 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15 }; -static const int sol_table_16[128] = { +static const int16_t sol_table_16[128] = { 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, From 08bd22a61b820160bff5f98cd51d2e0135d02e00 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 11 Sep 2011 13:18:51 -0400 Subject: [PATCH 34/34] dpcm: return error if packet is too small --- libavcodec/dpcm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index d4cf806b82..6ba8ab13ce 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -201,7 +201,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, break; } out *= av_get_bytes_per_sample(avctx->sample_fmt); - + if (out < 0) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } if (*data_size < out) { av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n"); return AVERROR(EINVAL);