Browse code

rv34: move inverse transform functions to DSP context

Janne Grunau authored on 2011/09/24 19:54:28
Showing 6 changed files
... ...
@@ -324,9 +324,9 @@ OBJS-$(CONFIG_RV10_DECODER)            += rv10.o
324 324
 OBJS-$(CONFIG_RV10_ENCODER)            += rv10enc.o
325 325
 OBJS-$(CONFIG_RV20_DECODER)            += rv10.o
326 326
 OBJS-$(CONFIG_RV20_ENCODER)            += rv20enc.o
327
-OBJS-$(CONFIG_RV30_DECODER)            += rv30.o rv34.o rv30dsp.o        \
327
+OBJS-$(CONFIG_RV30_DECODER)            += rv30.o rv34.o rv30dsp.o rv34dsp.o \
328 328
                                           mpegvideo.o error_resilience.o
329
-OBJS-$(CONFIG_RV40_DECODER)            += rv40.o rv34.o rv40dsp.o        \
329
+OBJS-$(CONFIG_RV40_DECODER)            += rv40.o rv34.o rv34dsp.o rv40dsp.o \
330 330
                                           mpegvideo.o error_resilience.o
331 331
 OBJS-$(CONFIG_S302M_DECODER)           += s302m.o
332 332
 OBJS-$(CONFIG_SGI_DECODER)             += sgidec.o
... ...
@@ -253,6 +253,9 @@ RV30_MC(avg_, 8)
253 253
 RV30_MC(avg_, 16)
254 254
 
255 255
 av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) {
256
+
257
+    ff_rv34dsp_init(c, dsp);
258
+
256 259
     c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0];
257 260
     c->put_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c;
258 261
     c->put_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c;
... ...
@@ -171,82 +171,6 @@ static av_cold void rv34_init_tables(void)
171 171
 
172 172
 /** @} */ // vlc group
173 173
 
174
-
175
-/**
176
- * @name RV30/40 inverse transform functions
177
- * @{
178
- */
179
-
180
-static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
181
-{
182
-    int i;
183
-
184
-    for(i = 0; i < 4; i++){
185
-        const int z0 = 13*(block[i+8*0] +    block[i+8*2]);
186
-        const int z1 = 13*(block[i+8*0] -    block[i+8*2]);
187
-        const int z2 =  7* block[i+8*1] - 17*block[i+8*3];
188
-        const int z3 = 17* block[i+8*1] +  7*block[i+8*3];
189
-
190
-        temp[4*i+0] = z0 + z3;
191
-        temp[4*i+1] = z1 + z2;
192
-        temp[4*i+2] = z1 - z2;
193
-        temp[4*i+3] = z0 - z3;
194
-    }
195
-}
196
-
197
-/**
198
- * Real Video 3.0/4.0 inverse transform
199
- * Code is almost the same as in SVQ3, only scaling is different.
200
- */
201
-static void rv34_inv_transform(DCTELEM *block){
202
-    int temp[16];
203
-    int i;
204
-
205
-    rv34_row_transform(temp, block);
206
-
207
-    for(i = 0; i < 4; i++){
208
-        const int z0 = 13*(temp[4*0+i] +    temp[4*2+i]) + 0x200;
209
-        const int z1 = 13*(temp[4*0+i] -    temp[4*2+i]) + 0x200;
210
-        const int z2 =  7* temp[4*1+i] - 17*temp[4*3+i];
211
-        const int z3 = 17* temp[4*1+i] +  7*temp[4*3+i];
212
-
213
-        block[i*8+0] = (z0 + z3) >> 10;
214
-        block[i*8+1] = (z1 + z2) >> 10;
215
-        block[i*8+2] = (z1 - z2) >> 10;
216
-        block[i*8+3] = (z0 - z3) >> 10;
217
-    }
218
-
219
-}
220
-
221
-/**
222
- * RealVideo 3.0/4.0 inverse transform for DC block
223
- *
224
- * Code is almost the same as rv34_inv_transform()
225
- * but final coefficients are multiplied by 1.5 and have no rounding.
226
- */
227
-static void rv34_inv_transform_noround(DCTELEM *block){
228
-    int temp[16];
229
-    int i;
230
-
231
-    rv34_row_transform(temp, block);
232
-
233
-    for(i = 0; i < 4; i++){
234
-        const int z0 = 13*(temp[4*0+i] +    temp[4*2+i]);
235
-        const int z1 = 13*(temp[4*0+i] -    temp[4*2+i]);
236
-        const int z2 =  7* temp[4*1+i] - 17*temp[4*3+i];
237
-        const int z3 = 17* temp[4*1+i] +  7*temp[4*3+i];
238
-
239
-        block[i*8+0] = ((z0 + z3) * 3) >> 11;
240
-        block[i*8+1] = ((z1 + z2) * 3) >> 11;
241
-        block[i*8+2] = ((z1 - z2) * 3) >> 11;
242
-        block[i*8+3] = ((z0 - z3) * 3) >> 11;
243
-    }
244
-
245
-}
246
-
247
-/** @} */ // transform
248
-
249
-
250 174
 /**
251 175
  * @name RV30/40 4x4 block decoding functions
252 176
  * @{
... ...
@@ -1226,7 +1150,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
1226 1226
         memset(block16, 0, sizeof(block16));
1227 1227
         rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
1228 1228
         rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
1229
-        rv34_inv_transform_noround(block16);
1229
+        r->rdsp.rv34_inv_transform_tab[1](block16);
1230 1230
     }
1231 1231
 
1232 1232
     for(i = 0; i < 16; i++, cbp >>= 1){
... ...
@@ -1238,7 +1162,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
1238 1238
         rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]);
1239 1239
         if(r->is16) //FIXME: optimize
1240 1240
             s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
1241
-        rv34_inv_transform(s->block[blknum] + blkoff);
1241
+        r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
1242 1242
     }
1243 1243
     if(r->block_type == RV34_MB_P_MIX16x16)
1244 1244
         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
... ...
@@ -1248,7 +1172,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
1248 1248
         blkoff = ((i & 1) << 2) + ((i & 2) << 4);
1249 1249
         rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
1250 1250
         rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
1251
-        rv34_inv_transform(s->block[blknum] + blkoff);
1251
+        r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
1252 1252
     }
1253 1253
     if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos]))
1254 1254
         rv34_output_macroblock(r, intra_types, cbp2, r->is16);
1255 1255
new file mode 100644
... ...
@@ -0,0 +1,106 @@
0
+/*
1
+ * RV30/40 decoder common dsp functions
2
+ * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
3
+ * Copyright (c) 2011 Janne Grunau
4
+ *
5
+ * This file is part of Libav.
6
+ *
7
+ * Libav is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * Libav is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with Libav; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
+ */
21
+
22
+/**
23
+ * @file
24
+ * RV30/40 decoder common dsp functions
25
+ */
26
+#include "dsputil.h"
27
+#include "rv34dsp.h"
28
+
29
+/**
30
+ * @name RV30/40 inverse transform functions
31
+ * @{
32
+ */
33
+
34
+static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
35
+{
36
+    int i;
37
+
38
+    for(i = 0; i < 4; i++){
39
+        const int z0 = 13*(block[i+8*0] +    block[i+8*2]);
40
+        const int z1 = 13*(block[i+8*0] -    block[i+8*2]);
41
+        const int z2 =  7* block[i+8*1] - 17*block[i+8*3];
42
+        const int z3 = 17* block[i+8*1] +  7*block[i+8*3];
43
+
44
+        temp[4*i+0] = z0 + z3;
45
+        temp[4*i+1] = z1 + z2;
46
+        temp[4*i+2] = z1 - z2;
47
+        temp[4*i+3] = z0 - z3;
48
+    }
49
+}
50
+
51
+/**
52
+ * Real Video 3.0/4.0 inverse transform
53
+ * Code is almost the same as in SVQ3, only scaling is different.
54
+ */
55
+static void rv34_inv_transform_c(DCTELEM *block){
56
+    int temp[16];
57
+    int i;
58
+
59
+    rv34_row_transform(temp, block);
60
+
61
+    for(i = 0; i < 4; i++){
62
+        const int z0 = 13*(temp[4*0+i] +    temp[4*2+i]) + 0x200;
63
+        const int z1 = 13*(temp[4*0+i] -    temp[4*2+i]) + 0x200;
64
+        const int z2 =  7* temp[4*1+i] - 17*temp[4*3+i];
65
+        const int z3 = 17* temp[4*1+i] +  7*temp[4*3+i];
66
+
67
+        block[i*8+0] = (z0 + z3) >> 10;
68
+        block[i*8+1] = (z1 + z2) >> 10;
69
+        block[i*8+2] = (z1 - z2) >> 10;
70
+        block[i*8+3] = (z0 - z3) >> 10;
71
+    }
72
+}
73
+
74
+/**
75
+ * RealVideo 3.0/4.0 inverse transform for DC block
76
+ *
77
+ * Code is almost the same as rv34_inv_transform()
78
+ * but final coefficients are multiplied by 1.5 and have no rounding.
79
+ */
80
+static void rv34_inv_transform_noround_c(DCTELEM *block){
81
+    int temp[16];
82
+    int i;
83
+
84
+    rv34_row_transform(temp, block);
85
+
86
+    for(i = 0; i < 4; i++){
87
+        const int z0 = 13*(temp[4*0+i] +    temp[4*2+i]);
88
+        const int z1 = 13*(temp[4*0+i] -    temp[4*2+i]);
89
+        const int z2 =  7* temp[4*1+i] - 17*temp[4*3+i];
90
+        const int z3 = 17* temp[4*1+i] +  7*temp[4*3+i];
91
+
92
+        block[i*8+0] = ((z0 + z3) * 3) >> 11;
93
+        block[i*8+1] = ((z1 + z2) * 3) >> 11;
94
+        block[i*8+2] = ((z1 - z2) * 3) >> 11;
95
+        block[i*8+3] = ((z0 - z3) * 3) >> 11;
96
+    }
97
+}
98
+
99
+/** @} */ // transform
100
+
101
+
102
+av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) {
103
+    c->rv34_inv_transform_tab[0] = rv34_inv_transform_c;
104
+    c->rv34_inv_transform_tab[1] = rv34_inv_transform_noround_c;
105
+}
... ...
@@ -34,15 +34,19 @@ typedef void (*rv40_weight_func)(uint8_t *dst/*align width (8 or 16)*/,
34 34
                                  uint8_t *src2/*align width (8 or 16)*/,
35 35
                                  int w1, int w2, int stride);
36 36
 
37
+typedef void (*rv34_inv_transform_func)(DCTELEM *block);
38
+
37 39
 typedef struct RV34DSPContext {
38 40
     qpel_mc_func put_pixels_tab[4][16];
39 41
     qpel_mc_func avg_pixels_tab[4][16];
40 42
     h264_chroma_mc_func put_chroma_pixels_tab[3];
41 43
     h264_chroma_mc_func avg_chroma_pixels_tab[3];
42 44
     rv40_weight_func rv40_weight_pixels_tab[2];
45
+    rv34_inv_transform_func rv34_inv_transform_tab[2];
43 46
 } RV34DSPContext;
44 47
 
45 48
 void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp);
49
+void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp);
46 50
 void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp);
47 51
 
48 52
 void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp);
... ...
@@ -295,6 +295,9 @@ RV40_WEIGHT_FUNC(16)
295 295
 RV40_WEIGHT_FUNC(8)
296 296
 
297 297
 av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) {
298
+
299
+    ff_rv34dsp_init(c, dsp);
300
+
298 301
     c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0];
299 302
     c->put_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c;
300 303
     c->put_pixels_tab[0][ 2] = dsp->put_h264_qpel_pixels_tab[0][2];