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;
119 frame->i_row_bits = x264_malloc( i_lines/16 * sizeof( int ) );
120 frame->i_row_qp = x264_malloc( i_lines/16 * sizeof( int ) );
121 for( i = 0; i < h->param.i_bframe + 2; i++ )
122 for( j = 0; j < h->param.i_bframe + 2; j++ )
123 frame->i_row_satds[i][j] = x264_malloc( i_lines/16 * sizeof( int ) );
128 void x264_frame_delete( x264_frame_t *frame )
131 for( i = 0; i < frame->i_plane; i++ )
132 x264_free( frame->buffer[i] );
133 for( i = 4; i < 12; i++ ) /* filtered planes */
134 x264_free( frame->buffer[i] );
135 for( i = 0; i < X264_BFRAME_MAX+2; i++ )
136 for( j = 0; j < X264_BFRAME_MAX+2; j++ )
137 x264_free( frame->i_row_satds[i][j] );
138 x264_free( frame->i_row_bits );
139 x264_free( frame->i_row_qp );
140 x264_free( frame->mb_type );
141 x264_free( frame->mv[0] );
142 x264_free( frame->mv[1] );
143 x264_free( frame->ref[0] );
144 x264_free( frame->ref[1] );
148 void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
150 dst->i_type = src->i_type;
151 dst->i_qpplus1 = src->i_qpplus1;
152 dst->i_pts = src->i_pts;
154 switch( src->img.i_csp & X264_CSP_MASK )
157 h->csp.i420( dst, &src->img, h->param.i_width, h->param.i_height );
160 h->csp.yv12( dst, &src->img, h->param.i_width, h->param.i_height );
163 h->csp.i422( dst, &src->img, h->param.i_width, h->param.i_height );
166 h->csp.i444( dst, &src->img, h->param.i_width, h->param.i_height );
169 h->csp.yuyv( dst, &src->img, h->param.i_width, h->param.i_height );
172 h->csp.rgb( dst, &src->img, h->param.i_width, h->param.i_height );
175 h->csp.bgr( dst, &src->img, h->param.i_width, h->param.i_height );
178 h->csp.bgra( dst, &src->img, h->param.i_width, h->param.i_height );
182 x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
189 static void plane_expand_border( uint8_t *pix, int i_stride, int i_height, int i_pad )
191 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
192 const int i_width = i_stride - 2*i_pad;
195 for( y = 0; y < i_height; y++ )
198 memset( PPIXEL(-i_pad, y), PPIXEL(0, y)[0], i_pad );
200 memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_pad );
203 for( y = 0; y < i_pad; y++ )
204 memcpy( PPIXEL(-i_pad, -y-1), PPIXEL(-i_pad, 0), i_stride );
206 for( y = 0; y < i_pad; y++ )
207 memcpy( PPIXEL(-i_pad, i_height+y), PPIXEL(-i_pad, i_height-1), i_stride );
211 void x264_frame_expand_border( x264_frame_t *frame )
214 for( i = 0; i < frame->i_plane; i++ )
216 int i_pad = i ? 16 : 32;
217 plane_expand_border( frame->plane[i], frame->i_stride[i], frame->i_lines[i], i_pad );
221 void x264_frame_expand_border_filtered( x264_frame_t *frame )
223 /* during filtering, 8 extra pixels were filtered on each edge.
224 we want to expand border from the last filtered pixel */
226 for( i = 1; i < 4; i++ )
227 plane_expand_border( frame->filtered[i] - 8*frame->i_stride[0] - 8, frame->i_stride[0], frame->i_lines[0]+2*8, 24 );
230 void x264_frame_expand_border_lowres( x264_frame_t *frame )
233 for( i = 0; i < 4; i++ )
234 plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_lines_lowres, 32 );
237 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
240 for( i = 0; i < frame->i_plane; i++ )
242 int i_subsample = i ? 1 : 0;
243 int i_width = h->param.i_width >> i_subsample;
244 int i_height = h->param.i_height >> i_subsample;
245 int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;
246 int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;
250 for( y = 0; y < i_height; y++ )
251 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
252 frame->plane[i][y*frame->i_stride[i] + i_width - 1],
257 for( y = i_height; y < i_height + i_pady; y++ );
258 memcpy( &frame->plane[i][y*frame->i_stride[i]],
259 &frame->plane[i][(i_height-1)*frame->i_stride[i]],
266 /* Deblocking filter */
268 static const int i_alpha_table[52] =
270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
271 0, 0, 0, 0, 0, 0, 4, 4, 5, 6,
272 7, 8, 9, 10, 12, 13, 15, 17, 20, 22,
273 25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
274 80, 90,101,113,127,144,162,182,203,226,
277 static const int i_beta_table[52] =
279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280 0, 0, 0, 0, 0, 0, 2, 2, 2, 3,
281 3, 3, 3, 4, 4, 4, 6, 6, 7, 7,
282 8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
283 13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
286 static const int i_tc0_table[52][3] =
288 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
289 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
290 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 },
291 { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 },
292 { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 },
293 { 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 },
294 { 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 },
295 { 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 },
296 { 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 }
300 static inline int clip_uint8( int a )
308 static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
311 for( i = 0; i < 4; i++ ) {
316 for( d = 0; d < 4; d++ ) {
317 const int p2 = pix[-3*xstride];
318 const int p1 = pix[-2*xstride];
319 const int p0 = pix[-1*xstride];
320 const int q0 = pix[ 0*xstride];
321 const int q1 = pix[ 1*xstride];
322 const int q2 = pix[ 2*xstride];
324 if( abs( p0 - q0 ) < alpha &&
325 abs( p1 - p0 ) < beta &&
326 abs( q1 - q0 ) < beta ) {
331 if( abs( p2 - p0 ) < beta ) {
332 pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
335 if( abs( q2 - q0 ) < beta ) {
336 pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
340 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
341 pix[-1*xstride] = clip_uint8( p0 + delta ); /* p0' */
342 pix[ 0*xstride] = clip_uint8( q0 - delta ); /* q0' */
348 static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
350 deblock_luma_c( pix, stride, 1, alpha, beta, tc0 );
352 static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
354 deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
357 static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
360 for( i = 0; i < 4; i++ ) {
361 const int tc = tc0[i];
366 for( d = 0; d < 2; d++ ) {
367 const int p1 = pix[-2*xstride];
368 const int p0 = pix[-1*xstride];
369 const int q0 = pix[ 0*xstride];
370 const int q1 = pix[ 1*xstride];
372 if( abs( p0 - q0 ) < alpha &&
373 abs( p1 - p0 ) < beta &&
374 abs( q1 - q0 ) < beta ) {
376 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
377 pix[-1*xstride] = clip_uint8( p0 + delta ); /* p0' */
378 pix[ 0*xstride] = clip_uint8( q0 - delta ); /* q0' */
384 static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
386 deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
388 static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
390 deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
393 static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
396 for( d = 0; d < 16; d++ ) {
397 const int p2 = pix[-3*xstride];
398 const int p1 = pix[-2*xstride];
399 const int p0 = pix[-1*xstride];
400 const int q0 = pix[ 0*xstride];
401 const int q1 = pix[ 1*xstride];
402 const int q2 = pix[ 2*xstride];
404 if( abs( p0 - q0 ) < alpha &&
405 abs( p1 - p0 ) < beta &&
406 abs( q1 - q0 ) < beta ) {
408 if(abs( p0 - q0 ) < ((alpha >> 2) + 2) ){
409 if( abs( p2 - p0 ) < beta)
411 const int p3 = pix[-4*xstride];
413 pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
414 pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
415 pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
418 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
420 if( abs( q2 - q0 ) < beta)
422 const int q3 = pix[3*xstride];
424 pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
425 pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
426 pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
429 pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
433 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
434 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
440 static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
442 deblock_luma_intra_c( pix, stride, 1, alpha, beta );
444 static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
446 deblock_luma_intra_c( pix, 1, stride, alpha, beta );
449 static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
452 for( d = 0; d < 8; d++ ) {
453 const int p1 = pix[-2*xstride];
454 const int p0 = pix[-1*xstride];
455 const int q0 = pix[ 0*xstride];
456 const int q1 = pix[ 1*xstride];
458 if( abs( p0 - q0 ) < alpha &&
459 abs( p1 - p0 ) < beta &&
460 abs( q1 - q0 ) < beta ) {
462 pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2; /* p0' */
463 pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2; /* q0' */
469 static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
471 deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
473 static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
475 deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
478 static inline void deblock_edge( x264_t *h, uint8_t *pix, int i_stride, int bS[4], int i_qp, int b_chroma,
479 x264_deblock_inter_t pf_inter, x264_deblock_intra_t pf_intra )
482 const int index_a = x264_clip3( i_qp + h->sh.i_alpha_c0_offset, 0, 51 );
483 const int alpha = i_alpha_table[index_a];
484 const int beta = i_beta_table[x264_clip3( i_qp + h->sh.i_beta_offset, 0, 51 )];
489 tc[i] = (bS[i] ? i_tc0_table[index_a][bS[i] - 1] : -1) + b_chroma;
490 pf_inter( pix, i_stride, alpha, beta, tc );
492 pf_intra( pix, i_stride, alpha, beta );
496 void x264_frame_deblocking_filter( x264_t *h, int i_slice_type )
498 const int s8x8 = 2 * h->mb.i_mb_stride;
499 const int s4x4 = 4 * h->mb.i_mb_stride;
503 for( mb_y = 0, mb_x = 0; mb_y < h->sps->i_mb_height; )
505 const int mb_xy = mb_y * h->mb.i_mb_stride + mb_x;
506 const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
507 const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
508 const int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
509 const int i_edge_end = (h->mb.type[mb_xy] == P_SKIP) ? 1 : 4;
512 /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
513 * entropy coding, but per 64 coeffs for the purpose of deblocking */
514 if( !h->param.b_cabac && b_8x8_transform )
516 uint32_t *nnz = (uint32_t*)h->mb.non_zero_count[mb_xy];
517 if( nnz[0] ) nnz[0] = 0x01010101;
518 if( nnz[1] ) nnz[1] = 0x01010101;
519 if( nnz[2] ) nnz[2] = 0x01010101;
520 if( nnz[3] ) nnz[3] = 0x01010101;
523 /* i_dir == 0 -> vertical edge
524 * i_dir == 1 -> horizontal edge */
525 for( i_dir = 0; i_dir < 2; i_dir++ )
527 int i_start = (i_dir ? mb_y : mb_x) ? 0 : 1;
530 for( i_edge = i_start; i_edge < i_edge_end; i_edge++ )
532 int mbn_xy, mbn_8x8, mbn_4x4;
533 int bS[4]; /* filtering strength */
535 if( b_8x8_transform && (i_edge&1) )
538 mbn_xy = i_edge > 0 ? mb_xy : ( i_dir == 0 ? mb_xy - 1 : mb_xy - h->mb.i_mb_stride );
539 mbn_8x8 = i_edge > 0 ? mb_8x8 : ( i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8 );
540 mbn_4x4 = i_edge > 0 ? mb_4x4 : ( i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4 );
542 /* *** Get bS for each 4px for the current edge *** */
543 if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy] ) )
545 bS[0] = bS[1] = bS[2] = bS[3] = ( i_edge == 0 ? 4 : 3 );
550 for( i = 0; i < 4; i++ )
552 int x = i_dir == 0 ? i_edge : i;
553 int y = i_dir == 0 ? i : i_edge;
554 int xn = (x - (i_dir == 0 ? 1 : 0 ))&0x03;
555 int yn = (y - (i_dir == 0 ? 0 : 1 ))&0x03;
557 if( h->mb.non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 ||
558 h->mb.non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 )
564 /* FIXME: A given frame may occupy more than one position in
565 * the reference list. So we should compare the frame numbers,
566 * not the indices in the ref list.
567 * No harm yet, as we don't generate that case.*/
569 int i8p= mb_8x8+(x/2)+(y/2)*s8x8;
570 int i8q= mbn_8x8+(xn/2)+(yn/2)*s8x8;
571 int i4p= mb_4x4+x+y*s4x4;
572 int i4q= mbn_4x4+xn+yn*s4x4;
577 for( l = 0; l < 1 + (i_slice_type == SLICE_TYPE_B); l++ )
579 if( h->mb.ref[l][i8p] != h->mb.ref[l][i8q] ||
580 abs( h->mb.mv[l][i4p][0] - h->mb.mv[l][i4q][0] ) >= 4 ||
581 abs( h->mb.mv[l][i4p][1] - h->mb.mv[l][i4q][1] ) >= 4 )
593 i_qp = h->mb.qp[mb_xy];
594 i_qpn= h->mb.qp[mbn_xy];
599 deblock_edge( h, &h->fdec->plane[0][16*mb_y * h->fdec->i_stride[0] + 16*mb_x + 4*i_edge],
600 h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1, 0,
601 h->loopf.deblock_h_luma, h->loopf.deblock_h_luma_intra );
605 int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
606 i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
607 deblock_edge( h, &h->fdec->plane[1][8*(mb_y*h->fdec->i_stride[1]+mb_x)+2*i_edge],
608 h->fdec->i_stride[1], bS, i_qpc, 1,
609 h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
610 deblock_edge( h, &h->fdec->plane[2][8*(mb_y*h->fdec->i_stride[2]+mb_x)+2*i_edge],
611 h->fdec->i_stride[2], bS, i_qpc, 1,
612 h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
617 /* horizontal edge */
618 deblock_edge( h, &h->fdec->plane[0][(16*mb_y + 4*i_edge) * h->fdec->i_stride[0] + 16*mb_x],
619 h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1, 0,
620 h->loopf.deblock_v_luma, h->loopf.deblock_v_luma_intra );
624 int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
625 i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
626 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]],
627 h->fdec->i_stride[1], bS, i_qpc, 1,
628 h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
629 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]],
630 h->fdec->i_stride[2], bS, i_qpc, 1,
631 h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
639 if( mb_x >= h->sps->i_mb_width )
648 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
649 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
650 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
651 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
655 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
656 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
657 #elif defined( HAVE_MMXEXT )
658 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
659 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
661 void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
663 x264_deblock_v8_luma_mmxext( pix, stride, alpha, beta, tc0 );
664 x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
668 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
670 pf->deblock_v_luma = deblock_v_luma_c;
671 pf->deblock_h_luma = deblock_h_luma_c;
672 pf->deblock_v_chroma = deblock_v_chroma_c;
673 pf->deblock_h_chroma = deblock_h_chroma_c;
674 pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
675 pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
676 pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
677 pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
680 if( cpu&X264_CPU_MMXEXT )
682 pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
683 pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
684 pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
685 pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
688 if( cpu&X264_CPU_SSE2 )
690 pf->deblock_v_luma = x264_deblock_v_luma_sse2;
691 pf->deblock_h_luma = x264_deblock_h_luma_sse2;
694 pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
695 pf->deblock_h_luma = x264_deblock_h_luma_mmxext;