---
libavcodec/Makefile | 3 +-
libavcodec/vc1.h | 5 +
libavcodec/vc1_block.c | 338 ++---------------------------------------
libavcodec/vc1_loopfilter.c | 363 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 380 insertions(+), 329 deletions(-)
create mode 100644 libavcodec/vc1_loopfilter.c
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 6aaf621..cda2426 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -390,7 +390,8 @@ OBJS-$(CONFIG_V410_ENCODER) += v410enc.o
OBJS-$(CONFIG_V210X_DECODER) += v210x.o
OBJS-$(CONFIG_VB_DECODER) += vb.o
OBJS-$(CONFIG_VBLE_DECODER) += vble.o
-OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1.o vc1data.o
vc1dsp.o \
+OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o
vc1_loopfilter.o \
+ vc1.o vc1data.o vc1dsp.o \
msmpeg4dec.o msmpeg4.o msmpeg4data.o
OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o
OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index 780344a..b26632d 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -400,4 +400,9 @@ void ff_vc1_init_transposed_scantables(VC1Context *v);
int ff_vc1_decode_end(AVCodecContext *avctx);
void ff_vc1_decode_blocks(VC1Context *v);
+void ff_vc1_loop_filter_iblk(VC1Context *v, int pq);
+void ff_vc1_loop_filter_iblk_delayed(VC1Context *v, int pq);
+void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v);
+void ff_vc1_apply_p_loop_filter(VC1Context *v);
+
#endif /* AVCODEC_VC1_H */
diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 28bc2e9..8b3ee21 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -167,178 +167,6 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v)
inc_blk_idx(v->cur_blk_idx);
}
-static void vc1_loop_filter_iblk(VC1Context *v, int pq)
-{
- MpegEncContext *s = &v->s;
- int j;
- if (!s->first_slice_line) {
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq);
- if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize,
s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8,
s->linesize, pq);
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1], s->uvlinesize, pq);
- if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize, s->uvlinesize, pq);
- }
- }
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8 * s->linesize, s->linesize,
pq);
-
- if (s->mb_y == s->end_mb_y - 1) {
- if (s->mb_x) {
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq);
- v->vc1dsp.vc1_h_loop_filter8(s->dest[2], s->uvlinesize, pq);
- }
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] + 8, s->linesize, pq);
- }
-}
-
-static void vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
-{
- MpegEncContext *s = &v->s;
- int j;
-
- /* The loopfilter runs 1 row and 1 column behind the overlap filter, which
- * means it runs two rows/cols behind the decoding loop. */
- if (!s->first_slice_line) {
- if (s->mb_x) {
- if (s->mb_y >= s->start_mb_y + 2) {
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize -
16, s->linesize, pq);
-
- if (s->mb_x >= 2)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 *
s->linesize - 16, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize -
8, s->linesize, pq);
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize - 8, s->uvlinesize, pq);
- if (s->mb_x >= 2) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 *
s->uvlinesize - 8, s->uvlinesize, pq);
- }
- }
- }
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize - 16,
s->linesize, pq);
- }
-
- if (s->mb_x == s->mb_width - 1) {
- if (s->mb_y >= s->start_mb_y + 2) {
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize,
s->linesize, pq);
-
- if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 *
s->linesize, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize +
8, s->linesize, pq);
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize, s->uvlinesize, pq);
- if (s->mb_x >= 2) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 *
s->uvlinesize, s->uvlinesize, pq);
- }
- }
- }
- v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize,
s->linesize, pq);
- }
-
- if (s->mb_y == s->end_mb_y) {
- if (s->mb_x) {
- if (s->mb_x >= 2)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 *
s->linesize - 16, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize -
8, s->linesize, pq);
- if (s->mb_x >= 2) {
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize - 8, s->uvlinesize, pq);
- }
- }
- }
-
- if (s->mb_x == s->mb_width - 1) {
- if (s->mb_x)
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 *
s->linesize, s->linesize, pq);
- v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize +
8, s->linesize, pq);
- if (s->mb_x) {
- for (j = 0; j < 2; j++) {
- v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize, s->uvlinesize, pq);
- }
- }
- }
- }
- }
-}
-
-static void vc1_smooth_overlap_filter_iblk(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- int mb_pos;
-
- if (v->condover == CONDOVER_NONE)
- return;
-
- mb_pos = s->mb_x + s->mb_y * s->mb_stride;
-
- /* Within a MB, the horizontal overlap always runs before the vertical.
- * To accomplish that, we run the H on left and internal borders of the
- * currently decoded MB. Then, we wait for the next overlap iteration
- * to do H overlap on the right edge of this MB, before moving over and
- * running the V overlap. Therefore, the V overlap makes us trail by one
- * MB col and the H overlap filter makes us trail by one MB row. This
- * is reflected in the time at which we run the put_pixels loop. */
- if (v->condover == CONDOVER_ALL || v->pq >= 9 ||
v->over_flags_plane[mb_pos]) {
- if (s->mb_x && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
- v->over_flags_plane[mb_pos - 1])) {
- v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][1],
- v->block[v->cur_blk_idx][0]);
- v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][3],
- v->block[v->cur_blk_idx][2]);
- if (!(s->flags & CODEC_FLAG_GRAY)) {
- v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][4],
- v->block[v->cur_blk_idx][4]);
- v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][5],
- v->block[v->cur_blk_idx][5]);
- }
- }
- v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][0],
- v->block[v->cur_blk_idx][1]);
- v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][2],
- v->block[v->cur_blk_idx][3]);
-
- if (s->mb_x == s->mb_width - 1) {
- if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq
>= 9 ||
- v->over_flags_plane[mb_pos -
s->mb_stride])) {
- v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][2],
- v->block[v->cur_blk_idx][0]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][3],
- v->block[v->cur_blk_idx][1]);
- if (!(s->flags & CODEC_FLAG_GRAY)) {
- v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][4],
- v->block[v->cur_blk_idx][4]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][5],
- v->block[v->cur_blk_idx][5]);
- }
- }
- v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][0],
- v->block[v->cur_blk_idx][2]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][1],
- v->block[v->cur_blk_idx][3]);
- }
- }
- if (s->mb_x && (v->condover == CONDOVER_ALL || v->over_flags_plane[mb_pos
- 1])) {
- if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9
||
- v->over_flags_plane[mb_pos - s->mb_stride
- 1])) {
- v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][2],
- v->block[v->left_blk_idx][0]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][3],
- v->block[v->left_blk_idx][1]);
- if (!(s->flags & CODEC_FLAG_GRAY)) {
- v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][4],
- v->block[v->left_blk_idx][4]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][5],
- v->block[v->left_blk_idx][5]);
- }
- }
- v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][0],
- v->block[v->left_blk_idx][2]);
- v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][1],
- v->block[v->left_blk_idx][3]);
- }
-}
-
/** Do motion compensation over 1 macroblock
* Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
*/
@@ -3376,155 +3204,6 @@ static int vc1_decode_p_block(VC1Context *v, int16_t
block[64], int n,
static const int size_table [6] = { 0, 2, 3, 4, 5, 8 };
static const int offset_table[6] = { 0, 1, 3, 7, 15, 31 };
-static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int
block_num)
-{
- MpegEncContext *s = &v->s;
- int mb_cbp = v->cbp[s->mb_x - s->mb_stride],
- block_cbp = mb_cbp >> (block_num * 4), bottom_cbp,
- mb_is_intra = v->is_intra[s->mb_x - s->mb_stride],
- block_is_intra = mb_is_intra >> (block_num * 4), bottom_is_intra;
- int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
- uint8_t *dst;
-
- if (block_num > 3) {
- dst = s->dest[block_num - 3];
- } else {
- dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 -
8) * linesize;
- }
- if (s->mb_y != s->end_mb_y || block_num < 2) {
- int16_t (*mv)[2];
- int mv_stride;
-
- if (block_num > 3) {
- bottom_cbp = v->cbp[s->mb_x] >> (block_num * 4);
- bottom_is_intra = v->is_intra[s->mb_x] >> (block_num * 4);
- mv = &v->luma_mv[s->mb_x - s->mb_stride];
- mv_stride = s->mb_stride;
- } else {
- bottom_cbp = (block_num < 2) ? (mb_cbp >>
((block_num + 2) * 4))
- : (v->cbp[s->mb_x] >>
((block_num - 2) * 4));
- bottom_is_intra = (block_num < 2) ? (mb_is_intra >>
((block_num + 2) * 4))
- : (v->is_intra[s->mb_x] >>
((block_num - 2) * 4));
- mv_stride = s->b8_stride;
- mv =
&s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
- }
-
- if (bottom_is_intra & 1 || block_is_intra & 1 ||
- mv[0][0] != mv[mv_stride][0] || mv[0][1] != mv[mv_stride][1]) {
- v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
- } else {
- idx = ((bottom_cbp >> 2) | block_cbp) & 3;
- if (idx == 3) {
- v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
- } else if (idx) {
- if (idx == 1)
- v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
- else
- v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq);
- }
- }
- }
-
- dst -= 4 * linesize;
- ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xF;
- if (ttblk == TT_4X4 || ttblk == TT_8X4) {
- idx = (block_cbp | (block_cbp >> 2)) & 3;
- if (idx == 3) {
- v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
- } else if (idx) {
- if (idx == 1)
- v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
- else
- v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq);
- }
- }
-}
-
-static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int
block_num)
-{
- MpegEncContext *s = &v->s;
- int mb_cbp = v->cbp[s->mb_x - 1 - s->mb_stride],
- block_cbp = mb_cbp >> (block_num * 4), right_cbp,
- mb_is_intra = v->is_intra[s->mb_x - 1 - s->mb_stride],
- block_is_intra = mb_is_intra >> (block_num * 4), right_is_intra;
- int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
- uint8_t *dst;
-
- if (block_num > 3) {
- dst = s->dest[block_num - 3] - 8 * linesize;
- } else {
- dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 16) *
linesize - 8;
- }
-
- if (s->mb_x != s->mb_width || !(block_num & 5)) {
- int16_t (*mv)[2];
-
- if (block_num > 3) {
- right_cbp = v->cbp[s->mb_x - s->mb_stride] >> (block_num * 4);
- right_is_intra = v->is_intra[s->mb_x - s->mb_stride] >> (block_num
* 4);
- mv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
- } else {
- right_cbp = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride]
>> ((block_num - 1) * 4))
- : (mb_cbp
>> ((block_num + 1) * 4));
- right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x -
s->mb_stride] >> ((block_num - 1) * 4))
- : (mb_is_intra
>> ((block_num + 1) * 4));
- mv =
&s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2
- 2];
- }
- if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0]
|| mv[0][1] != mv[1][1]) {
- v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
- } else {
- idx = ((right_cbp >> 1) | block_cbp) & 5; // FIXME check
- if (idx == 5) {
- v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
- } else if (idx) {
- if (idx == 1)
- v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize, linesize,
v->pq);
- else
- v->vc1dsp.vc1_h_loop_filter4(dst, linesize,
v->pq);
- }
- }
- }
-
- dst -= 4;
- ttblk = (v->ttblk[s->mb_x - s->mb_stride - 1] >> (block_num * 4)) & 0xf;
- if (ttblk == TT_4X4 || ttblk == TT_4X8) {
- idx = (block_cbp | (block_cbp >> 1)) & 5;
- if (idx == 5) {
- v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
- } else if (idx) {
- if (idx == 1)
- v->vc1dsp.vc1_h_loop_filter4(dst + linesize * 4, linesize,
v->pq);
- else
- v->vc1dsp.vc1_h_loop_filter4(dst, linesize,
v->pq);
- }
- }
-}
-
-static void vc1_apply_p_loop_filter(VC1Context *v)
-{
- MpegEncContext *s = &v->s;
- int i;
-
- for (i = 0; i < 6; i++) {
- vc1_apply_p_v_loop_filter(v, i);
- }
-
- /* V always precedes H, therefore we run H one MB before V;
- * at the end of a row, we catch up to complete the row */
- if (s->mb_x) {
- for (i = 0; i < 6; i++) {
- vc1_apply_p_h_loop_filter(v, i);
- }
- if (s->mb_x == s->mb_width - 1) {
- s->mb_x++;
- ff_update_block_index(s);
- for (i = 0; i < 6; i++) {
- vc1_apply_p_h_loop_filter(v, i);
- }
- }
- }
-}
-
/** Decode one P-frame MB
*/
static int vc1_decode_p_mb(VC1Context *v)
@@ -4881,7 +4560,8 @@ static void vc1_decode_i_blocks(VC1Context *v)
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) vc1_loop_filter_iblk(v, v->pq);
+ if (v->s.loop_filter)
+ ff_vc1_loop_filter_iblk(v, v->pq);
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);
@@ -5006,9 +4686,10 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
v->vc1dsp.vc1_inv_trans_8x8(block[k]);
}
- vc1_smooth_overlap_filter_iblk(v);
+ ff_vc1_smooth_overlap_filter_iblk(v);
vc1_put_signed_blocks_clamped(v);
- if (v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq);
+ if (v->s.loop_filter)
+ ff_vc1_loop_filter_iblk_delayed(v, v->pq);
if (get_bits_count(&s->gb) > v->bits) {
// TODO: may need modification to handle slice coding
@@ -5033,7 +4714,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
ff_update_block_index(s);
vc1_put_signed_blocks_clamped(v);
if (v->s.loop_filter)
- vc1_loop_filter_iblk_delayed(v, v->pq);
+ ff_vc1_loop_filter_iblk_delayed(v, v->pq);
}
if (v->s.loop_filter)
ff_mpeg_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
@@ -5087,7 +4768,7 @@ static void vc1_decode_p_blocks(VC1Context *v)
vc1_decode_p_mb_intfr(v);
else vc1_decode_p_mb(v);
if (s->mb_y != s->start_mb_y && apply_loop_filter)
- vc1_apply_p_loop_filter(v);
+ ff_vc1_apply_p_loop_filter(v);
if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) <
0) {
// TODO: may need modification to handle slice coding
ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y,
ER_MB_ERROR);
@@ -5108,7 +4789,7 @@ static void vc1_decode_p_blocks(VC1Context *v)
init_block_index(v);
for (; s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
- vc1_apply_p_loop_filter(v);
+ ff_vc1_apply_p_loop_filter(v);
}
}
if (s->end_mb_y >= s->start_mb_y)
@@ -5166,7 +4847,8 @@ static void vc1_decode_b_blocks(VC1Context *v)
get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
return;
}
- if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
+ if (v->s.loop_filter)
+ ff_vc1_loop_filter_iblk(v, v->pq);
}
if (!v->s.loop_filter)
ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c
new file mode 100644
index 0000000..f2a90ac
--- /dev/null
+++ b/libavcodec/vc1_loopfilter.c
@@ -0,0 +1,363 @@
+/*
+ * VC-1 and WMV3 decoder
+ * Copyright (c) 2011 Mashiat Sarker Shakkhar
+ * Copyright (c) 2006-2007 Konstantin Shishkov
+ * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael
Niedermayer
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * VC-1 and WMV3 loopfilter
+ */
+
+#include "internal.h"
+#include "avcodec.h"
+#include "error_resilience.h"
+#include "mpegutils.h"
+#include "mpegvideo.h"
+#include "h263.h"
+#include "h264chroma.h"
+#include "qpeldsp.h"
+#include "vc1.h"
+#include "vc1data.h"
+#include "vc1acdata.h"
+#include "msmpeg4data.h"
+#include "unary.h"
+#include "mathops.h"
+
+void ff_vc1_loop_filter_iblk(VC1Context *v, int pq)
+{
+ MpegEncContext *s = &v->s;
+ int j;
+ if (!s->first_slice_line) {
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq);
+ if (s->mb_x)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize,
s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize + 8,
s->linesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1], s->uvlinesize, pq);
+ if (s->mb_x)
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize, s->uvlinesize, pq);
+ }
+ }
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] + 8 * s->linesize, s->linesize,
pq);
+
+ if (s->mb_y == s->end_mb_y - 1) {
+ if (s->mb_x) {
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0], s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[1], s->uvlinesize, pq);
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[2], s->uvlinesize, pq);
+ }
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] + 8, s->linesize, pq);
+ }
+}
+
+void ff_vc1_loop_filter_iblk_delayed(VC1Context *v, int pq)
+{
+ MpegEncContext *s = &v->s;
+ int j;
+
+ /* The loopfilter runs 1 row and 1 column behind the overlap filter, which
+ * means it runs two rows/cols behind the decoding loop. */
+ if (!s->first_slice_line) {
+ if (s->mb_x) {
+ if (s->mb_y >= s->start_mb_y + 2) {
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize -
16, s->linesize, pq);
+
+ if (s->mb_x >= 2)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 *
s->linesize - 16, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize -
8, s->linesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize - 8, s->uvlinesize, pq);
+ if (s->mb_x >= 2) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 *
s->uvlinesize - 8, s->uvlinesize, pq);
+ }
+ }
+ }
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize - 16,
s->linesize, pq);
+ }
+
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_y >= s->start_mb_y + 2) {
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 16 * s->linesize,
s->linesize, pq);
+
+ if (s->mb_x)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 *
s->linesize, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 32 * s->linesize +
8, s->linesize, pq);
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_v_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize, s->uvlinesize, pq);
+ if (s->mb_x >= 2) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 16 *
s->uvlinesize, s->uvlinesize, pq);
+ }
+ }
+ }
+ v->vc1dsp.vc1_v_loop_filter16(s->dest[0] - 8 * s->linesize,
s->linesize, pq);
+ }
+
+ if (s->mb_y == s->end_mb_y) {
+ if (s->mb_x) {
+ if (s->mb_x >= 2)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 *
s->linesize - 16, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize -
8, s->linesize, pq);
+ if (s->mb_x >= 2) {
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize - 8, s->uvlinesize, pq);
+ }
+ }
+ }
+
+ if (s->mb_x == s->mb_width - 1) {
+ if (s->mb_x)
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 *
s->linesize, s->linesize, pq);
+ v->vc1dsp.vc1_h_loop_filter16(s->dest[0] - 16 * s->linesize +
8, s->linesize, pq);
+ if (s->mb_x) {
+ for (j = 0; j < 2; j++) {
+ v->vc1dsp.vc1_h_loop_filter8(s->dest[j + 1] - 8 *
s->uvlinesize, s->uvlinesize, pq);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ff_vc1_smooth_overlap_filter_iblk(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ int mb_pos;
+
+ if (v->condover == CONDOVER_NONE)
+ return;
+
+ mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ /* Within a MB, the horizontal overlap always runs before the vertical.
+ * To accomplish that, we run the H on left and internal borders of the
+ * currently decoded MB. Then, we wait for the next overlap iteration
+ * to do H overlap on the right edge of this MB, before moving over and
+ * running the V overlap. Therefore, the V overlap makes us trail by one
+ * MB col and the H overlap filter makes us trail by one MB row. This
+ * is reflected in the time at which we run the put_pixels loop. */
+ if (v->condover == CONDOVER_ALL || v->pq >= 9 ||
v->over_flags_plane[mb_pos]) {
+ if (s->mb_x && (v->condover == CONDOVER_ALL || v->pq >= 9 ||
+ v->over_flags_plane[mb_pos - 1])) {
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][1],
+ v->block[v->cur_blk_idx][0]);
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][3],
+ v->block[v->cur_blk_idx][2]);
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][4],
+ v->block[v->cur_blk_idx][4]);
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->left_blk_idx][5],
+ v->block[v->cur_blk_idx][5]);
+ }
+ }
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][0],
+ v->block[v->cur_blk_idx][1]);
+ v->vc1dsp.vc1_h_s_overlap(v->block[v->cur_blk_idx][2],
+ v->block[v->cur_blk_idx][3]);
+
+ if (s->mb_x == s->mb_width - 1) {
+ if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq
>= 9 ||
+ v->over_flags_plane[mb_pos -
s->mb_stride])) {
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][2],
+ v->block[v->cur_blk_idx][0]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][3],
+ v->block[v->cur_blk_idx][1]);
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][4],
+ v->block[v->cur_blk_idx][4]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->top_blk_idx][5],
+ v->block[v->cur_blk_idx][5]);
+ }
+ }
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][0],
+ v->block[v->cur_blk_idx][2]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->cur_blk_idx][1],
+ v->block[v->cur_blk_idx][3]);
+ }
+ }
+ if (s->mb_x && (v->condover == CONDOVER_ALL || v->over_flags_plane[mb_pos
- 1])) {
+ if (!s->first_slice_line && (v->condover == CONDOVER_ALL || v->pq >= 9
||
+ v->over_flags_plane[mb_pos - s->mb_stride
- 1])) {
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][2],
+ v->block[v->left_blk_idx][0]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][3],
+ v->block[v->left_blk_idx][1]);
+ if (!(s->flags & CODEC_FLAG_GRAY)) {
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][4],
+ v->block[v->left_blk_idx][4]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->topleft_blk_idx][5],
+ v->block[v->left_blk_idx][5]);
+ }
+ }
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][0],
+ v->block[v->left_blk_idx][2]);
+ v->vc1dsp.vc1_v_s_overlap(v->block[v->left_blk_idx][1],
+ v->block[v->left_blk_idx][3]);
+ }
+}
+
+static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int
block_num)
+{
+ MpegEncContext *s = &v->s;
+ int mb_cbp = v->cbp[s->mb_x - s->mb_stride],
+ block_cbp = mb_cbp >> (block_num * 4), bottom_cbp,
+ mb_is_intra = v->is_intra[s->mb_x - s->mb_stride],
+ block_is_intra = mb_is_intra >> (block_num * 4), bottom_is_intra;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
+ uint8_t *dst;
+
+ if (block_num > 3) {
+ dst = s->dest[block_num - 3];
+ } else {
+ dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 -
8) * linesize;
+ }
+ if (s->mb_y != s->end_mb_y || block_num < 2) {
+ int16_t (*mv)[2];
+ int mv_stride;
+
+ if (block_num > 3) {
+ bottom_cbp = v->cbp[s->mb_x] >> (block_num * 4);
+ bottom_is_intra = v->is_intra[s->mb_x] >> (block_num * 4);
+ mv = &v->luma_mv[s->mb_x - s->mb_stride];
+ mv_stride = s->mb_stride;
+ } else {
+ bottom_cbp = (block_num < 2) ? (mb_cbp >>
((block_num + 2) * 4))
+ : (v->cbp[s->mb_x] >>
((block_num - 2) * 4));
+ bottom_is_intra = (block_num < 2) ? (mb_is_intra >>
((block_num + 2) * 4))
+ : (v->is_intra[s->mb_x] >>
((block_num - 2) * 4));
+ mv_stride = s->b8_stride;
+ mv =
&s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
+ }
+
+ if (bottom_is_intra & 1 || block_is_intra & 1 ||
+ mv[0][0] != mv[mv_stride][0] || mv[0][1] != mv[mv_stride][1]) {
+ v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
+ } else {
+ idx = ((bottom_cbp >> 2) | block_cbp) & 3;
+ if (idx == 3) {
+ v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
+ } else if (idx) {
+ if (idx == 1)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
+ else
+ v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq);
+ }
+ }
+ }
+
+ dst -= 4 * linesize;
+ ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xF;
+ if (ttblk == TT_4X4 || ttblk == TT_8X4) {
+ idx = (block_cbp | (block_cbp >> 2)) & 3;
+ if (idx == 3) {
+ v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);
+ } else if (idx) {
+ if (idx == 1)
+ v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);
+ else
+ v->vc1dsp.vc1_v_loop_filter4(dst, linesize, v->pq);
+ }
+ }
+}
+
+static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int
block_num)
+{
+ MpegEncContext *s = &v->s;
+ int mb_cbp = v->cbp[s->mb_x - 1 - s->mb_stride],
+ block_cbp = mb_cbp >> (block_num * 4), right_cbp,
+ mb_is_intra = v->is_intra[s->mb_x - 1 - s->mb_stride],
+ block_is_intra = mb_is_intra >> (block_num * 4), right_is_intra;
+ int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;
+ uint8_t *dst;
+
+ if (block_num > 3) {
+ dst = s->dest[block_num - 3] - 8 * linesize;
+ } else {
+ dst = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 16) *
linesize - 8;
+ }
+
+ if (s->mb_x != s->mb_width || !(block_num & 5)) {
+ int16_t (*mv)[2];
+
+ if (block_num > 3) {
+ right_cbp = v->cbp[s->mb_x - s->mb_stride] >> (block_num * 4);
+ right_is_intra = v->is_intra[s->mb_x - s->mb_stride] >> (block_num
* 4);
+ mv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
+ } else {
+ right_cbp = (block_num & 1) ? (v->cbp[s->mb_x - s->mb_stride]
>> ((block_num - 1) * 4))
+ : (mb_cbp
>> ((block_num + 1) * 4));
+ right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x -
s->mb_stride] >> ((block_num - 1) * 4))
+ : (mb_is_intra
>> ((block_num + 1) * 4));
+ mv =
&s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2
- 2];
+ }
+ if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0]
|| mv[0][1] != mv[1][1]) {
+ v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
+ } else {
+ idx = ((right_cbp >> 1) | block_cbp) & 5; // FIXME check
+ if (idx == 5) {
+ v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
+ } else if (idx) {
+ if (idx == 1)
+ v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize, linesize,
v->pq);
+ else
+ v->vc1dsp.vc1_h_loop_filter4(dst, linesize,
v->pq);
+ }
+ }
+ }
+
+ dst -= 4;
+ ttblk = (v->ttblk[s->mb_x - s->mb_stride - 1] >> (block_num * 4)) & 0xf;
+ if (ttblk == TT_4X4 || ttblk == TT_4X8) {
+ idx = (block_cbp | (block_cbp >> 1)) & 5;
+ if (idx == 5) {
+ v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
+ } else if (idx) {
+ if (idx == 1)
+ v->vc1dsp.vc1_h_loop_filter4(dst + linesize * 4, linesize,
v->pq);
+ else
+ v->vc1dsp.vc1_h_loop_filter4(dst, linesize,
v->pq);
+ }
+ }
+}
+
+void ff_vc1_apply_p_loop_filter(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ vc1_apply_p_v_loop_filter(v, i);
+ }
+
+ /* V always precedes H, therefore we run H one MB before V;
+ * at the end of a row, we catch up to complete the row */
+ if (s->mb_x) {
+ for (i = 0; i < 6; i++) {
+ vc1_apply_p_h_loop_filter(v, i);
+ }
+ if (s->mb_x == s->mb_width - 1) {
+ s->mb_x++;
+ ff_update_block_index(s);
+ for (i = 0; i < 6; i++) {
+ vc1_apply_p_h_loop_filter(v, i);
+ }
+ }
+ }
+}
--
2.1.0
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel