diff options
author | Paul B Mahol <onemda@gmail.com> | 2019-03-07 01:38:26 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2019-03-07 01:41:36 +0100 |
commit | 7b966af930d46494426cd33d7bd8b767e8bfff9e (patch) | |
tree | 9115248d942c4e235e95e5fdafe3a95dd780b31e | |
parent | 53248acfb3b23007c89ae822d7bcae451272d5a7 (diff) | |
download | ffmpeg-7b966af930d46494426cd33d7bd8b767e8bfff9e.tar.gz |
avcodec/imm4: fix artifacts on some files with special coding mode
-rw-r--r-- | libavcodec/imm4.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/libavcodec/imm4.c b/libavcodec/imm4.c index aeb29f5d44..b66689acab 100644 --- a/libavcodec/imm4.c +++ b/libavcodec/imm4.c @@ -138,7 +138,7 @@ static int get_cbphi(GetBitContext *gb, int x) } static int decode_block(AVCodecContext *avctx, GetBitContext *gb, - int block, int factor, int flag, int offset) + int block, int factor, int flag, int offset, int flag2) { IMM4Context *s = avctx->priv_data; const uint8_t *scantable = s->intra_scantable.permutated; @@ -169,11 +169,19 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb, break; } + if (s->hi == 2 && flag2 && block < 4) { + if (flag) + s->block[block][scantable[0]] *= 2; + s->block[block][scantable[1]] *= 2; + s->block[block][scantable[8]] *= 2; + s->block[block][scantable[16]] *= 2; + } + return 0; } static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb, - unsigned cbp, int flag, int offset) + unsigned cbp, int flag, int offset, unsigned flag2) { IMM4Context *s = avctx->priv_data; const uint8_t *scantable = s->intra_scantable.permutated; @@ -193,7 +201,7 @@ static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb, } if (cbp & (1 << (5 - i))) { - ret = decode_block(avctx, gb, i, s->factor, flag, offset); + ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2); if (ret < 0) return ret; } @@ -212,11 +220,7 @@ static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame return AVERROR_INVALIDDATA; s->factor = intra_cb[s->lo]; } else { - if (s->hi == 1) { - s->factor = s->lo * 2; - } else { - s->factor = s->lo * 2; - } + s->factor = s->lo * 2; } if (s->hi) { @@ -228,14 +232,14 @@ static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame for (y = 0; y < avctx->height; y += 16) { for (x = 0; x < avctx->width; x += 16) { - unsigned cbphi, cbplo; + unsigned flag, cbphi, cbplo; cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4; - skip_bits1(gb); + flag = get_bits1(gb); cbphi = get_cbphi(gb, 1); - ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset); + ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag); if (ret < 0) return ret; @@ -268,11 +272,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, return AVERROR_INVALIDDATA; s->factor = inter_cb[s->lo]; } else { - if (s->hi == 1) { - s->factor = s->lo * 2; - } else { - s->factor = s->lo * 2; - } + s->factor = s->lo * 2; } if (s->hi) { @@ -285,7 +285,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, for (y = 0; y < avctx->height; y += 16) { for (x = 0; x < avctx->width; x += 16) { int reverse, intra_block, value; - unsigned cbphi, cbplo; + unsigned cbphi, cbplo, flag2 = 0; if (get_bits1(gb)) { copy_block16(frame->data[0] + y * frame->linesize[0] + x, @@ -307,12 +307,12 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, intra_block = value & 0x07; reverse = intra_block == 3; if (reverse) - skip_bits1(gb); + flag2 = get_bits1(gb); cbplo = value >> 4; cbphi = get_cbphi(gb, reverse); if (intra_block) { - ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset); + ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2); if (ret < 0) return ret; @@ -329,8 +329,9 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1), frame->linesize[2], s->block[5]); } else { - skip_bits(gb, 2); - ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset); + flag2 = get_bits1(gb); + skip_bits1(gb); + ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2); if (ret < 0) return ret; |