2 * RV30/40 decoder common dsp functions
3 * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
4 * Copyright (c) 2011 Janne Grunau
6 * This file is part of Libav.
8 * Libav is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * Libav is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * RV30/40 decoder common dsp functions
29 #include "libavutil/common.h"
32 * @name RV30/40 inverse transform functions
36 static av_always_inline
void rv34_row_transform(int temp
[16], int16_t *block
)
40 for(i
= 0; i
< 4; i
++){
41 const int z0
= 13*(block
[i
+4*0] + block
[i
+4*2]);
42 const int z1
= 13*(block
[i
+4*0] - block
[i
+4*2]);
43 const int z2
= 7* block
[i
+4*1] - 17*block
[i
+4*3];
44 const int z3
= 17* block
[i
+4*1] + 7*block
[i
+4*3];
46 temp
[4*i
+0] = z0
+ z3
;
47 temp
[4*i
+1] = z1
+ z2
;
48 temp
[4*i
+2] = z1
- z2
;
49 temp
[4*i
+3] = z0
- z3
;
54 * Real Video 3.0/4.0 inverse transform + sample reconstruction
55 * Code is almost the same as in SVQ3, only scaling is different.
57 static void rv34_idct_add_c(uint8_t *dst
, ptrdiff_t stride
, int16_t *block
){
61 rv34_row_transform(temp
, block
);
62 memset(block
, 0, 16*sizeof(int16_t));
64 for(i
= 0; i
< 4; i
++){
65 const int z0
= 13*(temp
[4*0+i
] + temp
[4*2+i
]) + 0x200;
66 const int z1
= 13*(temp
[4*0+i
] - temp
[4*2+i
]) + 0x200;
67 const int z2
= 7* temp
[4*1+i
] - 17*temp
[4*3+i
];
68 const int z3
= 17* temp
[4*1+i
] + 7*temp
[4*3+i
];
70 dst
[0] = av_clip_uint8( dst
[0] + ( (z0
+ z3
) >> 10 ) );
71 dst
[1] = av_clip_uint8( dst
[1] + ( (z1
+ z2
) >> 10 ) );
72 dst
[2] = av_clip_uint8( dst
[2] + ( (z1
- z2
) >> 10 ) );
73 dst
[3] = av_clip_uint8( dst
[3] + ( (z0
- z3
) >> 10 ) );
80 * RealVideo 3.0/4.0 inverse transform for DC block
82 * Code is almost the same as rv34_inv_transform()
83 * but final coefficients are multiplied by 1.5 and have no rounding.
85 static void rv34_inv_transform_noround_c(int16_t *block
){
89 rv34_row_transform(temp
, block
);
91 for(i
= 0; i
< 4; i
++){
92 const int z0
= 39*(temp
[4*0+i
] + temp
[4*2+i
]);
93 const int z1
= 39*(temp
[4*0+i
] - temp
[4*2+i
]);
94 const int z2
= 21* temp
[4*1+i
] - 51*temp
[4*3+i
];
95 const int z3
= 51* temp
[4*1+i
] + 21*temp
[4*3+i
];
97 block
[i
*4+0] = (z0
+ z3
) >> 11;
98 block
[i
*4+1] = (z1
+ z2
) >> 11;
99 block
[i
*4+2] = (z1
- z2
) >> 11;
100 block
[i
*4+3] = (z0
- z3
) >> 11;
104 static void rv34_idct_dc_add_c(uint8_t *dst
, ptrdiff_t stride
, int dc
)
108 dc
= (13*13*dc
+ 0x200) >> 10;
109 for (i
= 0; i
< 4; i
++)
111 for (j
= 0; j
< 4; j
++)
112 dst
[j
] = av_clip_uint8( dst
[j
] + dc
);
118 static void rv34_inv_transform_dc_noround_c(int16_t *block
)
120 int16_t dc
= (13 * 13 * 3 * block
[0]) >> 11;
123 for (i
= 0; i
< 4; i
++, block
+= 4)
124 for (j
= 0; j
< 4; j
++)
128 /** @} */ // transform
131 av_cold
void ff_rv34dsp_init(RV34DSPContext
*c
)
133 c
->rv34_inv_transform
= rv34_inv_transform_noround_c
;
134 c
->rv34_inv_transform_dc
= rv34_inv_transform_dc_noround_c
;
136 c
->rv34_idct_add
= rv34_idct_add_c
;
137 c
->rv34_idct_dc_add
= rv34_idct_dc_add_c
;
140 ff_rv34dsp_init_arm(c
);
142 ff_rv34dsp_init_x86(c
);