avcodec/vc1: change the internal ordering of blocks within a macroblock

The overlap filter needs to cover a full macroblock vertical edge when the
FIELDTX value for two neighbouring macroblocks is not equal. By changing
the internal ordering of the blocks from row major to column major, we do
not need to reinterlace a FIELDTX coded macroblock before running the overlap
filter.

Signed-off-by: Jerome Borsboom <jerome.borsboom@carpalis.nl>
This commit is contained in:
Jerome Borsboom 2018-06-20 13:11:03 +02:00 committed by Carl Eugen Hoyos
parent 1cf6129d13
commit f92e95e9b5
1 changed files with 33 additions and 32 deletions

View File

@ -45,6 +45,9 @@ static const uint8_t offset_table[2][9] = {
{ 0, 1, 3, 7, 15, 31, 63, 127, 255 }, { 0, 1, 3, 7, 15, 31, 63, 127, 255 },
}; };
// mapping table for internal block representation
static const int block_map[6] = {0, 2, 1, 3, 4, 5};
/***********************************************************************/ /***********************************************************************/
/** /**
* @name VC-1 Bitplane decoding * @name VC-1 Bitplane decoding
@ -86,11 +89,11 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed)
v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i] - 2]) { v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i] - 2]) {
dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + ((i & 1) - 2) * 8; dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + ((i & 1) - 2) * 8;
if (put_signed) if (put_signed)
s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][i], s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][block_map[i]],
i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
i > 3 ? s->uvlinesize : s->linesize); i > 3 ? s->uvlinesize : s->linesize);
else else
s->idsp.put_pixels_clamped(v->block[v->topleft_blk_idx][i], s->idsp.put_pixels_clamped(v->block[v->topleft_blk_idx][block_map[i]],
i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
i > 3 ? s->uvlinesize : s->linesize); i > 3 ? s->uvlinesize : s->linesize);
} }
@ -102,11 +105,11 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed)
v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i]]) { v->mb_type[0][s->block_index[i] - 2 * s->block_wrap[i]]) {
dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + (i & 1) * 8; dest = s->dest[0] + ((i & 2) - 4) * 4 * s->linesize + (i & 1) * 8;
if (put_signed) if (put_signed)
s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][i], s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][block_map[i]],
i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
i > 3 ? s->uvlinesize : s->linesize); i > 3 ? s->uvlinesize : s->linesize);
else else
s->idsp.put_pixels_clamped(v->block[v->top_blk_idx][i], s->idsp.put_pixels_clamped(v->block[v->top_blk_idx][block_map[i]],
i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
i > 3 ? s->uvlinesize : s->linesize); i > 3 ? s->uvlinesize : s->linesize);
} }
@ -125,11 +128,11 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed)
else else
dest = s->dest[0] + (i & 2) * 4 * s->linesize + ((i & 1) - 2) * 8; dest = s->dest[0] + (i & 2) * 4 * s->linesize + ((i & 1) - 2) * 8;
if (put_signed) if (put_signed)
s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][i], s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][block_map[i]],
i > 3 ? s->dest[i - 3] - 8 : dest, i > 3 ? s->dest[i - 3] - 8 : dest,
i > 3 ? s->uvlinesize : s->linesize << fieldtx); i > 3 ? s->uvlinesize : s->linesize << fieldtx);
else else
s->idsp.put_pixels_clamped(v->block[v->left_blk_idx][i], s->idsp.put_pixels_clamped(v->block[v->left_blk_idx][block_map[i]],
i > 3 ? s->dest[i - 3] - 8 : dest, i > 3 ? s->dest[i - 3] - 8 : dest,
i > 3 ? s->uvlinesize : s->linesize << fieldtx); i > 3 ? s->uvlinesize : s->linesize << fieldtx);
} }
@ -145,11 +148,11 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed)
else else
dest = s->dest[0] + (i & 2) * 4 * s->linesize + (i & 1) * 8; dest = s->dest[0] + (i & 2) * 4 * s->linesize + (i & 1) * 8;
if (put_signed) if (put_signed)
s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i], s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][block_map[i]],
i > 3 ? s->dest[i - 3] : dest, i > 3 ? s->dest[i - 3] : dest,
i > 3 ? s->uvlinesize : s->linesize << fieldtx); i > 3 ? s->uvlinesize : s->linesize << fieldtx);
else else
s->idsp.put_pixels_clamped(v->block[v->cur_blk_idx][i], s->idsp.put_pixels_clamped(v->block[v->cur_blk_idx][block_map[i]],
i > 3 ? s->dest[i - 3] : dest, i > 3 ? s->dest[i - 3] : dest,
i > 3 ? s->uvlinesize : s->linesize << fieldtx); i > 3 ? s->uvlinesize : s->linesize << fieldtx);
} }
@ -1348,18 +1351,18 @@ static int vc1_decode_p_mb(VC1Context *v)
if (i == 1 || i == 3 || s->mb_x) if (i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1]; v->c_avail = v->mb_type[0][s->block_index[i] - 1];
vc1_decode_intra_block(v, v->block[v->cur_blk_idx][i], i, val, mquant, vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant,
(i & 4) ? v->codingset2 : v->codingset); (i & 4) ? v->codingset2 : v->codingset);
if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
continue; continue;
v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]); v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[i]]);
if (v->rangeredfrm) if (v->rangeredfrm)
for (j = 0; j < 64; j++) for (j = 0; j < 64; j++)
v->block[v->cur_blk_idx][i][j] <<= 1; v->block[v->cur_blk_idx][block_map[i]][j] <<= 1;
block_cbp |= 0xF << (i << 2); block_cbp |= 0xF << (i << 2);
block_intra |= 1 << i; block_intra |= 1 << i;
} else if (val) { } else if (val) {
pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][i], i, mquant, ttmb, first_block, pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][block_map[i]], i, mquant, ttmb, first_block,
s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize, s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize,
CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), &block_tt); CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), &block_tt);
block_cbp |= pat << (i << 2); block_cbp |= pat << (i << 2);
@ -1449,18 +1452,18 @@ static int vc1_decode_p_mb(VC1Context *v)
if (i == 1 || i == 3 || s->mb_x) if (i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1]; v->c_avail = v->mb_type[0][s->block_index[i] - 1];
vc1_decode_intra_block(v, v->block[v->cur_blk_idx][i], i, is_coded[i], mquant, vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, is_coded[i], mquant,
(i & 4) ? v->codingset2 : v->codingset); (i & 4) ? v->codingset2 : v->codingset);
if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
continue; continue;
v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]); v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[i]]);
if (v->rangeredfrm) if (v->rangeredfrm)
for (j = 0; j < 64; j++) for (j = 0; j < 64; j++)
v->block[v->cur_blk_idx][i][j] <<= 1; v->block[v->cur_blk_idx][block_map[i]][j] <<= 1;
block_cbp |= 0xF << (i << 2); block_cbp |= 0xF << (i << 2);
block_intra |= 1 << i; block_intra |= 1 << i;
} else if (is_coded[i]) { } else if (is_coded[i]) {
pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][i], i, mquant, ttmb, pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][block_map[i]], i, mquant, ttmb,
first_block, s->dest[dst_idx] + off, first_block, s->dest[dst_idx] + off,
(i & 4) ? s->uvlinesize : s->linesize, (i & 4) ? s->uvlinesize : s->linesize,
CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY),
@ -1591,11 +1594,11 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
if (i == 1 || i == 3 || s->mb_x) if (i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1]; v->c_avail = v->mb_type[0][s->block_index[i] - 1];
vc1_decode_intra_block(v, v->block[v->cur_blk_idx][i], i, val, mquant, vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant,
(i & 4) ? v->codingset2 : v->codingset); (i & 4) ? v->codingset2 : v->codingset);
if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
continue; continue;
v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]); v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[i]]);
if (i < 4) if (i < 4)
off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize; off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
else else
@ -1671,7 +1674,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
else else
off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize)); off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
if (val) { if (val) {
pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][i], i, mquant, ttmb, pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][block_map[i]], i, mquant, ttmb,
first_block, s->dest[dst_idx] + off, first_block, s->dest[dst_idx] + off,
(i & 4) ? s->uvlinesize : (s->linesize << fieldtx), (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), &block_tt); CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), &block_tt);
@ -1757,11 +1760,11 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
if (i == 1 || i == 3 || s->mb_x) if (i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1]; v->c_avail = v->mb_type[0][s->block_index[i] - 1];
vc1_decode_intra_block(v, v->block[v->cur_blk_idx][i], i, val, mquant, vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant,
(i & 4) ? v->codingset2 : v->codingset); (i & 4) ? v->codingset2 : v->codingset);
if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
continue; continue;
v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][i]); v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[i]]);
off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
block_cbp |= 0xf << (i << 2); block_cbp |= 0xf << (i << 2);
} }
@ -1806,7 +1809,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
val = ((cbp >> (5 - i)) & 1); val = ((cbp >> (5 - i)) & 1);
off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
if (val) { if (val) {
pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][i], i, mquant, ttmb, pat = vc1_decode_p_block(v, v->block[v->cur_blk_idx][block_map[i]], i, mquant, ttmb,
first_block, s->dest[dst_idx] + off, first_block, s->dest[dst_idx] + off,
(i & 4) ? s->uvlinesize : s->linesize, (i & 4) ? s->uvlinesize : s->linesize,
CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY),
@ -2541,9 +2544,8 @@ static void vc1_decode_i_blocks(VC1Context *v)
s->mb_x = 0; s->mb_x = 0;
init_block_index(v); init_block_index(v);
for (; s->mb_x < v->end_mb_x; s->mb_x++) { for (; s->mb_x < v->end_mb_x; s->mb_x++) {
int16_t (*block)[64] = v->block[v->cur_blk_idx];
ff_update_block_index(s); ff_update_block_index(s);
s->bdsp.clear_blocks(block[0]); s->bdsp.clear_blocks(v->block[v->cur_blk_idx][0]);
mb_pos = s->mb_x + s->mb_y * s->mb_width; mb_pos = s->mb_x + s->mb_y * s->mb_width;
s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
s->current_picture.qscale_table[mb_pos] = v->pq; s->current_picture.qscale_table[mb_pos] = v->pq;
@ -2568,11 +2570,11 @@ static void vc1_decode_i_blocks(VC1Context *v)
} }
cbp |= val << (5 - k); cbp |= val << (5 - k);
vc1_decode_i_block(v, block[k], k, val, (k < 4) ? v->codingset : v->codingset2); vc1_decode_i_block(v, v->block[v->cur_blk_idx][block_map[k]], k, val, (k < 4) ? v->codingset : v->codingset2);
if (CONFIG_GRAY && k > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) if (CONFIG_GRAY && k > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
continue; continue;
v->vc1dsp.vc1_inv_trans_8x8(block[k]); v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[k]]);
} }
if (v->overlap && v->pq >= 9) { if (v->overlap && v->pq >= 9) {
@ -2580,13 +2582,13 @@ static void vc1_decode_i_blocks(VC1Context *v)
if (v->rangeredfrm) if (v->rangeredfrm)
for (k = 0; k < 6; k++) for (k = 0; k < 6; k++)
for (j = 0; j < 64; j++) for (j = 0; j < 64; j++)
block[k][j] <<= 1; v->block[v->cur_blk_idx][block_map[k]][j] <<= 1;
vc1_put_blocks_clamped(v, 1); vc1_put_blocks_clamped(v, 1);
} else { } else {
if (v->rangeredfrm) if (v->rangeredfrm)
for (k = 0; k < 6; k++) for (k = 0; k < 6; k++)
for (j = 0; j < 64; j++) for (j = 0; j < 64; j++)
block[k][j] = (block[k][j] - 64) << 1; v->block[v->cur_blk_idx][block_map[k]][j] = (v->block[v->cur_blk_idx][block_map[k]][j] - 64) << 1;
vc1_put_blocks_clamped(v, 0); vc1_put_blocks_clamped(v, 0);
} }
@ -2673,10 +2675,9 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
s->mb_x = 0; s->mb_x = 0;
init_block_index(v); init_block_index(v);
for (;s->mb_x < s->mb_width; s->mb_x++) { for (;s->mb_x < s->mb_width; s->mb_x++) {
int16_t (*block)[64] = v->block[v->cur_blk_idx];
mquant = v->pq; mquant = v->pq;
ff_update_block_index(s); ff_update_block_index(s);
s->bdsp.clear_blocks(block[0]); s->bdsp.clear_blocks(v->block[v->cur_blk_idx][0]);
mb_pos = s->mb_x + s->mb_y * s->mb_stride; mb_pos = s->mb_x + s->mb_y * s->mb_stride;
s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
@ -2718,12 +2719,12 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
v->a_avail = !s->first_slice_line || (k == 2 || k == 3); v->a_avail = !s->first_slice_line || (k == 2 || k == 3);
v->c_avail = !!s->mb_x || (k == 1 || k == 3); v->c_avail = !!s->mb_x || (k == 1 || k == 3);
vc1_decode_i_block_adv(v, block[k], k, val, vc1_decode_i_block_adv(v, v->block[v->cur_blk_idx][block_map[k]], k, val,
(k < 4) ? v->codingset : v->codingset2, mquant); (k < 4) ? v->codingset : v->codingset2, mquant);
if (CONFIG_GRAY && k > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) if (CONFIG_GRAY && k > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
continue; continue;
v->vc1dsp.vc1_inv_trans_8x8(block[k]); v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[k]]);
} }
if (v->overlap && (v->pq >= 9 || v->condover != CONDOVER_NONE)) if (v->overlap && (v->pq >= 9 || v->condover != CONDOVER_NONE))