X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvc1_block.c;h=86320db959a36b08935e33c3459e19f2b8d9999c;hb=6f9d7c556d5f466c604fe76723950b834c5d1af4;hp=21ab1081697696184aa5ff9aafeaffda292bd82a;hpb=c0402e1e30c2318359af1bce1d652f4616b21566;p=ffmpeg diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 21ab1081697..86320db959a 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -45,6 +45,9 @@ static const uint8_t offset_table[2][9] = { { 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 @@ -66,7 +69,7 @@ static inline void init_block_index(VC1Context *v) /** @} */ //Bitplane group -static void vc1_put_signed_blocks_clamped(VC1Context *v) +static void vc1_put_blocks_clamped(VC1Context *v, int put_signed) { MpegEncContext *s = &v->s; uint8_t *dest; @@ -85,20 +88,30 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) if (i > 3 ? v->mb_type[0][s->block_index[i] - s->block_wrap[i] - 1] : 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; - s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, - i > 3 ? s->uvlinesize : s->linesize); + if (put_signed) + 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->uvlinesize : s->linesize); + else + 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->uvlinesize : s->linesize); } } } - if (s->mb_x == s->mb_width - 1) { + if (s->mb_x == v->end_mb_x - 1) { for (i = 0; i < block_count; i++) { if (i > 3 ? v->mb_type[0][s->block_index[i] - 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; - s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, - i > 3 ? s->uvlinesize : s->linesize); + if (put_signed) + 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->uvlinesize : s->linesize); + else + 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->uvlinesize : s->linesize); } } } @@ -114,13 +127,18 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) dest = s->dest[0] + ((i & 2) >> 1) * s->linesize + ((i & 1) - 2) * 8; else dest = s->dest[0] + (i & 2) * 4 * s->linesize + ((i & 1) - 2) * 8; - s->idsp.put_signed_pixels_clamped(v->block[v->left_blk_idx][i], - i > 3 ? s->dest[i - 3] - 8 : dest, - i > 3 ? s->uvlinesize : s->linesize << fieldtx); + if (put_signed) + 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->uvlinesize : s->linesize << fieldtx); + else + 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->uvlinesize : s->linesize << fieldtx); } } } - if (s->mb_x == s->mb_width - 1) { + if (s->mb_x == v->end_mb_x - 1) { if (v->fcm == ILACE_FRAME) fieldtx = v->fieldtx_plane[s->mb_y * s->mb_stride + s->mb_x]; for (i = 0; i < block_count; i++) { @@ -129,9 +147,14 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) dest = s->dest[0] + ((i & 2) >> 1) * s->linesize + (i & 1) * 8; else dest = s->dest[0] + (i & 2) * 4 * s->linesize + (i & 1) * 8; - s->idsp.put_signed_pixels_clamped(v->block[v->cur_blk_idx][i], - i > 3 ? s->dest[i - 3] : dest, - i > 3 ? s->uvlinesize : s->linesize << fieldtx); + if (put_signed) + 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->uvlinesize : s->linesize << fieldtx); + else + s->idsp.put_pixels_clamped(v->block[v->cur_blk_idx][block_map[i]], + i > 3 ? s->dest[i - 3] : dest, + i > 3 ? s->uvlinesize : s->linesize << fieldtx); } } } @@ -184,7 +207,7 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v) if ((edges&8) && \ s->mb_y == ((s->mb_height >> v->field_mode) - 1)) \ mquant = -v->altpq; \ - if (!mquant || mquant > 31) { \ + if (!mquant || mquant > 31 || mquant < -31) { \ av_log(v->s.avctx, AV_LOG_ERROR, \ "Overriding invalid mquant %d\n", mquant); \ mquant = 1; \ @@ -1328,18 +1351,18 @@ static int vc1_decode_p_mb(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) 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); if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) 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) 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_intra |= 1 << i; } 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, CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), &block_tt); block_cbp |= pat << (i << 2); @@ -1429,18 +1452,18 @@ static int vc1_decode_p_mb(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) 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); if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) 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) 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_intra |= 1 << 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, (i & 4) ? s->uvlinesize : s->linesize, CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), @@ -1469,7 +1492,7 @@ static int vc1_decode_p_mb(VC1Context *v) end: if (v->overlap && v->pq >= 9) ff_vc1_p_overlap_filter(v); - vc1_put_signed_blocks_clamped(v); + vc1_put_blocks_clamped(v, 1); v->cbp[s->mb_x] = block_cbp; v->ttblk[s->mb_x] = block_tt; @@ -1571,11 +1594,11 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) 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); if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) 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) off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize; else @@ -1651,7 +1674,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) else off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize)); 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, (i & 4) ? s->uvlinesize : (s->linesize << fieldtx), CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), &block_tt); @@ -1680,7 +1703,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) } if (v->overlap && v->pq >= 9) ff_vc1_p_overlap_filter(v); - vc1_put_signed_blocks_clamped(v); + vc1_put_blocks_clamped(v, 1); v->cbp[s->mb_x] = block_cbp; v->ttblk[s->mb_x] = block_tt; @@ -1737,11 +1760,11 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) 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); if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) 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); block_cbp |= 0xf << (i << 2); } @@ -1786,7 +1809,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; 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, (i & 4) ? s->uvlinesize : s->linesize, CONFIG_GRAY && (i & 4) && (s->avctx->flags & AV_CODEC_FLAG_GRAY), @@ -1800,7 +1823,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) } if (v->overlap && v->pq >= 9) ff_vc1_p_overlap_filter(v); - vc1_put_signed_blocks_clamped(v); + vc1_put_blocks_clamped(v, 1); v->cbp[s->mb_x] = block_cbp; v->ttblk[s->mb_x] = block_tt; @@ -2517,30 +2540,27 @@ static void vc1_decode_i_blocks(VC1Context *v) s->mb_x = s->mb_y = 0; s->mb_intra = 1; s->first_slice_line = 1; - for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) { + for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { s->mb_x = 0; init_block_index(v); for (; s->mb_x < v->end_mb_x; s->mb_x++) { - uint8_t *dst[6]; ff_update_block_index(s); - dst[0] = s->dest[0]; - dst[1] = dst[0] + 8; - dst[2] = s->dest[0] + s->linesize * 8; - dst[3] = dst[2] + 8; - dst[4] = s->dest[1]; - dst[5] = s->dest[2]; - s->bdsp.clear_blocks(s->block[0]); + s->bdsp.clear_blocks(v->block[v->cur_blk_idx][0]); mb_pos = s->mb_x + s->mb_y * s->mb_width; s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; s->current_picture.qscale_table[mb_pos] = v->pq; - s->current_picture.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.motion_val[1][s->block_index[0]][1] = 0; + for (int i = 0; i < 4; i++) { + s->current_picture.motion_val[1][s->block_index[i]][0] = 0; + s->current_picture.motion_val[1][s->block_index[i]][1] = 0; + } // do actual MB decoding and displaying cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); v->s.ac_pred = get_bits1(&v->s.gb); for (k = 0; k < 6; k++) { + v->mb_type[0][s->block_index[k]] = 1; + val = ((cbp >> (5 - k)) & 1); if (k < 4) { @@ -2550,52 +2570,30 @@ static void vc1_decode_i_blocks(VC1Context *v) } cbp |= val << (5 - k); - vc1_decode_i_block(v, s->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)) continue; - v->vc1dsp.vc1_inv_trans_8x8(s->block[k]); - if (v->pq >= 9 && v->overlap) { - if (v->rangeredfrm) + v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[k]]); + } + + if (v->overlap && v->pq >= 9) { + ff_vc1_i_overlap_filter(v); + if (v->rangeredfrm) + for (k = 0; k < 6; k++) for (j = 0; j < 64; j++) - s->block[k][j] <<= 1; - s->idsp.put_signed_pixels_clamped(s->block[k], dst[k], - k & 4 ? s->uvlinesize - : s->linesize); - } else { - if (v->rangeredfrm) + v->block[v->cur_blk_idx][block_map[k]][j] <<= 1; + vc1_put_blocks_clamped(v, 1); + } else { + if (v->rangeredfrm) + for (k = 0; k < 6; k++) for (j = 0; j < 64; j++) - s->block[k][j] = (s->block[k][j] - 64) << 1; - s->idsp.put_pixels_clamped(s->block[k], dst[k], - k & 4 ? s->uvlinesize - : s->linesize); - } + 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); } - if (v->pq >= 9 && v->overlap) { - if (s->mb_x) { - v->vc1dsp.vc1_h_overlap(s->dest[0], s->linesize); - v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize); - if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { - v->vc1dsp.vc1_h_overlap(s->dest[1], s->uvlinesize); - v->vc1dsp.vc1_h_overlap(s->dest[2], s->uvlinesize); - } - } - v->vc1dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize); - v->vc1dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize); - if (!s->first_slice_line) { - v->vc1dsp.vc1_v_overlap(s->dest[0], s->linesize); - v->vc1dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize); - if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { - v->vc1dsp.vc1_v_overlap(s->dest[1], s->uvlinesize); - v->vc1dsp.vc1_v_overlap(s->dest[2], s->uvlinesize); - } - } - v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize); - v->vc1dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize); - } if (v->s.loop_filter) - ff_vc1_loop_filter_iblk(v, v->pq); + ff_vc1_i_loop_filter(v); if (get_bits_count(&s->gb) > v->bits) { ff_er_add_slice(&s->er, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR); @@ -2603,6 +2601,11 @@ static void vc1_decode_i_blocks(VC1Context *v) get_bits_count(&s->gb), v->bits); return; } + + v->topleft_blk_idx = (v->topleft_blk_idx + 1) % (v->end_mb_x + 2); + v->top_blk_idx = (v->top_blk_idx + 1) % (v->end_mb_x + 2); + v->left_blk_idx = (v->left_blk_idx + 1) % (v->end_mb_x + 2); + v->cur_blk_idx = (v->cur_blk_idx + 1) % (v->end_mb_x + 2); } if (!v->s.loop_filter) ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16); @@ -2672,14 +2675,15 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->mb_x = 0; init_block_index(v); for (;s->mb_x < s->mb_width; s->mb_x++) { - int16_t (*block)[64] = v->block[v->cur_blk_idx]; mquant = v->pq; 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; s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA; - s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; - s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; + for (int i = 0; i < 4; i++) { + s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = 0; + s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = 0; + } // do actual MB decoding and displaying if (v->fieldtx_is_raw) @@ -2715,17 +2719,17 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) v->a_avail = !s->first_slice_line || (k == 2 || 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); if (CONFIG_GRAY && k > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) 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->condover != CONDOVER_NONE) + if (v->overlap && (v->pq >= 9 || v->condover != CONDOVER_NONE)) ff_vc1_i_overlap_filter(v); - vc1_put_signed_blocks_clamped(v); + vc1_put_blocks_clamped(v, 1); if (v->s.loop_filter) ff_vc1_i_loop_filter(v);