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 if( !frame ) return NULL;
40 memset( frame, 0, sizeof(x264_frame_t) );
42 /* allocate frame data (+64 for extra data for me) */
43 i_stride = ( ( h->param.i_width + 15 )&0xfffff0 )+ 64;
44 i_lines = ( ( h->param.i_height + 15 )&0xfffff0 );
47 for( i = 0; i < 3; i++ )
53 if( h->param.i_csp == X264_CSP_I420 )
55 else if( h->param.i_csp == X264_CSP_I422 )
58 frame->i_stride[i] = i_stride / i_divw;
59 frame->i_lines[i] = i_lines / i_divh;
60 CHECKED_MALLOC( frame->buffer[i],
61 frame->i_stride[i] * ( frame->i_lines[i] + 64 / i_divh ) );
62 frame->plane[i] = ((uint8_t*)frame->buffer[i]) +
63 frame->i_stride[i] * 32 / i_divh + 32 / i_divw;
65 frame->i_stride[3] = 0;
66 frame->i_lines[3] = 0;
67 frame->buffer[3] = NULL;
68 frame->plane[3] = NULL;
70 frame->filtered[0] = frame->plane[0];
71 for( i = 0; i < 3; i++ )
73 CHECKED_MALLOC( frame->buffer[4+i],
74 frame->i_stride[0] * ( 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 CHECKED_MALLOC( frame->buffer[7+i],
86 frame->i_stride_lowres * ( 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 CHECKED_MALLOC( frame->buffer[11],
95 frame->i_stride[0] * (frame->i_lines[0] + 64) * sizeof(uint16_t) );
96 frame->integral = (uint16_t*)frame->buffer[11] + frame->i_stride[0] * 32 + 32;
100 frame->i_type = X264_TYPE_AUTO;
101 frame->i_qpplus1 = 0;
104 frame->i_frame_num = -1;
106 CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
107 CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
108 CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
109 if( h->param.i_bframe )
111 CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );
112 CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );
117 frame->ref[1] = NULL;
120 CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
121 CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );
122 for( i = 0; i < h->param.i_bframe + 2; i++ )
123 for( j = 0; j < h->param.i_bframe + 2; j++ )
124 CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );
129 x264_frame_delete( frame );
133 void x264_frame_delete( x264_frame_t *frame )
136 for( i = 0; i < 12; i++ )
137 x264_free( frame->buffer[i] );
138 for( i = 0; i < X264_BFRAME_MAX+2; i++ )
139 for( j = 0; j < X264_BFRAME_MAX+2; j++ )
140 x264_free( frame->i_row_satds[i][j] );
141 x264_free( frame->i_row_bits );
142 x264_free( frame->i_row_qp );
143 x264_free( frame->mb_type );
144 x264_free( frame->mv[0] );
145 x264_free( frame->mv[1] );
146 x264_free( frame->ref[0] );
147 x264_free( frame->ref[1] );
151 void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
153 dst->i_type = src->i_type;
154 dst->i_qpplus1 = src->i_qpplus1;
155 dst->i_pts = src->i_pts;
157 switch( src->img.i_csp & X264_CSP_MASK )
160 h->csp.i420( dst, &src->img, h->param.i_width, h->param.i_height );
163 h->csp.yv12( dst, &src->img, h->param.i_width, h->param.i_height );
166 h->csp.i422( dst, &src->img, h->param.i_width, h->param.i_height );
169 h->csp.i444( dst, &src->img, h->param.i_width, h->param.i_height );
172 h->csp.yuyv( dst, &src->img, h->param.i_width, h->param.i_height );
175 h->csp.rgb( dst, &src->img, h->param.i_width, h->param.i_height );
178 h->csp.bgr( dst, &src->img, h->param.i_width, h->param.i_height );
181 h->csp.bgra( dst, &src->img, h->param.i_width, h->param.i_height );
185 x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
192 static void plane_expand_border( uint8_t *pix, int i_stride, int i_height, int i_pad )
194 #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
195 const int i_width = i_stride - 2*i_pad;
198 for( y = 0; y < i_height; y++ )
201 memset( PPIXEL(-i_pad, y), PPIXEL(0, y)[0], i_pad );
203 memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_pad );
206 for( y = 0; y < i_pad; y++ )
207 memcpy( PPIXEL(-i_pad, -y-1), PPIXEL(-i_pad, 0), i_stride );
209 for( y = 0; y < i_pad; y++ )
210 memcpy( PPIXEL(-i_pad, i_height+y), PPIXEL(-i_pad, i_height-1), i_stride );
214 void x264_frame_expand_border( x264_frame_t *frame )
217 for( i = 0; i < frame->i_plane; i++ )
219 int i_pad = i ? 16 : 32;
220 plane_expand_border( frame->plane[i], frame->i_stride[i], frame->i_lines[i], i_pad );
224 void x264_frame_expand_border_filtered( x264_frame_t *frame )
226 /* during filtering, 8 extra pixels were filtered on each edge.
227 we want to expand border from the last filtered pixel */
229 for( i = 1; i < 4; i++ )
230 plane_expand_border( frame->filtered[i] - 8*frame->i_stride[0] - 8, frame->i_stride[0], frame->i_lines[0]+2*8, 24 );
233 void x264_frame_expand_border_lowres( x264_frame_t *frame )
236 for( i = 0; i < 4; i++ )
237 plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_lines_lowres, 32 );
240 void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
243 for( i = 0; i < frame->i_plane; i++ )
245 int i_subsample = i ? 1 : 0;
246 int i_width = h->param.i_width >> i_subsample;
247 int i_height = h->param.i_height >> i_subsample;
248 int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;
249 int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;
253 for( y = 0; y < i_height; y++ )
254 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
255 frame->plane[i][y*frame->i_stride[i] + i_width - 1],
260 for( y = i_height; y < i_height + i_pady; y++ )
261 memcpy( &frame->plane[i][y*frame->i_stride[i]],
262 &frame->plane[i][(i_height-1)*frame->i_stride[i]],
269 /* Deblocking filter */
271 static const int i_alpha_table[52] =
273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 4, 4, 5, 6,
275 7, 8, 9, 10, 12, 13, 15, 17, 20, 22,
276 25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
277 80, 90,101,113,127,144,162,182,203,226,
280 static const int i_beta_table[52] =
282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283 0, 0, 0, 0, 0, 0, 2, 2, 2, 3,
284 3, 3, 3, 4, 4, 4, 6, 6, 7, 7,
285 8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
286 13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
289 static const int i_tc0_table[52][3] =
291 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
292 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
293 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 },
294 { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 },
295 { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 },
296 { 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 },
297 { 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 },
298 { 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 },
299 { 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 }
303 static inline int clip_uint8( int a )
311 static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
314 for( i = 0; i < 4; i++ ) {
319 for( d = 0; d < 4; d++ ) {
320 const int p2 = pix[-3*xstride];
321 const int p1 = pix[-2*xstride];
322 const int p0 = pix[-1*xstride];
323 const int q0 = pix[ 0*xstride];
324 const int q1 = pix[ 1*xstride];
325 const int q2 = pix[ 2*xstride];
327 if( abs( p0 - q0 ) < alpha &&
328 abs( p1 - p0 ) < beta &&
329 abs( q1 - q0 ) < beta ) {
334 if( abs( p2 - p0 ) < beta ) {
335 pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
338 if( abs( q2 - q0 ) < beta ) {
339 pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
343 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
344 pix[-1*xstride] = clip_uint8( p0 + delta ); /* p0' */
345 pix[ 0*xstride] = clip_uint8( q0 - delta ); /* q0' */
351 static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
353 deblock_luma_c( pix, stride, 1, alpha, beta, tc0 );
355 static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
357 deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
360 static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
363 for( i = 0; i < 4; i++ ) {
364 const int tc = tc0[i];
369 for( d = 0; d < 2; d++ ) {
370 const int p1 = pix[-2*xstride];
371 const int p0 = pix[-1*xstride];
372 const int q0 = pix[ 0*xstride];
373 const int q1 = pix[ 1*xstride];
375 if( abs( p0 - q0 ) < alpha &&
376 abs( p1 - p0 ) < beta &&
377 abs( q1 - q0 ) < beta ) {
379 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
380 pix[-1*xstride] = clip_uint8( p0 + delta ); /* p0' */
381 pix[ 0*xstride] = clip_uint8( q0 - delta ); /* q0' */
387 static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
389 deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
391 static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
393 deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
396 static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
399 for( d = 0; d < 16; d++ ) {
400 const int p2 = pix[-3*xstride];
401 const int p1 = pix[-2*xstride];
402 const int p0 = pix[-1*xstride];
403 const int q0 = pix[ 0*xstride];
404 const int q1 = pix[ 1*xstride];
405 const int q2 = pix[ 2*xstride];
407 if( abs( p0 - q0 ) < alpha &&
408 abs( p1 - p0 ) < beta &&
409 abs( q1 - q0 ) < beta ) {
411 if(abs( p0 - q0 ) < ((alpha >> 2) + 2) ){
412 if( abs( p2 - p0 ) < beta)
414 const int p3 = pix[-4*xstride];
416 pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
417 pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
418 pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
421 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
423 if( abs( q2 - q0 ) < beta)
425 const int q3 = pix[3*xstride];
427 pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
428 pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
429 pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
432 pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
436 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
437 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
443 static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
445 deblock_luma_intra_c( pix, stride, 1, alpha, beta );
447 static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
449 deblock_luma_intra_c( pix, 1, stride, alpha, beta );
452 static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
455 for( d = 0; d < 8; d++ ) {
456 const int p1 = pix[-2*xstride];
457 const int p0 = pix[-1*xstride];
458 const int q0 = pix[ 0*xstride];
459 const int q1 = pix[ 1*xstride];
461 if( abs( p0 - q0 ) < alpha &&
462 abs( p1 - p0 ) < beta &&
463 abs( q1 - q0 ) < beta ) {
465 pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2; /* p0' */
466 pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2; /* q0' */
472 static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
474 deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
476 static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
478 deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
481 static inline void deblock_edge( x264_t *h, uint8_t *pix, int i_stride, int bS[4], int i_qp, int b_chroma,
482 x264_deblock_inter_t pf_inter, x264_deblock_intra_t pf_intra )
485 const int index_a = x264_clip3( i_qp + h->sh.i_alpha_c0_offset, 0, 51 );
486 const int alpha = i_alpha_table[index_a];
487 const int beta = i_beta_table[x264_clip3( i_qp + h->sh.i_beta_offset, 0, 51 )];
492 tc[i] = (bS[i] ? i_tc0_table[index_a][bS[i] - 1] : -1) + b_chroma;
493 pf_inter( pix, i_stride, alpha, beta, tc );
495 pf_intra( pix, i_stride, alpha, beta );
499 void x264_frame_deblocking_filter( x264_t *h, int i_slice_type )
501 const int s8x8 = 2 * h->mb.i_mb_stride;
502 const int s4x4 = 4 * h->mb.i_mb_stride;
506 for( mb_y = 0, mb_x = 0; mb_y < h->sps->i_mb_height; )
508 const int mb_xy = mb_y * h->mb.i_mb_stride + mb_x;
509 const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
510 const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
511 const int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
512 const int i_edge_end = (h->mb.type[mb_xy] == P_SKIP) ? 1 : 4;
515 /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
516 * entropy coding, but per 64 coeffs for the purpose of deblocking */
517 if( !h->param.b_cabac && b_8x8_transform )
519 uint32_t *nnz = (uint32_t*)h->mb.non_zero_count[mb_xy];
520 if( nnz[0] ) nnz[0] = 0x01010101;
521 if( nnz[1] ) nnz[1] = 0x01010101;
522 if( nnz[2] ) nnz[2] = 0x01010101;
523 if( nnz[3] ) nnz[3] = 0x01010101;
526 /* i_dir == 0 -> vertical edge
527 * i_dir == 1 -> horizontal edge */
528 for( i_dir = 0; i_dir < 2; i_dir++ )
530 int i_start = (i_dir ? mb_y : mb_x) ? 0 : 1;
533 for( i_edge = i_start; i_edge < i_edge_end; i_edge++ )
535 int mbn_xy, mbn_8x8, mbn_4x4;
536 int bS[4]; /* filtering strength */
538 if( b_8x8_transform && (i_edge&1) )
541 mbn_xy = i_edge > 0 ? mb_xy : ( i_dir == 0 ? mb_xy - 1 : mb_xy - h->mb.i_mb_stride );
542 mbn_8x8 = i_edge > 0 ? mb_8x8 : ( i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8 );
543 mbn_4x4 = i_edge > 0 ? mb_4x4 : ( i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4 );
545 /* *** Get bS for each 4px for the current edge *** */
546 if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy] ) )
548 bS[0] = bS[1] = bS[2] = bS[3] = ( i_edge == 0 ? 4 : 3 );
553 for( i = 0; i < 4; i++ )
555 int x = i_dir == 0 ? i_edge : i;
556 int y = i_dir == 0 ? i : i_edge;
557 int xn = (x - (i_dir == 0 ? 1 : 0 ))&0x03;
558 int yn = (y - (i_dir == 0 ? 0 : 1 ))&0x03;
560 if( h->mb.non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 ||
561 h->mb.non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 )
567 /* FIXME: A given frame may occupy more than one position in
568 * the reference list. So we should compare the frame numbers,
569 * not the indices in the ref list.
570 * No harm yet, as we don't generate that case.*/
572 int i8p= mb_8x8+(x/2)+(y/2)*s8x8;
573 int i8q= mbn_8x8+(xn/2)+(yn/2)*s8x8;
574 int i4p= mb_4x4+x+y*s4x4;
575 int i4q= mbn_4x4+xn+yn*s4x4;
580 for( l = 0; l < 1 + (i_slice_type == SLICE_TYPE_B); l++ )
582 if( h->mb.ref[l][i8p] != h->mb.ref[l][i8q] ||
583 abs( h->mb.mv[l][i4p][0] - h->mb.mv[l][i4q][0] ) >= 4 ||
584 abs( h->mb.mv[l][i4p][1] - h->mb.mv[l][i4q][1] ) >= 4 )
596 i_qp = h->mb.qp[mb_xy];
597 i_qpn= h->mb.qp[mbn_xy];
602 deblock_edge( h, &h->fdec->plane[0][16*mb_y * h->fdec->i_stride[0] + 16*mb_x + 4*i_edge],
603 h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1, 0,
604 h->loopf.deblock_h_luma, h->loopf.deblock_h_luma_intra );
608 int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
609 i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
610 deblock_edge( h, &h->fdec->plane[1][8*(mb_y*h->fdec->i_stride[1]+mb_x)+2*i_edge],
611 h->fdec->i_stride[1], bS, i_qpc, 1,
612 h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
613 deblock_edge( h, &h->fdec->plane[2][8*(mb_y*h->fdec->i_stride[2]+mb_x)+2*i_edge],
614 h->fdec->i_stride[2], bS, i_qpc, 1,
615 h->loopf.deblock_h_chroma, h->loopf.deblock_h_chroma_intra );
620 /* horizontal edge */
621 deblock_edge( h, &h->fdec->plane[0][(16*mb_y + 4*i_edge) * h->fdec->i_stride[0] + 16*mb_x],
622 h->fdec->i_stride[0], bS, (i_qp+i_qpn+1) >> 1, 0,
623 h->loopf.deblock_v_luma, h->loopf.deblock_v_luma_intra );
627 int i_qpc = ( i_chroma_qp_table[x264_clip3( i_qp + h->pps->i_chroma_qp_index_offset, 0, 51 )] +
628 i_chroma_qp_table[x264_clip3( i_qpn + h->pps->i_chroma_qp_index_offset, 0, 51 )] + 1 ) >> 1;
629 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]],
630 h->fdec->i_stride[1], bS, i_qpc, 1,
631 h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
632 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]],
633 h->fdec->i_stride[2], bS, i_qpc, 1,
634 h->loopf.deblock_v_chroma, h->loopf.deblock_v_chroma_intra );
642 if( mb_x >= h->sps->i_mb_width )
651 void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
652 void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
653 void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
654 void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
658 void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
659 void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
660 #elif defined( HAVE_MMXEXT )
661 void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
662 void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
664 void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
666 x264_deblock_v8_luma_mmxext( pix, stride, alpha, beta, tc0 );
667 x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
671 void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
673 pf->deblock_v_luma = deblock_v_luma_c;
674 pf->deblock_h_luma = deblock_h_luma_c;
675 pf->deblock_v_chroma = deblock_v_chroma_c;
676 pf->deblock_h_chroma = deblock_h_chroma_c;
677 pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
678 pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
679 pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
680 pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
683 if( cpu&X264_CPU_MMXEXT )
685 pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
686 pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
687 pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
688 pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
691 if( cpu&X264_CPU_SSE2 )
693 pf->deblock_v_luma = x264_deblock_v_luma_sse2;
694 pf->deblock_h_luma = x264_deblock_h_luma_sse2;
697 pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
698 pf->deblock_h_luma = x264_deblock_h_luma_mmxext;