X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpeg4videodec.c;h=055afabc7e25ad9f2f181f44799cc031d40c7e7b;hb=8fec9fca69c22fc41d8602d8bdf547f14c70fc06;hp=4c77081237d8b03079b7d3fa5c6489e96a9461ab;hpb=203bbaccfaaeac9548862e83792d38509a8c8167;p=ffmpeg diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 4c77081237d..055afabc7e2 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -402,7 +402,7 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g llabs(sprite_offset[0][i] + sprite_delta[i][1] * (h+16LL)) >= INT_MAX || llabs(sprite_offset[0][i] + sprite_delta[i][0] * (w+16LL) + sprite_delta[i][1] * (h+16LL)) >= INT_MAX || llabs(sprite_delta[i][0] * (w+16LL)) >= INT_MAX || - llabs(sprite_delta[i][1] * (w+16LL)) >= INT_MAX || + llabs(sprite_delta[i][1] * (h+16LL)) >= INT_MAX || llabs(sd[0]) >= INT_MAX || llabs(sd[1]) >= INT_MAX || llabs(sprite_offset[0][i] + sd[0] * (w+16LL)) >= INT_MAX || @@ -598,7 +598,7 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n) len >>= s->quarter_sample; if (s->real_sprite_warping_points == 1) { - if (ctx->divx_version == 500 && ctx->divx_build == 413) + if (ctx->divx_version == 500 && ctx->divx_build == 413 && a >= s->quarter_sample) sum = s->sprite_offset[0][n] / (1 << (a - s->quarter_sample)); else sum = RSHIFT(s->sprite_offset[0][n] * (1 << s->quarter_sample), a); @@ -1826,6 +1826,7 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n uint32_t flc; const int min = -1 * (1 << (s->avctx->bits_per_raw_sample + 6)); const int max = ((1 << (s->avctx->bits_per_raw_sample + 6)) - 1); + int shift = 3 - s->dct_precision; mismatch = 1; @@ -1899,14 +1900,20 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n code >>= 1; run = (1 << (additional_code_len - 1)) + code; idx += run; + if (idx > 63) + return AVERROR_INVALIDDATA; j = scantable[idx++]; block[j] = sign ? 1 : -1; } else if (group >= 13 && group <= 20) { /* Level value (Table B.49) */ + if (idx > 63) + return AVERROR_INVALIDDATA; j = scantable[idx++]; block[j] = get_xbits(&s->gb, additional_code_len); } else if (group == 21) { /* Escape */ + if (idx > 63) + return AVERROR_INVALIDDATA; j = scantable[idx++]; additional_code_len = s->avctx->bits_per_raw_sample + s->dct_precision + 4; flc = get_bits(&s->gb, additional_code_len); @@ -1915,7 +1922,7 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n else block[j] = flc; } - block[j] = ((8 * 2 * block[j] * quant_matrix[j] * s->qscale) >> s->dct_precision) / 32; + block[j] = ((block[j] * quant_matrix[j] * s->qscale) * (1 << shift)) / 16; block[j] = av_clip(block[j], min, max); mismatch ^= block[j]; } @@ -1968,6 +1975,10 @@ static int mpeg4_decode_dpcm_macroblock(MpegEncContext *s, int16_t macroblock[25 if (rice_prefix_code == 11) dpcm_residual = get_bits(&s->gb, s->avctx->bits_per_raw_sample); else { + if (rice_prefix_code == 12) { + av_log(s->avctx, AV_LOG_ERROR, "Forbidden rice_prefix_code\n"); + return AVERROR_INVALIDDATA; + } rice_suffix_code = get_bitsz(&s->gb, rice_parameter); dpcm_residual = (rice_prefix_code << rice_parameter) + rice_suffix_code; } @@ -3052,6 +3063,8 @@ static int decode_studio_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) if (get_bits_left(gb) <= 32) return 0; + s->partitioned_frame = 0; + s->interlaced_dct = 0; s->decode_mb = mpeg4_decode_studio_mb; decode_smpte_tc(ctx, gb); @@ -3197,11 +3210,13 @@ static int decode_studio_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) /** * Decode MPEG-4 headers. - * @return <0 if no VOP found (or a damaged one) + * + * @param header If set the absence of a VOP is not treated as error; otherwise, it is treated as such. + * @return <0 if an error occurred * FRAME_SKIPPED if a not coded VOP is found - * 0 if a VOP is found + * 0 else */ -int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb) +int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb, int header) { MpegEncContext *s = &ctx->m; unsigned startcode, v; @@ -3230,6 +3245,8 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb) (ctx->divx_version >= 0 || ctx->xvid_build >= 0) || s->codec_tag == AV_RL32("QMP4")) { av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits); return FRAME_SKIPPED; // divx bug + } else if (header && get_bits_count(gb) == gb->size_in_bits) { + return 0; // ordinary return value for parsing of extradata } else return AVERROR_INVALIDDATA; // end of stream }