Browse code

Move VC1 loop filter to DSPContext

Originally committed as revision 18520 to svn://svn.ffmpeg.org/ffmpeg/trunk

David Conrad authored on 2009/04/15 15:20:22
Showing 3 changed files
... ...
@@ -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;