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 *****************************************************************************/
29 x264_frame_t *x264_frame_new( x264_t *h )
31 x264_frame_t *frame = x264_malloc( sizeof( x264_frame_t ) );
34 int i_mb_count = h->mb.i_mb_count;
38 memset( frame, 0, sizeof(x264_frame_t) );
40 /* allocate frame data (+64 for extra data for me) */
41 i_stride = ( ( h->param.i_width + 15 )&0xfffff0 )+ 64;
42 i_lines = ( ( h->param.i_height + 15 )&0xfffff0 );
45 for( i = 0; i < 3; i++ )
51 if( h->param.i_csp == X264_CSP_I420 )
53 else if( h->param.i_csp == X264_CSP_I422 )
56 frame->i_stride[i] = i_stride / i_divw;
57 frame->i_lines[i] = i_lines / i_divh;
58 frame->buffer[i] = x264_malloc( frame->i_stride[i] *
59 ( frame->i_lines[i] + 64 / i_divh ) );
61 frame->plane[i] = ((uint8_t*)frame->buffer[i]) +
62 frame->i_stride[i] * 32 / i_divh + 32 / i_divw;
64 frame->i_stride[3] = 0;
65 frame->i_lines[3] = 0;
66 frame->buffer[3] = NULL;
67 frame->plane[3] = NULL;
69 frame->filtered[0] = frame->plane[0];
70 for( i = 0; i < 3; i++ )
72 frame->buffer[4+i] = x264_malloc( frame->i_stride[0] *
73 ( frame->i_lines[0] + 64 ) );
75 frame->filtered[i+1] = ((uint8_t*)frame->buffer[4+i]) +
76 frame->i_stride[0] * 32 + 32;
79 if( h->frames.b_have_lowres )
81 frame->i_stride_lowres = frame->i_stride[0]/2 + 32;
82 frame->i_lines_lowres = frame->i_lines[0]/2;
83 for( i = 0; i < 4; i++ )
85 frame->buffer[7+i] = x264_malloc( frame->i_stride_lowres *
86 ( frame->i_lines[0]/2 + 64 ) );
87 frame->lowres[i] = ((uint8_t*)frame->buffer[7+i]) +
88 frame->i_stride_lowres * 32 + 32;
92 if( h->param.analyse.i_me_method == X264_ME_ESA )
94 frame->buffer[11] = x264_malloc( frame->i_stride[0] * (frame->i_lines[0] + 64) * sizeof(uint16_t) );
95 frame->integral = (uint16_t*)frame->buffer[11] + frame->i_stride[0] * 32 + 32;
99 frame->i_type = X264_TYPE_AUTO;
100 frame->i_qpplus1 = 0;
103 frame->i_frame_num = -1;
105 frame->mb_type= x264_malloc( i_mb_count * sizeof( int8_t) );
106 frame->mv[0] = x264_malloc( 2*16 * i_mb_count * sizeof( int16_t ) );
107 frame->ref[0] = x264_malloc( 4 * i_mb_count * sizeof( int8_t ) );
108 if( h->param.i_bframe )
110 frame->mv[1] = x264_malloc( 2*16 * i_mb_count * sizeof( int16_t ) );
111 frame->ref[1] = x264_malloc( 4 * i_mb_count * sizeof( int8_t ) );
116 frame->ref[1] = NULL;
122 void x264_frame_delete( x264_frame_t *frame )
125 for( i = 0; i < frame->i_plane; i++ )
127 x264_free( frame->buffer[i] );
129 for( i = 4; i < 12; i++ ) /* filtered planes */
131 x264_free( frame->buffer[i] );
133 x264_free( frame->mb_type );
134 x264_free( frame->mv[0] );
135 x264_free( frame->mv[1] );
136 x264_free( frame->ref[0] );
137 x264_free( frame->ref[1] );
141 void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
143 dst->i_type = src->i_type;
144 dst->i_qpplus1 = src->i_qpplus1;
145 dst->i_pts = src->i_pts;
147 switch( src->img.i_csp & X264_CSP_MASK )
150 h->csp.i420( dst, &src->img, h->param.i_width, h->param.i_height );
153 h->csp.yv12( dst, &src->img, h->param.i_width, h->param.i_height );
156 h->csp.i422( dst, &src->img, h->param.i_width, h->param.i_height );
159 h->csp.i444( dst, &src->img, h->param.i_width, h->param.i_height );
162 h->csp.yuyv( dst, &src->img, h->param.i_width, h->param.i_height );
165 h->csp.rgb( dst, &src->img, h->param.i_width, h->param.i_height );
168 h->csp.bgr( dst, &src->img, h->param.i_width, h->param.i_height );
171 h->csp.bgra( dst, &src->img, h->param.i_width, h->param.i_height );
175 x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
182 static void plane_expand_border( uint8_t *pix, int i_stride, int i_height, int i_pad )
184 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
185 const int i_width = i_stride - 2*i_pad;
188 for( y = 0; y < i_height; y++ )
191 memset( PPIXEL(-i_pad, y), PPIXEL(0, y)[0], i_pad );
193 memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_pad );
196 for( y = 0; y < i_pad; y++ )
197 memcpy( PPIXEL(-i_pad, -y-1), PPIXEL(-i_pad, 0), i_stride );
199 for( y = 0; y < i_pad; y++ )
200 memcpy( PPIXEL(-i_pad, i_height+y), PPIXEL(-i_pad, i_height-1), i_stride );
204 void x264_frame_expand_border( x264_frame_t *frame )
207 for( i = 0; i < frame->i_plane; i++ )
209 int i_pad = i ? 16 : 32;
210 plane_expand_border( frame->plane[i], frame->i_stride[i], frame->i_lines[i], i_pad );
214 void x264_frame_expand_border_filtered( x264_frame_t *frame )
216 /* during filtering, 8 extra pixels were filtered on each edge.
217 we want to expand border from the last filtered pixel */
219 for( i = 1; i < 4; i++ )
220 plane_expand_border( frame->filtered[i] - 8*frame->i_stride[0] - 8, frame->i_stride[0], frame->i_lines[0]+2*8, 24 );
223 void x264_frame_expand_border_lowres( x264_frame_t *frame )
226 for( i = 0; i < 4; i++ )
227 plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_lines_lowres, 32 );
230 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
233 for( i = 0; i < frame->i_plane; i++ )
235 int i_subsample = i ? 1 : 0;
236 int i_width = h->param.i_width >> i_subsample;
237 int i_height = h->param.i_height >> i_subsample;
238 int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;
239 int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;
243 for( y = 0; y < i_height; y++ )
244 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
245 frame->plane[i][y*frame->i_stride[i] + i_width - 1],
250 for( y = i_height; y < i_height + i_pady; y++ );
251 memcpy( &frame->plane[i][y*frame->i_stride[i]],
252 &frame->plane[i][(i_height-1)*frame->i_stride[i]],
259 /* Deblocking filter */
261 static const int i_alpha_table[52] =
263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264 0, 0, 0, 0, 0, 0, 4, 4, 5, 6,
265 7, 8, 9, 10, 12, 13, 15, 17, 20, 22,
266 25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
267 80, 90,101,113,127,144,162,182,203,226,
270 static const int i_beta_table[52] =
272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 0, 0, 2, 2, 2, 3,
274 3, 3, 3, 4, 4, 4, 6, 6, 7, 7,
275 8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
276 13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
279 static const int i_tc0_table[52][3] =
281 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
282 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
283 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 },
284 { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 },
285 { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 },
286 { 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 },
287 { 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 },
288 { 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 },
289 { 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 }
293 static inline int clip_uint8( int a )
301 static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
304 for( i = 0; i < 4; i++ ) {
309 for( d = 0; d < 4; d++ ) {
310 const int p2 = pix[-3*xstride];
311 const int p1 = pix[-2*xstride];
312 const int p0 = pix[-1*xstride];
313 const int q0 = pix[ 0*xstride];
314 const int q1 = pix[ 1*xstride];
315 const int q2 = pix[ 2*xstride];
317 if( abs( p0 - q0 ) < alpha &&
318 abs( p1 - p0 ) < beta &&
319 abs( q1 - q0 ) < beta ) {
324 if( abs( p2 - p0 ) < beta ) {
325 pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
328 if( abs( q2 - q0 ) < beta ) {
329 pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
333 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
334 pix[-1*xstride] = clip_uint8( p0 + delta ); /* p0' */
335 pix[ 0*xstride] = clip_uint8( q0 - delta ); /* q0' */
341 static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
343 deblock_luma_c( pix, stride, 1, alpha, beta, tc0 );
345 static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
347 deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
350 static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
353 for( i = 0; i < 4; i++ ) {
354 const int tc = tc0[i];
359 for( d = 0; d < 2; d++ ) {
360 const int p1 = pix[-2*xstride];
361 const int p0 = pix[-1*xstride];
362 const int q0 = pix[ 0*xstride];
363 const int q1 = pix[ 1*xstride];
365 if( abs( p0 - q0 ) < alpha &&
366 abs( p1 - p0 ) < beta &&
367 abs( q1 - q0 ) < beta ) {
369 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
370 pix[-1*xstride] = clip_uint8( p0 + delta ); /* p0' */
371 pix[ 0*xstride] = clip_uint8( q0 - delta ); /* q0' */
377 static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
379 deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
381 static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
383 deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
386 static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
389 for( d = 0; d < 16; d++ ) {
390 const int p2 = pix[-3*xstride];
391 const int p1 = pix[-2*xstride];
392 const int p0 = pix[-1*xstride];
393 const int q0 = pix[ 0*xstride];
394 const int q1 = pix[ 1*xstride];
395 const int q2 = pix[ 2*xstride];
397 if( abs( p0 - q0 ) < alpha &&
398 abs( p1 - p0 ) < beta &&
399 abs( q1 - q0 ) < beta ) {
401 if(abs( p0 - q0 ) < ((alpha >> 2) + 2) ){
402 if( abs( p2 - p0 ) < beta)
404 const int p3 = pix[-4*xstride];
406 pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
407 pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
408 pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
411 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
413 if( abs( q2 - q0 ) < beta)
415 const int q3 = pix[3*xstride];
417 pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
418 pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
419 pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
422 pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
426 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
427 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
433 static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
435 deblock_luma_intra_c( pix, stride, 1, alpha, beta );
437 static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
439 deblock_luma_intra_c( pix, 1, stride, alpha, beta );
442 static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
445 for( d = 0; d < 8; d++ ) {
446 const int p1 = pix[-2*xstride];
447 const int p0 = pix[-1*xstride];
448 const int q0 = pix[ 0*xstride];
449 const int q1 = pix[ 1*xstride];
451 if( abs( p0 - q0 ) < alpha &&
452 abs( p1 - p0 ) < beta &&
453 abs( q1 - q0 ) < beta ) {
455 pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2; /* p0' */
456 pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2; /* q0' */
462 static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
464 deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
466 static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
468 deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
471 static inline void deblock_edge( x264_t *h, uint8_t *pix, int i_stride, int bS[4], int i_qp, int b_chroma,
472 x264_deblock_inter_t pf_inter, x264_deblock_intra_t pf_intra )
475 const int index_a = x264_clip3( i_qp + h->sh.i_alpha_c0_offset, 0, 51 );
476 const int alpha = i_alpha_table[index_a];
477 const int beta = i_beta_table[x264_clip3( i_qp + h->sh.i_beta_offset, 0, 51 )];
482 tc[i] = (bS[i] ? i_tc0_table[index_a][bS[i] - 1] : -1) + b_chroma;
483 pf_inter( pix, i_stride, alpha, beta, tc );
485 pf_intra( pix, i_stride, alpha, beta );
489 void x264_frame_deblocking_filter( x264_t *h, int i_slice_type )
491 const int s8x8 = 2 * h->mb.i_mb_stride;
492 const int s4x4 = 4 * h->mb.i_mb_stride;
496 for( mb_y = 0, mb_x = 0; mb_y < h->sps->i_mb_height; )
498 const int mb_xy = mb_y * h->mb.i_mb_stride + mb_x;
499 const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
500 const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
503 const int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
505 /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
506 * entropy coding, but per 64 coeffs for the purpose of deblocking */
507 if( !h->param.b_cabac && b_8x8_transform )
509 uint32_t *nnz = (uint32_t*)h->mb.non_zero_count[mb_xy];
510 if( nnz[0] ) nnz[0] = 0x01010101;
511 if( nnz[1] ) nnz[1] = 0x01010101;
512 if( nnz[2] ) nnz[2] = 0x01010101;
513 if( nnz[3] ) nnz[3] = 0x01010101;
516 /* i_dir == 0 -> vertical edge
517 * i_dir == 1 -> horizontal edge */
518 for( i_dir = 0; i_dir < 2; i_dir++ )
523 i_start = (( i_dir == 0 && mb_x != 0 ) || ( i_dir == 1 && mb_y != 0 ) ) ? 0 : 1;
525 for( i_edge = i_start; i_edge < 4; i_edge++ )
527 int mbn_xy = i_edge > 0 ? mb_xy : ( i_dir == 0 ? mb_xy - 1 : mb_xy - h->mb.i_mb_stride );
528 int mbn_8x8 = i_edge > 0 ? mb_8x8 : ( i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8 );
529 int mbn_4x4 = i_edge > 0 ? mb_4x4 : ( i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4 );
531 int bS[4]; /* filtering strength */
533 /* *** Get bS for each 4px for the current edge *** */
534 if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy] ) )
536 bS[0] = bS[1] = bS[2] = bS[3] = ( i_edge == 0 ? 4 : 3 );
541 for( i = 0; i < 4; i++ )
543 int x = i_dir == 0 ? i_edge : i;
544 int y = i_dir == 0 ? i : i_edge;
545 int xn = (x - (i_dir == 0 ? 1 : 0 ))&0x03;
546 int yn = (y - (i_dir == 0 ? 0 : 1 ))&0x03;
548 if( h->mb.non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 ||
549 h->mb.non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 )
555 /* FIXME: A given frame may occupy more than one position in
556 * the reference list. So we should compare the frame numbers,
557 * not the indices in the ref list.
558 * No harm yet, as we don't generate that case.*/
560 int i8p= mb_8x8+(x/2)+(y/2)*s8x8;
561 int i8q= mbn_8x8+(xn/2)+(yn/2)*s8x8;
562 int i4p= mb_4x4+x+y*s4x4;
563 int i4q= mbn_4x4+xn+yn*s4x4;
568 for( l = 0; l < 1 + (i_slice_type == SLICE_TYPE_B); l++ )
570 if( h->mb.ref[l][i8p] != h->mb.ref[l][i8q] ||
571 abs( h->mb.mv[l][i4p][0] - h->mb.mv[l][i4q][0] ) >= 4 ||
572 abs( h->mb.mv[l][i4p][1] - h->mb.mv[l][i4q][1] ) >= 4 )
584 i_qp = h->mb.qp[mb_xy];
585 i_qpn= h->mb.qp[mbn_xy];
590 if( !b_8x8_transform || !(i_edge & 1) )
592 deblock_edge( h, &h->fdec->plane[0][16*mb_y * h->fdec->i_stride[0] + 16*mb_x + 4*i_edge],
593 h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1, 0,
594 h->loopf.deblock_h_luma, h->loopf.deblock_h_luma_intra );
599 int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
600 i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
601 deblock_edge( h, &h->fdec->plane[1][8*(mb_y*h->fdec->i_stride[1]+mb_x)+2*i_edge],
602 h->fdec->i_stride[1], bS, i_qpc, 1,
603 h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
604 deblock_edge( h, &h->fdec->plane[2][8*(mb_y*h->fdec->i_stride[2]+mb_x)+2*i_edge],
605 h->fdec->i_stride[2], bS, i_qpc, 1,
606 h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
611 /* horizontal edge */
612 if( !b_8x8_transform || !(i_edge & 1) )
614 deblock_edge( h, &h->fdec->plane[0][(16*mb_y + 4*i_edge) * h->fdec->i_stride[0] + 16*mb_x],
615 h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1, 0,
616 h->loopf.deblock_v_luma, h->loopf.deblock_v_luma_intra );
621 int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
622 i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
623 deblock_edge( h, &h->fdec->plane[1][8*(mb_y*h->fdec->i_stride[1]+mb_x)+2*i_edge*h->fdec->i_stride[1]],
624 h->fdec->i_stride[1], bS, i_qpc, 1,
625 h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
626 deblock_edge( h, &h->fdec->plane[2][8*(mb_y*h->fdec->i_stride[2]+mb_x)+2*i_edge*h->fdec->i_stride[2]],
627 h->fdec->i_stride[2], bS, i_qpc, 1,
628 h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
636 if( mb_x >= h->sps->i_mb_width )
645 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
646 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
647 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
648 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
652 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
653 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
654 #elif defined( HAVE_MMXEXT )
655 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
656 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
658 void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
660 x264_deblock_v8_luma_mmxext( pix, stride, alpha, beta, tc0 );
661 x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
665 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
667 pf->deblock_v_luma = deblock_v_luma_c;
668 pf->deblock_h_luma = deblock_h_luma_c;
669 pf->deblock_v_chroma = deblock_v_chroma_c;
670 pf->deblock_h_chroma = deblock_h_chroma_c;
671 pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
672 pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
673 pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
674 pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
677 if( cpu&X264_CPU_MMXEXT )
679 pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
680 pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
681 pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
682 pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
685 if( cpu&X264_CPU_SSE2 )
687 pf->deblock_v_luma = x264_deblock_v_luma_sse2;
688 pf->deblock_h_luma = x264_deblock_h_luma_sse2;
691 pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
692 pf->deblock_h_luma = x264_deblock_h_luma_mmxext;