diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h index 29b11eb92e..9ac18943a2 100644 --- a/libavcodec/mpeg4video.h +++ b/libavcodec/mpeg4video.h @@ -44,24 +44,15 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my); /** * Predict the dc. - * encoding quantized level -> quantized diff - * decoding quantized diff -> quantized level * @param n block index (0-3 are luma, 4-5 are chroma) * @param dir_ptr pointer to an integer where the prediction direction will be stored */ -static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level, - int *dir_ptr, int encoding) +static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int *dir_ptr) { - int a, b, c, wrap, pred, scale, ret; - int16_t *dc_val; + int a, b, c, wrap, pred; + const int16_t *dc_val; /* find prediction */ - if (n < 4) - scale = s->y_dc_scale; - else - scale = s->c_dc_scale; - if (IS_3IV1) - scale = 8; wrap = s->block_wrap[n]; dc_val = s->dc_val[0] + s->block_index[n]; @@ -93,37 +84,7 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level, pred = a; *dir_ptr = 0; /* left */ } - /* we assume pred is positive */ - pred = FASTDIV((pred + (scale >> 1)), scale); - - if (encoding) { - ret = level - pred; - } else { - level += pred; - ret = level; - } - level *= scale; - if (level & (~2047)) { - if (!s->encoding && (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE))) { - if (level < 0) { - av_log(s->avctx, AV_LOG_ERROR, - "dc<0 at %dx%d\n", s->mb_x, s->mb_y); - return AVERROR_INVALIDDATA; - } - if (level > 2048 + scale) { - av_log(s->avctx, AV_LOG_ERROR, - "dc overflow at %dx%d\n", s->mb_x, s->mb_y); - return AVERROR_INVALIDDATA; - } - } - if (level < 0) - level = 0; - else if (!(s->workaround_bugs & FF_BUG_DC_CLIP)) - level = 2047; - } - dc_val[0] = level; - - return ret; + return pred; } #endif /* AVCODEC_MPEG4VIDEO_H */ diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 2a340ea682..31d00dd0b9 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -880,6 +880,43 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n) return sum; } +static inline int mpeg4_get_level_dc(MpegEncContext *s, int n, int pred, int level) +{ + int scale = n < 4 ? s->y_dc_scale : s->c_dc_scale; + int ret; + + if (IS_3IV1) + scale = 8; + + /* we assume pred is positive */ + pred = FASTDIV((pred + (scale >> 1)), scale); + + level += pred; + ret = level; + level *= scale; + if (level & (~2047)) { + if (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) { + if (level < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "dc<0 at %dx%d\n", s->mb_x, s->mb_y); + return AVERROR_INVALIDDATA; + } + if (level > 2048 + scale) { + av_log(s->avctx, AV_LOG_ERROR, + "dc overflow at %dx%d\n", s->mb_x, s->mb_y); + return AVERROR_INVALIDDATA; + } + } + if (level < 0) + level = 0; + else if (!(s->workaround_bugs & FF_BUG_DC_CLIP)) + level = 2047; + } + s->dc_val[0][s->block_index[n]] = level; + + return ret; +} + /** * Decode the dc value. * @param n block index (0-3 are luma, 4-5 are chroma) @@ -888,7 +925,7 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n) */ static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr) { - int level, code; + int level, code, pred; if (n < 4) code = get_vlc2(&s->gb, dc_lum, DC_VLC_BITS, 1); @@ -926,7 +963,8 @@ static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr) } } - return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0); + pred = ff_mpeg4_pred_dc(s, n, dir_ptr); + return mpeg4_get_level_dc(s, n, pred, level); } /** @@ -1290,7 +1328,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, int use_intra_dc_vlc, int rvlc) { MpegEncContext *s = &ctx->m; - int level, i, last, run, qmul, qadd; + int level, i, last, run, qmul, qadd, pred; int av_uninit(dc_pred_dir); const RLTable *rl; const RL_VLC_ELEM *rl_vlc; @@ -1317,7 +1355,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, i = 0; } else { i = -1; - ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0); + pred = ff_mpeg4_pred_dc(s, n, &dc_pred_dir); } if (!coded) goto not_coded; @@ -1540,7 +1578,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, not_coded: if (intra) { if (!use_intra_dc_vlc) { - block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0); + block[0] = mpeg4_get_level_dc(s, n, pred, block[0]); i -= i >> 31; // if (i == -1) i = 0; } diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index 64fb96a0cf..26f9b40ff7 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -806,8 +806,14 @@ void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], const uint8_t *scan_table[6]; int i; - for (i = 0; i < 6; i++) - dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1); + for (int i = 0; i < 6; i++) { + int pred = ff_mpeg4_pred_dc(s, i, &dir[i]); + int scale = i < 4 ? s->y_dc_scale : s->c_dc_scale; + + pred = FASTDIV((pred + (scale >> 1)), scale); + dc_diff[i] = block[i][0] - pred; + s->dc_val[0][s->block_index[i]] = av_clip_uintp2(block[i][0] * scale, 11); + } if (s->avctx->flags & AV_CODEC_FLAG_AC_PRED) { s->ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);