ffmpeg / libavcodec / h264dsp_internal.h @ 21a7c936
History  View  Annotate  Download (9.93 KB)
1 
/*


2 
* H.26L/H.264/AVC/JVT/1449610/... encoder/decoder

3 
* Copyright (c) 20032011 Michael Niedermayer <michaelni@gmx.at>

4 
*

5 
* This file is part of FFmpeg.

6 
*

7 
* FFmpeg 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 
* FFmpeg 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 FFmpeg; if not, write to the Free Software

19 
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 021101301 USA

20 
*/

21  
22 
/**

23 
* @file

24 
* H.264 / AVC / MPEG4 part10 DSP functions.

25 
* @author Michael Niedermayer <michaelni@gmx.at>

26 
*/

27  
28 
#include "dsputil.h" 
29  
30 
#define BIT_DEPTH 8 
31 
#define pixel uint8_t

32 
#define av_clip_pixel av_clip_uint8

33 
#define FUNCC(a) a ## _c 
34  
35 
#define op_scale1(x) block[x] = av_clip_pixel( (block[x]*weight + offset) >> log2_denom )

36 
#define op_scale2(x) dst[x] = av_clip_pixel( (src[x]*weights + dst[x]*weightd + offset) >> (log2_denom+1)) 
37 
#define H264_WEIGHT(W,H) \

38 
static void FUNCC(weight_h264_pixels ## W ## x ## H)(uint8_t *p_block, int stride, int log2_denom, int weight, int offset){ \ 
39 
int y; \

40 
pixel *block = (pixel*)p_block; \ 
41 
stride >>= sizeof(pixel)1; \ 
42 
offset <<= (log2_denom + (BIT_DEPTH8)); \

43 
if(log2_denom) offset += 1<<(log2_denom1); \ 
44 
for(y=0; y<H; y++, block += stride){ \ 
45 
op_scale1(0); \

46 
op_scale1(1); \

47 
if(W==2) continue; \ 
48 
op_scale1(2); \

49 
op_scale1(3); \

50 
if(W==4) continue; \ 
51 
op_scale1(4); \

52 
op_scale1(5); \

53 
op_scale1(6); \

54 
op_scale1(7); \

55 
if(W==8) continue; \ 
56 
op_scale1(8); \

57 
op_scale1(9); \

58 
op_scale1(10); \

59 
op_scale1(11); \

60 
op_scale1(12); \

61 
op_scale1(13); \

62 
op_scale1(14); \

63 
op_scale1(15); \

64 
} \ 
65 
} \ 
66 
static void FUNCC(biweight_h264_pixels ## W ## x ## H)(uint8_t *p_dst, uint8_t *p_src, int stride, int log2_denom, int weightd, int weights, int offset){ \ 
67 
int y; \

68 
pixel *dst = (pixel*)p_dst; \ 
69 
pixel *src = (pixel*)p_src; \ 
70 
stride >>= sizeof(pixel)1; \ 
71 
offset = ((offset + 1)  1) << log2_denom; \ 
72 
for(y=0; y<H; y++, dst += stride, src += stride){ \ 
73 
op_scale2(0); \

74 
op_scale2(1); \

75 
if(W==2) continue; \ 
76 
op_scale2(2); \

77 
op_scale2(3); \

78 
if(W==4) continue; \ 
79 
op_scale2(4); \

80 
op_scale2(5); \

81 
op_scale2(6); \

82 
op_scale2(7); \

83 
if(W==8) continue; \ 
84 
op_scale2(8); \

85 
op_scale2(9); \

86 
op_scale2(10); \

87 
op_scale2(11); \

88 
op_scale2(12); \

89 
op_scale2(13); \

90 
op_scale2(14); \

91 
op_scale2(15); \

92 
} \ 
93 
} 
94  
95 
H264_WEIGHT(16,16) 
96 
H264_WEIGHT(16,8) 
97 
H264_WEIGHT(8,16) 
98 
H264_WEIGHT(8,8) 
99 
H264_WEIGHT(8,4) 
100 
H264_WEIGHT(4,8) 
101 
H264_WEIGHT(4,4) 
102 
H264_WEIGHT(4,2) 
103 
H264_WEIGHT(2,4) 
104 
H264_WEIGHT(2,2) 
105  
106 
#undef op_scale1

107 
#undef op_scale2

108 
#undef H264_WEIGHT

109  
110 
static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma)(uint8_t *p_pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) 
111 
{ 
112 
pixel *pix = (pixel*)p_pix; 
113 
int i, d;

114 
xstride >>= sizeof(pixel)1; 
115 
ystride >>= sizeof(pixel)1; 
116 
for( i = 0; i < 4; i++ ) { 
117 
if( tc0[i] < 0 ) { 
118 
pix += 4*ystride;

119 
continue;

120 
} 
121 
for( d = 0; d < 4; d++ ) { 
122 
const int p0 = pix[1*xstride]; 
123 
const int p1 = pix[2*xstride]; 
124 
const int p2 = pix[3*xstride]; 
125 
const int q0 = pix[0]; 
126 
const int q1 = pix[1*xstride]; 
127 
const int q2 = pix[2*xstride]; 
128  
129 
if( FFABS( p0  q0 ) < alpha &&

130 
FFABS( p1  p0 ) < beta && 
131 
FFABS( q1  q0 ) < beta ) { 
132  
133 
int tc = tc0[i];

134 
int i_delta;

135  
136 
if( FFABS( p2  p0 ) < beta ) {

137 
if(tc0[i])

138 
pix[2*xstride] = p1 + av_clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1)  p1, tc0[i], tc0[i] ); 
139 
tc++; 
140 
} 
141 
if( FFABS( q2  q0 ) < beta ) {

142 
if(tc0[i])

143 
pix[ xstride] = q1 + av_clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1)  q1, tc0[i], tc0[i] ); 
144 
tc++; 
145 
} 
146  
147 
i_delta = av_clip( (((q0  p0 ) << 2) + (p1  q1) + 4) >> 3, tc, tc ); 
148 
pix[xstride] = av_clip_pixel( p0 + i_delta ); /* p0' */

149 
pix[0] = av_clip_pixel( q0  i_delta ); /* q0' */ 
150 
} 
151 
pix += ystride; 
152 
} 
153 
} 
154 
} 
155 
static void FUNCC(h264_v_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) 
156 
{ 
157 
FUNCC(h264_loop_filter_luma)(pix, stride, sizeof(pixel), alpha, beta, tc0);

158 
} 
159 
static void FUNCC(h264_h_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) 
160 
{ 
161 
FUNCC(h264_loop_filter_luma)(pix, sizeof(pixel), stride, alpha, beta, tc0);

162 
} 
163  
164 
static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma_intra)(uint8_t *p_pix, int xstride, int ystride, int alpha, int beta) 
165 
{ 
166 
pixel *pix = (pixel*)p_pix; 
167 
int d;

168 
xstride >>= sizeof(pixel)1; 
169 
ystride >>= sizeof(pixel)1; 
170 
for( d = 0; d < 16; d++ ) { 
171 
const int p2 = pix[3*xstride]; 
172 
const int p1 = pix[2*xstride]; 
173 
const int p0 = pix[1*xstride]; 
174  
175 
const int q0 = pix[ 0*xstride]; 
176 
const int q1 = pix[ 1*xstride]; 
177 
const int q2 = pix[ 2*xstride]; 
178  
179 
if( FFABS( p0  q0 ) < alpha &&

180 
FFABS( p1  p0 ) < beta && 
181 
FFABS( q1  q0 ) < beta ) { 
182  
183 
if(FFABS( p0  q0 ) < (( alpha >> 2 ) + 2 )){ 
184 
if( FFABS( p2  p0 ) < beta)

185 
{ 
186 
const int p3 = pix[4*xstride]; 
187 
/* p0', p1', p2' */

188 
pix[1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; 
189 
pix[2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; 
190 
pix[3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; 
191 
} else {

192 
/* p0' */

193 
pix[1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; 
194 
} 
195 
if( FFABS( q2  q0 ) < beta)

196 
{ 
197 
const int q3 = pix[3*xstride]; 
198 
/* q0', q1', q2' */

199 
pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3; 
200 
pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; 
201 
pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3; 
202 
} else {

203 
/* q0' */

204 
pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2; 
205 
} 
206 
}else{

207 
/* p0', q0' */

208 
pix[1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; 
209 
pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2; 
210 
} 
211 
} 
212 
pix += ystride; 
213 
} 
214 
} 
215 
static void FUNCC(h264_v_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta) 
216 
{ 
217 
FUNCC(h264_loop_filter_luma_intra)(pix, stride, sizeof(pixel), alpha, beta);

218 
} 
219 
static void FUNCC(h264_h_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta) 
220 
{ 
221 
FUNCC(h264_loop_filter_luma_intra)(pix, sizeof(pixel), stride, alpha, beta);

222 
} 
223  
224 
static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma)(uint8_t *p_pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) 
225 
{ 
226 
pixel *pix = (pixel*)p_pix; 
227 
int i, d;

228 
xstride >>= sizeof(pixel)1; 
229 
ystride >>= sizeof(pixel)1; 
230 
for( i = 0; i < 4; i++ ) { 
231 
const int tc = tc0[i]; 
232 
if( tc <= 0 ) { 
233 
pix += 2*ystride;

234 
continue;

235 
} 
236 
for( d = 0; d < 2; d++ ) { 
237 
const int p0 = pix[1*xstride]; 
238 
const int p1 = pix[2*xstride]; 
239 
const int q0 = pix[0]; 
240 
const int q1 = pix[1*xstride]; 
241  
242 
if( FFABS( p0  q0 ) < alpha &&

243 
FFABS( p1  p0 ) < beta && 
244 
FFABS( q1  q0 ) < beta ) { 
245  
246 
int delta = av_clip( (((q0  p0 ) << 2) + (p1  q1) + 4) >> 3, tc, tc ); 
247  
248 
pix[xstride] = av_clip_pixel( p0 + delta ); /* p0' */

249 
pix[0] = av_clip_pixel( q0  delta ); /* q0' */ 
250 
} 
251 
pix += ystride; 
252 
} 
253 
} 
254 
} 
255 
static void FUNCC(h264_v_loop_filter_chroma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) 
256 
{ 
257 
FUNCC(h264_loop_filter_chroma)(pix, stride, sizeof(pixel), alpha, beta, tc0);

258 
} 
259 
static void FUNCC(h264_h_loop_filter_chroma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) 
260 
{ 
261 
FUNCC(h264_loop_filter_chroma)(pix, sizeof(pixel), stride, alpha, beta, tc0);

262 
} 
263  
264 
static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma_intra)(uint8_t *p_pix, int xstride, int ystride, int alpha, int beta) 
265 
{ 
266 
pixel *pix = (pixel*)p_pix; 
267 
int d;

268 
xstride >>= sizeof(pixel)1; 
269 
ystride >>= sizeof(pixel)1; 
270 
for( d = 0; d < 8; d++ ) { 
271 
const int p0 = pix[1*xstride]; 
272 
const int p1 = pix[2*xstride]; 
273 
const int q0 = pix[0]; 
274 
const int q1 = pix[1*xstride]; 
275  
276 
if( FFABS( p0  q0 ) < alpha &&

277 
FFABS( p1  p0 ) < beta && 
278 
FFABS( q1  q0 ) < beta ) { 
279  
280 
pix[xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */ 
281 
pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */ 
282 
} 
283 
pix += ystride; 
284 
} 
285 
} 
286 
static void FUNCC(h264_v_loop_filter_chroma_intra)(uint8_t *pix, int stride, int alpha, int beta) 
287 
{ 
288 
FUNCC(h264_loop_filter_chroma_intra)(pix, stride, sizeof(pixel), alpha, beta);

289 
} 
290 
static void FUNCC(h264_h_loop_filter_chroma_intra)(uint8_t *pix, int stride, int alpha, int beta) 
291 
{ 
292 
FUNCC(h264_loop_filter_chroma_intra)(pix, sizeof(pixel), stride, alpha, beta);

293 
} 