From d341d5fd2cd7e301a20dcb50f3e1445571765023 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 8 Oct 2011 01:37:20 +0100 Subject: [PATCH 01/14] dnxhdenc: fixed signed multiplication overflow The low 32 bits of a multiplication are the same for signed and unsigned operands. Casting to unsigned before multiplying is thus equivalent while avoiding signed overflow, which is undefined by the C99 standard. Signed-off-by: Mans Rullgard --- libavcodec/dnxhdenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index db460856d6..89e5c085ab 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -623,7 +623,7 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int jobnr, int for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x, pix += 16) { unsigned mb = mb_y * ctx->m.mb_width + mb_x; int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize); - int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8; + int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)sum*sum)>>8)+128)>>8; ctx->mb_cmp[mb].value = varc; ctx->mb_cmp[mb].mb = mb; } From f7f7c1942b8f0b4dd10eecacd52678c028d28272 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 2 Oct 2011 14:41:34 -0400 Subject: [PATCH 02/14] adpcmdec: remove unneeded zeroing of *data_size --- libavcodec/adpcm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 98da4591b0..eb244bd05d 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -358,7 +358,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, samples = data; samples_end= samples + *data_size/2; - *data_size= 0; src = buf; st = avctx->channels == 2 ? 1 : 0; From 8140a1288ff2498adcbb67db73ef9862b518bb88 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 2 Oct 2011 14:43:28 -0400 Subject: [PATCH 03/14] adpcmdec: remove unneeded buf_size==0 check. This is already done by avcodec_decode_audio3() --- libavcodec/adpcm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index eb244bd05d..8ab3bd8954 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -347,9 +347,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, uint32_t samples_in_chunk; int count1, count2; - if (!buf_size) - return 0; - //should protect all 4bit ADPCM variants //8 is needed for CODEC_ID_ADPCM_IMA_WAV with 2 channels // From ff5790c76102ef2574e94c77edf2d7e81eb40752 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 2 Oct 2011 15:58:54 -0400 Subject: [PATCH 04/14] adpcmdec: do not terminate early in ADPCM IMA Duck DK3 decoder. There are still 2 nibbles to decode once the last byte in the packet has been read. Updated FATE reference. --- libavcodec/adpcm.c | 6 +- tests/ref/fate/duck-dk3 | 2 +- tests/ref/fate/truemotion1-15 | 226 +++++++++++++++++----------------- tests/ref/fate/truemotion1-24 | 56 ++++----- 4 files changed, 147 insertions(+), 143 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 8ab3bd8954..200957b26c 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -325,8 +325,11 @@ static void xa_decode(short *out, const unsigned char *in, } \ else \ { \ + if (end_of_packet) \ + break; \ last_byte = *src++; \ - if (src >= buf + buf_size) break; \ + if (src >= buf + buf_size) \ + end_of_packet = 1; \ nibble = last_byte & 0x0F; \ decode_top_nibble_next = 1; \ } @@ -534,6 +537,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, unsigned char last_byte = 0; unsigned char nibble; int decode_top_nibble_next = 0; + int end_of_packet = 0; int diff_channel; if (avctx->block_align != 0 && buf_size > avctx->block_align) diff --git a/tests/ref/fate/duck-dk3 b/tests/ref/fate/duck-dk3 index 08c0fd1909..9aad92beed 100644 --- a/tests/ref/fate/duck-dk3 +++ b/tests/ref/fate/duck-dk3 @@ -1 +1 @@ -62fbe4db4a49cb044f57f92cce9993c5 +bb952ae86c72d461aef7583685ec0a4d diff --git a/tests/ref/fate/truemotion1-15 b/tests/ref/fate/truemotion1-15 index d103f01970..d9925c73c6 100644 --- a/tests/ref/fate/truemotion1-15 +++ b/tests/ref/fate/truemotion1-15 @@ -1,218 +1,218 @@ 0, 0, 161280, 0x7041748d -1, 0, 10832, 0xe1a811fa -1, 5527, 10832, 0xb47841f9 +1, 0, 10836, 0x2a531236 +1, 5529, 10836, 0xc58f45af 0, 6000, 161280, 0x3cc4dfb5 -1, 11053, 10832, 0x839eedf1 +1, 11057, 10836, 0x436cf135 0, 12000, 161280, 0xca3af22d -1, 16580, 10832, 0xb48b1f60 +1, 16586, 10836, 0x3a6022cc 0, 18000, 161280, 0x23ad1d85 -1, 22106, 10832, 0x743936c0 +1, 22114, 10836, 0x57e83a4a 0, 24000, 161280, 0x9c9cf364 -1, 27633, 10832, 0xe1f039fb +1, 27643, 10836, 0xca4b3a1b 0, 30000, 161280, 0x1551d6a8 -1, 33159, 10832, 0xef00751a +1, 33171, 10836, 0xc3da7536 0, 36000, 161280, 0xc39f6b95 -1, 38686, 10832, 0x401ed099 +1, 38700, 10836, 0x8c57d47b 0, 42000, 161280, 0x3b036dcc -1, 44212, 10832, 0x432a53bd +1, 44229, 10836, 0x9a79572b 0, 48000, 161280, 0xa6fac1db -1, 49739, 10832, 0xc4276bfd +1, 49757, 10836, 0x7dbd6fd3 0, 54000, 161280, 0x67656b62 -1, 55265, 10832, 0x51f0fa8c +1, 55286, 10836, 0x4454fdde 0, 60000, 161280, 0xb41f47d1 -1, 60792, 10832, 0xcebae622 +1, 60814, 10836, 0x68aae686 0, 66000, 161280, 0xc207249e -1, 66318, 10832, 0xe9f6dc1f -1, 71845, 10832, 0xda087fee +1, 66343, 10836, 0x61f2df35 +1, 71871, 10836, 0xe36883c6 0, 72000, 161280, 0xbee8f843 -1, 77371, 10832, 0x67a621bb +1, 77400, 10836, 0xefa62217 0, 78000, 161280, 0x092acf46 -1, 82898, 10832, 0xd7be207f +1, 82929, 10836, 0x63b92479 0, 84000, 161280, 0x8d9e2680 -1, 88424, 10832, 0x19d32507 +1, 88457, 10836, 0xaf452579 0, 90000, 161280, 0x8becc20c -1, 93951, 10832, 0xe1a3fbfa +1, 93986, 10836, 0xdbb10001 0, 96000, 161280, 0x655e444e -1, 99478, 10832, 0xd10df779 +1, 99514, 10836, 0xafb7f7a7 0, 102000, 161280, 0x5c112da0 -1, 105004, 10832, 0x4428e1a7 +1, 105043, 10836, 0xd4b1e591 0, 108000, 161280, 0x232fa9eb -1, 110531, 10832, 0x7ea9b33d +1, 110571, 10836, 0x4d44b3bb 0, 114000, 161280, 0x9721745d -1, 116057, 10832, 0x6852a5a5 +1, 116100, 10836, 0xff2ea5b3 0, 120000, 161280, 0x92f1d880 -1, 121584, 10832, 0xfeb78863 +1, 121629, 10836, 0x214e88ad 0, 126000, 161280, 0x16233978 -1, 127110, 10832, 0xf157f928 +1, 127157, 10836, 0xde8bfc9a 0, 132000, 161280, 0x19a27e69 -1, 132637, 10832, 0x86414b3e +1, 132686, 10836, 0xb3cc4b6a 0, 138000, 161280, 0x7b6ad73a -1, 138163, 10832, 0x2e28cdf6 -1, 143690, 10832, 0x00212e44 +1, 138214, 10836, 0x670bce40 +1, 143743, 10836, 0xc17d31b2 0, 144000, 161280, 0xa7a674aa -1, 149216, 10832, 0x2d7f9378 +1, 149271, 10836, 0x7bcb9392 0, 150000, 161280, 0x4e434abb -1, 154743, 10832, 0x84cb25d7 +1, 154800, 10836, 0x230e28c9 0, 156000, 161280, 0xb96eea14 -1, 160269, 10832, 0x3aca41fa +1, 160329, 10836, 0x42df4204 0, 162000, 161280, 0x1350188c -1, 165796, 10832, 0x27ad34b9 +1, 165857, 10836, 0xfa9134b9 0, 168000, 161280, 0x79c6f305 -1, 171322, 10832, 0xe665144a +1, 171386, 10836, 0x418c1844 0, 174000, 161280, 0xa9c7782d -1, 176849, 10832, 0xf9546626 +1, 176914, 10836, 0x93ba66b6 0, 180000, 161280, 0x40a4f456 -1, 182376, 10832, 0xe71c4f22 +1, 182443, 10836, 0x264a4ffa 0, 186000, 161280, 0xaf291ed6 -1, 187902, 10832, 0x5e61869c +1, 187971, 10836, 0x82c78a8e 0, 192000, 161280, 0xab29b4e1 -1, 193429, 10832, 0x571d2c10 +1, 193500, 10836, 0x10d22fdc 0, 198000, 161280, 0xbfcd2712 -1, 198955, 10832, 0xf0e08cd5 +1, 199029, 10836, 0x2d25906b 0, 204000, 161280, 0xff22a0d7 -1, 204482, 10832, 0x66650e49 +1, 204557, 10836, 0xa8a111fb 0, 210000, 161280, 0xb0ae88a9 -1, 210008, 10832, 0x4024deaf -1, 215535, 10832, 0xda7bdb14 +1, 210086, 10836, 0xbd95df87 +1, 215614, 10836, 0x500ddec0 0, 216000, 161280, 0x811d1259 -1, 221061, 10832, 0xc27a342f +1, 221143, 10836, 0x95d9350b 0, 222000, 161280, 0x593c39a1 -1, 226588, 10832, 0x574fe679 +1, 226671, 10836, 0xfa54ea1f 0, 228000, 161280, 0x5a5a97f8 -1, 232114, 10832, 0x37db464e +1, 232200, 10836, 0x51b2467e 0, 234000, 161280, 0xa5639ecf -1, 237641, 10832, 0xb1fa2a83 +1, 237729, 10836, 0x5d772af9 0, 240000, 161280, 0x543920c6 -1, 243167, 10832, 0x3d98d9b7 +1, 243257, 10836, 0xae25dd8d 0, 246000, 161280, 0xb41689ee -1, 248694, 10832, 0xb7c908e2 +1, 248786, 10836, 0xe4bd0cb0 0, 252000, 161280, 0xc0ad83de -1, 254220, 10832, 0x9f7e44d8 +1, 254314, 10836, 0xb33544f0 0, 258000, 161280, 0x9e9e7456 -1, 259747, 10832, 0xae9b8774 +1, 259843, 10836, 0xd5658b12 0, 264000, 161280, 0x777ccbfe -1, 265273, 10832, 0x36916e3f +1, 265371, 10836, 0xeff66e5d 0, 270000, 161280, 0x9c2df916 -1, 270800, 10832, 0xd785f5ef +1, 270900, 10836, 0xb1fff6c5 0, 276000, 161280, 0xe0c13b35 -1, 276327, 10832, 0x2a3a5673 -1, 281853, 10832, 0x7320e379 +1, 276429, 10836, 0x84db56b5 +1, 281957, 10836, 0x0230e3c9 0, 282000, 161280, 0x39bfa5a5 -1, 287380, 10832, 0xec787be5 +1, 287486, 10836, 0xe58a7faf 0, 288000, 161280, 0x35dfb264 -1, 292906, 10832, 0xd0d13aa0 +1, 293014, 10836, 0xc4003e2a 0, 294000, 161280, 0x43018613 -1, 298433, 10832, 0x34dfcb17 +1, 298543, 10836, 0x6360cbbf 0, 300000, 161280, 0x43584b8a -1, 303959, 10832, 0x1a9c29f1 +1, 304071, 10836, 0xc29c2a05 0, 306000, 161280, 0xa5cd230a -1, 309486, 10832, 0x3e73dcc1 +1, 309600, 10836, 0xb294dd11 0, 312000, 161280, 0x6fe2cfb3 -1, 315012, 10832, 0x7855b053 +1, 315129, 10836, 0x4388b43b 0, 318000, 161280, 0x88a7c0db -1, 320539, 10832, 0x5588df8f +1, 320657, 10836, 0xdd7be367 0, 324000, 161280, 0x476f1cd2 -1, 326065, 10832, 0x6f621299 +1, 326186, 10836, 0xb9f612a9 0, 330000, 161280, 0x96401d49 -1, 331592, 10832, 0xce7f39c2 +1, 331714, 10836, 0xb64a39fe 0, 336000, 161280, 0x7d932919 -1, 337118, 10832, 0xd88e6552 +1, 337243, 10836, 0x6eba6594 0, 342000, 161280, 0x06465481 -1, 342645, 10832, 0xddc63597 +1, 342771, 10836, 0xb4af35c1 0, 348000, 161280, 0x39631520 -1, 348171, 10832, 0xe3071865 -1, 353698, 10832, 0x2a44a123 +1, 348300, 10836, 0x4e581c49 +1, 353829, 10836, 0xb062a19f 0, 354000, 161280, 0xc3fff780 -1, 359224, 10832, 0x08d85d45 +1, 359357, 10836, 0x87cd6135 0, 360000, 161280, 0xa81faf28 -1, 364751, 10832, 0x4dc5f83a +1, 364886, 10836, 0x37bffbd6 0, 366000, 161280, 0x7a311f4f -1, 370278, 10832, 0x89497812 +1, 370414, 10836, 0x6c797900 0, 372000, 161280, 0x52f9b931 -1, 375804, 10832, 0x9ee1db54 +1, 375943, 10836, 0x1615df36 0, 378000, 161280, 0x938cf016 -1, 381331, 10832, 0x5277d611 +1, 381471, 10836, 0xb472d9e9 0, 384000, 161280, 0xf8f6e19c -1, 386857, 10832, 0x570a619c +1, 387000, 10836, 0xdfff626e 0, 390000, 161280, 0xca90561b -1, 392384, 10832, 0xa217d70f +1, 392529, 10836, 0xffa6d771 0, 396000, 161280, 0x8594d06b -1, 397910, 10832, 0x6f0ecbf4 +1, 398057, 10836, 0xa7f3cf96 0, 402000, 161280, 0xea32bf3b -1, 403437, 10832, 0x2704b114 +1, 403586, 10836, 0xf556b50a 0, 408000, 161280, 0x4646111a -1, 408963, 10832, 0xf24e679f +1, 409114, 10836, 0x99b86b39 0, 414000, 161280, 0xee891162 -1, 414490, 10832, 0x05572099 +1, 414643, 10836, 0x886920d3 0, 420000, 161280, 0xcfc32082 -1, 420016, 10832, 0x33942d0c -1, 425543, 10832, 0xa77ea674 +1, 420171, 10836, 0xefb0305a +1, 425700, 10836, 0x4ab7aa32 0, 426000, 161280, 0x863c281a -1, 431069, 10832, 0xeba663bc +1, 431229, 10836, 0x7f106530 0, 432000, 161280, 0x01b591aa -1, 436596, 10832, 0x1338524a +1, 436757, 10836, 0x6461559a 0, 438000, 161280, 0x211fbc62 -1, 442122, 10832, 0x6182b0b3 +1, 442286, 10836, 0x25e3b12b 0, 444000, 161280, 0xae2bafe2 -1, 447649, 10832, 0xa410a364 +1, 447814, 10836, 0x32cfa3ba 0, 450000, 161280, 0xcfe46dca -1, 453176, 10832, 0x2f4374b0 +1, 453343, 10836, 0x0bff78a4 0, 456000, 161280, 0xcf8fe8a3 -1, 458702, 10832, 0xf41f3a07 +1, 458871, 10836, 0xe4323d53 0, 462000, 161280, 0x3f8474eb -1, 464229, 10832, 0x2b1c50c6 +1, 464400, 10836, 0x70b35196 0, 468000, 161280, 0x06da345a -1, 469755, 10832, 0x3692ac89 +1, 469929, 10836, 0xf2b8b07f 0, 474000, 161280, 0xbd4d3280 -1, 475282, 10832, 0x5d6bc87e +1, 475457, 10836, 0x826cc972 0, 480000, 161280, 0xb5e70fea -1, 480808, 10832, 0x1b1cda0c +1, 480986, 10836, 0x8a0fdce8 0, 486000, 161280, 0x0c99c804 -1, 486335, 10832, 0x11eaa15f -1, 491861, 10832, 0x73c7d7ef +1, 486514, 10836, 0xa072a503 0, 492000, 161280, 0x19841ed4 -1, 497388, 10832, 0x65d7e3be +1, 492043, 10836, 0xd698d8e7 +1, 497571, 10836, 0xfe80e794 0, 498000, 161280, 0xf81dea50 -1, 502914, 10832, 0xb9c00688 +1, 503100, 10836, 0xdd580a5a 0, 504000, 161280, 0x7777d81c -1, 508441, 10832, 0x0b98c125 +1, 508629, 10836, 0x121bc1bb 0, 510000, 161280, 0x0497cfd8 -1, 513967, 10832, 0x331ed413 +1, 514157, 10836, 0x8cebd7d9 0, 516000, 161280, 0x50b6eb64 -1, 519494, 10832, 0x9b68f485 +1, 519686, 10836, 0x6eaef4d7 0, 522000, 161280, 0x5071fc07 -1, 525020, 10832, 0x1b865c55 +1, 525214, 10836, 0x8f0b5d0b 0, 528000, 161280, 0xbb7527fb -1, 530547, 10832, 0x68cef565 +1, 530743, 10836, 0x40ccf61f 0, 534000, 161280, 0x13054f1f -1, 536073, 10832, 0x3a605f15 +1, 536271, 10836, 0xb6db5f1d 0, 540000, 161280, 0x4b78fb27 -1, 541600, 10832, 0xd72ff22e +1, 541800, 10836, 0xa089f250 0, 546000, 161280, 0xf504968f -1, 547127, 10832, 0x1c672b67 +1, 547329, 10836, 0xd3512f2b 0, 552000, 161280, 0x555b10b7 -1, 552653, 10832, 0xfd1a7e7e +1, 552857, 10836, 0xfa127f74 0, 558000, 161280, 0xcc0dde40 -1, 558180, 10832, 0x9bf20ead -1, 563706, 10832, 0x00000000 +1, 558386, 10836, 0xd6a60ead +1, 563914, 10836, 0x00000000 0, 564000, 161280, 0xcc0dde40 -1, 569233, 10832, 0x00000000 +1, 569443, 10836, 0x00000000 0, 570000, 161280, 0x367f60c8 -1, 574759, 10832, 0x00000000 +1, 574971, 10836, 0x00000000 0, 576000, 161280, 0x367f60c8 -1, 580286, 10832, 0x00000000 +1, 580500, 10836, 0x00000000 0, 582000, 161280, 0x367f60c8 -1, 585812, 10832, 0x00000000 +1, 586029, 10836, 0x00000000 0, 588000, 161280, 0x367f60c8 -1, 591339, 10832, 0x00000000 +1, 591557, 10836, 0x00000000 0, 594000, 161280, 0x367f60c8 -1, 596865, 10832, 0x00000000 +1, 597086, 10836, 0x00000000 0, 600000, 161280, 0x367f60c8 -1, 602392, 10832, 0x00000000 +1, 602614, 10836, 0x00000000 0, 606000, 161280, 0x367f60c8 -1, 607918, 10832, 0x00000000 +1, 608143, 10836, 0x00000000 0, 612000, 161280, 0x367f60c8 -1, 613445, 10832, 0x00000000 +1, 613671, 10836, 0x00000000 0, 618000, 161280, 0x367f60c8 -1, 618971, 10832, 0x00000000 +1, 619200, 10836, 0x00000000 0, 624000, 161280, 0x367f60c8 diff --git a/tests/ref/fate/truemotion1-24 b/tests/ref/fate/truemotion1-24 index b0b1c4e44e..054f6b38e8 100644 --- a/tests/ref/fate/truemotion1-24 +++ b/tests/ref/fate/truemotion1-24 @@ -1,43 +1,43 @@ 0, 0, 69120, 0x68beb30f -1, 0, 10832, 0x1597b4c8 -1, 5527, 10832, 0xf9479f8b +1, 0, 10836, 0xedecb6a7 +1, 5529, 10836, 0x8098a323 0, 6000, 69120, 0x3976f5cf -1, 11053, 10832, 0x8db50e74 +1, 11057, 10836, 0xcfa1112e 0, 12000, 69120, 0xf815bc3c -1, 16580, 10832, 0x2b33ecbb +1, 16586, 10836, 0xe241ede4 0, 18000, 69120, 0xa7cc0ae6 -1, 22106, 10832, 0x8d0f537b +1, 22114, 10836, 0xddf254bb 0, 24000, 69120, 0xd85ac282 -1, 27633, 10832, 0x922081c7 +1, 27643, 10836, 0xa16c8507 0, 30000, 69120, 0xf7fd7edb -1, 33159, 10832, 0x40291f19 +1, 33171, 10836, 0xbe211f93 0, 36000, 69120, 0x433bb6f6 -1, 38686, 10832, 0x88f5271a +1, 38700, 10836, 0x26c7283d 0, 42000, 69120, 0xdbac8bee -1, 44212, 10832, 0x55c6bbe5 +1, 44229, 10836, 0x4d18be56 0, 48000, 69120, 0x88e2a799 -1, 49739, 10832, 0x9b51ae82 +1, 49757, 10836, 0x57b9af6f 0, 54000, 69120, 0x49617b26 -1, 55265, 10832, 0xcdf2409b +1, 55286, 10836, 0xd5864280 0, 60000, 69120, 0xeb44ca01 -1, 60792, 10832, 0x0933b1a4 +1, 60814, 10836, 0xd582b451 0, 66000, 69120, 0x6fea37e8 -1, 66318, 10832, 0x24b77006 -1, 71845, 10832, 0xf612fa8a +1, 66343, 10836, 0xec13731d +1, 71871, 10836, 0xe3d4fbb8 0, 72000, 69120, 0xf55d74c7 -1, 77371, 10832, 0x99884b06 +1, 77400, 10836, 0xcbb54d18 0, 78000, 69120, 0xb5082ca7 -1, 82898, 10832, 0x3c746fbe +1, 82929, 10836, 0xff7e7133 0, 84000, 69120, 0x5876d758 -1, 88424, 10832, 0x05f3b08a -1, 93951, 10832, 0xa6560483 -1, 99478, 10832, 0xd98a8e19 -1, 105004, 10832, 0xf98a0b2e -1, 110531, 10832, 0xb1039582 -1, 116057, 10832, 0x85dd5c3f -1, 121584, 10832, 0x19fc801a -1, 127110, 10832, 0x95805089 -1, 132637, 10832, 0x576fdec3 -1, 138163, 10832, 0x704a0905 -1, 143690, 10832, 0xf87ce1fa -1, 149216, 10832, 0xfc0076b9 +1, 88457, 10836, 0xcc28b1a7 +1, 93986, 10836, 0xbf9e07a5 +1, 99514, 10836, 0x16408f38 +1, 105043, 10836, 0x2b000c9f +1, 110571, 10836, 0x0ccd9811 +1, 116100, 10836, 0xf9575d48 +1, 121629, 10836, 0x1ee68190 +1, 127157, 10836, 0xde435373 +1, 132686, 10836, 0xd83be17a +1, 138214, 10836, 0x9a7f0bbe +1, 143743, 10836, 0x8709e4d3 +1, 149271, 10836, 0xde1879cb From 439998e18bdbdabd010fd9ab676a7298b62bf53d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 2 Oct 2011 16:07:55 -0400 Subject: [PATCH 05/14] adpcmdec: check remaining buffer size before decoding next block in the ADPCM IMA WAV decoder. --- libavcodec/adpcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 200957b26c..774193e1b2 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -431,7 +431,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (*src++) av_log(avctx, AV_LOG_ERROR, "unused byte should be null but is %d!!\n", src[-1]); /* unused */ } - while(src < buf + buf_size){ + while (src <= buf + buf_size - (avctx->channels * 4)) { for (i = 0; i < avctx->channels; i++) { cs = &c->status[i]; for (m = 0; m < 4; m++) { From a62c0f94ee5c96e98b1f91d9f1ab9f568037bb00 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 2 Oct 2011 10:18:17 -0400 Subject: [PATCH 06/14] adpcmdec: calculate actual number of output samples for each decoder. This also allows for removing some of the buf_size checks and using the sample count for some of the decoding loops. --- libavcodec/adpcm.c | 351 +++++++++++++++++++++++++++++---------------- 1 file changed, 231 insertions(+), 120 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 774193e1b2..55f518b15b 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -315,6 +315,173 @@ static void xa_decode(short *out, const unsigned char *in, } } +/** + * Get the number of samples that will be decoded from the packet. + * In one case, this is actually the maximum number of samples possible to + * decode with the given buf_size. + * + * @param[out] coded_samples set to the number of samples as coded in the + * packet, or 0 if the codec does not encode the + * number of samples in each frame. + */ +static int get_nb_samples(AVCodecContext *avctx, const uint8_t *buf, + int buf_size, int *coded_samples) +{ + ADPCMDecodeContext *s = avctx->priv_data; + int nb_samples = 0; + int ch = avctx->channels; + int has_coded_samples = 0; + int header_size; + + *coded_samples = 0; + + switch (avctx->codec->id) { + /* constant, only check buf_size */ + case CODEC_ID_ADPCM_EA_XAS: + if (buf_size < 76 * ch) + return 0; + nb_samples = 128; + break; + case CODEC_ID_ADPCM_IMA_QT: + if (buf_size < 34 * ch) + return 0; + nb_samples = 64; + break; + /* simple 4-bit adpcm */ + case CODEC_ID_ADPCM_CT: + case CODEC_ID_ADPCM_IMA_EA_SEAD: + case CODEC_ID_ADPCM_IMA_WS: + case CODEC_ID_ADPCM_YAMAHA: + nb_samples = buf_size * 2 / ch; + break; + } + if (nb_samples) + return nb_samples; + + /* simple 4-bit adpcm, with header */ + header_size = 0; + switch (avctx->codec->id) { + case CODEC_ID_ADPCM_4XM: + case CODEC_ID_ADPCM_IMA_ISS: header_size = 4 * ch; break; + case CODEC_ID_ADPCM_IMA_AMV: header_size = 8; break; + case CODEC_ID_ADPCM_IMA_SMJPEG: header_size = 4; break; + } + if (header_size > 0) + return (buf_size - header_size) * 2 / ch; + + /* more complex formats */ + switch (avctx->codec->id) { + case CODEC_ID_ADPCM_EA: + has_coded_samples = 1; + if (buf_size < 4) + return 0; + *coded_samples = AV_RL32(buf); + *coded_samples -= *coded_samples % 28; + nb_samples = (buf_size - 12) / 30 * 28; + break; + case CODEC_ID_ADPCM_IMA_EA_EACS: + has_coded_samples = 1; + if (buf_size < 4) + return 0; + *coded_samples = AV_RL32(buf); + nb_samples = (buf_size - (4 + 8 * ch)) * 2 / ch; + break; + case CODEC_ID_ADPCM_EA_MAXIS_XA: + nb_samples = ((buf_size - ch) / (2 * ch)) * 2 * ch; + break; + case CODEC_ID_ADPCM_EA_R1: + case CODEC_ID_ADPCM_EA_R2: + case CODEC_ID_ADPCM_EA_R3: + /* maximum number of samples */ + /* has internal offsets and a per-frame switch to signal raw 16-bit */ + has_coded_samples = 1; + if (buf_size < 4) + return 0; + switch (avctx->codec->id) { + case CODEC_ID_ADPCM_EA_R1: + header_size = 4 + 9 * ch; + *coded_samples = AV_RL32(buf); + break; + case CODEC_ID_ADPCM_EA_R2: + header_size = 4 + 5 * ch; + *coded_samples = AV_RL32(buf); + break; + case CODEC_ID_ADPCM_EA_R3: + header_size = 4 + 5 * ch; + *coded_samples = AV_RB32(buf); + break; + } + *coded_samples -= *coded_samples % 28; + nb_samples = (buf_size - header_size) * 2 / ch; + nb_samples -= nb_samples % 28; + break; + case CODEC_ID_ADPCM_IMA_DK3: + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = ((buf_size - 16) * 8 / 3) / ch; + break; + case CODEC_ID_ADPCM_IMA_DK4: + nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch; + break; + case CODEC_ID_ADPCM_IMA_WAV: + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = 1 + (buf_size - 4 * ch) / (4 * ch) * 8; + break; + case CODEC_ID_ADPCM_MS: + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = 2 + (buf_size - 7 * ch) * 2 / ch; + break; + case CODEC_ID_ADPCM_SBPRO_2: + case CODEC_ID_ADPCM_SBPRO_3: + case CODEC_ID_ADPCM_SBPRO_4: + { + int samples_per_byte; + switch (avctx->codec->id) { + case CODEC_ID_ADPCM_SBPRO_2: samples_per_byte = 4; break; + case CODEC_ID_ADPCM_SBPRO_3: samples_per_byte = 3; break; + case CODEC_ID_ADPCM_SBPRO_4: samples_per_byte = 2; break; + } + if (!s->status[0].step_index) { + nb_samples++; + buf_size -= ch; + } + nb_samples += buf_size * samples_per_byte / ch; + break; + } + case CODEC_ID_ADPCM_SWF: + { + int buf_bits = buf_size * 8 - 2; + int nbits = (buf[0] >> 6) + 2; + int block_hdr_size = 22 * ch; + int block_size = block_hdr_size + nbits * ch * 4095; + int nblocks = buf_bits / block_size; + int bits_left = buf_bits - nblocks * block_size; + nb_samples = nblocks * 4096; + if (bits_left >= block_hdr_size) + nb_samples += 1 + (bits_left - block_hdr_size) / (nbits * ch); + break; + } + case CODEC_ID_ADPCM_THP: + has_coded_samples = 1; + if (buf_size < 8) + return 0; + *coded_samples = AV_RB32(&buf[4]); + *coded_samples -= *coded_samples % 14; + nb_samples = (buf_size - 80) / (8 * ch) * 14; + break; + case CODEC_ID_ADPCM_XA: + nb_samples = (buf_size / 128) * 224 / ch; + break; + } + + /* validate coded sample count */ + if (has_coded_samples && (*coded_samples <= 0 || *coded_samples > nb_samples)) + return AVERROR_INVALIDDATA; + + return nb_samples; +} /* DK3 ADPCM support macro */ #define DK3_GET_NEXT_NIBBLE() \ @@ -344,20 +511,33 @@ static int adpcm_decode_frame(AVCodecContext *avctx, ADPCMChannelStatus *cs; int n, m, channel, i; short *samples; - short *samples_end; const uint8_t *src; int st; /* stereo */ - uint32_t samples_in_chunk; int count1, count2; + int nb_samples, coded_samples, out_bps, out_size; - //should protect all 4bit ADPCM variants - //8 is needed for CODEC_ID_ADPCM_IMA_WAV with 2 channels - // - if(*data_size/4 < buf_size + 8) - return -1; + nb_samples = get_nb_samples(avctx, buf, buf_size, &coded_samples); + if (nb_samples <= 0) { + av_log(avctx, AV_LOG_ERROR, "invalid number of samples in packet\n"); + return AVERROR_INVALIDDATA; + } + + out_bps = av_get_bytes_per_sample(avctx->sample_fmt); + out_size = nb_samples * avctx->channels * out_bps; + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n"); + return AVERROR(EINVAL); + } + /* use coded_samples when applicable */ + /* it is always <= nb_samples, so the output buffer will be large enough */ + if (coded_samples) { + if (coded_samples != nb_samples) + av_log(avctx, AV_LOG_WARNING, "mismatch in coded sample count\n"); + nb_samples = coded_samples; + out_size = nb_samples * avctx->channels * out_bps; + } samples = data; - samples_end= samples + *data_size/2; src = buf; st = avctx->channels == 2 ? 1 : 0; @@ -366,10 +546,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_ADPCM_IMA_QT: /* 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; @@ -410,15 +586,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src ++; } } - if (st) - samples--; break; case CODEC_ID_ADPCM_IMA_WAV: if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; -// samples_per_block= (block_align-4*chanels)*8 / (bits_per_sample * chanels) + 1; - for(i=0; ichannels; i++){ cs = &(c->status[i]); cs->predictor = *samples++ = (int16_t)bytestream_get_le16(&src); @@ -431,7 +603,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (*src++) av_log(avctx, AV_LOG_ERROR, "unused byte should be null but is %d!!\n", src[-1]); /* unused */ } - while (src <= buf + buf_size - (avctx->channels * 4)) { + for (n = (nb_samples - 1) / 8; n > 0; n--) { for (i = 0; i < avctx->channels; i++) { cs = &c->status[i]; for (m = 0; m < 4; m++) { @@ -455,20 +627,17 @@ static int adpcm_decode_frame(AVCodecContext *avctx, c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88); } - m= (buf_size - (src - buf))>>st; - 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++; + for (n = nb_samples >> 1; n > 0; n--, src++) { + 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; } } - samples -= (avctx->channels - 1); break; case CODEC_ID_ADPCM_MS: { @@ -476,9 +645,6 @@ 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 - 7 * avctx->channels; - if (n < 0) - return -1; block_predictor = av_clip(*src++, 0, 6); c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor]; @@ -502,10 +668,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (st) *samples++ = c->status[1].sample2; *samples++ = c->status[0].sample1; if (st) *samples++ = c->status[1].sample1; - for(;n>0;n--) { + for(n = (nb_samples - 2) >> (1 - st); n > 0; n--, src++) { *samples++ = adpcm_ms_expand_nibble(&c->status[0 ], src[0] >> 4 ); *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F); - src ++; } break; } @@ -513,12 +678,6 @@ 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); @@ -526,8 +685,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src++; *samples++ = cs->predictor; } - while (n-- > 0) { - uint8_t v = *src++; + for (n = nb_samples >> (1 - st); n > 0; n--, 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); } @@ -543,9 +702,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (avctx->block_align != 0 && buf_size > avctx->block_align) buf_size = avctx->block_align; - if(buf_size + 16 > (samples_end - samples)*3/8) - return -1; - c->status[0].predictor = (int16_t)AV_RL16(src + 10); c->status[1].predictor = (int16_t)AV_RL16(src + 12); c->status[0].step_index = src[14]; @@ -586,12 +742,6 @@ 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); @@ -599,9 +749,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src++; } - while (n-- > 0) { + for (n = nb_samples >> (1 - st); n > 0; n--, src++) { uint8_t v1, v2; - uint8_t v = *src++; + uint8_t v = *src; /* nibbles are swapped for mono */ if (st) { v1 = v >> 4; @@ -630,28 +780,21 @@ static int adpcm_decode_frame(AVCodecContext *avctx, buf_size -= 128; } break; - case CODEC_ID_ADPCM_IMA_EA_EACS: { - unsigned header_size = 4 + (8<> (1-st); - - if (buf_size < header_size || samples_in_chunk > buf_size - header_size) { - src += buf_size - 4; - break; - } + case CODEC_ID_ADPCM_IMA_EA_EACS: + src += 4; // skip sample count (already read) for (i=0; i<=st; i++) c->status[i].step_index = bytestream_get_le32(&src); for (i=0; i<=st; i++) c->status[i].predictor = bytestream_get_le32(&src); - for (; samples_in_chunk; samples_in_chunk--, src++) { + for (n = nb_samples >> (1 - st); n > 0; n--, src++) { *samples++ = adpcm_ima_expand_nibble(&c->status[0], *src>>4, 3); *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3); } break; - } case CODEC_ID_ADPCM_IMA_EA_SEAD: - for (; src < buf+buf_size; src++) { + for (n = nb_samples >> (1 - st); n > 0; n--, src++) { *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6); *samples++ = adpcm_ima_expand_nibble(&c->status[st],src[0]&0x0F, 6); } @@ -666,22 +809,15 @@ static int adpcm_decode_frame(AVCodecContext *avctx, /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces, each coding 28 stereo samples. */ - if (buf_size < 12) { - av_log(avctx, AV_LOG_ERROR, "frame too small\n"); - return AVERROR(EINVAL); - } - samples_in_chunk = AV_RL32(src); - if (samples_in_chunk / 28 > (buf_size - 12) / 30) { - av_log(avctx, AV_LOG_ERROR, "invalid frame\n"); - return AVERROR(EINVAL); - } - src += 4; + + src += 4; // skip sample count (already read) + current_left_sample = (int16_t)bytestream_get_le16(&src); previous_left_sample = (int16_t)bytestream_get_le16(&src); current_right_sample = (int16_t)bytestream_get_le16(&src); previous_right_sample = (int16_t)bytestream_get_le16(&src); - for (count1 = 0; count1 < samples_in_chunk/28;count1++) { + for (count1 = 0; count1 < nb_samples / 28; count1++) { coeff1l = ea_adpcm_table[ *src >> 4 ]; coeff2l = ea_adpcm_table[(*src >> 4 ) + 4]; coeff1r = ea_adpcm_table[*src & 0x0F]; @@ -728,7 +864,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, shift[channel] = (*src & 0x0F) + 8; src++; } - for (count1 = 0; count1 < (buf_size - avctx->channels) / avctx->channels; count1++) { + for (count1 = 0; count1 < nb_samples / 2; count1++) { for(i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */ for(channel = 0; channel < avctx->channels; channel++) { int32_t sample = (int32_t)(((*(src+channel) >> i) & 0x0F) << 0x1C) >> shift[channel]; @@ -742,6 +878,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } src+=avctx->channels; } + /* consume whole packet */ + src = buf + buf_size; break; } case CODEC_ID_ADPCM_EA_R1: @@ -759,14 +897,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, uint16_t *samplesC; const uint8_t *srcC; const uint8_t *src_end = buf + buf_size; + int count = 0; - samples_in_chunk = (big_endian ? bytestream_get_be32(&src) - : bytestream_get_le32(&src)) / 28; - if (samples_in_chunk > UINT32_MAX/(28*avctx->channels) || - 28*samples_in_chunk*avctx->channels > samples_end-samples) { - src += buf_size - 4; - break; - } + src += 4; // skip sample count (already read) for (channel=0; channelchannels; channel++) { int32_t offset = (big_endian ? bytestream_get_be32(&src) @@ -785,7 +918,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, previous_sample = c->status[channel].prev_sample; } - for (count1=0; count1 src_end - 30*2) break; @@ -819,6 +952,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } } } + if (!count) { + count = count1; + } else if (count != count1) { + av_log(avctx, AV_LOG_WARNING, "per-channel sample count mismatch\n"); + count = FFMAX(count, count1); + } if (avctx->codec->id != CODEC_ID_ADPCM_EA_R1) { c->status[channel].predictor = current_sample; @@ -826,16 +965,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } } - src = src + buf_size - (4 + 4*avctx->channels); - samples += 28 * samples_in_chunk * avctx->channels; + out_size = count * 28 * avctx->channels * out_bps; + src = src_end; break; } case CODEC_ID_ADPCM_EA_XAS: - if (samples_end-samples < 32*4*avctx->channels - || buf_size < (4+15)*4*avctx->channels) { - src += buf_size; - break; - } for (channel=0; channelchannels; channel++) { int coeff[2][4], shift[4]; short *s2, *s = &samples[channel]; @@ -859,7 +993,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } } } - samples += 32*4*avctx->channels; break; case CODEC_ID_ADPCM_IMA_AMV: case CODEC_ID_ADPCM_IMA_SMJPEG: @@ -869,7 +1002,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV) src+=4; - while (src < buf + buf_size) { + for (n = nb_samples >> (1 - st); n > 0; n--, src++) { char hi, lo; lo = *src & 0x0F; hi = *src >> 4; @@ -881,12 +1014,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, lo, 3); *samples++ = adpcm_ima_expand_nibble(&c->status[0], hi, 3); - src++; } break; case CODEC_ID_ADPCM_CT: - while (src < buf + buf_size) { - uint8_t v = *src++; + for (n = nb_samples >> (1 - st); n > 0; n--, 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); } @@ -900,27 +1032,26 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if (st) *samples++ = 128 * (*src++ - 0x80); c->status[0].step_index = 1; + nb_samples--; } if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_4) { - while (src < buf + buf_size) { + for (n = nb_samples >> (1 - st); n > 0; n--, src++) { *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], src[0] >> 4, 4, 0); *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], src[0] & 0x0F, 4, 0); - src++; } } else if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_3) { - while (src < buf + buf_size && samples + 2 < samples_end) { + for (n = nb_samples / 3; n > 0; n--, src++) { *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], src[0] >> 5 , 3, 0); *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], (src[0] >> 2) & 0x07, 3, 0); *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], src[0] & 0x03, 2, 0); - src++; } } else { - while (src < buf + buf_size && samples + 3 < samples_end) { + for (n = nb_samples >> (2 - st); n > 0; n--, src++) { *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], src[0] >> 6 , 2, 2); *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], @@ -929,7 +1060,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, (src[0] >> 2) & 0x03, 2, 2); *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], src[0] & 0x03, 2, 2); - src++; } } break; @@ -984,10 +1114,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, c->status[i].predictor = av_clip_int16(c->status[i].predictor); *samples++ = c->status[i].predictor; - if (samples >= samples_end) { - av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); - return -1; - } } } } @@ -995,8 +1121,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, break; } case CODEC_ID_ADPCM_YAMAHA: - while (src < buf + buf_size) { - uint8_t v = *src++; + for (n = nb_samples >> (1 - st); n > 0; n--, 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 ); } @@ -1004,17 +1130,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_ADPCM_THP: { int table[2][16]; - unsigned int samplecnt; int prev[2][2]; int ch; - if (buf_size < 80) { - av_log(avctx, AV_LOG_ERROR, "frame too small\n"); - return -1; - } - - src+=4; - samplecnt = bytestream_get_be32(&src); + src += 4; // skip channel size + src += 4; // skip number of samples (already read) for (i = 0; i < 32; i++) table[0][i] = (int16_t)bytestream_get_be16(&src); @@ -1023,16 +1143,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, for (i = 0; i < 4; i++) prev[0][i] = (int16_t)bytestream_get_be16(&src); - if (samplecnt >= (samples_end - samples) / (st + 1)) { - av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); - return -1; - } - for (ch = 0; ch <= st; ch++) { samples = (unsigned short *) data + ch; /* Read in every sample for this channel. */ - for (i = 0; i < samplecnt / 14; i++) { + for (i = 0; i < nb_samples / 14; i++) { int index = (*src >> 4) & 7; unsigned int exp = 28 - (*src++ & 15); int factor1 = table[ch][index * 2]; @@ -1056,17 +1171,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } } } - - /* In the previous loop, in case stereo is used, samples is - increased exactly one time too often. */ - samples -= st; break; } default: return -1; } - *data_size = (uint8_t *)samples - (uint8_t *)data; + *data_size = out_size; return src - buf; } From 723229c11f1400e6a09c8a1c9c27193f376eb1d1 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 15 Oct 2011 00:03:55 +0200 Subject: [PATCH 07/14] matroskadec: fix out of bounds write Signed-off-by: Janne Grunau --- libavformat/matroskadec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 89df095cd8..237e9295e0 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1783,7 +1783,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, lace_size[n] = lace_size[n - 1] + snum; total += lace_size[n]; } - lace_size[n] = size - total; + lace_size[laces - 1] = size - total; break; } } From f05c2fb6eb1f9ddaec3c07d1874ba62ec0891269 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 14 Oct 2011 23:21:46 +0200 Subject: [PATCH 08/14] vp8: fix return value if update_dimensions fails Signed-off-by: Janne Grunau --- libavcodec/vp8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index a8b23f0d0d..6268048d37 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -273,7 +273,7 @@ static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size) if (!s->macroblocks_base || /* first frame */ width != s->avctx->width || height != s->avctx->height) { - if ((ret = update_dimensions(s, width, height) < 0)) + if ((ret = update_dimensions(s, width, height)) < 0) return ret; } From 56535793810584f5b3ae59e62cea66fe22d0307d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 14 Oct 2011 23:27:52 +0200 Subject: [PATCH 09/14] vp8: force reallocation in update_thread_context after frame size change Signed-off-by: Janne Grunau --- libavcodec/vp8.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 6268048d37..691324eeb0 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -33,6 +33,19 @@ # include "arm/vp8.h" #endif +static void free_buffers(VP8Context *s) +{ + av_freep(&s->macroblocks_base); + av_freep(&s->filter_strength); + av_freep(&s->intra4x4_pred_mode_top); + av_freep(&s->top_nnz); + av_freep(&s->edge_emu_buffer); + av_freep(&s->top_border); + av_freep(&s->segmentation_map); + + s->macroblocks = NULL; +} + static void vp8_decode_flush(AVCodecContext *avctx) { VP8Context *s = avctx->priv_data; @@ -45,15 +58,7 @@ static void vp8_decode_flush(AVCodecContext *avctx) } memset(s->framep, 0, sizeof(s->framep)); - av_freep(&s->macroblocks_base); - av_freep(&s->filter_strength); - av_freep(&s->intra4x4_pred_mode_top); - av_freep(&s->top_nnz); - av_freep(&s->edge_emu_buffer); - av_freep(&s->top_border); - av_freep(&s->segmentation_map); - - s->macroblocks = NULL; + free_buffers(s); } static int update_dimensions(VP8Context *s, int width, int height) @@ -1750,6 +1755,11 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo { VP8Context *s = dst->priv_data, *s_src = src->priv_data; + if (s->macroblocks_base && + (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) { + free_buffers(s); + } + s->prob[0] = s_src->prob[!s_src->update_probabilities]; s->segmentation = s_src->segmentation; s->lf_delta = s_src->lf_delta; From 0f0b5d643401d4d83322eeee0e57eb5a226ef9ab Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 14 Oct 2011 23:43:29 +0200 Subject: [PATCH 10/14] vp8: prevent read from uninitialized memory in decode_mvs Signed-off-by: Janne Grunau --- libavcodec/vp8.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 691324eeb0..7442b99252 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -492,6 +492,7 @@ void decode_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y) AV_ZERO32(&near_mv[0]); AV_ZERO32(&near_mv[1]); + AV_ZERO32(&near_mv[2]); /* Process MB on top, left and top-left */ #define MV_EDGE_CHECK(n)\ From feadcd1bdcbb4601f4ff01878027264fde985ee1 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 14 Oct 2011 23:46:06 +0200 Subject: [PATCH 11/14] pthread: copy coded frame dimensions in update_context_from_thread Signed-off-by: Janne Grunau --- libavcodec/pthread.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index e546c21ddd..94df4ec5a2 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -332,6 +332,9 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, dst->height = src->height; dst->pix_fmt = src->pix_fmt; + dst->coded_width = src->coded_width; + dst->coded_height = src->coded_height; + dst->has_b_frames = src->has_b_frames; dst->idct_algo = src->idct_algo; dst->slice_count = src->slice_count; From 7b6883898ff9000b9a9e71fc1fb6e842ec850a79 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 14 Oct 2011 23:47:45 +0200 Subject: [PATCH 12/14] pthread: prevent updating AVCodecContext from itself in frame_thread_free Signed-off-by: Janne Grunau --- libavcodec/pthread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 94df4ec5a2..42f4382e7d 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -633,7 +633,7 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count) park_frame_worker_threads(fctx, thread_count); - if (fctx->prev_thread) + if (fctx->prev_thread && fctx->prev_thread != fctx->threads) update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0); fctx->die = 1; From cd14e297e63c89dfe44ebfe4e6a82b617352a081 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 15 Oct 2011 14:35:10 +0100 Subject: [PATCH 13/14] prores: do not set pixel format on codec init The pixel format is not known until the frame header is parsed. Guessing it here only causes trouble for the caller if the guess turns out to be wrong (and actually causes very wrong output by avconv/avplay). Signed-off-by: Mans Rullgard --- libavcodec/proresdec.c | 2 -- tests/ref/fate/prores-alpha | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c index 2e0cbf1f26..ca465f4d8e 100644 --- a/libavcodec/proresdec.c +++ b/libavcodec/proresdec.c @@ -105,8 +105,6 @@ static av_cold int decode_init(AVCodecContext *avctx) ctx->total_slices = 0; ctx->slice_data = NULL; - avctx->pix_fmt = PIX_FMT_YUV422P10; // set default pixel format - avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE; ff_proresdsp_init(&ctx->dsp); diff --git a/tests/ref/fate/prores-alpha b/tests/ref/fate/prores-alpha index f8df87deee..8ad611de6f 100644 --- a/tests/ref/fate/prores-alpha +++ b/tests/ref/fate/prores-alpha @@ -1,2 +1,2 @@ -0, 0, 12441600, 0x5188265d +0, 0, 12441600, 0x79c18863 0, 3003, 12441600, 0x79c18863 From 91038cdbd160310174aad6833d1d08c65d850e78 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 15 Oct 2011 14:35:49 +0100 Subject: [PATCH 14/14] prores: get correct size for coded V plane if alpha is present The size check must be updated to take into account both manners in which v_data_size might be set. Signed-off-by: Mans Rullgard --- libavcodec/proresdec.c | 6 ++++-- tests/ref/fate/prores-alpha | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c index ca465f4d8e..b4c794564b 100644 --- a/libavcodec/proresdec.c +++ b/libavcodec/proresdec.c @@ -546,9 +546,11 @@ static int decode_slice(AVCodecContext *avctx, ProresThreadData *td) hdr_size = buf[0] >> 3; y_data_size = AV_RB16(buf + 2); u_data_size = AV_RB16(buf + 4); - v_data_size = slice_data_size - y_data_size - u_data_size - hdr_size; + v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : + slice_data_size - y_data_size - u_data_size - hdr_size; - if (v_data_size < 0 || hdr_size < 6) { + if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size || + v_data_size < 0 || hdr_size < 6) { av_log(avctx, AV_LOG_ERROR, "invalid data size\n"); return AVERROR_INVALIDDATA; } diff --git a/tests/ref/fate/prores-alpha b/tests/ref/fate/prores-alpha index 8ad611de6f..45926528d8 100644 --- a/tests/ref/fate/prores-alpha +++ b/tests/ref/fate/prores-alpha @@ -1,2 +1,2 @@ -0, 0, 12441600, 0x79c18863 -0, 3003, 12441600, 0x79c18863 +0, 0, 12441600, 0x9d3dc525 +0, 3003, 12441600, 0x9d3dc525