diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-09-22 13:28:41 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-09-22 13:28:52 +0200 |
commit | 506ad68d87f967640519a4d568c9236d53642a9a (patch) | |
tree | 9d1df3092861b041207bd859546dc8ceb1eef726 | |
parent | ef475620b55a166b2131fd478391d4054f19ecd5 (diff) | |
parent | ce3ce08850f1690dff01d9bb4ed6a4274d52771e (diff) | |
download | ffmpeg-506ad68d87f967640519a4d568c9236d53642a9a.tar.gz |
Merge commit 'ce3ce08850f1690dff01d9bb4ed6a4274d52771e' into release/0.10
* commit 'ce3ce08850f1690dff01d9bb4ed6a4274d52771e':
dca: Error out on missing DSYNC
pcm: always use codec->id instead of codec_id
mlpdec: Do not set invalid context in read_restart_header
pcx: Do not overread source buffer in pcx_rle_decode
wmavoice: conceal clearly corrupted blocks
iff: Do not read over the source buffer
qdm2: Conceal broken samples
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/dca.c | 1 | ||||
-rw-r--r-- | libavcodec/iff.c | 2 | ||||
-rw-r--r-- | libavcodec/mlpdec.c | 30 | ||||
-rw-r--r-- | libavcodec/pcm.c | 2 | ||||
-rw-r--r-- | libavcodec/pcx.c | 27 | ||||
-rw-r--r-- | libavcodec/qdm2.c | 16 | ||||
-rw-r--r-- | libavcodec/wmavoice.c | 21 |
7 files changed, 68 insertions, 31 deletions
diff --git a/libavcodec/dca.c b/libavcodec/dca.c index f8ae33d40c..a442e7f06b 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -1253,6 +1253,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) #endif } else { av_log(s->avctx, AV_LOG_ERROR, "Didn't get subframe DSYNC\n"); + return AVERROR_INVALIDDATA; } } diff --git a/libavcodec/iff.c b/libavcodec/iff.c index eca795aa66..5ea1a0dba3 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -514,7 +514,7 @@ static int decode_frame_ilbm(AVCodecContext *avctx, } } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { - for(y = 0; y < avctx->height; y++ ) { + for (y = 0; y < avctx->height && buf < buf_end; y++ ) { uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; memset(row, 0, avctx->width); for (plane = 0; plane < s->bpp && buf < buf_end; plane++) { diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 47aee286ff..3d3e10bbf1 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -369,9 +369,10 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, uint8_t checksum; uint8_t lossless_check; int start_count = get_bits_count(gbp); - const int max_matrix_channel = m->avctx->codec_id == CODEC_ID_MLP - ? MAX_MATRIX_CHANNEL_MLP - : MAX_MATRIX_CHANNEL_TRUEHD; + int min_channel, max_channel, max_matrix_channel; + const int std_max_matrix_channel = m->avctx->codec_id == CODEC_ID_MLP + ? MAX_MATRIX_CHANNEL_MLP + : MAX_MATRIX_CHANNEL_TRUEHD; sync_word = get_bits(gbp, 13); @@ -390,18 +391,18 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, skip_bits(gbp, 16); /* Output timestamp */ - s->min_channel = get_bits(gbp, 4); - s->max_channel = get_bits(gbp, 4); - s->max_matrix_channel = get_bits(gbp, 4); + min_channel = get_bits(gbp, 4); + max_channel = get_bits(gbp, 4); + max_matrix_channel = get_bits(gbp, 4); - if (s->max_matrix_channel > max_matrix_channel) { + if (max_matrix_channel > std_max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, "Max matrix channel cannot be greater than %d.\n", max_matrix_channel); return AVERROR_INVALIDDATA; } - if (s->max_channel != s->max_matrix_channel) { + if (max_channel != max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, "Max channel must be equal max matrix channel.\n"); return AVERROR_INVALIDDATA; @@ -416,15 +417,20 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, return AVERROR_INVALIDDATA; } - if (s->min_channel > s->max_channel) { + if (min_channel > max_channel) { av_log(m->avctx, AV_LOG_ERROR, "Substream min channel cannot be greater than max channel.\n"); return AVERROR_INVALIDDATA; } - if (m->avctx->request_channels > 0 - && s->max_channel + 1 >= m->avctx->request_channels - && substr < m->max_decoded_substream) { + + s->min_channel = min_channel; + s->max_channel = max_channel; + s->max_matrix_channel = max_matrix_channel; + + if (m->avctx->request_channels > 0 && + m->avctx->request_channels <= s->max_channel + 1 && + m->max_decoded_substream > substr) { av_log(m->avctx, AV_LOG_DEBUG, "Extracting %d channel downmix from substream %d. " "Further substreams will be skipped.\n", diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 650003793c..e658c9663f 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -268,7 +268,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, /* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */ samples_per_block = 1; - if (CODEC_ID_PCM_DVD == avctx->codec_id) { + if (avctx->codec->id == CODEC_ID_PCM_DVD) { if (avctx->bits_per_coded_sample != 20 && avctx->bits_per_coded_sample != 24) { av_log(avctx, AV_LOG_ERROR, diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index 6339dc05c8..b23a0a8d51 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -43,16 +43,19 @@ static av_cold int pcx_init(AVCodecContext *avctx) { /** * @return advanced src pointer */ -static const uint8_t *pcx_rle_decode(const uint8_t *src, uint8_t *dst, - unsigned int bytes_per_scanline, int compressed) { +static const uint8_t *pcx_rle_decode(const uint8_t *src, + const uint8_t *end, + uint8_t *dst, + unsigned int bytes_per_scanline, + int compressed) { unsigned int i = 0; unsigned char run, value; if (compressed) { - while (i<bytes_per_scanline) { + while (i < bytes_per_scanline && src < end) { run = 1; value = *src++; - if (value >= 0xc0) { + if (value >= 0xc0 && src < end) { run = value & 0x3f; value = *src++; } @@ -87,6 +90,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x, bytes_per_scanline; uint8_t *ptr; + const uint8_t *buf_end = buf + buf_size; uint8_t const *bufstart = buf; uint8_t *scanline; int ret = -1; @@ -115,7 +119,8 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, nplanes = buf[65]; bytes_per_scanline = nplanes * bytes_per_line; - if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8) { + if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8 || + (!compressed && bytes_per_scanline > buf_size / h)) { av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); return -1; } @@ -163,7 +168,8 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (nplanes == 3 && bits_per_pixel == 8) { for (y=0; y<h; y++) { - buf = pcx_rle_decode(buf, scanline, bytes_per_scanline, compressed); + buf = pcx_rle_decode(buf, buf_end, + scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) { ptr[3*x ] = scanline[x ]; @@ -178,7 +184,8 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *palstart = bufstart + buf_size - 769; for (y=0; y<h; y++, ptr+=stride) { - buf = pcx_rle_decode(buf, scanline, bytes_per_scanline, compressed); + buf = pcx_rle_decode(buf, buf_end, + scanline, bytes_per_scanline, compressed); memcpy(ptr, scanline, w); } @@ -197,7 +204,8 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, for (y=0; y<h; y++) { init_get_bits(&s, scanline, bytes_per_scanline<<3); - buf = pcx_rle_decode(buf, scanline, bytes_per_scanline, compressed); + buf = pcx_rle_decode(buf, buf_end, + scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) ptr[x] = get_bits(&s, bits_per_pixel); @@ -208,7 +216,8 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, int i; for (y=0; y<h; y++) { - buf = pcx_rle_decode(buf, scanline, bytes_per_scanline, compressed); + buf = pcx_rle_decode(buf, buf_end, + scanline, bytes_per_scanline, compressed); for (x=0; x<w; x++) { int m = 0x80 >> (x&7), v = 0; diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 5572b9d881..b1bdb536c6 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -498,7 +498,8 @@ static void build_sb_samples_from_noise (QDM2Context *q, int sb) * @param channels number of channels * @param coding_method q->coding_method[0][0][0] */ -static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method) +static int fix_coding_method_array(int sb, int channels, + sb_int8_array coding_method) { int j,k; int ch; @@ -507,8 +508,10 @@ static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_ for (ch = 0; ch < channels; ch++) { for (j = 0; j < 64; ) { - if((coding_method[ch][sb][j] - 8) > 22) { - run = 1; + if (coding_method[ch][sb][j] < 8) + return -1; + if ((coding_method[ch][sb][j] - 8) > 22) { + run = 1; case_val = 8; } else { switch (switchtable[coding_method[ch][sb][j]-8]) { @@ -533,6 +536,7 @@ static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_ j += run; } } + return 0; } @@ -802,7 +806,11 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l if (q->coding_method[1][sb][j] > q->coding_method[0][sb][j]) q->coding_method[0][sb][j] = q->coding_method[1][sb][j]; - fix_coding_method_array(sb, q->nb_channels, q->coding_method); + if (fix_coding_method_array(sb, q->nb_channels, + q->coding_method)) { + build_sb_samples_from_noise(q, sb); + continue; + } channels = 1; } diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index b35eaa7224..922c1a2ebd 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1046,9 +1046,10 @@ static void aw_parse_coords(WMAVoiceContext *s, GetBitContext *gb, * @param gb bit I/O context * @param block_idx block index in frame [0, 1] * @param fcb structure containing fixed codebook vector info + * @return -1 on error, 0 otherwise */ -static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, - int block_idx, AMRFixed *fcb) +static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, + int block_idx, AMRFixed *fcb) { uint16_t use_mask_mem[9]; // only 5 are used, rest is padding uint16_t *use_mask = use_mask_mem + 2; @@ -1110,7 +1111,7 @@ static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, else if (use_mask[2]) idx = 0x2F; else if (use_mask[3]) idx = 0x3F; else if (use_mask[4]) idx = 0x4F; - else return; + else return -1; idx -= av_log2_16bit(use_mask[idx >> 4]); } if (use_mask[idx >> 4] & (0x8000 >> (idx & 15))) { @@ -1127,6 +1128,7 @@ static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, /* set offset for next block, relative to start of that block */ n = (MAX_FRAMESIZE / 2 - start_off) % fcb->pitch_lag; s->aw_next_pulse_off_cache = n ? fcb->pitch_lag - n : 0; + return 0; } /** @@ -1289,7 +1291,18 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, * (fixed) codebook pulses of the speech signal. */ if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) { aw_pulse_set1(s, gb, block_idx, &fcb); - aw_pulse_set2(s, gb, block_idx, &fcb); + if (aw_pulse_set2(s, gb, block_idx, &fcb)) { + /* Conceal the block with silence and return. + * Skip the correct amount of bits to read the next + * block from the correct offset. */ + int r_idx = pRNG(s->frame_cntr, block_idx, size); + + for (n = 0; n < size; n++) + excitation[n] = + wmavoice_std_codebook[r_idx + n] * s->silence_gain; + skip_bits(gb, 7 + 1); + return; + } } else /* FCB_TYPE_EXC_PULSES */ { int offset_nbits = 5 - frame_desc->log_n_blocks; |