ffmpeg / libavcodec / h264dsp_internal.h @ 8dbe5856
History  View  Annotate  Download (9.84 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 "h264_high_depth.h" 
29  
30 
#define op_scale1(x) block[x] = av_clip_pixel( (block[x]*weight + offset) >> log2_denom )

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

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

35 
pixel *block = (pixel*)p_block; \ 
36 
stride >>= sizeof(pixel)1; \ 
37 
offset <<= (log2_denom + (BIT_DEPTH8)); \

38 
if(log2_denom) offset += 1<<(log2_denom1); \ 
39 
for(y=0; y<H; y++, block += stride){ \ 
40 
op_scale1(0); \

41 
op_scale1(1); \

42 
if(W==2) continue; \ 
43 
op_scale1(2); \

44 
op_scale1(3); \

45 
if(W==4) continue; \ 
46 
op_scale1(4); \

47 
op_scale1(5); \

48 
op_scale1(6); \

49 
op_scale1(7); \

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

52 
op_scale1(9); \

53 
op_scale1(10); \

54 
op_scale1(11); \

55 
op_scale1(12); \

56 
op_scale1(13); \

57 
op_scale1(14); \

58 
op_scale1(15); \

59 
} \ 
60 
} \ 
61 
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){ \ 
62 
int y; \

63 
pixel *dst = (pixel*)p_dst; \ 
64 
pixel *src = (pixel*)p_src; \ 
65 
stride >>= sizeof(pixel)1; \ 
66 
offset = ((offset + 1)  1) << log2_denom; \ 
67 
for(y=0; y<H; y++, dst += stride, src += stride){ \ 
68 
op_scale2(0); \

69 
op_scale2(1); \

70 
if(W==2) continue; \ 
71 
op_scale2(2); \

72 
op_scale2(3); \

73 
if(W==4) continue; \ 
74 
op_scale2(4); \

75 
op_scale2(5); \

76 
op_scale2(6); \

77 
op_scale2(7); \

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

80 
op_scale2(9); \

81 
op_scale2(10); \

82 
op_scale2(11); \

83 
op_scale2(12); \

84 
op_scale2(13); \

85 
op_scale2(14); \

86 
op_scale2(15); \

87 
} \ 
88 
} 
89  
90 
H264_WEIGHT(16,16) 
91 
H264_WEIGHT(16,8) 
92 
H264_WEIGHT(8,16) 
93 
H264_WEIGHT(8,8) 
94 
H264_WEIGHT(8,4) 
95 
H264_WEIGHT(4,8) 
96 
H264_WEIGHT(4,4) 
97 
H264_WEIGHT(4,2) 
98 
H264_WEIGHT(2,4) 
99 
H264_WEIGHT(2,2) 
100  
101 
#undef op_scale1

102 
#undef op_scale2

103 
#undef H264_WEIGHT

104  
105 
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) 
106 
{ 
107 
pixel *pix = (pixel*)p_pix; 
108 
int i, d;

109 
xstride >>= sizeof(pixel)1; 
110 
ystride >>= sizeof(pixel)1; 
111 
for( i = 0; i < 4; i++ ) { 
112 
if( tc0[i] < 0 ) { 
113 
pix += 4*ystride;

114 
continue;

115 
} 
116 
for( d = 0; d < 4; d++ ) { 
117 
const int p0 = pix[1*xstride]; 
118 
const int p1 = pix[2*xstride]; 
119 
const int p2 = pix[3*xstride]; 
120 
const int q0 = pix[0]; 
121 
const int q1 = pix[1*xstride]; 
122 
const int q2 = pix[2*xstride]; 
123  
124 
if( FFABS( p0  q0 ) < alpha &&

125 
FFABS( p1  p0 ) < beta && 
126 
FFABS( q1  q0 ) < beta ) { 
127  
128 
int tc = tc0[i];

129 
int i_delta;

130  
131 
if( FFABS( p2  p0 ) < beta ) {

132 
if(tc0[i])

133 
pix[2*xstride] = p1 + av_clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1)  p1, tc0[i], tc0[i] ); 
134 
tc++; 
135 
} 
136 
if( FFABS( q2  q0 ) < beta ) {

137 
if(tc0[i])

138 
pix[ xstride] = q1 + av_clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1)  q1, tc0[i], tc0[i] ); 
139 
tc++; 
140 
} 
141  
142 
i_delta = av_clip( (((q0  p0 ) << 2) + (p1  q1) + 4) >> 3, tc, tc ); 
143 
pix[xstride] = av_clip_pixel( p0 + i_delta ); /* p0' */

144 
pix[0] = av_clip_pixel( q0  i_delta ); /* q0' */ 
145 
} 
146 
pix += ystride; 
147 
} 
148 
} 
149 
} 
150 
static void FUNCC(h264_v_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) 
151 
{ 
152 
FUNCC(h264_loop_filter_luma)(pix, stride, sizeof(pixel), alpha, beta, tc0);

153 
} 
154 
static void FUNCC(h264_h_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) 
155 
{ 
156 
FUNCC(h264_loop_filter_luma)(pix, sizeof(pixel), stride, alpha, beta, tc0);

157 
} 
158  
159 
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) 
160 
{ 
161 
pixel *pix = (pixel*)p_pix; 
162 
int d;

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

175 
FFABS( p1  p0 ) < beta && 
176 
FFABS( q1  q0 ) < beta ) { 
177  
178 
if(FFABS( p0  q0 ) < (( alpha >> 2 ) + 2 )){ 
179 
if( FFABS( p2  p0 ) < beta)

180 
{ 
181 
const int p3 = pix[4*xstride]; 
182 
/* p0', p1', p2' */

183 
pix[1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; 
184 
pix[2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; 
185 
pix[3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; 
186 
} else {

187 
/* p0' */

188 
pix[1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; 
189 
} 
190 
if( FFABS( q2  q0 ) < beta)

191 
{ 
192 
const int q3 = pix[3*xstride]; 
193 
/* q0', q1', q2' */

194 
pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3; 
195 
pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; 
196 
pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3; 
197 
} else {

198 
/* q0' */

199 
pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2; 
200 
} 
201 
}else{

202 
/* p0', q0' */

203 
pix[1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; 
204 
pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2; 
205 
} 
206 
} 
207 
pix += ystride; 
208 
} 
209 
} 
210 
static void FUNCC(h264_v_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta) 
211 
{ 
212 
FUNCC(h264_loop_filter_luma_intra)(pix, stride, sizeof(pixel), alpha, beta);

213 
} 
214 
static void FUNCC(h264_h_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta) 
215 
{ 
216 
FUNCC(h264_loop_filter_luma_intra)(pix, sizeof(pixel), stride, alpha, beta);

217 
} 
218  
219 
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) 
220 
{ 
221 
pixel *pix = (pixel*)p_pix; 
222 
int i, d;

223 
xstride >>= sizeof(pixel)1; 
224 
ystride >>= sizeof(pixel)1; 
225 
for( i = 0; i < 4; i++ ) { 
226 
const int tc = tc0[i]; 
227 
if( tc <= 0 ) { 
228 
pix += 2*ystride;

229 
continue;

230 
} 
231 
for( d = 0; d < 2; d++ ) { 
232 
const int p0 = pix[1*xstride]; 
233 
const int p1 = pix[2*xstride]; 
234 
const int q0 = pix[0]; 
235 
const int q1 = pix[1*xstride]; 
236  
237 
if( FFABS( p0  q0 ) < alpha &&

238 
FFABS( p1  p0 ) < beta && 
239 
FFABS( q1  q0 ) < beta ) { 
240  
241 
int delta = av_clip( (((q0  p0 ) << 2) + (p1  q1) + 4) >> 3, tc, tc ); 
242  
243 
pix[xstride] = av_clip_pixel( p0 + delta ); /* p0' */

244 
pix[0] = av_clip_pixel( q0  delta ); /* q0' */ 
245 
} 
246 
pix += ystride; 
247 
} 
248 
} 
249 
} 
250 
static void FUNCC(h264_v_loop_filter_chroma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) 
251 
{ 
252 
FUNCC(h264_loop_filter_chroma)(pix, stride, sizeof(pixel), alpha, beta, tc0);

253 
} 
254 
static void FUNCC(h264_h_loop_filter_chroma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) 
255 
{ 
256 
FUNCC(h264_loop_filter_chroma)(pix, sizeof(pixel), stride, alpha, beta, tc0);

257 
} 
258  
259 
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) 
260 
{ 
261 
pixel *pix = (pixel*)p_pix; 
262 
int d;

263 
xstride >>= sizeof(pixel)1; 
264 
ystride >>= sizeof(pixel)1; 
265 
for( d = 0; d < 8; d++ ) { 
266 
const int p0 = pix[1*xstride]; 
267 
const int p1 = pix[2*xstride]; 
268 
const int q0 = pix[0]; 
269 
const int q1 = pix[1*xstride]; 
270  
271 
if( FFABS( p0  q0 ) < alpha &&

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

284 
} 
285 
static void FUNCC(h264_h_loop_filter_chroma_intra)(uint8_t *pix, int stride, int alpha, int beta) 
286 
{ 
287 
FUNCC(h264_loop_filter_chroma_intra)(pix, sizeof(pixel), stride, alpha, beta);

288 
} 