diff options
author | Michael Niedermayer <[email protected]> | 2013-08-27 17:48:04 +0200 |
---|---|---|
committer | Michael Niedermayer <[email protected]> | 2013-08-27 17:54:01 +0200 |
commit | fd85d031626bf1b6af12b4b5444e53c3bb614e3e (patch) | |
tree | 1ad817e1e80264d9a18f4d7c8a6e4eeddc24cc86 | |
parent | 9b89041a86a4eccc1ffe50e7857b2d5c1c5fe8b4 (diff) | |
parent | fbbe487b1c1f21339cff9ca86c3dfc495ad1c2c6 (diff) |
Merge commit 'fbbe487b1c1f21339cff9ca86c3dfc495ad1c2c6' into release/1.1
* commit 'fbbe487b1c1f21339cff9ca86c3dfc495ad1c2c6':
indeo: Sanitize ff_ivi_init_planes fail paths
indeo5: return proper error codes
indeo: Bound-check before applying motion compensation
indeo: Bound-check before applying transform
indeo4: Validate scantable dimension
indeo4: Check the quantization matrix index
indeo4: Do not access missing reference MV
ac3dec: Increment channel pointers only once per channel
dca: Respect the current limits in the downmixing capabilities
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
qdm2: refactor joined stereo support
Conflicts:
libavcodec/ac3dec.c
libavcodec/dcadec.c
libavcodec/iff.c
libavcodec/indeo4.c
libavcodec/indeo5.c
libavcodec/ivi_common.c
libavcodec/mlpdec.c
libavcodec/pcx.c
Merged-by: Michael Niedermayer <[email protected]>
-rw-r--r-- | libavcodec/dcadec.c | 9 | ||||
-rw-r--r-- | libavcodec/indeo4.c | 46 | ||||
-rw-r--r-- | libavcodec/indeo5.c | 101 | ||||
-rw-r--r-- | libavcodec/ivi_common.c | 59 | ||||
-rw-r--r-- | libavcodec/ivi_common.h | 2 | ||||
-rw-r--r-- | libavcodec/mlpdec.c | 33 | ||||
-rw-r--r-- | libavcodec/pcm.c | 2 | ||||
-rw-r--r-- | libavcodec/pcx.c | 15 | ||||
-rw-r--r-- | libavcodec/qdm2.c | 35 | ||||
-rw-r--r-- | libavcodec/wmavoice.c | 21 |
10 files changed, 207 insertions, 116 deletions
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c index e7ae6e2d20..ea5b230797 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -971,7 +971,13 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) "Invalid channel mode %d\n", am); return AVERROR_INVALIDDATA; } - for (j = base_channel; j < FFMIN(s->prim_channels, FF_ARRAY_ELEMS(dca_default_coeffs[am])); j++) { + if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) { + av_log_ask_for_sample(s->avctx, "Downmixing %d channels", + s->prim_channels); + return AVERROR_PATCHWELCOME; + } + + for (j = base_channel; j < s->prim_channels; j++) { s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; } @@ -1425,6 +1431,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/indeo4.c b/libavcodec/indeo4.c index 0766ed489a..a33caa084f 100644 --- a/libavcodec/indeo4.c +++ b/libavcodec/indeo4.c @@ -211,6 +211,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { if (ff_ivi_init_planes(ctx->planes, &pic_conf)) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); + ctx->pic_conf.luma_bands = 0; return AVERROR(ENOMEM); } @@ -353,7 +354,13 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->inv_transform = transforms[transform_id].inv_trans; band->dc_transform = transforms[transform_id].dc_trans; band->is_2d_trans = transforms[transform_id].is_2d_trans; - band->transform_size= (transform_id < 10) ? 8 : 4; + if (transform_id < 10) + band->transform_size = 8; + else + band->transform_size = 4; + + if (band->blk_size != band->transform_size) + return AVERROR_INVALIDDATA; scan_indx = get_bits(&ctx->gb, 4); if ((scan_indx>4 && scan_indx<10) != (band->blk_size==4)) { @@ -364,6 +371,12 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n"); return AVERROR_INVALIDDATA; } + if (scan_indx > 4 && scan_indx < 10) { + if (band->blk_size != 4) + return AVERROR_INVALIDDATA; + } else if (band->blk_size != 8) + return AVERROR_INVALIDDATA; + band->scan = scan_index_to_tab[scan_indx]; band->scan_size = band->blk_size; @@ -372,8 +385,9 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n"); return AVERROR_INVALIDDATA; } - if (quant_mat > 21) { - av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix encountered!\n"); + if (quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) { + av_log_ask_for_sample(avctx, "Quantization matrix %d", + quant_mat); return AVERROR_INVALIDDATA; } band->quant_mat = quant_mat; @@ -504,8 +518,11 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, } } } else { - if (band->inherit_mv && ref_mb) { - mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */ + if (band->inherit_mv) { + /* copy mb_type from corresponding reference mb */ + if (!ref_mb) + return AVERROR_INVALIDDATA; + mb->type = ref_mb->type; } else if (ctx->frame_type == FRAMETYPE_INTRA || ctx->frame_type == FRAMETYPE_INTRA1) { mb->type = 0; /* mb_type is always INTRA for intra-frames */ @@ -528,15 +545,16 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, if (!mb->type) { mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */ } else { - if (band->inherit_mv && ref_mb) { - /* motion vector inheritance */ - if (mv_scale) { - mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); - mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); - } else { - mb->mv_x = ref_mb->mv_x; - mb->mv_y = ref_mb->mv_y; - } + if (band->inherit_mv) { + if (ref_mb) + /* motion vector inheritance */ + if (mv_scale) { + mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); + mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); + } else { + mb->mv_x = ref_mb->mv_x; + mb->mv_y = ref_mb->mv_y; + } } else { /* decode motion vector deltas */ mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c index 52dddd2ad9..6f6de8706d 100644 --- a/libavcodec/indeo5.c +++ b/libavcodec/indeo5.c @@ -74,7 +74,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) tile_size = (ctx->gop_flags & 0x40) ? 64 << get_bits(&ctx->gb, 2) : 0; if (tile_size > 256) { av_log(avctx, AV_LOG_ERROR, "Invalid tile size: %d\n", tile_size); - return -1; + return AVERROR_INVALIDDATA; } /* decode number of wavelet bands */ @@ -85,7 +85,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) if (is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n", pic_conf.luma_bands, pic_conf.chroma_bands); - return -1; + return AVERROR_INVALIDDATA; } pic_size_indx = get_bits(&ctx->gb, 4); @@ -98,8 +98,8 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) } if (ctx->gop_flags & 2) { - av_log(avctx, AV_LOG_ERROR, "YV12 picture format not supported!\n"); - return -1; + av_log_missing_feature(avctx, "YV12 picture format", 0); + return AVERROR_PATCHWELCOME; } pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2; @@ -113,11 +113,11 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) } /* check if picture layout was changed and reallocate buffers */ - if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { + if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf) || ctx->gop_invalid) { result = ff_ivi_init_planes(ctx->planes, &pic_conf); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); - return -1; + return result; } ctx->pic_conf = pic_conf; ctx->is_scalable = is_scalable; @@ -146,51 +146,54 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) } if (get_bits1(&ctx->gb)) { - av_log(avctx, AV_LOG_ERROR, "Extended transform info encountered!\n"); - return -1; + av_log_missing_feature(avctx, "Extended transform info", 0); + return AVERROR_PATCHWELCOME; } /* select transform function and scan pattern according to plane and band number */ switch ((p << 2) + i) { case 0: - band->inv_transform = ff_ivi_inverse_slant_8x8; - band->dc_transform = ff_ivi_dc_slant_2d; - band->scan = ff_zigzag_direct; - band->transform_size= 8; + band->inv_transform = ff_ivi_inverse_slant_8x8; + band->dc_transform = ff_ivi_dc_slant_2d; + band->scan = ff_zigzag_direct; + band->transform_size = 8; break; case 1: - band->inv_transform = ff_ivi_row_slant8; - band->dc_transform = ff_ivi_dc_row_slant; - band->scan = ff_ivi_vertical_scan_8x8; - band->transform_size= 8; + band->inv_transform = ff_ivi_row_slant8; + band->dc_transform = ff_ivi_dc_row_slant; + band->scan = ff_ivi_vertical_scan_8x8; + band->transform_size = 8; break; case 2: - band->inv_transform = ff_ivi_col_slant8; - band->dc_transform = ff_ivi_dc_col_slant; - band->scan = ff_ivi_horizontal_scan_8x8; - band->transform_size= 8; + band->inv_transform = ff_ivi_col_slant8; + band->dc_transform = ff_ivi_dc_col_slant; + band->scan = ff_ivi_horizontal_scan_8x8; + band->transform_size = 8; break; case 3: - band->inv_transform = ff_ivi_put_pixels_8x8; - band->dc_transform = ff_ivi_put_dc_pixel_8x8; - band->scan = ff_ivi_horizontal_scan_8x8; - band->transform_size= 8; + band->inv_transform = ff_ivi_put_pixels_8x8; + band->dc_transform = ff_ivi_put_dc_pixel_8x8; + band->scan = ff_ivi_horizontal_scan_8x8; + band->transform_size = 8; break; case 4: - band->inv_transform = ff_ivi_inverse_slant_4x4; - band->dc_transform = ff_ivi_dc_slant_2d; - band->scan = ff_ivi_direct_scan_4x4; - band->transform_size= 4; + band->inv_transform = ff_ivi_inverse_slant_4x4; + band->dc_transform = ff_ivi_dc_slant_2d; + band->scan = ff_ivi_direct_scan_4x4; + band->transform_size = 4; break; } band->is_2d_trans = band->inv_transform == ff_ivi_inverse_slant_8x8 || band->inv_transform == ff_ivi_inverse_slant_4x4; + if (band->transform_size != band->blk_size) + return AVERROR_INVALIDDATA; + /* select dequant matrix according to plane and band number */ if (!p) { quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0; @@ -216,7 +219,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) if (get_bits(&ctx->gb, 2)) { av_log(avctx, AV_LOG_ERROR, "End marker missing!\n"); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -246,17 +249,17 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) if (blk_size_changed) { result = ff_ivi_init_tiles(ctx->planes, pic_conf.tile_width, pic_conf.tile_height); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate internal structures!\n"); - return -1; + return result; } } if (ctx->gop_flags & 8) { if (get_bits(&ctx->gb, 3)) { av_log(avctx, AV_LOG_ERROR, "Alignment bits are not zero!\n"); - return -1; + return AVERROR_INVALIDDATA; } if (get_bits1(&ctx->gb)) @@ -305,25 +308,27 @@ static inline void skip_hdr_extension(GetBitContext *gb) */ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) { + int ret; + if (get_bits(&ctx->gb, 5) != 0x1F) { av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n"); - return -1; + return AVERROR_INVALIDDATA; } ctx->prev_frame_type = ctx->frame_type; ctx->frame_type = get_bits(&ctx->gb, 3); if (ctx->frame_type >= 5) { av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d \n", ctx->frame_type); - return -1; + return AVERROR_INVALIDDATA; } ctx->frame_num = get_bits(&ctx->gb, 8); if (ctx->frame_type == FRAMETYPE_INTRA) { - ctx->gop_invalid = 1; - if (decode_gop_header(ctx, avctx)) { + if ((ret = decode_gop_header(ctx, avctx)) < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid GOP header, skipping frames.\n"); - return AVERROR_INVALIDDATA; + ctx->gop_invalid = 1; + return ret; } ctx->gop_invalid = 0; } @@ -346,8 +351,10 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) skip_hdr_extension(&ctx->gb); /* XXX: untested */ /* decode macroblock huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, IVI_MB_HUFF, &ctx->mb_vlc, avctx)) - return -1; + ret = ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, + IVI_MB_HUFF, &ctx->mb_vlc, avctx); + if (ret < 0) + return ret; skip_bits(&ctx->gb, 3); /* FIXME: unknown meaning! */ } @@ -369,7 +376,7 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, AVCodecContext *avctx) { - int i; + int i, ret; uint8_t band_flags; band_flags = get_bits(&ctx->gb, 8); @@ -393,7 +400,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, if (band->num_corr > 61) { av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n", band->num_corr); - return -1; + return AVERROR_INVALIDDATA; } /* read correction pairs */ @@ -405,8 +412,10 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->rvmap_sel = (band_flags & 0x40) ? get_bits(&ctx->gb, 3) : 8; /* decode block huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, &band->blk_vlc, avctx)) - return -1; + ret = ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, + &band->blk_vlc, avctx); + if (ret < 0) + return ret; band->checksum_present = get_bits1(&ctx->gb); if (band->checksum_present) @@ -473,7 +482,7 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, if (get_bits1(&ctx->gb)) { if (ctx->frame_type == FRAMETYPE_INTRA) { av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n"); - return -1; + return AVERROR_INVALIDDATA; } mb->type = 1; /* empty macroblocks are always INTER */ mb->cbp = 0; /* all blocks are empty */ @@ -648,7 +657,7 @@ static av_cold int decode_init(AVCodecContext *avctx) result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf); if (result) { av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n"); - return -1; + return AVERROR_INVALIDDATA; } ctx->buf_switch = 0; diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index d083c3643a..ab35c59185 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -44,16 +44,22 @@ static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); -static int ivi_mc(ivi_mc_func mc, int16_t *buf, const int16_t *ref_buf, - int offs, int mv_x, int mv_y, uint32_t pitch, - int mc_type) +static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc, + int offs, int mv_x, int mv_y, int mc_type) { - int ref_offs = offs + mv_y * pitch + mv_x; + int ref_offs = offs + mv_y * band->pitch + mv_x; + int buf_size = band->pitch * band->aheight; + int min_size = band->pitch * (band->blk_size - 1) + band->blk_size; + int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1); - if (offs < 0 || ref_offs < 0 || !ref_buf) + if (offs < 0 || ref_offs < 0 || !band->ref_buf) + return AVERROR_INVALIDDATA; + if (buf_size - min_size < offs) + return AVERROR_INVALIDDATA; + if (buf_size - min_size - ref_size < ref_offs) return AVERROR_INVALIDDATA; - mc(buf + offs, ref_buf + ref_offs, pitch, mc_type); + mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type); return 0; } @@ -239,6 +245,7 @@ static av_cold void ivi_free_buffers(IVIPlaneDesc *planes) av_freep(&planes[p].bands[b].tiles); } av_freep(&planes[p].bands); + planes[p].num_bands = 0; } } @@ -251,6 +258,10 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) ivi_free_buffers(planes); + if (cfg->pic_width < 1 || cfg->pic_height < 1 || + cfg->luma_bands < 1 || cfg->chroma_bands < 1) + return AVERROR_INVALIDDATA; + /* fill in the descriptor of the luminance plane */ planes[0].width = cfg->pic_width; planes[0].height = cfg->pic_height; @@ -411,6 +422,20 @@ static int ivi_dec_tile_data_size(GetBitContext *gb) return len; } +static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs, + int blk_size) +{ + int buf_size = band->pitch * band->aheight - buf_offs; + int min_size = (blk_size - 1) * band->pitch + blk_size; + + if (min_size > buf_size) + return AVERROR_INVALIDDATA; + + band->dc_transform(prev_dc, band->buf + buf_offs, + band->pitch, blk_size); + + return 0; +} static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, ivi_mc_func mc, int mv_x, int mv_y, @@ -428,6 +453,12 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, int num_coeffs = blk_size * blk_size; int col_mask = blk_size - 1; int scan_pos = -1; + int min_size = band->pitch * (band->transform_size - 1) + + band->transform_size; + int buf_size = band->pitch * band->aheight - offs; + + if (min_size > buf_size) + return AVERROR_INVALIDDATA; if (!band->scan) { av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n"); @@ -498,8 +529,7 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, /* apply motion compensation */ if (!is_intra) - return ivi_mc(mc, band->buf, band->ref_buf, offs, mv_x, mv_y, - band->pitch, mc_type); + return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type); return 0; } @@ -595,11 +625,12 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, /* for intra blocks apply the dc slant transform */ /* for inter - perform the motion compensation without delta */ if (is_intra) { - band->dc_transform(&prev_dc, band->buf + buf_offs, - band->pitch, blk_size); + ret = ivi_dc_transform(band, &prev_dc, buf_offs, blk_size); + if (ret < 0) + return ret; } else { - ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf, - buf_offs, mv_x, mv_y, band->pitch, mc_type); + ret = ivi_mc(band, mc_no_delta_func, buf_offs, + mv_x, mv_y, mc_type); if (ret < 0) return ret; } @@ -721,8 +752,8 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, for (blk = 0; blk < num_blocks; blk++) { /* adjust block position in the buffer according with its number */ offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch); - ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf, - offs, mv_x, mv_y, band->pitch, mc_type); + ret = ivi_mc(band, mc_no_delta_func, offs, + mv_x, mv_y, mc_type); if (ret < 0) return ret; } diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index fcea5f6b4f..81ab7b0fa9 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -160,9 +160,9 @@ typedef struct IVIBandDesc { int num_tiles; ///< number of tiles in this band IVITile *tiles; ///< array of tile descriptors InvTransformPtr *inv_transform; + int transform_size; DCTransformPtr *dc_transform; int is_2d_trans; ///< 1 indicates that the two-dimensional inverse transform is used - int transform_size; ///< block size of the transform int32_t checksum; ///< for debug purposes int checksum_present; int bufsize; ///< band buffer size in bytes diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 28b5502ad0..6b9b649993 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -404,10 +404,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 == AV_CODEC_ID_MLP - ? MAX_MATRIX_CHANNEL_MLP - : MAX_MATRIX_CHANNEL_TRUEHD; - int max_channel, min_channel, matrix_channel; + int min_channel, max_channel, max_matrix_channel; + const int std_max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP + ? MAX_MATRIX_CHANNEL_MLP + : MAX_MATRIX_CHANNEL_TRUEHD; sync_word = get_bits(gbp, 13); @@ -426,18 +426,18 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, skip_bits(gbp, 16); /* Output timestamp */ - min_channel = get_bits(gbp, 4); - max_channel = get_bits(gbp, 4); - 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 (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); + std_max_matrix_channel); return AVERROR_INVALIDDATA; } - if (max_channel != 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; @@ -458,13 +458,14 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, return AVERROR_INVALIDDATA; } - s->min_channel = min_channel; - s->max_channel = max_channel; - s->max_matrix_channel = matrix_channel; - 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 ea6fabd47b..b2898aebe3 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -311,7 +311,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, /* av_get_bits_per_sample returns 0 for AV_CODEC_ID_PCM_DVD */ samples_per_block = 1; - if (AV_CODEC_ID_PCM_DVD == avctx->codec_id) { + if (avctx->codec->id == AV_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 bac818c586..3aed3a3e2b 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -42,18 +42,20 @@ static av_cold int pcx_init(AVCodecContext *avctx) return 0; } -static void pcx_rle_decode(GetByteContext *gb, uint8_t *dst, - unsigned int bytes_per_scanline, int compressed) +static void pcx_rle_decode(GetByteContext *gb, + 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 && bytestream2_get_bytes_left(gb)>0) { run = 1; value = bytestream2_get_byte(gb); - if (value >= 0xc0) { - run = value & 0x3f; + if (value >= 0xc0 && bytestream2_get_bytes_left(gb)>0) { + run = value & 0x3f; value = bytestream2_get_byte(gb); } while (i<bytes_per_scanline && run--) @@ -119,7 +121,8 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, bytes_per_line = bytestream2_get_le16u(&gb); 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 + 7) / 8 || + (!compressed && bytes_per_scanline > bytestream2_get_bytes_left(&gb) / h)) { av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 8d9a60b2f3..e75aa3c95a 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -535,8 +535,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; @@ -544,6 +544,8 @@ static void fix_coding_method_array(int sb, int channels, for (ch = 0; ch < channels; ch++) { for (j = 0; j < 64; ) { + if (coding_method[ch][sb][j] < 8) + return -1; if ((coding_method[ch][sb][j] - 8) > 22) { run = 1; case_val = 8; @@ -589,6 +591,7 @@ static void fix_coding_method_array(int sb, int channels, j += run; } } + return 0; } /** @@ -817,7 +820,7 @@ static int synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max) { int sb, j, k, n, ch, run, channels; - int joined_stereo, zero_encoding, chs; + int joined_stereo, zero_encoding; int type34_first; float type34_div = 0; float type34_predictor; @@ -855,7 +858,11 @@ static int synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, 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; } @@ -978,16 +985,18 @@ static int synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb, } if (joined_stereo) { - float tmp[10][MPA_MAX_CHANNELS]; - - for (k = 0; k < run; k++) { - tmp[k][0] = samples[k]; - tmp[k][1] = (sign_bits[(j + k) / 8]) ? -samples[k] : samples[k]; + for (k = 0; k < run && j + k < 128; k++) { + q->sb_samples[0][j + k][sb] = + q->tone_level[0][sb][(j + k) / 2] * samples[k]; + if (q->nb_channels == 2) { + if (sign_bits[(j + k) / 8]) + q->sb_samples[1][j + k][sb] = + q->tone_level[1][sb][(j + k) / 2] * -samples[k]; + else + q->sb_samples[1][j + k][sb] = + q->tone_level[1][sb][(j + k) / 2] * samples[k]; + } } - for (chs = 0; chs < q->nb_channels; chs++) - for (k = 0; k < run; k++) - if ((j + k) < 128) - q->sb_samples[chs][j + k][sb] = q->tone_level[chs][sb][((j + k)/2)] * tmp[k][chs]; } else { for (k = 0; k < run; k++) if ((j + k) < 128) diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 0ae3748911..02e14be92a 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1050,9 +1050,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; @@ -1114,7 +1115,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))) { @@ -1131,6 +1132,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; } /** @@ -1293,7 +1295,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; |