1 /*****************************************************************************
2 * frame.c: h264 encoder library
3 *****************************************************************************
4 * Copyright (C) 2003 Laurent Aimar
5 * $Id: frame.c,v 1.1 2004/06/03 19:27:06 fenrir Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
32 x264_frame_t *x264_frame_new( x264_t *h )
34 x264_frame_t *frame = x264_malloc( sizeof(x264_frame_t) );
37 int i_mb_count = h->mb.i_mb_count;
40 int i_padv = PADV << h->param.b_interlaced;
42 if( !frame ) return NULL;
44 memset( frame, 0, sizeof(x264_frame_t) );
46 /* allocate frame data (+64 for extra data for me) */
47 i_stride = ( ( h->param.i_width + 15 ) & -16 )+ 2*PADH;
48 i_lines = ( ( h->param.i_height + 15 ) & -16 );
49 if( h->param.b_interlaced )
50 i_lines = ( i_lines + 31 ) & -32;
53 for( i = 0; i < 3; i++ )
59 if( h->param.i_csp == X264_CSP_I420 )
61 else if( h->param.i_csp == X264_CSP_I422 )
64 frame->i_stride[i] = i_stride / i_divw;
65 frame->i_lines[i] = i_lines / i_divh;
66 CHECKED_MALLOC( frame->buffer[i],
67 frame->i_stride[i] * ( frame->i_lines[i] + 2*i_padv / i_divh ) );
69 frame->plane[i] = ((uint8_t*)frame->buffer[i]) +
70 frame->i_stride[i] * i_padv / i_divh + PADH / i_divw;
72 frame->i_stride[3] = 0;
73 frame->i_lines[3] = 0;
74 frame->buffer[3] = NULL;
75 frame->plane[3] = NULL;
77 frame->filtered[0] = frame->plane[0];
78 for( i = 0; i < 3; i++ )
80 CHECKED_MALLOC( frame->buffer[4+i],
81 frame->i_stride[0] * ( frame->i_lines[0] + 2*i_padv ) );
82 frame->filtered[i+1] = ((uint8_t*)frame->buffer[4+i]) +
83 frame->i_stride[0] * i_padv + PADH;
86 if( h->frames.b_have_lowres )
88 frame->i_stride_lowres = frame->i_stride[0]/2 + PADH;
89 frame->i_lines_lowres = frame->i_lines[0]/2;
90 for( i = 0; i < 4; i++ )
92 CHECKED_MALLOC( frame->buffer_lowres[i],
93 frame->i_stride_lowres * ( frame->i_lines[0]/2 + 2*i_padv ) );
94 frame->lowres[i] = ((uint8_t*)frame->buffer_lowres[i]) +
95 frame->i_stride_lowres * i_padv + PADH;
99 if( h->param.analyse.i_me_method == X264_ME_ESA )
101 CHECKED_MALLOC( frame->buffer[7],
102 2 * frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) );
103 frame->integral = (uint16_t*)frame->buffer[7] + frame->i_stride[0] * i_padv + PADH;
107 frame->i_type = X264_TYPE_AUTO;
108 frame->i_qpplus1 = 0;
111 frame->i_frame_num = -1;
113 CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
114 CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
115 CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
116 if( h->param.i_bframe )
118 CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );
119 CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );
124 frame->ref[1] = NULL;
127 CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
128 CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );
129 for( i = 0; i < h->param.i_bframe + 2; i++ )
130 for( j = 0; j < h->param.i_bframe + 2; j++ )
131 CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );
136 x264_frame_delete( frame );
140 void x264_frame_delete( x264_frame_t *frame )
143 for( i = 0; i < 8; i++ )
144 x264_free( frame->buffer[i] );
145 for( i = 0; i < 4; i++ )
146 x264_free( frame->buffer_lowres[i] );
147 for( i = 0; i < X264_BFRAME_MAX+2; i++ )
148 for( j = 0; j < X264_BFRAME_MAX+2; j++ )
149 x264_free( frame->i_row_satds[i][j] );
150 x264_free( frame->i_row_bits );
151 x264_free( frame->i_row_qp );
152 x264_free( frame->mb_type );
153 x264_free( frame->mv[0] );
154 x264_free( frame->mv[1] );
155 x264_free( frame->ref[0] );
156 x264_free( frame->ref[1] );
160 void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
162 dst->i_type = src->i_type;
163 dst->i_qpplus1 = src->i_qpplus1;
164 dst->i_pts = src->i_pts;
166 switch( src->img.i_csp & X264_CSP_MASK )
169 h->csp.i420( dst, &src->img, h->param.i_width, h->param.i_height );
172 h->csp.yv12( dst, &src->img, h->param.i_width, h->param.i_height );
175 h->csp.i422( dst, &src->img, h->param.i_width, h->param.i_height );
178 h->csp.i444( dst, &src->img, h->param.i_width, h->param.i_height );
181 h->csp.yuyv( dst, &src->img, h->param.i_width, h->param.i_height );
184 h->csp.rgb( dst, &src->img, h->param.i_width, h->param.i_height );
187 h->csp.bgr( dst, &src->img, h->param.i_width, h->param.i_height );
190 h->csp.bgra( dst, &src->img, h->param.i_width, h->param.i_height );
194 x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
201 static void plane_expand_border( uint8_t *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv )
203 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
205 for( y = 0; y < i_height; y++ )
208 memset( PPIXEL(-i_padh, y), PPIXEL(0, y)[0], i_padh );
210 memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_padh );
213 for( y = 0; y < i_padv; y++ )
214 memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), i_width+2*i_padh );
216 for( y = 0; y < i_padv; y++ )
217 memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), i_width+2*i_padh );
221 void x264_frame_expand_border( x264_t *h, x264_frame_t *frame )
224 for( i = 0; i < frame->i_plane; i++ )
226 int stride = frame->i_stride[i];
227 int width = 16*h->sps->i_mb_width >> !!i;
228 int height = 16*h->sps->i_mb_height >> !!i;
229 int padh = PADH >> !!i;
230 int padv = PADV >> !!i;
231 if( h->param.b_interlaced )
233 plane_expand_border( frame->plane[i], stride*2, width, height>>1, padh, padv );
234 plane_expand_border( frame->plane[i]+stride, stride*2, width, height>>1, padh, padv );
238 plane_expand_border( frame->plane[i], stride, width, height, padh, padv );
243 void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame )
245 /* during filtering, 8 extra pixels were filtered on each edge.
246 we want to expand border from the last filtered pixel */
247 int stride = frame->i_stride[0];
248 int width = 16*h->sps->i_mb_width;
249 int height = 16*h->sps->i_mb_height;
253 for( i = 1; i < 4; i++ )
255 if( h->param.b_interlaced )
257 plane_expand_border( frame->filtered[i] - 16*stride - 8, stride*2, width+16, (height>>1)+16, padh, padv );
258 plane_expand_border( frame->filtered[i] - 15*stride - 8, stride*2, width+16, (height>>1)+16, padh, padv );
262 plane_expand_border( frame->filtered[i] - 8*stride - 8, stride, width+16, height+16, padh, padv );
267 void x264_frame_expand_border_lowres( x264_frame_t *frame )
270 for( i = 0; i < 4; i++ )
271 plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_stride_lowres - 2*PADH, frame->i_lines_lowres, PADH, PADV );
274 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
277 for( i = 0; i < frame->i_plane; i++ )
279 int i_subsample = i ? 1 : 0;
280 int i_width = h->param.i_width >> i_subsample;
281 int i_height = h->param.i_height >> i_subsample;
282 int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;
283 int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;
287 for( y = 0; y < i_height; y++ )
288 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
289 frame->plane[i][y*frame->i_stride[i] + i_width - 1],
294 //FIXME interlace? or just let it pad using the wrong field
295 for( y = i_height; y < i_height + i_pady; y++ )
296 memcpy( &frame->plane[i][y*frame->i_stride[i]],
297 &frame->plane[i][(i_height-1)*frame->i_stride[i]],
304 /* Deblocking filter */
306 static const int i_alpha_table[52] =
308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 4, 4, 5, 6,
310 7, 8, 9, 10, 12, 13, 15, 17, 20, 22,
311 25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
312 80, 90,101,113,127,144,162,182,203,226,
315 static const int i_beta_table[52] =
317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 2, 2, 2, 3,
319 3, 3, 3, 4, 4, 4, 6, 6, 7, 7,
320 8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
321 13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
324 static const int i_tc0_table[52][3] =
326 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
327 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
328 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 },
329 { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 },
330 { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 },
331 { 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 },
332 { 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 },
333 { 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 },
334 { 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 }
338 static inline int clip_uint8( int a )
346 static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
349 for( i = 0; i < 4; i++ ) {
354 for( d = 0; d < 4; d++ ) {
355 const int p2 = pix[-3*xstride];
356 const int p1 = pix[-2*xstride];
357 const int p0 = pix[-1*xstride];
358 const int q0 = pix[ 0*xstride];
359 const int q1 = pix[ 1*xstride];
360 const int q2 = pix[ 2*xstride];
362 if( abs( p0 - q0 ) < alpha &&
363 abs( p1 - p0 ) < beta &&
364 abs( q1 - q0 ) < beta ) {
369 if( abs( p2 - p0 ) < beta ) {
370 pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
373 if( abs( q2 - q0 ) < beta ) {
374 pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
378 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
379 pix[-1*xstride] = clip_uint8( p0 + delta ); /* p0' */
380 pix[ 0*xstride] = clip_uint8( q0 - delta ); /* q0' */
386 static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
388 deblock_luma_c( pix, stride, 1, alpha, beta, tc0 );
390 static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
392 deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
395 static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
398 for( i = 0; i < 4; i++ ) {
399 const int tc = tc0[i];
404 for( d = 0; d < 2; d++ ) {
405 const int p1 = pix[-2*xstride];
406 const int p0 = pix[-1*xstride];
407 const int q0 = pix[ 0*xstride];
408 const int q1 = pix[ 1*xstride];
410 if( abs( p0 - q0 ) < alpha &&
411 abs( p1 - p0 ) < beta &&
412 abs( q1 - q0 ) < beta ) {
414 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
415 pix[-1*xstride] = clip_uint8( p0 + delta ); /* p0' */
416 pix[ 0*xstride] = clip_uint8( q0 - delta ); /* q0' */
422 static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
424 deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
426 static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
428 deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
431 static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
434 for( d = 0; d < 16; d++ ) {
435 const int p2 = pix[-3*xstride];
436 const int p1 = pix[-2*xstride];
437 const int p0 = pix[-1*xstride];
438 const int q0 = pix[ 0*xstride];
439 const int q1 = pix[ 1*xstride];
440 const int q2 = pix[ 2*xstride];
442 if( abs( p0 - q0 ) < alpha &&
443 abs( p1 - p0 ) < beta &&
444 abs( q1 - q0 ) < beta ) {
446 if(abs( p0 - q0 ) < ((alpha >> 2) + 2) ){
447 if( abs( p2 - p0 ) < beta)
449 const int p3 = pix[-4*xstride];
451 pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
452 pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
453 pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
456 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
458 if( abs( q2 - q0 ) < beta)
460 const int q3 = pix[3*xstride];
462 pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
463 pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
464 pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
467 pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
471 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
472 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
478 static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
480 deblock_luma_intra_c( pix, stride, 1, alpha, beta );
482 static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
484 deblock_luma_intra_c( pix, 1, stride, alpha, beta );
487 static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
490 for( d = 0; d < 8; d++ ) {
491 const int p1 = pix[-2*xstride];
492 const int p0 = pix[-1*xstride];
493 const int q0 = pix[ 0*xstride];
494 const int q1 = pix[ 1*xstride];
496 if( abs( p0 - q0 ) < alpha &&
497 abs( p1 - p0 ) < beta &&
498 abs( q1 - q0 ) < beta ) {
500 pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2; /* p0' */
501 pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2; /* q0' */
507 static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
509 deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
511 static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
513 deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
516 static inline void deblock_edge( x264_t *h, uint8_t *pix, int i_stride, int bS[4], int i_qp, int b_chroma,
517 x264_deblock_inter_t pf_inter, x264_deblock_intra_t pf_intra )
520 const int index_a = x264_clip3( i_qp + h->sh.i_alpha_c0_offset, 0, 51 );
521 const int alpha = i_alpha_table[index_a];
522 const int beta = i_beta_table[x264_clip3( i_qp + h->sh.i_beta_offset, 0, 51 )];
527 tc[i] = (bS[i] ? i_tc0_table[index_a][bS[i] - 1] : -1) + b_chroma;
528 pf_inter( pix, i_stride, alpha, beta, tc );
530 pf_intra( pix, i_stride, alpha, beta );
534 void x264_frame_deblocking_filter( x264_t *h, int i_slice_type )
536 const int s8x8 = 2 * h->mb.i_mb_stride;
537 const int s4x4 = 4 * h->mb.i_mb_stride;
538 const int b_interlaced = h->param.b_interlaced;
539 const int mvy_limit = 4 >> b_interlaced;
542 int i_stride2[3] = { h->fdec->i_stride[0] << b_interlaced,
543 h->fdec->i_stride[1] << b_interlaced,
544 h->fdec->i_stride[2] << b_interlaced };
546 for( mb_y = 0, mb_x = 0; mb_y < h->sps->i_mb_height; )
548 const int mb_xy = mb_y * h->mb.i_mb_stride + mb_x;
549 const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
550 const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
551 const int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
552 const int i_edge_end = (h->mb.type[mb_xy] == P_SKIP) ? 1 : 4;
555 int i_pix_y[3] = { 16*mb_y*h->fdec->i_stride[0] + 16*mb_x,
556 8*mb_y*h->fdec->i_stride[1] + 8*mb_x,
557 8*mb_y*h->fdec->i_stride[2] + 8*mb_x };
558 if( b_interlaced && (mb_y&1) )
560 i_pix_y[0] -= 15*h->fdec->i_stride[0];
561 i_pix_y[1] -= 7*h->fdec->i_stride[1];
562 i_pix_y[2] -= 7*h->fdec->i_stride[2];
565 /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
566 * entropy coding, but per 64 coeffs for the purpose of deblocking */
567 if( !h->param.b_cabac && b_8x8_transform )
569 uint32_t *nnz = (uint32_t*)h->mb.non_zero_count[mb_xy];
570 if( nnz[0] ) nnz[0] = 0x01010101;
571 if( nnz[1] ) nnz[1] = 0x01010101;
572 if( nnz[2] ) nnz[2] = 0x01010101;
573 if( nnz[3] ) nnz[3] = 0x01010101;
576 /* i_dir == 0 -> vertical edge
577 * i_dir == 1 -> horizontal edge */
578 for( i_dir = 0; i_dir < 2; i_dir++ )
580 int i_start = (i_dir ? (mb_y <= b_interlaced) : (mb_x == 0));
583 for( i_edge = i_start; i_edge < i_edge_end; i_edge++ )
585 int mbn_xy, mbn_8x8, mbn_4x4;
586 int bS[4]; /* filtering strength */
588 if( b_8x8_transform && (i_edge&1) )
591 mbn_xy = i_edge > 0 ? mb_xy : ( i_dir == 0 ? mb_xy - 1 : mb_xy - h->mb.i_mb_stride );
592 mbn_8x8 = i_edge > 0 ? mb_8x8 : ( i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8 );
593 mbn_4x4 = i_edge > 0 ? mb_4x4 : ( i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4 );
595 if( b_interlaced && i_edge == 0 && i_dir == 1 )
597 mbn_xy -= h->mb.i_mb_stride;
602 /* *** Get bS for each 4px for the current edge *** */
603 if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy] ) )
605 bS[0] = bS[1] = bS[2] = bS[3] = ( i_edge == 0 && !(b_interlaced && i_dir) ? 4 : 3 );
610 for( i = 0; i < 4; i++ )
612 int x = i_dir == 0 ? i_edge : i;
613 int y = i_dir == 0 ? i : i_edge;
614 int xn = (x - (i_dir == 0 ? 1 : 0 ))&0x03;
615 int yn = (y - (i_dir == 0 ? 0 : 1 ))&0x03;
617 if( h->mb.non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 ||
618 h->mb.non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 )
624 /* FIXME: A given frame may occupy more than one position in
625 * the reference list. So we should compare the frame numbers,
626 * not the indices in the ref list.
627 * No harm yet, as we don't generate that case.*/
629 int i8p= mb_8x8+(x/2)+(y/2)*s8x8;
630 int i8q= mbn_8x8+(xn/2)+(yn/2)*s8x8;
631 int i4p= mb_4x4+x+y*s4x4;
632 int i4q= mbn_4x4+xn+yn*s4x4;
637 for( l = 0; l < 1 + (i_slice_type == SLICE_TYPE_B); l++ )
639 if( h->mb.ref[l][i8p] != h->mb.ref[l][i8q] ||
640 abs( h->mb.mv[l][i4p][0] - h->mb.mv[l][i4q][0] ) >= 4 ||
641 abs( h->mb.mv[l][i4p][1] - h->mb.mv[l][i4q][1] ) >= mvy_limit )
653 i_qp = h->mb.qp[mb_xy];
654 i_qpn= h->mb.qp[mbn_xy];
659 deblock_edge( h, &h->fdec->plane[0][i_pix_y[0] + 4*i_edge],
660 i_stride2[0], bS, (i_qp+i_qpn+1) >> 1, 0,
661 h->loopf.deblock_h_luma, h->loopf.deblock_h_luma_intra );
665 int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
666 i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
667 deblock_edge( h, &h->fdec->plane[1][i_pix_y[1] + 2*i_edge],
668 i_stride2[1], bS, i_qpc, 1,
669 h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
670 deblock_edge( h, &h->fdec->plane[2][i_pix_y[2] + 2*i_edge],
671 i_stride2[2], bS, i_qpc, 1,
672 h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
677 /* horizontal edge */
678 deblock_edge( h, &h->fdec->plane[0][i_pix_y[0] + 4*i_edge*i_stride2[0]],
679 i_stride2[0], bS, (i_qp+i_qpn+1) >> 1, 0,
680 h->loopf.deblock_v_luma, h->loopf.deblock_v_luma_intra );
684 int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
685 i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
686 deblock_edge( h, &h->fdec->plane[1][i_pix_y[1] + 2*i_edge*i_stride2[1]],
687 i_stride2[1], bS, i_qpc, 1,
688 h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
689 deblock_edge( h, &h->fdec->plane[2][i_pix_y[2] + 2*i_edge*i_stride2[2]],
690 i_stride2[2], bS, i_qpc, 1,
691 h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
698 if( !b_interlaced || (mb_y&1) )
700 if( mb_x >= h->sps->i_mb_width )
706 mb_y ^= b_interlaced;
711 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
712 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
713 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
714 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
717 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
718 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
720 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
721 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
723 void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
725 x264_deblock_v8_luma_mmxext( pix, stride, alpha, beta, tc0 );
726 x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
731 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
733 pf->deblock_v_luma = deblock_v_luma_c;
734 pf->deblock_h_luma = deblock_h_luma_c;
735 pf->deblock_v_chroma = deblock_v_chroma_c;
736 pf->deblock_h_chroma = deblock_h_chroma_c;
737 pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
738 pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
739 pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
740 pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
743 if( cpu&X264_CPU_MMXEXT )
745 pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
746 pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
747 pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
748 pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
751 if( cpu&X264_CPU_SSE2 )
753 pf->deblock_v_luma = x264_deblock_v_luma_sse2;
754 pf->deblock_h_luma = x264_deblock_h_luma_sse2;
757 pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
758 pf->deblock_h_luma = x264_deblock_h_luma_mmxext;