1242 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1242 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * 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 FFmpeg.
 | |
|  *
 | |
|  * FFmpeg 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.
 | |
|  *
 | |
|  * FFmpeg 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 FFmpeg; 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 "avcodec.h"
 | |
| #include "mpegvideo.h"
 | |
| #include "vc1.h"
 | |
| #include "vc1dsp.h"
 | |
| 
 | |
| static av_always_inline void vc1_h_overlap_filter(VC1Context *v, int16_t (*left_block)[64],
 | |
|                                                   int16_t (*right_block)[64], int left_fieldtx,
 | |
|                                                   int right_fieldtx, int block_num)
 | |
| {
 | |
|     switch (block_num) {
 | |
|     case 0:
 | |
|         v->vc1dsp.vc1_h_s_overlap(left_block[2],
 | |
|                                   right_block[0],
 | |
|                                   left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8,
 | |
|                                   left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8,
 | |
|                                   left_fieldtx || right_fieldtx ? 0 : 1);
 | |
|         break;
 | |
| 
 | |
|     case 1:
 | |
|         v->vc1dsp.vc1_h_s_overlap(right_block[0],
 | |
|                                   right_block[2],
 | |
|                                   8,
 | |
|                                   8,
 | |
|                                   right_fieldtx ? 0 : 1);
 | |
|         break;
 | |
| 
 | |
|     case 2:
 | |
|         v->vc1dsp.vc1_h_s_overlap(!left_fieldtx && right_fieldtx ? left_block[2] + 8 : left_block[3],
 | |
|                                   left_fieldtx && !right_fieldtx ? right_block[0] + 8 : right_block[1],
 | |
|                                   left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8,
 | |
|                                   left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8,
 | |
|                                   left_fieldtx || right_fieldtx ? 2 : 1);
 | |
|         break;
 | |
| 
 | |
|     case 3:
 | |
|         v->vc1dsp.vc1_h_s_overlap(right_block[1],
 | |
|                                   right_block[3],
 | |
|                                   8,
 | |
|                                   8,
 | |
|                                   right_fieldtx ? 2 : 1);
 | |
|         break;
 | |
| 
 | |
|     case 4:
 | |
|     case 5:
 | |
|         v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num], 8, 8, 1);
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static av_always_inline void vc1_v_overlap_filter(VC1Context *v, int16_t (*top_block)[64],
 | |
|                                                   int16_t (*bottom_block)[64], int block_num)
 | |
| {
 | |
|     switch (block_num) {
 | |
|     case 0:
 | |
|         v->vc1dsp.vc1_v_s_overlap(top_block[1], bottom_block[0]);
 | |
|         break;
 | |
| 
 | |
|     case 1:
 | |
|         v->vc1dsp.vc1_v_s_overlap(top_block[3], bottom_block[2]);
 | |
|         break;
 | |
| 
 | |
|     case 2:
 | |
|         v->vc1dsp.vc1_v_s_overlap(bottom_block[0], bottom_block[1]);
 | |
|         break;
 | |
| 
 | |
|     case 3:
 | |
|         v->vc1dsp.vc1_v_s_overlap(bottom_block[2], bottom_block[3]);
 | |
|         break;
 | |
| 
 | |
|     case 4:
 | |
|     case 5:
 | |
|         v->vc1dsp.vc1_v_s_overlap(top_block[block_num], bottom_block[block_num]);
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void ff_vc1_i_overlap_filter(VC1Context *v)
 | |
| {
 | |
|     MpegEncContext *s = &v->s;
 | |
|     int16_t (*topleft_blk)[64], (*top_blk)[64], (*left_blk)[64], (*cur_blk)[64];
 | |
|     int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
 | |
|     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
 | |
|     int i;
 | |
| 
 | |
|     topleft_blk = v->block[v->topleft_blk_idx];
 | |
|     top_blk = v->block[v->top_blk_idx];
 | |
|     left_blk = v->block[v->left_blk_idx];
 | |
|     cur_blk = v->block[v->cur_blk_idx];
 | |
| 
 | |
|     /* Within a MB, the horizontal overlap always runs before the vertical.
 | |
|      * To accomplish that, we run the H on the left and internal vertical
 | |
|      * 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 on the top and internal horizontal
 | |
|      * borders. Therefore, the H overlap trails by one MB col and the
 | |
|      * V overlap trails by one MB row. This is reflected in the time at which
 | |
|      * we run the put_pixels loop, i.e. delayed by one row and one column. */
 | |
|     for (i = 0; i < block_count; i++) {
 | |
|         if (s->mb_x == 0 && (i & 5) != 1)
 | |
|             continue;
 | |
| 
 | |
|         if (v->pq >= 9 || (v->profile == PROFILE_ADVANCED &&
 | |
|                            (v->condover == CONDOVER_ALL ||
 | |
|                             (v->over_flags_plane[mb_pos] &&
 | |
|                              ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1])))))
 | |
|             vc1_h_overlap_filter(v,
 | |
|                                  s->mb_x ? left_blk : cur_blk, cur_blk,
 | |
|                                  v->fcm == ILACE_FRAME && s->mb_x && v->fieldtx_plane[mb_pos - 1],
 | |
|                                  v->fcm == ILACE_FRAME && v->fieldtx_plane[mb_pos],
 | |
|                                  i);
 | |
|     }
 | |
| 
 | |
|     if (v->fcm != ILACE_FRAME)
 | |
|         for (i = 0; i < block_count; i++) {
 | |
|             if (s->first_slice_line && !(i & 2))
 | |
|                 continue;
 | |
| 
 | |
|             if (s->mb_x &&
 | |
|                 (v->pq >= 9 || (v->profile == PROFILE_ADVANCED &&
 | |
|                                 (v->condover == CONDOVER_ALL ||
 | |
|                                  (v->over_flags_plane[mb_pos - 1] &&
 | |
|                                   ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride]))))))
 | |
|                 vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i);
 | |
|             if (s->mb_x == s->mb_width - 1 &&
 | |
|                 (v->pq >= 9 || (v->profile == PROFILE_ADVANCED &&
 | |
|                                 (v->condover == CONDOVER_ALL ||
 | |
|                                  (v->over_flags_plane[mb_pos] &&
 | |
|                                   ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride]))))))
 | |
|                 vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i);
 | |
|         }
 | |
| }
 | |
| 
 | |
| void ff_vc1_p_overlap_filter(VC1Context *v)
 | |
| {
 | |
|     MpegEncContext *s = &v->s;
 | |
|     int16_t (*topleft_blk)[64], (*top_blk)[64], (*left_blk)[64], (*cur_blk)[64];
 | |
|     int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
 | |
|     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
 | |
|     int i;
 | |
| 
 | |
|     topleft_blk = v->block[v->topleft_blk_idx];
 | |
|     top_blk = v->block[v->top_blk_idx];
 | |
|     left_blk = v->block[v->left_blk_idx];
 | |
|     cur_blk = v->block[v->cur_blk_idx];
 | |
| 
 | |
|     for (i = 0; i < block_count; i++) {
 | |
|         if (s->mb_x == 0 && (i & 5) != 1)
 | |
|             continue;
 | |
| 
 | |
|         if (v->mb_type[0][s->block_index[i]] && v->mb_type[0][s->block_index[i] - 1])
 | |
|             vc1_h_overlap_filter(v,
 | |
|                                  s->mb_x ? left_blk : cur_blk, cur_blk,
 | |
|                                  v->fcm == ILACE_FRAME && s->mb_x && v->fieldtx_plane[mb_pos - 1],
 | |
|                                  v->fcm == ILACE_FRAME && v->fieldtx_plane[mb_pos],
 | |
|                                  i);
 | |
|     }
 | |
| 
 | |
|     if (v->fcm != ILACE_FRAME)
 | |
|         for (i = 0; i < block_count; i++) {
 | |
|             if (s->first_slice_line && !(i & 2))
 | |
|                 continue;
 | |
| 
 | |
|             if (s->mb_x && v->mb_type[0][s->block_index[i] - 2 + (i > 3)] &&
 | |
|                 v->mb_type[0][s->block_index[i] - s->block_wrap[i] - 2 + (i > 3)])
 | |
|                 vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i);
 | |
|             if (s->mb_x == s->mb_width - 1)
 | |
|                 if (v->mb_type[0][s->block_index[i]] &&
 | |
|                     v->mb_type[0][s->block_index[i] - s->block_wrap[i]])
 | |
|                     vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i);
 | |
|         }
 | |
| }
 | |
| 
 | |
| #define LEFT_EDGE   (1 << 0)
 | |
| #define RIGHT_EDGE  (1 << 1)
 | |
| #define TOP_EDGE    (1 << 2)
 | |
| #define BOTTOM_EDGE (1 << 3)
 | |
| 
 | |
| static av_always_inline void vc1_i_h_loop_filter(VC1Context *v, uint8_t *dest,
 | |
|                                                  uint32_t flags, int block_num)
 | |
| {
 | |
|     MpegEncContext *s  = &v->s;
 | |
|     int pq = v->pq;
 | |
|     uint8_t *dst;
 | |
| 
 | |
|     if (block_num & 2)
 | |
|         return;
 | |
| 
 | |
|     if (!(flags & LEFT_EDGE) || (block_num & 5) == 1) {
 | |
|         if (block_num > 3)
 | |
|             dst = dest;
 | |
|         else
 | |
|             dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
 | |
| 
 | |
|         if (v->fcm == ILACE_FRAME)
 | |
|             if (block_num > 3) {
 | |
|                 v->vc1dsp.vc1_h_loop_filter4(dst, 2 * s->uvlinesize, pq);
 | |
|                 v->vc1dsp.vc1_h_loop_filter4(dst + s->uvlinesize, 2 * s->uvlinesize, pq);
 | |
|             } else {
 | |
|                 v->vc1dsp.vc1_h_loop_filter8(dst, 2 * s->linesize, pq);
 | |
|                 v->vc1dsp.vc1_h_loop_filter8(dst + s->linesize, 2 * s->linesize, pq);
 | |
|             }
 | |
|         else
 | |
|             if (block_num > 3)
 | |
|                 v->vc1dsp.vc1_h_loop_filter8(dst, s->uvlinesize, pq);
 | |
|             else
 | |
|                 v->vc1dsp.vc1_h_loop_filter16(dst, s->linesize, pq);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static av_always_inline void vc1_i_v_loop_filter(VC1Context *v, uint8_t *dest,
 | |
|                                                  uint32_t flags, uint8_t fieldtx,
 | |
|                                                  int block_num)
 | |
| {
 | |
|     MpegEncContext *s  = &v->s;
 | |
|     int pq = v->pq;
 | |
|     uint8_t *dst;
 | |
| 
 | |
|     if ((block_num & 5) == 1)
 | |
|         return;
 | |
| 
 | |
|     if (!(flags & TOP_EDGE) || block_num & 2) {
 | |
|         if (block_num > 3)
 | |
|             dst = dest;
 | |
|         else
 | |
|             dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
 | |
| 
 | |
|         if (v->fcm == ILACE_FRAME) {
 | |
|             if (block_num > 3) {
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst, 2 * s->uvlinesize, pq);
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + s->uvlinesize, 2 * s->uvlinesize, pq);
 | |
|             } else if (block_num < 2 || !fieldtx) {
 | |
|                 v->vc1dsp.vc1_v_loop_filter16(dst, 2 * s->linesize, pq);
 | |
|                 v->vc1dsp.vc1_v_loop_filter16(dst + s->linesize, 2 * s->linesize, pq);
 | |
|             }
 | |
|         } else
 | |
|             if (block_num > 3)
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst, s->uvlinesize, pq);
 | |
|             else
 | |
|                 v->vc1dsp.vc1_v_loop_filter16(dst, s->linesize, pq);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void ff_vc1_i_loop_filter(VC1Context *v)
 | |
| {
 | |
|     MpegEncContext *s = &v->s;
 | |
|     int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
 | |
|     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
 | |
|     uint8_t *dest, fieldtx;
 | |
|     uint32_t flags = 0;
 | |
|     int i;
 | |
| 
 | |
|     /* Within a MB, the vertical loop filter always runs before the horizontal.
 | |
|      * To accomplish that, we run the V loop filter on top and internal
 | |
|      * horizontal borders of the last overlap filtered MB. Then, we wait for
 | |
|      * the loop filter iteration on the next row to do V loop filter on the
 | |
|      * bottom edge of this MB, before moving over and running the H loop
 | |
|      * filter on the left and internal vertical borders. Therefore, the loop
 | |
|      * filter trails by one row and one column relative to the overlap filter
 | |
|      * and two rows and two columns relative to the decoding loop. */
 | |
|     if (!s->first_slice_line) {
 | |
|         dest = s->dest[0] - 16 * s->linesize - 16;
 | |
|         flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
 | |
|         if (s->mb_x) {
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, flags, fieldtx, i);
 | |
|         }
 | |
|         if (s->mb_x == v->end_mb_x - 1) {
 | |
|             dest += 16;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, flags, fieldtx, i);
 | |
|         }
 | |
|     }
 | |
|     if (s->mb_y == s->end_mb_y - 1) {
 | |
|         dest = s->dest[0] - 16;
 | |
|         flags = s->first_slice_line ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
 | |
|         if (s->mb_x) {
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - 1];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, flags, fieldtx, i);
 | |
|         }
 | |
|         if (s->mb_x == v->end_mb_x - 1) {
 | |
|             dest += 16;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, flags, fieldtx, i);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (s->mb_y >= s->start_mb_y + 2) {
 | |
|         dest = s->dest[0] - 32 * s->linesize - 16;
 | |
|         if (s->mb_x) {
 | |
|             flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest, flags, i);
 | |
|         }
 | |
|         if (s->mb_x == v->end_mb_x - 1) {
 | |
|             dest += 16;
 | |
|             flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest, flags, i);
 | |
|         }
 | |
|     }
 | |
|     if (s->mb_y == s->end_mb_y - 1) {
 | |
|         if (s->mb_y >= s->start_mb_y + 1) {
 | |
|             dest = s->dest[0] - 16 * s->linesize - 16;
 | |
|             if (s->mb_x) {
 | |
|                 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, flags, i);
 | |
|             }
 | |
|             if (s->mb_x == v->end_mb_x - 1) {
 | |
|                 flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
 | |
|                 dest += 16;
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, flags, i);
 | |
|             }
 | |
|         }
 | |
|         dest = s->dest[0] - 16;
 | |
|         if (s->mb_x) {
 | |
|             flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, flags, i);
 | |
|         }
 | |
|         if (s->mb_x == v->end_mb_x - 1) {
 | |
|             dest += 16;
 | |
|             flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, flags, i);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static av_always_inline void vc1_p_h_loop_filter(VC1Context *v, uint8_t *dest, uint32_t *cbp,
 | |
|                                                  uint8_t *is_intra, int16_t (*mv)[2], uint8_t *mv_f,
 | |
|                                                  int *ttblk, uint32_t flags, int block_num)
 | |
| {
 | |
|     MpegEncContext *s  = &v->s;
 | |
|     int pq = v->pq;
 | |
|     uint32_t left_cbp = cbp[0] >> (block_num * 4), right_cbp;
 | |
|     uint8_t left_is_intra, right_is_intra;
 | |
|     int tt;
 | |
|     int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize;
 | |
|     uint8_t *dst;
 | |
| 
 | |
|     if (block_num > 3)
 | |
|         dst = dest;
 | |
|     else
 | |
|         dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
 | |
| 
 | |
|     if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
 | |
|         left_is_intra = is_intra[0] & (1 << block_num);
 | |
| 
 | |
|         if (block_num > 3) {
 | |
|             right_is_intra = is_intra[1] & (1 << block_num);
 | |
|             right_cbp = cbp[1] >> (block_num * 4);
 | |
|         } else if (block_num & 1) {
 | |
|             right_is_intra = is_intra[1] & (1 << block_num - 1);
 | |
|             right_cbp = cbp[1] >> ((block_num - 1) * 4);
 | |
|         } else {
 | |
|             right_is_intra = is_intra[0] & (1 << block_num + 1);
 | |
|             right_cbp = cbp[0] >> ((block_num + 1) * 4);
 | |
|         }
 | |
| 
 | |
|         if (left_is_intra || right_is_intra ||
 | |
|             mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1] ||
 | |
|             (v->fcm == ILACE_FIELD && mv_f[0] != mv_f[1]))
 | |
|             v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq);
 | |
|         else {
 | |
|             idx = (left_cbp | (right_cbp >> 1)) & 5;
 | |
|             if (idx & 1)
 | |
|                 v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 8, linesize, pq);
 | |
|             if (idx & 4)
 | |
|                 v->vc1dsp.vc1_h_loop_filter4(dst + 8, linesize, pq);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     tt = ttblk[0] >> (block_num * 4) & 0xf;
 | |
|     if (tt == TT_4X4 || tt == TT_4X8) {
 | |
|         if (left_cbp & 3)
 | |
|             v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
 | |
|         if (left_cbp & 12)
 | |
|             v->vc1dsp.vc1_h_loop_filter4(dst + 4, linesize, pq);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static av_always_inline void vc1_p_v_loop_filter(VC1Context *v, uint8_t *dest, uint32_t *cbp,
 | |
|                                                  uint8_t *is_intra, int16_t (*mv)[2], uint8_t *mv_f,
 | |
|                                                  int *ttblk, uint32_t flags, int block_num)
 | |
| {
 | |
|     MpegEncContext *s  = &v->s;
 | |
|     int pq = v->pq;
 | |
|     uint32_t top_cbp = cbp[0] >> (block_num * 4), bottom_cbp;
 | |
|     uint8_t top_is_intra, bottom_is_intra;
 | |
|     int tt;
 | |
|     int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize;
 | |
|     uint8_t *dst;
 | |
| 
 | |
|     if (block_num > 3)
 | |
|         dst = dest;
 | |
|     else
 | |
|         dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
 | |
| 
 | |
|     if(!(flags & BOTTOM_EDGE) || block_num < 2) {
 | |
|         top_is_intra = is_intra[0] & (1 << block_num);
 | |
| 
 | |
|         if (block_num > 3) {
 | |
|             bottom_is_intra = is_intra[s->mb_stride] & (1 << block_num);
 | |
|             bottom_cbp = cbp[s->mb_stride] >> (block_num * 4);
 | |
|         } else if (block_num < 2) {
 | |
|             bottom_is_intra = is_intra[0] & (1 << block_num + 2);
 | |
|             bottom_cbp = cbp[0] >> ((block_num + 2) * 4);
 | |
|         } else {
 | |
|             bottom_is_intra = is_intra[s->mb_stride] & (1 << block_num - 2);
 | |
|             bottom_cbp = cbp[s->mb_stride] >> ((block_num - 2) * 4);
 | |
|         }
 | |
| 
 | |
|         if (top_is_intra || bottom_is_intra ||
 | |
|             mv[0][0] != mv[block_num > 3 ? s->mb_stride : s->b8_stride][0] ||
 | |
|             mv[0][1] != mv[block_num > 3 ? s->mb_stride : s->b8_stride][1] ||
 | |
|             (v->fcm == ILACE_FIELD && mv_f[0] != mv_f[block_num > 3 ? s->mb_stride : s->b8_stride]))
 | |
|             v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, linesize, pq);
 | |
|         else {
 | |
|             idx = (top_cbp | (bottom_cbp >> 2)) & 3;
 | |
|             if (idx & 1)
 | |
|                 v->vc1dsp.vc1_v_loop_filter4(dst + 8 * linesize + 4, linesize, pq);
 | |
|             if (idx & 2)
 | |
|                 v->vc1dsp.vc1_v_loop_filter4(dst + 8 * linesize, linesize, pq);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     tt = ttblk[0] >> (block_num * 4) & 0xf;
 | |
|     if (tt == TT_4X4 || tt == TT_8X4) {
 | |
|         if (top_cbp & 5)
 | |
|             v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
 | |
|         if (top_cbp & 10)
 | |
|             v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize, linesize, pq);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void ff_vc1_p_loop_filter(VC1Context *v)
 | |
| {
 | |
|     MpegEncContext *s = &v->s;
 | |
|     int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
 | |
|     uint8_t *dest;
 | |
|     uint32_t *cbp;
 | |
|     uint8_t *is_intra;
 | |
|     int16_t (*uvmv)[2];
 | |
|     int *ttblk;
 | |
|     uint32_t flags;
 | |
|     int i;
 | |
| 
 | |
|     /* Within a MB, the vertical loop filter always runs before the horizontal.
 | |
|      * To accomplish that, we run the V loop filter on all applicable
 | |
|      * horizontal borders of the MB above the last overlap filtered MB. Then,
 | |
|      * we wait for the next loop filter iteration to do H loop filter on all
 | |
|      * applicable vertical borders of this MB. Therefore, the loop filter
 | |
|      * trails by one row and one column relative to the overlap filter and two
 | |
|      * rows and two columns relative to the decoding loop. */
 | |
|     if (s->mb_y >= s->start_mb_y + 2) {
 | |
|         if (s->mb_x) {
 | |
|             dest = s->dest[0] - 32 * s->linesize - 16;
 | |
|             cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 1];
 | |
|             is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 1];
 | |
|             uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 1];
 | |
|             ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
 | |
|             flags = s->mb_y == s->start_mb_y + 2 ? TOP_EDGE : 0;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_v_loop_filter(v,
 | |
|                                     i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest,
 | |
|                                     cbp,
 | |
|                                     is_intra,
 | |
|                                     i > 3 ? uvmv :
 | |
|                                             &s->current_picture.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
 | |
|                                     i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 1 + v->mb_off] :
 | |
|                                             &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
 | |
|                                     ttblk,
 | |
|                                     flags,
 | |
|                                     i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             dest = s->dest[0] - 32 * s->linesize;
 | |
|             cbp = &v->cbp[s->mb_x - 2 * s->mb_stride];
 | |
|             is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride];
 | |
|             uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride];
 | |
|             ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
 | |
|             flags = s->mb_y == s->start_mb_y + 2 ? TOP_EDGE : 0;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_v_loop_filter(v,
 | |
|                                     i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest,
 | |
|                                     cbp,
 | |
|                                     is_intra,
 | |
|                                     i > 3 ? uvmv :
 | |
|                                             &s->current_picture.motion_val[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
 | |
|                                     i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride + v->mb_off] :
 | |
|                                             &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
 | |
|                                     ttblk,
 | |
|                                     flags,
 | |
|                                     i);
 | |
|         }
 | |
|     }
 | |
|     if (s->mb_y == s->end_mb_y - 1) {
 | |
|         if (s->mb_x) {
 | |
|             if (s->mb_y >= s->start_mb_y + 1) {
 | |
|                 dest = s->dest[0] - 16 * s->linesize - 16;
 | |
|                 cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
 | |
|                 is_intra = &v->is_intra[s->mb_x - s->mb_stride - 1];
 | |
|                 uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
 | |
|                 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
 | |
|                 flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_v_loop_filter(v,
 | |
|                                         i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
 | |
|                                         cbp,
 | |
|                                         is_intra,
 | |
|                                         i > 3 ? uvmv :
 | |
|                                                 &s->current_picture.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
 | |
|                                         i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 1 + v->mb_off] :
 | |
|                                                 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
 | |
|                                         ttblk,
 | |
|                                         flags,
 | |
|                                         i);
 | |
|             }
 | |
|             dest = s->dest[0] - 16;
 | |
|             cbp = &v->cbp[s->mb_x - 1];
 | |
|             is_intra = &v->is_intra[s->mb_x - 1];
 | |
|             uvmv = &v->luma_mv[s->mb_x - 1];
 | |
|             ttblk = &v->ttblk[s->mb_x - 1];
 | |
|             flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_v_loop_filter(v,
 | |
|                                     i > 3 ? s->dest[i - 3] - 8 : dest,
 | |
|                                     cbp,
 | |
|                                     is_intra,
 | |
|                                     i > 3 ? uvmv :
 | |
|                                             &s->current_picture.motion_val[0][s->block_index[i] - 2 + v->blocks_off],
 | |
|                                     i > 3 ? &v->mv_f[0][s->block_index[i] - 1 + v->mb_off] :
 | |
|                                             &v->mv_f[0][s->block_index[i] - 2 + v->blocks_off],
 | |
|                                     ttblk,
 | |
|                                     flags,
 | |
|                                     i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             if (s->mb_y >= s->start_mb_y + 1) {
 | |
|                 dest = s->dest[0] - 16 * s->linesize;
 | |
|                 cbp = &v->cbp[s->mb_x - s->mb_stride];
 | |
|                 is_intra = &v->is_intra[s->mb_x - s->mb_stride];
 | |
|                 uvmv = &v->luma_mv[s->mb_x - s->mb_stride];
 | |
|                 ttblk = &v->ttblk[s->mb_x - s->mb_stride];
 | |
|                 flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_v_loop_filter(v,
 | |
|                                         i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
 | |
|                                         cbp,
 | |
|                                         is_intra,
 | |
|                                         i > 3 ? uvmv :
 | |
|                                                 &s->current_picture.motion_val[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
 | |
|                                         i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride + v->mb_off] :
 | |
|                                                 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
 | |
|                                         ttblk,
 | |
|                                         flags,
 | |
|                                         i);
 | |
|             }
 | |
|             dest = s->dest[0];
 | |
|             cbp = &v->cbp[s->mb_x];
 | |
|             is_intra = &v->is_intra[s->mb_x];
 | |
|             uvmv = &v->luma_mv[s->mb_x];
 | |
|             ttblk = &v->ttblk[s->mb_x];
 | |
|             flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_v_loop_filter(v,
 | |
|                                     i > 3 ? s->dest[i - 3] : dest,
 | |
|                                     cbp,
 | |
|                                     is_intra,
 | |
|                                     i > 3 ? uvmv :
 | |
|                                             &s->current_picture.motion_val[0][s->block_index[i] + v->blocks_off],
 | |
|                                     i > 3 ? &v->mv_f[0][s->block_index[i] + v->mb_off] :
 | |
|                                             &v->mv_f[0][s->block_index[i] + v->blocks_off],
 | |
|                                     ttblk,
 | |
|                                     flags,
 | |
|                                     i);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (s->mb_y >= s->start_mb_y + 2) {
 | |
|         if (s->mb_x >= 2) {
 | |
|             dest = s->dest[0] - 32 * s->linesize - 32;
 | |
|             cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 2];
 | |
|             is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 2];
 | |
|             uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 2];
 | |
|             ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 2];
 | |
|             flags = s->mb_x == 2 ? LEFT_EDGE : 0;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_h_loop_filter(v,
 | |
|                                     i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 16 : dest,
 | |
|                                     cbp,
 | |
|                                     is_intra,
 | |
|                                     i > 3 ? uvmv :
 | |
|                                             &s->current_picture.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 4 + v->blocks_off],
 | |
|                                     i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 2 + v->mb_off] :
 | |
|                                             &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 4 + v->blocks_off],
 | |
|                                     ttblk,
 | |
|                                     flags,
 | |
|                                     i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             if (s->mb_x >= 1) {
 | |
|                 dest = s->dest[0] - 32 * s->linesize - 16;
 | |
|                 cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 1];
 | |
|                 is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 1];
 | |
|                 uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 1];
 | |
|                 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
 | |
|                 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                         vc1_p_h_loop_filter(v,
 | |
|                                             i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest,
 | |
|                                             cbp,
 | |
|                                             is_intra,
 | |
|                                             i > 3 ? uvmv :
 | |
|                                                     &s->current_picture.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
 | |
|                                             i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 1 + v->mb_off] :
 | |
|                                                     &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
 | |
|                                             ttblk,
 | |
|                                             flags,
 | |
|                                             i);
 | |
|             }
 | |
|             dest = s->dest[0] - 32 * s->linesize;
 | |
|             cbp = &v->cbp[s->mb_x - 2 * s->mb_stride];
 | |
|             is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride];
 | |
|             uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride];
 | |
|             ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
 | |
|             flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_h_loop_filter(v,
 | |
|                                     i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest,
 | |
|                                     cbp,
 | |
|                                     is_intra,
 | |
|                                     i > 3 ? uvmv :
 | |
|                                             &s->current_picture.motion_val[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
 | |
|                                     i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride + v->mb_off] :
 | |
|                                             &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
 | |
|                                     ttblk,
 | |
|                                     flags,
 | |
|                                     i);
 | |
|         }
 | |
|     }
 | |
|     if (s->mb_y == s->end_mb_y - 1) {
 | |
|         if (s->mb_y >= s->start_mb_y + 1) {
 | |
|             if (s->mb_x >= 2) {
 | |
|                 dest = s->dest[0] - 16 * s->linesize - 32;
 | |
|                 cbp = &v->cbp[s->mb_x - s->mb_stride - 2];
 | |
|                 is_intra = &v->is_intra[s->mb_x - s->mb_stride - 2];
 | |
|                 uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 2];
 | |
|                 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 2];
 | |
|                 flags = s->mb_x == 2 ? LEFT_EDGE : 0;
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_h_loop_filter(v,
 | |
|                                         i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 16 : dest,
 | |
|                                         cbp,
 | |
|                                         is_intra,
 | |
|                                         i > 3 ? uvmv :
 | |
|                                                 &s->current_picture.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 4 + v->blocks_off],
 | |
|                                         i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 2 + v->mb_off] :
 | |
|                                                 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 4 + v->blocks_off],
 | |
|                                         ttblk,
 | |
|                                         flags,
 | |
|                                         i);
 | |
|             }
 | |
|             if (s->mb_x == s->mb_width - 1) {
 | |
|                 if (s->mb_x >= 1) {
 | |
|                     dest = s->dest[0] - 16 * s->linesize - 16;
 | |
|                     cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
 | |
|                     is_intra = &v->is_intra[s->mb_x - s->mb_stride - 1];
 | |
|                     uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
 | |
|                     ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
 | |
|                     flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|                     for (i = 0; i < block_count; i++)
 | |
|                             vc1_p_h_loop_filter(v,
 | |
|                                                 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
 | |
|                                                 cbp,
 | |
|                                                 is_intra,
 | |
|                                                 i > 3 ? uvmv :
 | |
|                                                         &s->current_picture.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
 | |
|                                                 i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 1 + v->mb_off] :
 | |
|                                                         &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
 | |
|                                                 ttblk,
 | |
|                                                 flags,
 | |
|                                                 i);
 | |
|                 }
 | |
|                 dest = s->dest[0] - 16 * s->linesize;
 | |
|                 cbp = &v->cbp[s->mb_x - s->mb_stride];
 | |
|                 is_intra = &v->is_intra[s->mb_x - s->mb_stride];
 | |
|                 uvmv = &v->luma_mv[s->mb_x - s->mb_stride];
 | |
|                 ttblk = &v->ttblk[s->mb_x - s->mb_stride];
 | |
|                 flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_h_loop_filter(v,
 | |
|                                         i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
 | |
|                                         cbp,
 | |
|                                         is_intra,
 | |
|                                         i > 3 ? uvmv :
 | |
|                                                 &s->current_picture.motion_val[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
 | |
|                                         i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride + v->mb_off] :
 | |
|                                                 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
 | |
|                                         ttblk,
 | |
|                                         flags,
 | |
|                                         i);
 | |
|             }
 | |
|         }
 | |
|         if (s->mb_x >= 2) {
 | |
|             dest = s->dest[0] - 32;
 | |
|             cbp = &v->cbp[s->mb_x - 2];
 | |
|             is_intra = &v->is_intra[s->mb_x - 2];
 | |
|             uvmv = &v->luma_mv[s->mb_x - 2];
 | |
|             ttblk = &v->ttblk[s->mb_x - 2];
 | |
|             flags = s->mb_x == 2 ? LEFT_EDGE : 0;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_h_loop_filter(v,
 | |
|                                     i > 3 ? s->dest[i - 3] - 16 : dest,
 | |
|                                     cbp,
 | |
|                                     is_intra,
 | |
|                                     i > 3 ? uvmv :
 | |
|                                             &s->current_picture.motion_val[0][s->block_index[i] - 4 + v->blocks_off],
 | |
|                                     i > 3 ? &v->mv_f[0][s->block_index[i] - 2 + v->mb_off] :
 | |
|                                             &v->mv_f[0][s->block_index[i] - 4 + v->blocks_off],
 | |
|                                     ttblk,
 | |
|                                     flags,
 | |
|                                     i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             if (s->mb_x >= 1) {
 | |
|                 dest = s->dest[0] - 16;
 | |
|                 cbp = &v->cbp[s->mb_x - 1];
 | |
|                 is_intra = &v->is_intra[s->mb_x - 1];
 | |
|                 uvmv = &v->luma_mv[s->mb_x - 1];
 | |
|                 ttblk = &v->ttblk[s->mb_x - 1];
 | |
|                 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_h_loop_filter(v,
 | |
|                                         i > 3 ? s->dest[i - 3] - 8 : dest,
 | |
|                                         cbp,
 | |
|                                         is_intra,
 | |
|                                         i > 3 ? uvmv :
 | |
|                                                 &s->current_picture.motion_val[0][s->block_index[i] - 2 + v->blocks_off],
 | |
|                                         i > 3 ? &v->mv_f[0][s->block_index[i] - 1 + v->mb_off] :
 | |
|                                                 &v->mv_f[0][s->block_index[i] - 2 + v->blocks_off],
 | |
|                                         ttblk,
 | |
|                                         flags,
 | |
|                                         i);
 | |
|             }
 | |
|             dest = s->dest[0];
 | |
|             cbp = &v->cbp[s->mb_x];
 | |
|             is_intra = &v->is_intra[s->mb_x];
 | |
|             uvmv = &v->luma_mv[s->mb_x];
 | |
|             ttblk = &v->ttblk[s->mb_x];
 | |
|             flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_h_loop_filter(v,
 | |
|                                     i > 3 ? s->dest[i - 3] : dest,
 | |
|                                     cbp,
 | |
|                                     is_intra,
 | |
|                                     i > 3 ? uvmv :
 | |
|                                             &s->current_picture.motion_val[0][s->block_index[i] + v->blocks_off],
 | |
|                                     i > 3 ? &v->mv_f[0][s->block_index[i] + v->mb_off] :
 | |
|                                             &v->mv_f[0][s->block_index[i] + v->blocks_off],
 | |
|                                     ttblk,
 | |
|                                     flags,
 | |
|                                     i);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static av_always_inline void vc1_p_h_intfr_loop_filter(VC1Context *v, uint8_t *dest, int *ttblk,
 | |
|                                                        uint32_t flags, uint8_t fieldtx, int block_num)
 | |
| {
 | |
|     MpegEncContext *s  = &v->s;
 | |
|     int pq = v->pq;
 | |
|     int tt;
 | |
|     int linesize  = block_num > 3 ? s->uvlinesize : s->linesize;
 | |
|     uint8_t *dst;
 | |
| 
 | |
|     if (block_num > 3)
 | |
|         dst = dest;
 | |
|     else
 | |
|         dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
 | |
| 
 | |
|     tt = ttblk[0] >> (block_num * 4) & 0xf;
 | |
|     if (block_num < 4) {
 | |
|         if (fieldtx) {
 | |
|             if (block_num < 2) {
 | |
|                 if (tt == TT_4X4 || tt == TT_4X8)
 | |
|                     v->vc1dsp.vc1_h_loop_filter8(dst + 4, 2 * linesize, pq);
 | |
|                 if (!(flags & RIGHT_EDGE) || block_num == 0)
 | |
|                     v->vc1dsp.vc1_h_loop_filter8(dst + 8, 2 * linesize, pq);
 | |
|             } else {
 | |
|                 if (tt == TT_4X4 || tt == TT_4X8)
 | |
|                     v->vc1dsp.vc1_h_loop_filter8(dst - 7 * linesize + 4, 2 * linesize, pq);
 | |
|                 if (!(flags & RIGHT_EDGE) || block_num == 2)
 | |
|                     v->vc1dsp.vc1_h_loop_filter8(dst - 7 * linesize + 8, 2 * linesize, pq);
 | |
|             }
 | |
|         } else {
 | |
|             if(tt == TT_4X4 || tt == TT_4X8) {
 | |
|                 v->vc1dsp.vc1_h_loop_filter4(dst + 4, 2 * linesize, pq);
 | |
|                 v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 4, 2 * linesize, pq);
 | |
|             }
 | |
|             if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
 | |
|                 v->vc1dsp.vc1_h_loop_filter4(dst + 8, 2 * linesize, pq);
 | |
|                 v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 8, 2 * linesize, pq);
 | |
|             }
 | |
|         }
 | |
|     } else {
 | |
|         if (tt == TT_4X4 || tt == TT_4X8) {
 | |
|             v->vc1dsp.vc1_h_loop_filter4(dst + 4, 2 * linesize, pq);
 | |
|             v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 4, 2 * linesize, pq);
 | |
|         }
 | |
|         if (!(flags & RIGHT_EDGE)) {
 | |
|             v->vc1dsp.vc1_h_loop_filter4(dst + 8, 2 * linesize, pq);
 | |
|             v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 8, 2 * linesize, pq);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static av_always_inline void vc1_p_v_intfr_loop_filter(VC1Context *v, uint8_t *dest, int *ttblk,
 | |
|                                                        uint32_t flags, uint8_t fieldtx, int block_num)
 | |
| {
 | |
|     MpegEncContext *s  = &v->s;
 | |
|     int pq = v->pq;
 | |
|     int tt;
 | |
|     int linesize  = block_num > 3 ? s->uvlinesize : s->linesize;
 | |
|     uint8_t *dst;
 | |
| 
 | |
|     if (block_num > 3)
 | |
|         dst = dest;
 | |
|     else
 | |
|         dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
 | |
| 
 | |
|     tt = ttblk[0] >> (block_num * 4) & 0xf;
 | |
|     if (block_num < 4) {
 | |
|         if (fieldtx) {
 | |
|             if (block_num < 2) {
 | |
|                 if (tt == TT_4X4 || tt == TT_8X4)
 | |
|                     v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
 | |
|                 if (!(flags & BOTTOM_EDGE))
 | |
|                     v->vc1dsp.vc1_v_loop_filter8(dst + 16 * linesize, 2 * linesize, pq);
 | |
|             } else {
 | |
|                 if (tt == TT_4X4 || tt == TT_8X4)
 | |
|                     v->vc1dsp.vc1_v_loop_filter8(dst + linesize, 2 * linesize, pq);
 | |
|                 if (!(flags & BOTTOM_EDGE))
 | |
|                     v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
 | |
|             }
 | |
|         } else {
 | |
|             if (block_num < 2) {
 | |
|                 if (!(flags & TOP_EDGE) && (tt == TT_4X4 || tt == TT_8X4)) {
 | |
|                     v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
 | |
|                     v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
 | |
|                 }
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
 | |
|             } else if (!(flags & BOTTOM_EDGE)) {
 | |
|                 if (tt == TT_4X4 || tt == TT_8X4) {
 | |
|                     v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
 | |
|                     v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
 | |
|                 }
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
 | |
|             }
 | |
|         }
 | |
|     } else {
 | |
|         if (!(flags & BOTTOM_EDGE)) {
 | |
|             if (!(flags & TOP_EDGE) && (tt == TT_4X4 || tt == TT_8X4)) {
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
 | |
|             }
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
 | |
|                 v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| void ff_vc1_p_intfr_loop_filter(VC1Context *v)
 | |
| {
 | |
|     MpegEncContext *s = &v->s;
 | |
|     int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
 | |
|     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
 | |
|     uint8_t *dest;
 | |
|     int *ttblk;
 | |
|     uint32_t flags;
 | |
|     uint8_t fieldtx;
 | |
|     int i;
 | |
| 
 | |
|     /* Within a MB, the vertical loop filter always runs before the horizontal.
 | |
|      * To accomplish that, we run the V loop filter on all applicable
 | |
|      * horizontal borders of the MB above the last overlap filtered MB. Then,
 | |
|      * we wait for the loop filter iteration on the next row and next column to
 | |
|      * do H loop filter on all applicable vertical borders of this MB.
 | |
|      * Therefore, the loop filter trails by two rows and one column relative to
 | |
|      * the overlap filter and two rows and two columns relative to the decoding
 | |
|      * loop. */
 | |
|     if (s->mb_x) {
 | |
|         if (s->mb_y >= s->start_mb_y + 1) {
 | |
|             dest = s->dest[0] - 16 * s->linesize - 16;
 | |
|             ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
 | |
|             flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_v_intfr_loop_filter(v,
 | |
|                                           i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
 | |
|                                           ttblk,
 | |
|                                           flags,
 | |
|                                           fieldtx,
 | |
|                                           i);
 | |
|         }
 | |
|     }
 | |
|     if (s->mb_x == s->mb_width - 1) {
 | |
|         if (s->mb_y >= s->start_mb_y + 1) {
 | |
|             dest = s->dest[0] - 16 * s->linesize;
 | |
|             ttblk = &v->ttblk[s->mb_x - s->mb_stride];
 | |
|             flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_v_intfr_loop_filter(v,
 | |
|                                           i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
 | |
|                                           ttblk,
 | |
|                                           flags,
 | |
|                                           fieldtx,
 | |
|                                           i);
 | |
|         }
 | |
|     }
 | |
|     if (s->mb_y == s->end_mb_y - 1) {
 | |
|         if (s->mb_x) {
 | |
|             dest = s->dest[0] - 16;
 | |
|             ttblk = &v->ttblk[s->mb_x - 1];
 | |
|             flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - 1];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_v_intfr_loop_filter(v,
 | |
|                                           i > 3 ? s->dest[i - 3] - 8 : dest,
 | |
|                                           ttblk,
 | |
|                                           flags,
 | |
|                                           fieldtx,
 | |
|                                           i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             dest = s->dest[0];
 | |
|             ttblk = &v->ttblk[s->mb_x];
 | |
|             flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_v_intfr_loop_filter(v,
 | |
|                                           i > 3 ? s->dest[i - 3] : dest,
 | |
|                                           ttblk,
 | |
|                                           flags,
 | |
|                                           fieldtx,
 | |
|                                           i);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (s->mb_y >= s->start_mb_y + 2) {
 | |
|         if (s->mb_x >= 2) {
 | |
|             dest = s->dest[0] - 32 * s->linesize - 32;
 | |
|             ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 2];
 | |
|             flags = s->mb_x == 2 ? LEFT_EDGE : 0;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride - 2];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_h_intfr_loop_filter(v,
 | |
|                                           i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 16 : dest,
 | |
|                                           ttblk,
 | |
|                                           flags,
 | |
|                                           fieldtx,
 | |
|                                           i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             if (s->mb_x >= 1) {
 | |
|                 dest = s->dest[0] - 32 * s->linesize - 16;
 | |
|                 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
 | |
|                 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|                 fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride - 1];
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_h_intfr_loop_filter(v,
 | |
|                                               i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest,
 | |
|                                               ttblk,
 | |
|                                               flags,
 | |
|                                               fieldtx,
 | |
|                                               i);
 | |
|             }
 | |
|             dest = s->dest[0] - 32 * s->linesize;
 | |
|             ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
 | |
|             flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_h_intfr_loop_filter(v,
 | |
|                                           i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest,
 | |
|                                           ttblk,
 | |
|                                           flags,
 | |
|                                           fieldtx,
 | |
|                                           i);
 | |
|         }
 | |
|     }
 | |
|     if (s->mb_y == s->end_mb_y - 1) {
 | |
|         if (s->mb_y >= s->start_mb_y + 1) {
 | |
|             if (s->mb_x >= 2) {
 | |
|                 dest = s->dest[0] - 16 * s->linesize - 32;
 | |
|                 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 2];
 | |
|                 flags = s->mb_x == 2 ? LEFT_EDGE : 0;
 | |
|                 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 2];
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_h_intfr_loop_filter(v,
 | |
|                                               i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 16 : dest,
 | |
|                                               ttblk,
 | |
|                                               flags,
 | |
|                                               fieldtx,
 | |
|                                               i);
 | |
|             }
 | |
|             if (s->mb_x == s->mb_width - 1) {
 | |
|                 if (s->mb_x >= 1) {
 | |
|                     dest = s->dest[0] - 16 * s->linesize - 16;
 | |
|                     ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
 | |
|                     flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|                     fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
 | |
|                     for (i = 0; i < block_count; i++)
 | |
|                         vc1_p_h_intfr_loop_filter(v,
 | |
|                                                   i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
 | |
|                                                   ttblk,
 | |
|                                                   flags,
 | |
|                                                   fieldtx,
 | |
|                                                   i);
 | |
|                 }
 | |
|                 dest = s->dest[0] - 16 * s->linesize;
 | |
|                 ttblk = &v->ttblk[s->mb_x - s->mb_stride];
 | |
|                 flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
 | |
|                 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_h_intfr_loop_filter(v,
 | |
|                                               i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
 | |
|                                               ttblk,
 | |
|                                               flags,
 | |
|                                               fieldtx,
 | |
|                                               i);
 | |
|             }
 | |
|         }
 | |
|         if (s->mb_x >= 2) {
 | |
|             dest = s->dest[0] - 32;
 | |
|             ttblk = &v->ttblk[s->mb_x - 2];
 | |
|             flags = s->mb_x == 2 ? LEFT_EDGE : 0;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos - 2];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_h_intfr_loop_filter(v,
 | |
|                                           i > 3 ? s->dest[i - 3] - 16 : dest,
 | |
|                                           ttblk,
 | |
|                                           flags,
 | |
|                                           fieldtx,
 | |
|                                           i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             if (s->mb_x >= 1) {
 | |
|                 dest = s->dest[0] - 16;
 | |
|                 ttblk = &v->ttblk[s->mb_x - 1];
 | |
|                 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|                 fieldtx = v->fieldtx_plane[mb_pos - 1];
 | |
|                 for (i = 0; i < block_count; i++)
 | |
|                     vc1_p_h_intfr_loop_filter(v,
 | |
|                                               i > 3 ? s->dest[i - 3] - 8 : dest,
 | |
|                                               ttblk,
 | |
|                                               flags,
 | |
|                                               fieldtx,
 | |
|                                               i);
 | |
|             }
 | |
|             dest = s->dest[0];
 | |
|             ttblk = &v->ttblk[s->mb_x];
 | |
|             flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
 | |
|             fieldtx = v->fieldtx_plane[mb_pos];
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_p_h_intfr_loop_filter(v,
 | |
|                                           i > 3 ? s->dest[i - 3] : dest,
 | |
|                                           ttblk,
 | |
|                                           flags,
 | |
|                                           fieldtx,
 | |
|                                           i);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static av_always_inline void vc1_b_h_intfi_loop_filter(VC1Context *v, uint8_t *dest, uint32_t *cbp,
 | |
|                                                        int *ttblk, uint32_t flags, int block_num)
 | |
| {
 | |
|     MpegEncContext *s  = &v->s;
 | |
|     int pq = v->pq;
 | |
|     uint8_t *dst;
 | |
|     uint32_t block_cbp = cbp[0] >> (block_num * 4);
 | |
|     int tt;
 | |
|     int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize;
 | |
| 
 | |
|     if (block_num > 3)
 | |
|         dst = dest;
 | |
|     else
 | |
|         dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
 | |
| 
 | |
|     if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
 | |
|         if (block_num > 3)
 | |
|             v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq);
 | |
|         else
 | |
|             v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq);
 | |
|     }
 | |
| 
 | |
|     tt = ttblk[0] >> (block_num * 4) & 0xf;
 | |
|     if (tt == TT_4X4 || tt == TT_4X8) {
 | |
|         idx = (block_cbp | (block_cbp >> 1)) & 5;
 | |
|         if (idx & 1)
 | |
|             v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
 | |
|         if (idx & 4)
 | |
|             v->vc1dsp.vc1_h_loop_filter4(dst + 4, linesize, pq);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static av_always_inline void vc1_b_v_intfi_loop_filter(VC1Context *v, uint8_t *dest, uint32_t *cbp,
 | |
|                                                        int *ttblk, uint32_t flags, int block_num)
 | |
| {
 | |
|     MpegEncContext *s  = &v->s;
 | |
|     int pq = v->pq;
 | |
|     uint8_t *dst;
 | |
|     uint32_t block_cbp = cbp[0] >> (block_num * 4);
 | |
|     int tt;
 | |
|     int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize;
 | |
| 
 | |
|     if (block_num > 3)
 | |
|         dst = dest;
 | |
|     else
 | |
|         dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
 | |
| 
 | |
|     if(!(flags & BOTTOM_EDGE) || block_num < 2)
 | |
|         v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, linesize, pq);
 | |
| 
 | |
|     tt = ttblk[0] >> (block_num * 4) & 0xf;
 | |
|     if (tt == TT_4X4 || tt == TT_8X4) {
 | |
|         idx = (block_cbp | (block_cbp >> 2)) & 3;
 | |
|         if (idx & 1)
 | |
|             v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
 | |
|         if (idx & 2)
 | |
|             v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize, linesize, pq);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void ff_vc1_b_intfi_loop_filter(VC1Context *v)
 | |
| {
 | |
|     MpegEncContext *s = &v->s;
 | |
|     int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
 | |
|     uint8_t *dest;
 | |
|     uint32_t *cbp;
 | |
|     int *ttblk;
 | |
|     uint32_t flags = 0;
 | |
|     int i;
 | |
| 
 | |
|     /* Within a MB, the vertical loop filter always runs before the horizontal.
 | |
|      * To accomplish that, we run the V loop filter on all applicable
 | |
|      * horizontal borders of the MB above the currently decoded MB. Then,
 | |
|      * we wait for the next loop filter iteration to do H loop filter on all
 | |
|      * applicable vertical borders of this MB. Therefore, the loop filter
 | |
|      * trails by one row and one column relative to the decoding loop. */
 | |
|     if (!s->first_slice_line) {
 | |
|         dest = s->dest[0] - 16 * s->linesize;
 | |
|         cbp = &v->cbp[s->mb_x - s->mb_stride];
 | |
|         ttblk = &v->ttblk[s->mb_x - s->mb_stride];
 | |
|         flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
 | |
|         for (i = 0; i < block_count; i++)
 | |
|             vc1_b_v_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, cbp, ttblk, flags, i);
 | |
|     }
 | |
|     if (s->mb_y == s->end_mb_y - 1) {
 | |
|         dest = s->dest[0];
 | |
|         cbp = &v->cbp[s->mb_x];
 | |
|         ttblk = &v->ttblk[s->mb_x];
 | |
|         flags = s->first_slice_line ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
 | |
|         for (i = 0; i < block_count; i++)
 | |
|             vc1_b_v_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, cbp, ttblk, flags, i);
 | |
|     }
 | |
| 
 | |
|     if (!s->first_slice_line) {
 | |
|         dest = s->dest[0] - 16 * s->linesize - 16;
 | |
|         cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
 | |
|         ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
 | |
|         if (s->mb_x) {
 | |
|             flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, cbp, ttblk, flags, i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             dest += 16;
 | |
|             cbp++;
 | |
|             ttblk++;
 | |
|             flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, cbp, ttblk, flags, i);
 | |
|         }
 | |
|     }
 | |
|     if (s->mb_y == s->end_mb_y - 1) {
 | |
|         dest = s->dest[0] - 16;
 | |
|         cbp = &v->cbp[s->mb_x - 1];
 | |
|         ttblk = &v->ttblk[s->mb_x - 1];
 | |
|         if (s->mb_x) {
 | |
|             flags = s->mb_x == 1 ? LEFT_EDGE : 0;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, cbp, ttblk, flags, i);
 | |
|         }
 | |
|         if (s->mb_x == s->mb_width - 1) {
 | |
|             dest += 16;
 | |
|             cbp++;
 | |
|             ttblk++;
 | |
|             flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
 | |
|             for (i = 0; i < block_count; i++)
 | |
|                 vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, cbp, ttblk, flags, i);
 | |
|         }
 | |
|     }
 | |
| }
 |