FFmpeg
Loading...
Searching...
No Matches
vc1_loopfilter.c
Go to the documentation of this file.
1/*
2 * VC-1 and WMV3 decoder
3 * Copyright (c) 2011 Mashiat Sarker Shakkhar
4 * Copyright (c) 2006-2007 Konstantin Shishkov
5 * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24/**
25 * @file
26 * VC-1 and WMV3 loopfilter
27 */
28
29#include "avcodec.h"
30#include "mpegvideo.h"
31#include "vc1.h"
32#include "vc1dsp.h"
33
34static av_always_inline void vc1_h_overlap_filter(VC1Context *v, int16_t (*left_block)[64],
35 int16_t (*right_block)[64], int left_fieldtx,
36 int right_fieldtx, int block_num)
37{
38 switch (block_num) {
39 case 0:
40 v->vc1dsp.vc1_h_s_overlap(left_block[2],
41 right_block[0],
42 left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8,
43 left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8,
44 left_fieldtx || right_fieldtx ? 0 : 1);
45 break;
46
47 case 1:
48 v->vc1dsp.vc1_h_s_overlap(right_block[0],
49 right_block[2],
50 8,
51 8,
52 right_fieldtx ? 0 : 1);
53 break;
54
55 case 2:
56 v->vc1dsp.vc1_h_s_overlap(!left_fieldtx && right_fieldtx ? left_block[2] + 8 : left_block[3],
57 left_fieldtx && !right_fieldtx ? right_block[0] + 8 : right_block[1],
58 left_fieldtx ^ right_fieldtx ? 16 - 8 * left_fieldtx : 8,
59 left_fieldtx ^ right_fieldtx ? 16 - 8 * right_fieldtx : 8,
60 left_fieldtx || right_fieldtx ? 2 : 1);
61 break;
62
63 case 3:
64 v->vc1dsp.vc1_h_s_overlap(right_block[1],
65 right_block[3],
66 8,
67 8,
68 right_fieldtx ? 2 : 1);
69 break;
70
71 case 4:
72 case 5:
73 v->vc1dsp.vc1_h_s_overlap(left_block[block_num], right_block[block_num], 8, 8, 1);
74 break;
75 }
76}
77
78static av_always_inline void vc1_v_overlap_filter(VC1Context *v, int16_t (*top_block)[64],
79 int16_t (*bottom_block)[64], int block_num)
80{
81 switch (block_num) {
82 case 0:
83 v->vc1dsp.vc1_v_s_overlap(top_block[1], bottom_block[0]);
84 break;
85
86 case 1:
87 v->vc1dsp.vc1_v_s_overlap(top_block[3], bottom_block[2]);
88 break;
89
90 case 2:
91 v->vc1dsp.vc1_v_s_overlap(bottom_block[0], bottom_block[1]);
92 break;
93
94 case 3:
95 v->vc1dsp.vc1_v_s_overlap(bottom_block[2], bottom_block[3]);
96 break;
97
98 case 4:
99 case 5:
100 v->vc1dsp.vc1_v_s_overlap(top_block[block_num], bottom_block[block_num]);
101 break;
102 }
103}
104
106{
107 MpegEncContext *s = &v->s;
108 int16_t (*topleft_blk)[64], (*top_blk)[64], (*left_blk)[64], (*cur_blk)[64];
109 int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
110 int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
111 int i;
112
113 topleft_blk = v->block[v->topleft_blk_idx];
114 top_blk = v->block[v->top_blk_idx];
115 left_blk = v->block[v->left_blk_idx];
116 cur_blk = v->block[v->cur_blk_idx];
117
118 /* Within a MB, the horizontal overlap always runs before the vertical.
119 * To accomplish that, we run the H on the left and internal vertical
120 * borders of the currently decoded MB. Then, we wait for the next overlap
121 * iteration to do H overlap on the right edge of this MB, before moving
122 * over and running the V overlap on the top and internal horizontal
123 * borders. Therefore, the H overlap trails by one MB col and the
124 * V overlap trails by one MB row. This is reflected in the time at which
125 * we run the put_pixels loop, i.e. delayed by one row and one column. */
126 for (i = 0; i < block_count; i++) {
127 if (s->mb_x == 0 && (i & 5) != 1)
128 continue;
129
130 if (v->pq >= 9 || (v->profile == PROFILE_ADVANCED &&
131 (v->condover == CONDOVER_ALL ||
132 (v->over_flags_plane[mb_pos] &&
133 ((i & 5) == 1 || v->over_flags_plane[mb_pos - 1])))))
135 s->mb_x ? left_blk : cur_blk, cur_blk,
136 v->fcm == ILACE_FRAME && s->mb_x && v->fieldtx_plane[mb_pos - 1],
137 v->fcm == ILACE_FRAME && v->fieldtx_plane[mb_pos],
138 i);
139 }
140
141 if (v->fcm != ILACE_FRAME)
142 for (i = 0; i < block_count; i++) {
143 if (s->first_slice_line && !(i & 2))
144 continue;
145
146 if (s->mb_x &&
147 (v->pq >= 9 || (v->profile == PROFILE_ADVANCED &&
148 (v->condover == CONDOVER_ALL ||
149 (v->over_flags_plane[mb_pos - 1] &&
150 ((i & 2) || v->over_flags_plane[mb_pos - 1 - s->mb_stride]))))))
151 vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i);
152 if (s->mb_x == s->mb_width - 1 &&
153 (v->pq >= 9 || (v->profile == PROFILE_ADVANCED &&
154 (v->condover == CONDOVER_ALL ||
155 (v->over_flags_plane[mb_pos] &&
156 ((i & 2) || v->over_flags_plane[mb_pos - s->mb_stride]))))))
157 vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i);
158 }
159}
160
162{
163 MpegEncContext *s = &v->s;
164 int16_t (*topleft_blk)[64], (*top_blk)[64], (*left_blk)[64], (*cur_blk)[64];
165 int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
166 int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
167 int i;
168
169 topleft_blk = v->block[v->topleft_blk_idx];
170 top_blk = v->block[v->top_blk_idx];
171 left_blk = v->block[v->left_blk_idx];
172 cur_blk = v->block[v->cur_blk_idx];
173
174 for (i = 0; i < block_count; i++) {
175 if (s->mb_x == 0 && (i & 5) != 1)
176 continue;
177
178 if (v->mb_type[s->block_index[i]] && v->mb_type[s->block_index[i] - 1])
180 s->mb_x ? left_blk : cur_blk, cur_blk,
181 v->fcm == ILACE_FRAME && s->mb_x && v->fieldtx_plane[mb_pos - 1],
182 v->fcm == ILACE_FRAME && v->fieldtx_plane[mb_pos],
183 i);
184 }
185
186 if (v->fcm != ILACE_FRAME)
187 for (i = 0; i < block_count; i++) {
188 if (s->first_slice_line && !(i & 2))
189 continue;
190
191 if (s->mb_x && v->mb_type[s->block_index[i] - 2 + (i > 3)] &&
192 v->mb_type[s->block_index[i] - s->block_wrap[i] - 2 + (i > 3)])
193 vc1_v_overlap_filter(v, s->first_slice_line ? left_blk : topleft_blk, left_blk, i);
194 if (s->mb_x == s->mb_width - 1)
195 if (v->mb_type[s->block_index[i]] &&
196 v->mb_type[s->block_index[i] - s->block_wrap[i]])
197 vc1_v_overlap_filter(v, s->first_slice_line ? cur_blk : top_blk, cur_blk, i);
198 }
199}
200
201#define LEFT_EDGE (1 << 0)
202#define RIGHT_EDGE (1 << 1)
203#define TOP_EDGE (1 << 2)
204#define BOTTOM_EDGE (1 << 3)
205
206static av_always_inline void vc1_i_h_loop_filter(VC1Context *v, uint8_t *dest,
207 uint32_t flags, int block_num)
208{
209 MpegEncContext *s = &v->s;
210 int pq = v->pq;
211 uint8_t *dst;
212
213 if (block_num & 2)
214 return;
215
216 if (!(flags & LEFT_EDGE) || (block_num & 5) == 1) {
217 if (block_num > 3)
218 dst = dest;
219 else
220 dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
221
222 if (v->fcm == ILACE_FRAME)
223 if (block_num > 3) {
224 v->vc1dsp.vc1_h_loop_filter4(dst, 2 * s->uvlinesize, pq);
225 v->vc1dsp.vc1_h_loop_filter4(dst + s->uvlinesize, 2 * s->uvlinesize, pq);
226 } else {
227 v->vc1dsp.vc1_h_loop_filter8(dst, 2 * s->linesize, pq);
228 v->vc1dsp.vc1_h_loop_filter8(dst + s->linesize, 2 * s->linesize, pq);
229 }
230 else
231 if (block_num > 3)
232 v->vc1dsp.vc1_h_loop_filter8(dst, s->uvlinesize, pq);
233 else
234 v->vc1dsp.vc1_h_loop_filter16(dst, s->linesize, pq);
235 }
236}
237
238static av_always_inline void vc1_i_v_loop_filter(VC1Context *v, uint8_t *dest,
239 uint32_t flags, uint8_t fieldtx,
240 int block_num)
241{
242 MpegEncContext *s = &v->s;
243 int pq = v->pq;
244 uint8_t *dst;
245
246 if ((block_num & 5) == 1)
247 return;
248
249 if (!(flags & TOP_EDGE) || block_num & 2) {
250 if (block_num > 3)
251 dst = dest;
252 else
253 dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
254
255 if (v->fcm == ILACE_FRAME) {
256 if (block_num > 3) {
257 v->vc1dsp.vc1_v_loop_filter8(dst, 2 * s->uvlinesize, pq);
258 v->vc1dsp.vc1_v_loop_filter8(dst + s->uvlinesize, 2 * s->uvlinesize, pq);
259 } else if (block_num < 2 || !fieldtx) {
260 v->vc1dsp.vc1_v_loop_filter16(dst, 2 * s->linesize, pq);
261 v->vc1dsp.vc1_v_loop_filter16(dst + s->linesize, 2 * s->linesize, pq);
262 }
263 } else
264 if (block_num > 3)
265 v->vc1dsp.vc1_v_loop_filter8(dst, s->uvlinesize, pq);
266 else
267 v->vc1dsp.vc1_v_loop_filter16(dst, s->linesize, pq);
268 }
269}
270
272{
273 MpegEncContext *s = &v->s;
274 int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
275 int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
276 uint8_t *dest, fieldtx;
277 uint32_t flags = 0;
278 int i;
279
280 /* Within a MB, the vertical loop filter always runs before the horizontal.
281 * To accomplish that, we run the V loop filter on top and internal
282 * horizontal borders of the last overlap filtered MB. Then, we wait for
283 * the loop filter iteration on the next row to do V loop filter on the
284 * bottom edge of this MB, before moving over and running the H loop
285 * filter on the left and internal vertical borders. Therefore, the loop
286 * filter trails by one row and one column relative to the overlap filter
287 * and two rows and two columns relative to the decoding loop. */
288 if (!s->first_slice_line) {
289 dest = s->dest[0] - 16 * s->linesize - 16;
290 flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
291 if (s->mb_x) {
292 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
293 for (i = 0; i < block_count; i++)
294 vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, flags, fieldtx, i);
295 }
296 if (s->mb_x == v->end_mb_x - 1) {
297 dest += 16;
298 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
299 for (i = 0; i < block_count; i++)
300 vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, flags, fieldtx, i);
301 }
302 }
303 if (s->mb_y == s->end_mb_y - 1) {
304 dest = s->dest[0] - 16;
305 flags = s->first_slice_line ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
306 if (s->mb_x) {
307 fieldtx = v->fieldtx_plane[mb_pos - 1];
308 for (i = 0; i < block_count; i++)
309 vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, flags, fieldtx, i);
310 }
311 if (s->mb_x == v->end_mb_x - 1) {
312 dest += 16;
313 fieldtx = v->fieldtx_plane[mb_pos];
314 for (i = 0; i < block_count; i++)
315 vc1_i_v_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, flags, fieldtx, i);
316 }
317 }
318
319 if (s->mb_y >= s->start_mb_y + 2) {
320 dest = s->dest[0] - 32 * s->linesize - 16;
321 if (s->mb_x) {
322 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
323 for (i = 0; i < block_count; i++)
324 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest, flags, i);
325 }
326 if (s->mb_x == v->end_mb_x - 1) {
327 dest += 16;
328 flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
329 for (i = 0; i < block_count; i++)
330 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest, flags, i);
331 }
332 }
333 if (s->mb_y == s->end_mb_y - 1) {
334 if (s->mb_y >= s->start_mb_y + 1) {
335 dest = s->dest[0] - 16 * s->linesize - 16;
336 if (s->mb_x) {
337 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
338 for (i = 0; i < block_count; i++)
339 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, flags, i);
340 }
341 if (s->mb_x == v->end_mb_x - 1) {
342 flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
343 dest += 16;
344 for (i = 0; i < block_count; i++)
345 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, flags, i);
346 }
347 }
348 dest = s->dest[0] - 16;
349 if (s->mb_x) {
350 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
351 for (i = 0; i < block_count; i++)
352 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, flags, i);
353 }
354 if (s->mb_x == v->end_mb_x - 1) {
355 dest += 16;
356 flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
357 for (i = 0; i < block_count; i++)
358 vc1_i_h_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, flags, i);
359 }
360 }
361}
362
363static av_always_inline void vc1_p_h_loop_filter(VC1Context *v, uint8_t *dest, uint32_t *cbp,
364 uint8_t *is_intra, int16_t (*mv)[2], uint8_t *mv_f,
365 int *ttblk, uint32_t flags, int block_num)
366{
367 MpegEncContext *s = &v->s;
368 int pq = v->pq;
369 uint32_t left_cbp = cbp[0] >> (block_num * 4), right_cbp;
370 uint8_t left_is_intra, right_is_intra;
371 int tt;
372 int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize;
373 uint8_t *dst;
374
375 if (block_num > 3)
376 dst = dest;
377 else
378 dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
379
380 if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
381 left_is_intra = is_intra[0] & (1 << block_num);
382
383 if (block_num > 3) {
384 right_is_intra = is_intra[1] & (1 << block_num);
385 right_cbp = cbp[1] >> (block_num * 4);
386 } else if (block_num & 1) {
387 right_is_intra = is_intra[1] & (1 << block_num - 1);
388 right_cbp = cbp[1] >> ((block_num - 1) * 4);
389 } else {
390 right_is_intra = is_intra[0] & (1 << block_num + 1);
391 right_cbp = cbp[0] >> ((block_num + 1) * 4);
392 }
393
394 if (left_is_intra || right_is_intra ||
395 mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1] ||
396 (v->fcm == ILACE_FIELD && mv_f[0] != mv_f[1]))
397 v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq);
398 else {
399 idx = (left_cbp | (right_cbp >> 1)) & 5;
400 if (idx & 1)
401 v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 8, linesize, pq);
402 if (idx & 4)
403 v->vc1dsp.vc1_h_loop_filter4(dst + 8, linesize, pq);
404 }
405 }
406
407 tt = ttblk[0] >> (block_num * 4) & 0xf;
408 if (tt == TT_4X4 || tt == TT_4X8) {
409 if (left_cbp & 3)
410 v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
411 if (left_cbp & 12)
412 v->vc1dsp.vc1_h_loop_filter4(dst + 4, linesize, pq);
413 }
414}
415
416static av_always_inline
417void vc1_p_v_loop_filter(VC1Context *v, uint8_t *dest, const uint32_t *cbp,
418 const uint8_t *is_intra, int16_t (*mv)[2], const uint8_t *mv_f,
419 const int *ttblk, uint32_t flags, int block_num)
420{
421 MpegEncContext *s = &v->s;
422 int pq = v->pq;
423 uint32_t top_cbp = cbp[0] >> (block_num * 4), bottom_cbp;
424 uint8_t top_is_intra, bottom_is_intra;
425 int tt;
426 int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize;
427 uint8_t *dst;
428
429 if (block_num > 3)
430 dst = dest;
431 else
432 dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
433
434 if(!(flags & BOTTOM_EDGE) || block_num < 2) {
435 top_is_intra = is_intra[0] & (1 << block_num);
436
437 if (block_num > 3) {
438 bottom_is_intra = is_intra[s->mb_stride] & (1 << block_num);
439 bottom_cbp = cbp[s->mb_stride] >> (block_num * 4);
440 } else if (block_num < 2) {
441 bottom_is_intra = is_intra[0] & (1 << block_num + 2);
442 bottom_cbp = cbp[0] >> ((block_num + 2) * 4);
443 } else {
444 bottom_is_intra = is_intra[s->mb_stride] & (1 << block_num - 2);
445 bottom_cbp = cbp[s->mb_stride] >> ((block_num - 2) * 4);
446 }
447
448 if (top_is_intra || bottom_is_intra ||
449 mv[0][0] != mv[block_num > 3 ? s->mb_stride : s->b8_stride][0] ||
450 mv[0][1] != mv[block_num > 3 ? s->mb_stride : s->b8_stride][1] ||
451 (v->fcm == ILACE_FIELD && mv_f[0] != mv_f[block_num > 3 ? s->mb_stride : s->b8_stride]))
452 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, linesize, pq);
453 else {
454 idx = (top_cbp | (bottom_cbp >> 2)) & 3;
455 if (idx & 1)
456 v->vc1dsp.vc1_v_loop_filter4(dst + 8 * linesize + 4, linesize, pq);
457 if (idx & 2)
458 v->vc1dsp.vc1_v_loop_filter4(dst + 8 * linesize, linesize, pq);
459 }
460 }
461
462 tt = ttblk[0] >> (block_num * 4) & 0xf;
463 if (tt == TT_4X4 || tt == TT_8X4) {
464 if (top_cbp & 5)
465 v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
466 if (top_cbp & 10)
467 v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize, linesize, pq);
468 }
469}
470
472{
473 MpegEncContext *s = &v->s;
474 int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
475 uint8_t *dest;
476 uint32_t *cbp;
477 uint8_t *is_intra;
478 int16_t (*uvmv)[2];
479 int *ttblk;
480 uint32_t flags;
481 int i;
482
483 /* Within a MB, the vertical loop filter always runs before the horizontal.
484 * To accomplish that, we run the V loop filter on all applicable
485 * horizontal borders of the MB above the last overlap filtered MB. Then,
486 * we wait for the next loop filter iteration to do H loop filter on all
487 * applicable vertical borders of this MB. Therefore, the loop filter
488 * trails by one row and one column relative to the overlap filter and two
489 * rows and two columns relative to the decoding loop. */
490 if (s->mb_y >= s->start_mb_y + 2) {
491 if (s->mb_x) {
492 dest = s->dest[0] - 32 * s->linesize - 16;
493 cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 1];
494 is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 1];
495 uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 1];
496 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
497 flags = s->mb_y == s->start_mb_y + 2 ? TOP_EDGE : 0;
498 for (i = 0; i < block_count; i++)
500 i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest,
501 cbp,
502 is_intra,
503 i > 3 ? uvmv :
504 &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
505 i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 1 + v->mb_off] :
506 &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
507 ttblk,
508 flags,
509 i);
510 }
511 if (s->mb_x == s->mb_width - 1) {
512 dest = s->dest[0] - 32 * s->linesize;
513 cbp = &v->cbp[s->mb_x - 2 * s->mb_stride];
514 is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride];
515 uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride];
516 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
517 flags = s->mb_y == s->start_mb_y + 2 ? TOP_EDGE : 0;
518 for (i = 0; i < block_count; i++)
520 i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest,
521 cbp,
522 is_intra,
523 i > 3 ? uvmv :
524 &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
525 i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride + v->mb_off] :
526 &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
527 ttblk,
528 flags,
529 i);
530 }
531 }
532 if (s->mb_y == s->end_mb_y - 1) {
533 if (s->mb_x) {
534 if (s->mb_y >= s->start_mb_y + 1) {
535 dest = s->dest[0] - 16 * s->linesize - 16;
536 cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
537 is_intra = &v->is_intra[s->mb_x - s->mb_stride - 1];
538 uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
539 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
540 flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
541 for (i = 0; i < block_count; i++)
543 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
544 cbp,
545 is_intra,
546 i > 3 ? uvmv :
547 &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
548 i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 1 + v->mb_off] :
549 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
550 ttblk,
551 flags,
552 i);
553 }
554 dest = s->dest[0] - 16;
555 cbp = &v->cbp[s->mb_x - 1];
556 is_intra = &v->is_intra[s->mb_x - 1];
557 uvmv = &v->luma_mv[s->mb_x - 1];
558 ttblk = &v->ttblk[s->mb_x - 1];
559 flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
560 for (i = 0; i < block_count; i++)
562 i > 3 ? s->dest[i - 3] - 8 : dest,
563 cbp,
564 is_intra,
565 i > 3 ? uvmv :
566 &s->cur_pic.motion_val[0][s->block_index[i] - 2 + v->blocks_off],
567 i > 3 ? &v->mv_f[0][s->block_index[i] - 1 + v->mb_off] :
568 &v->mv_f[0][s->block_index[i] - 2 + v->blocks_off],
569 ttblk,
570 flags,
571 i);
572 }
573 if (s->mb_x == s->mb_width - 1) {
574 if (s->mb_y >= s->start_mb_y + 1) {
575 dest = s->dest[0] - 16 * s->linesize;
576 cbp = &v->cbp[s->mb_x - s->mb_stride];
577 is_intra = &v->is_intra[s->mb_x - s->mb_stride];
578 uvmv = &v->luma_mv[s->mb_x - s->mb_stride];
579 ttblk = &v->ttblk[s->mb_x - s->mb_stride];
580 flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
581 for (i = 0; i < block_count; i++)
583 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
584 cbp,
585 is_intra,
586 i > 3 ? uvmv :
587 &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
588 i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride + v->mb_off] :
589 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
590 ttblk,
591 flags,
592 i);
593 }
594 dest = s->dest[0];
595 cbp = &v->cbp[s->mb_x];
596 is_intra = &v->is_intra[s->mb_x];
597 uvmv = &v->luma_mv[s->mb_x];
598 ttblk = &v->ttblk[s->mb_x];
599 flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
600 for (i = 0; i < block_count; i++)
602 i > 3 ? s->dest[i - 3] : dest,
603 cbp,
604 is_intra,
605 i > 3 ? uvmv :
606 &s->cur_pic.motion_val[0][s->block_index[i] + v->blocks_off],
607 i > 3 ? &v->mv_f[0][s->block_index[i] + v->mb_off] :
608 &v->mv_f[0][s->block_index[i] + v->blocks_off],
609 ttblk,
610 flags,
611 i);
612 }
613 }
614
615 if (s->mb_y >= s->start_mb_y + 2) {
616 if (s->mb_x >= 2) {
617 dest = s->dest[0] - 32 * s->linesize - 32;
618 cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 2];
619 is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 2];
620 uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 2];
621 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 2];
622 flags = s->mb_x == 2 ? LEFT_EDGE : 0;
623 for (i = 0; i < block_count; i++)
625 i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 16 : dest,
626 cbp,
627 is_intra,
628 i > 3 ? uvmv :
629 &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 4 + v->blocks_off],
630 i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 2 + v->mb_off] :
631 &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 4 + v->blocks_off],
632 ttblk,
633 flags,
634 i);
635 }
636 if (s->mb_x == s->mb_width - 1) {
637 if (s->mb_x >= 1) {
638 dest = s->dest[0] - 32 * s->linesize - 16;
639 cbp = &v->cbp[s->mb_x - 2 * s->mb_stride - 1];
640 is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride - 1];
641 uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride - 1];
642 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
643 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
644 for (i = 0; i < block_count; i++)
646 i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest,
647 cbp,
648 is_intra,
649 i > 3 ? uvmv :
650 &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
651 i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride - 1 + v->mb_off] :
652 &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride - 2 + v->blocks_off],
653 ttblk,
654 flags,
655 i);
656 }
657 dest = s->dest[0] - 32 * s->linesize;
658 cbp = &v->cbp[s->mb_x - 2 * s->mb_stride];
659 is_intra = &v->is_intra[s->mb_x - 2 * s->mb_stride];
660 uvmv = &v->luma_mv[s->mb_x - 2 * s->mb_stride];
661 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
662 flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
663 for (i = 0; i < block_count; i++)
665 i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest,
666 cbp,
667 is_intra,
668 i > 3 ? uvmv :
669 &s->cur_pic.motion_val[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
670 i > 3 ? &v->mv_f[0][s->block_index[i] - 2 * s->mb_stride + v->mb_off] :
671 &v->mv_f[0][s->block_index[i] - 4 * s->b8_stride + v->blocks_off],
672 ttblk,
673 flags,
674 i);
675 }
676 }
677 if (s->mb_y == s->end_mb_y - 1) {
678 if (s->mb_y >= s->start_mb_y + 1) {
679 if (s->mb_x >= 2) {
680 dest = s->dest[0] - 16 * s->linesize - 32;
681 cbp = &v->cbp[s->mb_x - s->mb_stride - 2];
682 is_intra = &v->is_intra[s->mb_x - s->mb_stride - 2];
683 uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 2];
684 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 2];
685 flags = s->mb_x == 2 ? LEFT_EDGE : 0;
686 for (i = 0; i < block_count; i++)
688 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 16 : dest,
689 cbp,
690 is_intra,
691 i > 3 ? uvmv :
692 &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 4 + v->blocks_off],
693 i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 2 + v->mb_off] :
694 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 4 + v->blocks_off],
695 ttblk,
696 flags,
697 i);
698 }
699 if (s->mb_x == s->mb_width - 1) {
700 if (s->mb_x >= 1) {
701 dest = s->dest[0] - 16 * s->linesize - 16;
702 cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
703 is_intra = &v->is_intra[s->mb_x - s->mb_stride - 1];
704 uvmv = &v->luma_mv[s->mb_x - s->mb_stride - 1];
705 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
706 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
707 for (i = 0; i < block_count; i++)
709 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
710 cbp,
711 is_intra,
712 i > 3 ? uvmv :
713 &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
714 i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride - 1 + v->mb_off] :
715 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride - 2 + v->blocks_off],
716 ttblk,
717 flags,
718 i);
719 }
720 dest = s->dest[0] - 16 * s->linesize;
721 cbp = &v->cbp[s->mb_x - s->mb_stride];
722 is_intra = &v->is_intra[s->mb_x - s->mb_stride];
723 uvmv = &v->luma_mv[s->mb_x - s->mb_stride];
724 ttblk = &v->ttblk[s->mb_x - s->mb_stride];
725 flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
726 for (i = 0; i < block_count; i++)
728 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
729 cbp,
730 is_intra,
731 i > 3 ? uvmv :
732 &s->cur_pic.motion_val[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
733 i > 3 ? &v->mv_f[0][s->block_index[i] - s->mb_stride + v->mb_off] :
734 &v->mv_f[0][s->block_index[i] - 2 * s->b8_stride + v->blocks_off],
735 ttblk,
736 flags,
737 i);
738 }
739 }
740 if (s->mb_x >= 2) {
741 dest = s->dest[0] - 32;
742 cbp = &v->cbp[s->mb_x - 2];
743 is_intra = &v->is_intra[s->mb_x - 2];
744 uvmv = &v->luma_mv[s->mb_x - 2];
745 ttblk = &v->ttblk[s->mb_x - 2];
746 flags = s->mb_x == 2 ? LEFT_EDGE : 0;
747 for (i = 0; i < block_count; i++)
749 i > 3 ? s->dest[i - 3] - 16 : dest,
750 cbp,
751 is_intra,
752 i > 3 ? uvmv :
753 &s->cur_pic.motion_val[0][s->block_index[i] - 4 + v->blocks_off],
754 i > 3 ? &v->mv_f[0][s->block_index[i] - 2 + v->mb_off] :
755 &v->mv_f[0][s->block_index[i] - 4 + v->blocks_off],
756 ttblk,
757 flags,
758 i);
759 }
760 if (s->mb_x == s->mb_width - 1) {
761 if (s->mb_x >= 1) {
762 dest = s->dest[0] - 16;
763 cbp = &v->cbp[s->mb_x - 1];
764 is_intra = &v->is_intra[s->mb_x - 1];
765 uvmv = &v->luma_mv[s->mb_x - 1];
766 ttblk = &v->ttblk[s->mb_x - 1];
767 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
768 for (i = 0; i < block_count; i++)
770 i > 3 ? s->dest[i - 3] - 8 : dest,
771 cbp,
772 is_intra,
773 i > 3 ? uvmv :
774 &s->cur_pic.motion_val[0][s->block_index[i] - 2 + v->blocks_off],
775 i > 3 ? &v->mv_f[0][s->block_index[i] - 1 + v->mb_off] :
776 &v->mv_f[0][s->block_index[i] - 2 + v->blocks_off],
777 ttblk,
778 flags,
779 i);
780 }
781 dest = s->dest[0];
782 cbp = &v->cbp[s->mb_x];
783 is_intra = &v->is_intra[s->mb_x];
784 uvmv = &v->luma_mv[s->mb_x];
785 ttblk = &v->ttblk[s->mb_x];
786 flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
787 for (i = 0; i < block_count; i++)
789 i > 3 ? s->dest[i - 3] : dest,
790 cbp,
791 is_intra,
792 i > 3 ? uvmv :
793 &s->cur_pic.motion_val[0][s->block_index[i] + v->blocks_off],
794 i > 3 ? &v->mv_f[0][s->block_index[i] + v->mb_off] :
795 &v->mv_f[0][s->block_index[i] + v->blocks_off],
796 ttblk,
797 flags,
798 i);
799 }
800 }
801}
802
803static av_always_inline void vc1_p_h_intfr_loop_filter(VC1Context *v, uint8_t *dest, const int *ttblk,
804 uint32_t flags, uint8_t fieldtx, int block_num)
805{
806 MpegEncContext *s = &v->s;
807 int pq = v->pq;
808 int tt;
809 int linesize = block_num > 3 ? s->uvlinesize : s->linesize;
810 uint8_t *dst;
811
812 if (block_num > 3)
813 dst = dest;
814 else
815 dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
816
817 tt = ttblk[0] >> (block_num * 4) & 0xf;
818 if (block_num < 4) {
819 if (fieldtx) {
820 if (block_num < 2) {
821 if (tt == TT_4X4 || tt == TT_4X8)
822 v->vc1dsp.vc1_h_loop_filter8(dst + 4, 2 * linesize, pq);
823 if (!(flags & RIGHT_EDGE) || block_num == 0)
824 v->vc1dsp.vc1_h_loop_filter8(dst + 8, 2 * linesize, pq);
825 } else {
826 if (tt == TT_4X4 || tt == TT_4X8)
827 v->vc1dsp.vc1_h_loop_filter8(dst - 7 * linesize + 4, 2 * linesize, pq);
828 if (!(flags & RIGHT_EDGE) || block_num == 2)
829 v->vc1dsp.vc1_h_loop_filter8(dst - 7 * linesize + 8, 2 * linesize, pq);
830 }
831 } else {
832 if(tt == TT_4X4 || tt == TT_4X8) {
833 v->vc1dsp.vc1_h_loop_filter4(dst + 4, 2 * linesize, pq);
834 v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 4, 2 * linesize, pq);
835 }
836 if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
837 v->vc1dsp.vc1_h_loop_filter4(dst + 8, 2 * linesize, pq);
838 v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 8, 2 * linesize, pq);
839 }
840 }
841 } else {
842 if (tt == TT_4X4 || tt == TT_4X8) {
843 v->vc1dsp.vc1_h_loop_filter4(dst + 4, 2 * linesize, pq);
844 v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 4, 2 * linesize, pq);
845 }
846 if (!(flags & RIGHT_EDGE)) {
847 v->vc1dsp.vc1_h_loop_filter4(dst + 8, 2 * linesize, pq);
848 v->vc1dsp.vc1_h_loop_filter4(dst + linesize + 8, 2 * linesize, pq);
849 }
850 }
851}
852
853static av_always_inline
854void vc1_p_v_intfr_loop_filter(VC1Context *v, uint8_t *dest, const int *ttblk,
855 uint32_t flags, uint8_t fieldtx, int block_num)
856{
857 MpegEncContext *s = &v->s;
858 int pq = v->pq;
859 int tt;
860 int linesize = block_num > 3 ? s->uvlinesize : s->linesize;
861 uint8_t *dst;
862
863 if (block_num > 3)
864 dst = dest;
865 else
866 dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
867
868 tt = ttblk[0] >> (block_num * 4) & 0xf;
869 if (block_num < 4) {
870 if (fieldtx) {
871 if (block_num < 2) {
872 if (tt == TT_4X4 || tt == TT_8X4)
873 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
874 if (!(flags & BOTTOM_EDGE))
875 v->vc1dsp.vc1_v_loop_filter8(dst + 16 * linesize, 2 * linesize, pq);
876 } else {
877 if (tt == TT_4X4 || tt == TT_8X4)
878 v->vc1dsp.vc1_v_loop_filter8(dst + linesize, 2 * linesize, pq);
879 if (!(flags & BOTTOM_EDGE))
880 v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
881 }
882 } else {
883 if (block_num < 2) {
884 if (!(flags & TOP_EDGE) && (tt == TT_4X4 || tt == TT_8X4)) {
885 v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
886 v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
887 }
888 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
889 v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
890 } else if (!(flags & BOTTOM_EDGE)) {
891 if (tt == TT_4X4 || tt == TT_8X4) {
892 v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
893 v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
894 }
895 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
896 v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
897 }
898 }
899 } else {
900 if (!(flags & BOTTOM_EDGE)) {
901 if (!(flags & TOP_EDGE) && (tt == TT_4X4 || tt == TT_8X4)) {
902 v->vc1dsp.vc1_v_loop_filter8(dst + 4 * linesize, 2 * linesize, pq);
903 v->vc1dsp.vc1_v_loop_filter8(dst + 5 * linesize, 2 * linesize, pq);
904 }
905 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, 2 * linesize, pq);
906 v->vc1dsp.vc1_v_loop_filter8(dst + 9 * linesize, 2 * linesize, pq);
907 }
908 }
909}
910
912{
913 MpegEncContext *s = &v->s;
914 int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
915 int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
916 uint8_t *dest;
917 int *ttblk;
918 uint32_t flags;
919 uint8_t fieldtx;
920 int i;
921
922 /* Within a MB, the vertical loop filter always runs before the horizontal.
923 * To accomplish that, we run the V loop filter on all applicable
924 * horizontal borders of the MB above the last overlap filtered MB. Then,
925 * we wait for the loop filter iteration on the next row and next column to
926 * do H loop filter on all applicable vertical borders of this MB.
927 * Therefore, the loop filter trails by two rows and one column relative to
928 * the overlap filter and two rows and two columns relative to the decoding
929 * loop. */
930 if (s->mb_x) {
931 if (s->mb_y >= s->start_mb_y + 1) {
932 dest = s->dest[0] - 16 * s->linesize - 16;
933 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
934 flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
935 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
936 for (i = 0; i < block_count; i++)
938 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
939 ttblk,
940 flags,
941 fieldtx,
942 i);
943 }
944 }
945 if (s->mb_x == s->mb_width - 1) {
946 if (s->mb_y >= s->start_mb_y + 1) {
947 dest = s->dest[0] - 16 * s->linesize;
948 ttblk = &v->ttblk[s->mb_x - s->mb_stride];
949 flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
950 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
951 for (i = 0; i < block_count; i++)
953 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
954 ttblk,
955 flags,
956 fieldtx,
957 i);
958 }
959 }
960 if (s->mb_y == s->end_mb_y - 1) {
961 if (s->mb_x) {
962 dest = s->dest[0] - 16;
963 ttblk = &v->ttblk[s->mb_x - 1];
964 flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
965 fieldtx = v->fieldtx_plane[mb_pos - 1];
966 for (i = 0; i < block_count; i++)
968 i > 3 ? s->dest[i - 3] - 8 : dest,
969 ttblk,
970 flags,
971 fieldtx,
972 i);
973 }
974 if (s->mb_x == s->mb_width - 1) {
975 dest = s->dest[0];
976 ttblk = &v->ttblk[s->mb_x];
977 flags = s->mb_y == s->start_mb_y ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
978 fieldtx = v->fieldtx_plane[mb_pos];
979 for (i = 0; i < block_count; i++)
981 i > 3 ? s->dest[i - 3] : dest,
982 ttblk,
983 flags,
984 fieldtx,
985 i);
986 }
987 }
988
989 if (s->mb_y >= s->start_mb_y + 2) {
990 if (s->mb_x >= 2) {
991 dest = s->dest[0] - 32 * s->linesize - 32;
992 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 2];
993 flags = s->mb_x == 2 ? LEFT_EDGE : 0;
994 fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride - 2];
995 for (i = 0; i < block_count; i++)
997 i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 16 : dest,
998 ttblk,
999 flags,
1000 fieldtx,
1001 i);
1002 }
1003 if (s->mb_x == s->mb_width - 1) {
1004 if (s->mb_x >= 1) {
1005 dest = s->dest[0] - 32 * s->linesize - 16;
1006 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride - 1];
1007 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
1008 fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride - 1];
1009 for (i = 0; i < block_count; i++)
1011 i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize - 8 : dest,
1012 ttblk,
1013 flags,
1014 fieldtx,
1015 i);
1016 }
1017 dest = s->dest[0] - 32 * s->linesize;
1018 ttblk = &v->ttblk[s->mb_x - 2 * s->mb_stride];
1019 flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
1020 fieldtx = v->fieldtx_plane[mb_pos - 2 * s->mb_stride];
1021 for (i = 0; i < block_count; i++)
1023 i > 3 ? s->dest[i - 3] - 16 * s->uvlinesize : dest,
1024 ttblk,
1025 flags,
1026 fieldtx,
1027 i);
1028 }
1029 }
1030 if (s->mb_y == s->end_mb_y - 1) {
1031 if (s->mb_y >= s->start_mb_y + 1) {
1032 if (s->mb_x >= 2) {
1033 dest = s->dest[0] - 16 * s->linesize - 32;
1034 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 2];
1035 flags = s->mb_x == 2 ? LEFT_EDGE : 0;
1036 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 2];
1037 for (i = 0; i < block_count; i++)
1039 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 16 : dest,
1040 ttblk,
1041 flags,
1042 fieldtx,
1043 i);
1044 }
1045 if (s->mb_x == s->mb_width - 1) {
1046 if (s->mb_x >= 1) {
1047 dest = s->dest[0] - 16 * s->linesize - 16;
1048 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
1049 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
1050 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride - 1];
1051 for (i = 0; i < block_count; i++)
1053 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest,
1054 ttblk,
1055 flags,
1056 fieldtx,
1057 i);
1058 }
1059 dest = s->dest[0] - 16 * s->linesize;
1060 ttblk = &v->ttblk[s->mb_x - s->mb_stride];
1061 flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
1062 fieldtx = v->fieldtx_plane[mb_pos - s->mb_stride];
1063 for (i = 0; i < block_count; i++)
1065 i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest,
1066 ttblk,
1067 flags,
1068 fieldtx,
1069 i);
1070 }
1071 }
1072 if (s->mb_x >= 2) {
1073 dest = s->dest[0] - 32;
1074 ttblk = &v->ttblk[s->mb_x - 2];
1075 flags = s->mb_x == 2 ? LEFT_EDGE : 0;
1076 fieldtx = v->fieldtx_plane[mb_pos - 2];
1077 for (i = 0; i < block_count; i++)
1079 i > 3 ? s->dest[i - 3] - 16 : dest,
1080 ttblk,
1081 flags,
1082 fieldtx,
1083 i);
1084 }
1085 if (s->mb_x == s->mb_width - 1) {
1086 if (s->mb_x >= 1) {
1087 dest = s->dest[0] - 16;
1088 ttblk = &v->ttblk[s->mb_x - 1];
1089 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
1090 fieldtx = v->fieldtx_plane[mb_pos - 1];
1091 for (i = 0; i < block_count; i++)
1093 i > 3 ? s->dest[i - 3] - 8 : dest,
1094 ttblk,
1095 flags,
1096 fieldtx,
1097 i);
1098 }
1099 dest = s->dest[0];
1100 ttblk = &v->ttblk[s->mb_x];
1101 flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
1102 fieldtx = v->fieldtx_plane[mb_pos];
1103 for (i = 0; i < block_count; i++)
1105 i > 3 ? s->dest[i - 3] : dest,
1106 ttblk,
1107 flags,
1108 fieldtx,
1109 i);
1110 }
1111 }
1112}
1113
1114static av_always_inline
1115void vc1_b_h_intfi_loop_filter(VC1Context *v, uint8_t *dest, const uint32_t *cbp,
1116 const int *ttblk, uint32_t flags, int block_num)
1117{
1118 MpegEncContext *s = &v->s;
1119 int pq = v->pq;
1120 uint8_t *dst;
1121 uint32_t block_cbp = cbp[0] >> (block_num * 4);
1122 int tt;
1123 int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize;
1124
1125 if (block_num > 3)
1126 dst = dest;
1127 else
1128 dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
1129
1130 if (!(flags & RIGHT_EDGE) || !(block_num & 5)) {
1131 v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq);
1132 }
1133
1134 tt = ttblk[0] >> (block_num * 4) & 0xf;
1135 if (tt == TT_4X4 || tt == TT_4X8) {
1136 idx = (block_cbp | (block_cbp >> 1)) & 5;
1137 if (idx & 1)
1138 v->vc1dsp.vc1_h_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
1139 if (idx & 4)
1140 v->vc1dsp.vc1_h_loop_filter4(dst + 4, linesize, pq);
1141 }
1142}
1143
1144static av_always_inline
1145void vc1_b_v_intfi_loop_filter(VC1Context *v, uint8_t *dest, const uint32_t *cbp,
1146 const int *ttblk, uint32_t flags, int block_num)
1147{
1148 MpegEncContext *s = &v->s;
1149 int pq = v->pq;
1150 uint8_t *dst;
1151 uint32_t block_cbp = cbp[0] >> (block_num * 4);
1152 int tt;
1153 int idx, linesize = block_num > 3 ? s->uvlinesize : s->linesize;
1154
1155 if (block_num > 3)
1156 dst = dest;
1157 else
1158 dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8;
1159
1160 if(!(flags & BOTTOM_EDGE) || block_num < 2)
1161 v->vc1dsp.vc1_v_loop_filter8(dst + 8 * linesize, linesize, pq);
1162
1163 tt = ttblk[0] >> (block_num * 4) & 0xf;
1164 if (tt == TT_4X4 || tt == TT_8X4) {
1165 idx = (block_cbp | (block_cbp >> 2)) & 3;
1166 if (idx & 1)
1167 v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize + 4, linesize, pq);
1168 if (idx & 2)
1169 v->vc1dsp.vc1_v_loop_filter4(dst + 4 * linesize, linesize, pq);
1170 }
1171}
1172
1174{
1175 MpegEncContext *s = &v->s;
1176 int block_count = CONFIG_GRAY && (s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 4 : 6;
1177 uint8_t *dest;
1178 const uint32_t *cbp;
1179 int *ttblk;
1180 uint32_t flags = 0;
1181 int i;
1182
1183 /* Within a MB, the vertical loop filter always runs before the horizontal.
1184 * To accomplish that, we run the V loop filter on all applicable
1185 * horizontal borders of the MB above the currently decoded MB. Then,
1186 * we wait for the next loop filter iteration to do H loop filter on all
1187 * applicable vertical borders of this MB. Therefore, the loop filter
1188 * trails by one row and one column relative to the decoding loop. */
1189 if (!s->first_slice_line) {
1190 dest = s->dest[0] - 16 * s->linesize;
1191 cbp = &v->cbp[s->mb_x - s->mb_stride];
1192 ttblk = &v->ttblk[s->mb_x - s->mb_stride];
1193 flags = s->mb_y == s->start_mb_y + 1 ? TOP_EDGE : 0;
1194 for (i = 0; i < block_count; i++)
1195 vc1_b_v_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, cbp, ttblk, flags, i);
1196 }
1197 if (s->mb_y == s->end_mb_y - 1) {
1198 dest = s->dest[0];
1199 cbp = &v->cbp[s->mb_x];
1200 ttblk = &v->ttblk[s->mb_x];
1201 flags = s->first_slice_line ? TOP_EDGE | BOTTOM_EDGE : BOTTOM_EDGE;
1202 for (i = 0; i < block_count; i++)
1203 vc1_b_v_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, cbp, ttblk, flags, i);
1204 }
1205
1206 if (!s->first_slice_line) {
1207 dest = s->dest[0] - 16 * s->linesize - 16;
1208 cbp = &v->cbp[s->mb_x - s->mb_stride - 1];
1209 ttblk = &v->ttblk[s->mb_x - s->mb_stride - 1];
1210 if (s->mb_x) {
1211 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
1212 for (i = 0; i < block_count; i++)
1213 vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize - 8 : dest, cbp, ttblk, flags, i);
1214 }
1215 if (s->mb_x == s->mb_width - 1) {
1216 dest += 16;
1217 cbp++;
1218 ttblk++;
1219 flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
1220 for (i = 0; i < block_count; i++)
1221 vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 * s->uvlinesize : dest, cbp, ttblk, flags, i);
1222 }
1223 }
1224 if (s->mb_y == s->end_mb_y - 1) {
1225 dest = s->dest[0] - 16;
1226 cbp = &v->cbp[s->mb_x - 1];
1227 ttblk = &v->ttblk[s->mb_x - 1];
1228 if (s->mb_x) {
1229 flags = s->mb_x == 1 ? LEFT_EDGE : 0;
1230 for (i = 0; i < block_count; i++)
1231 vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] - 8 : dest, cbp, ttblk, flags, i);
1232 }
1233 if (s->mb_x == s->mb_width - 1) {
1234 dest += 16;
1235 cbp++;
1236 ttblk++;
1237 flags = s->mb_x == 0 ? LEFT_EDGE | RIGHT_EDGE : RIGHT_EDGE;
1238 for (i = 0; i < block_count; i++)
1239 vc1_b_h_intfi_loop_filter(v, i > 3 ? s->dest[i - 3] : dest, cbp, ttblk, flags, i);
1240 }
1241 }
1242}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
Libavcodec external API header.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define AV_CODEC_FLAG_GRAY
Only decode/encode grayscale.
Definition avcodec.h:302
static const int8_t mv[256][2]
Definition 4xm.c:81
#define av_always_inline
Definition attributes.h:72
mpegvideo header.
MpegEncContext.
Definition mpegvideo.h:67
The VC1 Context.
Definition vc1.h:176
int topleft_blk_idx
Definition vc1.h:393
int profile
Sequence header data for all Profiles TODO: choose between ints, uint8_ts and monobit flags.
Definition vc1.h:220
uint8_t * over_flags_plane
Overflags bitplane.
Definition vc1.h:329
uint8_t * mb_type
Definition vc1.h:271
VC1DSPContext vc1dsp
Definition vc1.h:181
uint8_t * is_intra
Definition vc1.h:395
int end_mb_x
Horizontal macroblock limit (used only by mss2)
Definition vc1.h:401
uint8_t pq
Definition vc1.h:242
int cur_blk_idx
Definition vc1.h:393
int * ttblk
Transform type at the block level.
Definition vc1.h:266
int16_t(* block)[6][64]
Definition vc1.h:392
uint8_t * fieldtx_plane
Definition vc1.h:350
MpegEncContext s
Definition vc1.h:177
uint8_t * mv_f[2]
0: MV obtained from same field, 1: opposite field
Definition vc1.h:354
uint32_t * cbp
Definition vc1.h:394
enum FrameCodingMode fcm
Frame decoding info for Advanced profile.
Definition vc1.h:318
int blocks_off
Definition vc1.h:368
int16_t((* luma_mv)[2]
Definition vc1.h:396
uint8_t condover
Definition vc1.h:331
int mb_off
Definition vc1.h:368
int top_blk_idx
Definition vc1.h:393
int left_blk_idx
Definition vc1.h:393
void(* vc1_v_loop_filter16)(uint8_t *src, ptrdiff_t stride, int pq)
Definition vc1dsp.h:55
void(* vc1_v_loop_filter4)(uint8_t *src, ptrdiff_t stride, int pq)
Definition vc1dsp.h:51
void(* vc1_h_loop_filter8)(uint8_t *src, ptrdiff_t stride, int pq)
Definition vc1dsp.h:54
void(* vc1_h_loop_filter16)(uint8_t *src, ptrdiff_t stride, int pq)
Definition vc1dsp.h:56
void(* vc1_h_loop_filter4)(uint8_t *src, ptrdiff_t stride, int pq)
Definition vc1dsp.h:52
void(* vc1_v_loop_filter8)(uint8_t *src, ptrdiff_t stride, int pq)
Definition vc1dsp.h:53
void(* vc1_h_s_overlap)(int16_t *left, int16_t *right, ptrdiff_t left_stride, ptrdiff_t right_stride, int flags)
Definition vc1dsp.h:50
void(* vc1_v_s_overlap)(int16_t *top, int16_t *bottom)
Definition vc1dsp.h:49
@ CONDOVER_ALL
Definition vc1.h:141
@ TT_4X8
Definition vc1.h:121
@ TT_8X4
Definition vc1.h:118
@ TT_4X4
Definition vc1.h:122
@ ILACE_FIELD
in the bitstream is reported as 11b
Definition vc1.h:154
@ ILACE_FRAME
in the bitstream is reported as 10b
Definition vc1.h:153
@ PROFILE_ADVANCED
Definition vc1_common.h:52
void ff_vc1_p_overlap_filter(VC1Context *v)
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)
static av_always_inline void vc1_b_h_intfi_loop_filter(VC1Context *v, uint8_t *dest, const uint32_t *cbp, const int *ttblk, uint32_t flags, int block_num)
void ff_vc1_p_intfr_loop_filter(VC1Context *v)
static av_always_inline void vc1_p_h_intfr_loop_filter(VC1Context *v, uint8_t *dest, const int *ttblk, uint32_t flags, uint8_t fieldtx, int block_num)
void ff_vc1_b_intfi_loop_filter(VC1Context *v)
#define BOTTOM_EDGE
void ff_vc1_i_loop_filter(VC1Context *v)
static av_always_inline void vc1_i_h_loop_filter(VC1Context *v, uint8_t *dest, uint32_t flags, int block_num)
#define LEFT_EDGE
static av_always_inline void vc1_p_v_intfr_loop_filter(VC1Context *v, uint8_t *dest, const int *ttblk, uint32_t flags, uint8_t fieldtx, int block_num)
void ff_vc1_i_overlap_filter(VC1Context *v)
static av_always_inline void vc1_i_v_loop_filter(VC1Context *v, uint8_t *dest, uint32_t flags, uint8_t fieldtx, int block_num)
static av_always_inline void vc1_v_overlap_filter(VC1Context *v, int16_t(*top_block)[64], int16_t(*bottom_block)[64], int block_num)
void ff_vc1_p_loop_filter(VC1Context *v)
static av_always_inline void vc1_b_v_intfi_loop_filter(VC1Context *v, uint8_t *dest, const uint32_t *cbp, const int *ttblk, uint32_t flags, int block_num)
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)
#define TOP_EDGE
#define RIGHT_EDGE
static av_always_inline void vc1_p_v_loop_filter(VC1Context *v, uint8_t *dest, const uint32_t *cbp, const uint8_t *is_intra, int16_t(*mv)[2], const uint8_t *mv_f, const int *ttblk, uint32_t flags, int block_num)
VC-1 and WMV3 decoder.