Originally committed as revision 18520 to svn://svn.ffmpeg.org/ffmpeg/trunk
David Conrad authored on 2009/04/15 15:20:22... | ... |
@@ -482,6 +482,7 @@ typedef struct DSPContext { |
482 | 482 |
void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); |
483 | 483 |
void (*vc1_v_overlap)(uint8_t* src, int stride); |
484 | 484 |
void (*vc1_h_overlap)(uint8_t* src, int stride); |
485 |
+ void (*vc1_loop_filter)(uint8_t *src, int step, int stride, int len, int pq); |
|
485 | 486 |
/* put 8x8 block with bicubic interpolation and quarterpel precision |
486 | 487 |
* last argument is actually round value instead of height |
487 | 488 |
*/ |
... | ... |
@@ -310,87 +310,19 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) |
310 | 310 |
|
311 | 311 |
/** @} */ //Bitplane group |
312 | 312 |
|
313 |
-/** |
|
314 |
- * VC-1 in-loop deblocking filter for one line |
|
315 |
- * @param src source block type |
|
316 |
- * @param stride block stride |
|
317 |
- * @param pq block quantizer |
|
318 |
- * @return whether other 3 pairs should be filtered or not |
|
319 |
- * @see 8.6 |
|
320 |
- */ |
|
321 |
-static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){ |
|
322 |
- uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; |
|
323 |
- |
|
324 |
- int a0 = (2*(src[-2*stride] - src[ 1*stride]) - 5*(src[-1*stride] - src[ 0*stride]) + 4) >> 3; |
|
325 |
- int a0_sign = a0 >> 31; /* Store sign */ |
|
326 |
- a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */ |
|
327 |
- if(a0 < pq){ |
|
328 |
- int a1 = FFABS((2*(src[-4*stride] - src[-1*stride]) - 5*(src[-3*stride] - src[-2*stride]) + 4) >> 3); |
|
329 |
- int a2 = FFABS((2*(src[ 0*stride] - src[ 3*stride]) - 5*(src[ 1*stride] - src[ 2*stride]) + 4) >> 3); |
|
330 |
- if(a1 < a0 || a2 < a0){ |
|
331 |
- int clip = src[-1*stride] - src[ 0*stride]; |
|
332 |
- int clip_sign = clip >> 31; |
|
333 |
- clip = ((clip ^ clip_sign) - clip_sign)>>1; |
|
334 |
- if(clip){ |
|
335 |
- int a3 = FFMIN(a1, a2); |
|
336 |
- int d = 5 * (a3 - a0); |
|
337 |
- int d_sign = (d >> 31); |
|
338 |
- d = ((d ^ d_sign) - d_sign) >> 3; |
|
339 |
- d_sign ^= a0_sign; |
|
340 |
- |
|
341 |
- if( d_sign ^ clip_sign ) |
|
342 |
- d = 0; |
|
343 |
- else{ |
|
344 |
- d = FFMIN(d, clip); |
|
345 |
- d = (d ^ d_sign) - d_sign; /* Restore sign */ |
|
346 |
- src[-1*stride] = cm[src[-1*stride] - d]; |
|
347 |
- src[ 0*stride] = cm[src[ 0*stride] + d]; |
|
348 |
- } |
|
349 |
- return 1; |
|
350 |
- } |
|
351 |
- } |
|
352 |
- } |
|
353 |
- return 0; |
|
354 |
-} |
|
355 |
- |
|
356 |
-/** |
|
357 |
- * VC-1 in-loop deblocking filter |
|
358 |
- * @param src source block type |
|
359 |
- * @param step distance between horizontally adjacent elements |
|
360 |
- * @param stride distance between vertically adjacent elements |
|
361 |
- * @param len edge length to filter (4 or 8 pixels) |
|
362 |
- * @param pq block quantizer |
|
363 |
- * @see 8.6 |
|
364 |
- */ |
|
365 |
-static void vc1_loop_filter(uint8_t* src, int step, int stride, int len, int pq) |
|
366 |
-{ |
|
367 |
- int i; |
|
368 |
- int filt3; |
|
369 |
- |
|
370 |
- for(i = 0; i < len; i += 4){ |
|
371 |
- filt3 = vc1_filter_line(src + 2*step, stride, pq); |
|
372 |
- if(filt3){ |
|
373 |
- vc1_filter_line(src + 0*step, stride, pq); |
|
374 |
- vc1_filter_line(src + 1*step, stride, pq); |
|
375 |
- vc1_filter_line(src + 3*step, stride, pq); |
|
376 |
- } |
|
377 |
- src += step * 4; |
|
378 |
- } |
|
379 |
-} |
|
380 |
- |
|
381 | 313 |
static void vc1_loop_filter_iblk(MpegEncContext *s, int pq) |
382 | 314 |
{ |
383 | 315 |
int i, j; |
384 | 316 |
if(!s->first_slice_line) |
385 |
- vc1_loop_filter(s->dest[0], 1, s->linesize, 16, pq); |
|
386 |
- vc1_loop_filter(s->dest[0] + 8*s->linesize, 1, s->linesize, 16, pq); |
|
317 |
+ s->dsp.vc1_loop_filter(s->dest[0], 1, s->linesize, 16, pq); |
|
318 |
+ s->dsp.vc1_loop_filter(s->dest[0] + 8*s->linesize, 1, s->linesize, 16, pq); |
|
387 | 319 |
for(i = !s->mb_x*8; i < 16; i += 8) |
388 |
- vc1_loop_filter(s->dest[0] + i, s->linesize, 1, 16, pq); |
|
320 |
+ s->dsp.vc1_loop_filter(s->dest[0] + i, s->linesize, 1, 16, pq); |
|
389 | 321 |
for(j = 0; j < 2; j++){ |
390 | 322 |
if(!s->first_slice_line) |
391 |
- vc1_loop_filter(s->dest[j+1], 1, s->uvlinesize, 8, pq); |
|
323 |
+ s->dsp.vc1_loop_filter(s->dest[j+1], 1, s->uvlinesize, 8, pq); |
|
392 | 324 |
if(s->mb_x) |
393 |
- vc1_loop_filter(s->dest[j+1], s->uvlinesize, 1, 8, pq); |
|
325 |
+ s->dsp.vc1_loop_filter(s->dest[j+1], s->uvlinesize, 1, 8, pq); |
|
394 | 326 |
} |
395 | 327 |
} |
396 | 328 |
|
... | ... |
@@ -3050,9 +2982,9 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan |
3050 | 3050 |
s->dsp.vc1_inv_trans_8x8(block); |
3051 | 3051 |
s->dsp.add_pixels_clamped(block, dst, linesize); |
3052 | 3052 |
if(apply_filter && cbp_top & 0xC) |
3053 |
- vc1_loop_filter(dst, 1, linesize, 8, mquant); |
|
3053 |
+ s->dsp.vc1_loop_filter(dst, 1, linesize, 8, mquant); |
|
3054 | 3054 |
if(apply_filter && cbp_left & 0xA) |
3055 |
- vc1_loop_filter(dst, linesize, 1, 8, mquant); |
|
3055 |
+ s->dsp.vc1_loop_filter(dst, linesize, 1, 8, mquant); |
|
3056 | 3056 |
} |
3057 | 3057 |
break; |
3058 | 3058 |
case TT_4X4: |
... | ... |
@@ -3074,9 +3006,9 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan |
3074 | 3074 |
if(!(subblkpat & (1 << (3 - j))) && !skip_block){ |
3075 | 3075 |
s->dsp.vc1_inv_trans_4x4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off); |
3076 | 3076 |
if(apply_filter && (j&2 ? pat & (1<<(j-2)) : (cbp_top & (1 << (j + 2))))) |
3077 |
- vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, 1, linesize, 4, mquant); |
|
3077 |
+ s->dsp.vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, 1, linesize, 4, mquant); |
|
3078 | 3078 |
if(apply_filter && (j&1 ? pat & (1<<(j-1)) : (cbp_left & (1 << (j + 1))))) |
3079 |
- vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, linesize, 1, 4, mquant); |
|
3079 |
+ s->dsp.vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, linesize, 1, 4, mquant); |
|
3080 | 3080 |
} |
3081 | 3081 |
} |
3082 | 3082 |
break; |
... | ... |
@@ -3099,9 +3031,9 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan |
3099 | 3099 |
if(!(subblkpat & (1 << (1 - j))) && !skip_block){ |
3100 | 3100 |
s->dsp.vc1_inv_trans_8x4(dst + j*4*linesize, linesize, block + off); |
3101 | 3101 |
if(apply_filter && j ? pat & 0x3 : (cbp_top & 0xC)) |
3102 |
- vc1_loop_filter(dst + j*4*linesize, 1, linesize, 8, mquant); |
|
3102 |
+ s->dsp.vc1_loop_filter(dst + j*4*linesize, 1, linesize, 8, mquant); |
|
3103 | 3103 |
if(apply_filter && cbp_left & (2 << j)) |
3104 |
- vc1_loop_filter(dst + j*4*linesize, linesize, 1, 4, mquant); |
|
3104 |
+ s->dsp.vc1_loop_filter(dst + j*4*linesize, linesize, 1, 4, mquant); |
|
3105 | 3105 |
} |
3106 | 3106 |
} |
3107 | 3107 |
break; |
... | ... |
@@ -3124,9 +3056,9 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan |
3124 | 3124 |
if(!(subblkpat & (1 << (1 - j))) && !skip_block){ |
3125 | 3125 |
s->dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off); |
3126 | 3126 |
if(apply_filter && cbp_top & (2 << j)) |
3127 |
- vc1_loop_filter(dst + j*4, 1, linesize, 4, mquant); |
|
3127 |
+ s->dsp.vc1_loop_filter(dst + j*4, 1, linesize, 4, mquant); |
|
3128 | 3128 |
if(apply_filter && j ? pat & 0x5 : (cbp_left & 0xA)) |
3129 |
- vc1_loop_filter(dst + j*4, linesize, 1, 8, mquant); |
|
3129 |
+ s->dsp.vc1_loop_filter(dst + j*4, linesize, 1, 8, mquant); |
|
3130 | 3130 |
} |
3131 | 3131 |
} |
3132 | 3132 |
break; |
... | ... |
@@ -3249,9 +3181,9 @@ static int vc1_decode_p_mb(VC1Context *v) |
3249 | 3249 |
top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); |
3250 | 3250 |
} |
3251 | 3251 |
if(left_cbp & 0xC) |
3252 |
- vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); |
|
3252 |
+ s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); |
|
3253 | 3253 |
if(top_cbp & 0xA) |
3254 |
- vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); |
|
3254 |
+ s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); |
|
3255 | 3255 |
} |
3256 | 3256 |
block_cbp |= 0xF << (i << 2); |
3257 | 3257 |
} else if(val) { |
... | ... |
@@ -3266,9 +3198,9 @@ static int vc1_decode_p_mb(VC1Context *v) |
3266 | 3266 |
top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); |
3267 | 3267 |
} |
3268 | 3268 |
if(left_cbp & 0xC) |
3269 |
- vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); |
|
3269 |
+ s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); |
|
3270 | 3270 |
if(top_cbp & 0xA) |
3271 |
- vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); |
|
3271 |
+ s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); |
|
3272 | 3272 |
} |
3273 | 3273 |
pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); |
3274 | 3274 |
block_cbp |= pat << (i << 2); |
... | ... |
@@ -3380,9 +3312,9 @@ static int vc1_decode_p_mb(VC1Context *v) |
3380 | 3380 |
top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); |
3381 | 3381 |
} |
3382 | 3382 |
if(left_cbp & 0xC) |
3383 |
- vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); |
|
3383 |
+ s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); |
|
3384 | 3384 |
if(top_cbp & 0xA) |
3385 |
- vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); |
|
3385 |
+ s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); |
|
3386 | 3386 |
} |
3387 | 3387 |
block_cbp |= 0xF << (i << 2); |
3388 | 3388 |
} else if(is_coded[i]) { |
... | ... |
@@ -3397,9 +3329,9 @@ static int vc1_decode_p_mb(VC1Context *v) |
3397 | 3397 |
top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); |
3398 | 3398 |
} |
3399 | 3399 |
if(left_cbp & 0xC) |
3400 |
- vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); |
|
3400 |
+ s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); |
|
3401 | 3401 |
if(top_cbp & 0xA) |
3402 |
- vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); |
|
3402 |
+ s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); |
|
3403 | 3403 |
} |
3404 | 3404 |
pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); |
3405 | 3405 |
block_cbp |= pat << (i << 2); |
... | ... |
@@ -78,6 +78,73 @@ static void vc1_h_overlap_c(uint8_t* src, int stride) |
78 | 78 |
} |
79 | 79 |
} |
80 | 80 |
|
81 |
+/** |
|
82 |
+ * VC-1 in-loop deblocking filter for one line |
|
83 |
+ * @param src source block type |
|
84 |
+ * @param stride block stride |
|
85 |
+ * @param pq block quantizer |
|
86 |
+ * @return whether other 3 pairs should be filtered or not |
|
87 |
+ * @see 8.6 |
|
88 |
+ */ |
|
89 |
+static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){ |
|
90 |
+ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; |
|
91 |
+ |
|
92 |
+ int a0 = (2*(src[-2*stride] - src[ 1*stride]) - 5*(src[-1*stride] - src[ 0*stride]) + 4) >> 3; |
|
93 |
+ int a0_sign = a0 >> 31; /* Store sign */ |
|
94 |
+ a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */ |
|
95 |
+ if(a0 < pq){ |
|
96 |
+ int a1 = FFABS((2*(src[-4*stride] - src[-1*stride]) - 5*(src[-3*stride] - src[-2*stride]) + 4) >> 3); |
|
97 |
+ int a2 = FFABS((2*(src[ 0*stride] - src[ 3*stride]) - 5*(src[ 1*stride] - src[ 2*stride]) + 4) >> 3); |
|
98 |
+ if(a1 < a0 || a2 < a0){ |
|
99 |
+ int clip = src[-1*stride] - src[ 0*stride]; |
|
100 |
+ int clip_sign = clip >> 31; |
|
101 |
+ clip = ((clip ^ clip_sign) - clip_sign)>>1; |
|
102 |
+ if(clip){ |
|
103 |
+ int a3 = FFMIN(a1, a2); |
|
104 |
+ int d = 5 * (a3 - a0); |
|
105 |
+ int d_sign = (d >> 31); |
|
106 |
+ d = ((d ^ d_sign) - d_sign) >> 3; |
|
107 |
+ d_sign ^= a0_sign; |
|
108 |
+ |
|
109 |
+ if( d_sign ^ clip_sign ) |
|
110 |
+ d = 0; |
|
111 |
+ else{ |
|
112 |
+ d = FFMIN(d, clip); |
|
113 |
+ d = (d ^ d_sign) - d_sign; /* Restore sign */ |
|
114 |
+ src[-1*stride] = cm[src[-1*stride] - d]; |
|
115 |
+ src[ 0*stride] = cm[src[ 0*stride] + d]; |
|
116 |
+ } |
|
117 |
+ return 1; |
|
118 |
+ } |
|
119 |
+ } |
|
120 |
+ } |
|
121 |
+ return 0; |
|
122 |
+} |
|
123 |
+ |
|
124 |
+/** |
|
125 |
+ * VC-1 in-loop deblocking filter |
|
126 |
+ * @param src source block type |
|
127 |
+ * @param step distance between horizontally adjacent elements |
|
128 |
+ * @param stride distance between vertically adjacent elements |
|
129 |
+ * @param len edge length to filter (4 or 8 pixels) |
|
130 |
+ * @param pq block quantizer |
|
131 |
+ * @see 8.6 |
|
132 |
+ */ |
|
133 |
+static void vc1_loop_filter(uint8_t* src, int step, int stride, int len, int pq) |
|
134 |
+{ |
|
135 |
+ int i; |
|
136 |
+ int filt3; |
|
137 |
+ |
|
138 |
+ for(i = 0; i < len; i += 4){ |
|
139 |
+ filt3 = vc1_filter_line(src + 2*step, stride, pq); |
|
140 |
+ if(filt3){ |
|
141 |
+ vc1_filter_line(src + 0*step, stride, pq); |
|
142 |
+ vc1_filter_line(src + 1*step, stride, pq); |
|
143 |
+ vc1_filter_line(src + 3*step, stride, pq); |
|
144 |
+ } |
|
145 |
+ src += step * 4; |
|
146 |
+ } |
|
147 |
+} |
|
81 | 148 |
|
82 | 149 |
/** Do inverse transform on 8x8 block |
83 | 150 |
*/ |
... | ... |
@@ -450,6 +517,7 @@ void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) { |
450 | 450 |
dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c; |
451 | 451 |
dsp->vc1_h_overlap = vc1_h_overlap_c; |
452 | 452 |
dsp->vc1_v_overlap = vc1_v_overlap_c; |
453 |
+ dsp->vc1_loop_filter = vc1_loop_filter; |
|
453 | 454 |
|
454 | 455 |
dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_c; |
455 | 456 |
dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c; |