frame.c
上传用户:lctgjx
上传日期:2022-06-04
资源大小:8887k
文件大小:39k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * frame.c: h264 encoder library
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2008 x264 project
  5.  *
  6.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  7.  *          Loren Merritt <lorenm@u.washington.edu>
  8.  *          Jason Garrett-Glaser <darkshikari@gmail.com>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. #include "common.h"
  25. #define ALIGN(x,a) (((x)+((a)-1))&~((a)-1))
  26. x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
  27. {
  28.     x264_frame_t *frame;
  29.     int i, j;
  30.     int i_mb_count = h->mb.i_mb_count;
  31.     int i_stride, i_width, i_lines;
  32.     int i_padv = PADV << h->param.b_interlaced;
  33.     int luma_plane_size;
  34.     int chroma_plane_size;
  35.     int align = h->param.cpu&X264_CPU_CACHELINE_64 ? 64 : h->param.cpu&X264_CPU_CACHELINE_32 ? 32 : 16;
  36.     CHECKED_MALLOCZERO( frame, sizeof(x264_frame_t) );
  37.     /* allocate frame data (+64 for extra data for me) */
  38.     i_width  = ALIGN( h->param.i_width, 16 );
  39.     i_stride = ALIGN( i_width + 2*PADH, align );
  40.     i_lines  = ALIGN( h->param.i_height, 16<<h->param.b_interlaced );
  41.     frame->i_plane = 3;
  42.     for( i = 0; i < 3; i++ )
  43.     {
  44.         frame->i_stride[i] = ALIGN( i_stride >> !!i, align );
  45.         frame->i_width[i] = i_width >> !!i;
  46.         frame->i_lines[i] = i_lines >> !!i;
  47.     }
  48.     luma_plane_size = (frame->i_stride[0] * ( frame->i_lines[0] + 2*i_padv ));
  49.     chroma_plane_size = (frame->i_stride[1] * ( frame->i_lines[1] + 2*i_padv ));
  50.     for( i = 1; i < 3; i++ )
  51.     {
  52.         CHECKED_MALLOC( frame->buffer[i], chroma_plane_size );
  53.         frame->plane[i] = frame->buffer[i] + (frame->i_stride[i] * i_padv + PADH)/2;
  54.     }
  55.     for( i = 0; i < h->param.i_bframe + 2; i++ )
  56.         for( j = 0; j < h->param.i_bframe + 2; j++ )
  57.             CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );
  58.     frame->i_poc = -1;
  59.     frame->i_type = X264_TYPE_AUTO;
  60.     frame->i_qpplus1 = 0;
  61.     frame->i_pts = -1;
  62.     frame->i_frame = -1;
  63.     frame->i_frame_num = -1;
  64.     frame->i_lines_completed = -1;
  65.     frame->b_fdec = b_fdec;
  66.     /* all 4 luma planes allocated together, since the cacheline split code
  67.      * requires them to be in-phase wrt cacheline alignment. */
  68.     if( h->param.analyse.i_subpel_refine && b_fdec )
  69.     {
  70.         CHECKED_MALLOC( frame->buffer[0], 4*luma_plane_size);
  71.         for( i = 0; i < 4; i++ )
  72.             frame->filtered[i] = frame->buffer[0] + i*luma_plane_size + frame->i_stride[0] * i_padv + PADH;
  73.         frame->plane[0] = frame->filtered[0];
  74.     }
  75.     else
  76.     {
  77.         CHECKED_MALLOC( frame->buffer[0], luma_plane_size);
  78.         frame->plane[0] = frame->buffer[0] + frame->i_stride[0] * i_padv + PADH;
  79.     }
  80.     if( b_fdec ) /* fdec frame */
  81.     {
  82.         CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));
  83.         CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );
  84.         CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );
  85.         if( h->param.i_bframe )
  86.         {
  87.             CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );
  88.             CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );
  89.         }
  90.         else
  91.         {
  92.             frame->mv[1]  = NULL;
  93.             frame->ref[1] = NULL;
  94.         }
  95.         CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
  96.         CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );
  97.         if( h->param.analyse.i_me_method >= X264_ME_ESA )
  98.         {
  99.             CHECKED_MALLOC( frame->buffer[3],
  100.                             frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) << h->frames.b_have_sub8x8_esa );
  101.             frame->integral = (uint16_t*)frame->buffer[3] + frame->i_stride[0] * i_padv + PADH;
  102.         }
  103.     }
  104.     else /* fenc frame */
  105.     {
  106.         if( h->frames.b_have_lowres )
  107.         {
  108.             frame->i_width_lowres = frame->i_width[0]/2;
  109.             frame->i_stride_lowres = ALIGN( frame->i_width_lowres + 2*PADH, align );
  110.             frame->i_lines_lowres = frame->i_lines[0]/2;
  111.             luma_plane_size = frame->i_stride_lowres * ( frame->i_lines[0]/2 + 2*i_padv );
  112.             CHECKED_MALLOC( frame->buffer_lowres[0], 4 * luma_plane_size );
  113.             for( i = 0; i < 4; i++ )
  114.                 frame->lowres[i] = frame->buffer_lowres[0] + (frame->i_stride_lowres * i_padv + PADH) + i * luma_plane_size;
  115.             for( j = 0; j <= !!h->param.i_bframe; j++ )
  116.                 for( i = 0; i <= h->param.i_bframe; i++ )
  117.                 {
  118.                     CHECKED_MALLOCZERO( frame->lowres_mvs[j][i], 2*h->mb.i_mb_count*sizeof(int16_t) );
  119.                     CHECKED_MALLOC( frame->lowres_mv_costs[j][i], h->mb.i_mb_count*sizeof(int) );
  120.                 }
  121.             CHECKED_MALLOC( frame->i_propagate_cost, (i_mb_count+3) * sizeof(uint16_t) );
  122.             for( j = 0; j <= h->param.i_bframe+1; j++ )
  123.                 for( i = 0; i <= h->param.i_bframe+1; i++ )
  124.                 {
  125.                     CHECKED_MALLOC( frame->lowres_costs[j][i], (i_mb_count+3) * sizeof(uint16_t) );
  126.                     CHECKED_MALLOC( frame->lowres_inter_types[j][i], (i_mb_count+3)/4 * sizeof(uint8_t) );
  127.                 }
  128.             frame->i_intra_cost = frame->lowres_costs[0][0];
  129.             memset( frame->i_intra_cost, -1, (i_mb_count+3) * sizeof(uint16_t) );
  130.         }
  131.         if( h->param.rc.i_aq_mode )
  132.         {
  133.             CHECKED_MALLOC( frame->f_qp_offset, h->mb.i_mb_count * sizeof(float) );
  134.             CHECKED_MALLOC( frame->f_qp_offset_aq, h->mb.i_mb_count * sizeof(float) );
  135.             if( h->frames.b_have_lowres )
  136.                 /* shouldn't really be initialized, just silences a valgrind false-positive in x264_mbtree_propagate_cost_sse2 */
  137.                 CHECKED_MALLOCZERO( frame->i_inv_qscale_factor, (h->mb.i_mb_count+3) * sizeof(uint16_t) );
  138.         }
  139.     }
  140.     if( x264_pthread_mutex_init( &frame->mutex, NULL ) )
  141.         goto fail;
  142.     if( x264_pthread_cond_init( &frame->cv, NULL ) )
  143.         goto fail;
  144.     return frame;
  145. fail:
  146.     x264_free( frame );
  147.     return NULL;
  148. }
  149. void x264_frame_delete( x264_frame_t *frame )
  150. {
  151.     int i, j;
  152.     for( i = 0; i < 4; i++ )
  153.         x264_free( frame->buffer[i] );
  154.     for( i = 0; i < 4; i++ )
  155.         x264_free( frame->buffer_lowres[i] );
  156.     for( i = 0; i < X264_BFRAME_MAX+2; i++ )
  157.         for( j = 0; j < X264_BFRAME_MAX+2; j++ )
  158.             x264_free( frame->i_row_satds[i][j] );
  159.     for( j = 0; j < 2; j++ )
  160.         for( i = 0; i <= X264_BFRAME_MAX; i++ )
  161.         {
  162.             x264_free( frame->lowres_mvs[j][i] );
  163.             x264_free( frame->lowres_mv_costs[j][i] );
  164.         }
  165.     x264_free( frame->i_propagate_cost );
  166.     for( j = 0; j <= X264_BFRAME_MAX+1; j++ )
  167.         for( i = 0; i <= X264_BFRAME_MAX+1; i++ )
  168.         {
  169.             x264_free( frame->lowres_costs[j][i] );
  170.             x264_free( frame->lowres_inter_types[j][i] );
  171.         }
  172.     x264_free( frame->f_qp_offset );
  173.     x264_free( frame->f_qp_offset_aq );
  174.     x264_free( frame->i_inv_qscale_factor );
  175.     x264_free( frame->i_row_bits );
  176.     x264_free( frame->i_row_qp );
  177.     x264_free( frame->mb_type );
  178.     x264_free( frame->mv[0] );
  179.     x264_free( frame->mv[1] );
  180.     x264_free( frame->ref[0] );
  181.     x264_free( frame->ref[1] );
  182.     x264_pthread_mutex_destroy( &frame->mutex );
  183.     x264_pthread_cond_destroy( &frame->cv );
  184.     x264_free( frame );
  185. }
  186. int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
  187. {
  188.     int i_csp = src->img.i_csp & X264_CSP_MASK;
  189.     int i;
  190.     if( i_csp != X264_CSP_I420 && i_csp != X264_CSP_YV12 )
  191.     {
  192.         x264_log( h, X264_LOG_ERROR, "Arg invalid CSPn" );
  193.         return -1;
  194.     }
  195.     dst->i_type     = src->i_type;
  196.     dst->i_qpplus1  = src->i_qpplus1;
  197.     dst->i_pts      = src->i_pts;
  198.     dst->param      = src->param;
  199.     for( i=0; i<3; i++ )
  200.     {
  201.         int s = (i_csp == X264_CSP_YV12 && i) ? i^3 : i;
  202.         uint8_t *plane = src->img.plane[s];
  203.         int stride = src->img.i_stride[s];
  204.         int width = h->param.i_width >> !!i;
  205.         int height = h->param.i_height >> !!i;
  206.         if( src->img.i_csp & X264_CSP_VFLIP )
  207.         {
  208.             plane += (height-1)*stride;
  209.             stride = -stride;
  210.         }
  211.         h->mc.plane_copy( dst->plane[i], dst->i_stride[i], plane, stride, width, height );
  212.     }
  213.     return 0;
  214. }
  215. static void plane_expand_border( uint8_t *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv, int b_pad_top, int b_pad_bottom )
  216. {
  217. #define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )
  218.     int y;
  219.     for( y = 0; y < i_height; y++ )
  220.     {
  221.         /* left band */
  222.         memset( PPIXEL(-i_padh, y), PPIXEL(0, y)[0], i_padh );
  223.         /* right band */
  224.         memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_padh );
  225.     }
  226.     /* upper band */
  227.     if( b_pad_top )
  228.     for( y = 0; y < i_padv; y++ )
  229.         memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), i_width+2*i_padh );
  230.     /* lower band */
  231.     if( b_pad_bottom )
  232.     for( y = 0; y < i_padv; y++ )
  233.         memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), i_width+2*i_padh );
  234. #undef PPIXEL
  235. }
  236. void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
  237. {
  238.     int i;
  239.     int b_start = !mb_y;
  240.     if( mb_y & h->sh.b_mbaff )
  241.         return;
  242.     for( i = 0; i < frame->i_plane; i++ )
  243.     {
  244.         int stride = frame->i_stride[i];
  245.         int width = 16*h->sps->i_mb_width >> !!i;
  246.         int height = (b_end ? 16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff : 16) >> !!i;
  247.         int padh = PADH >> !!i;
  248.         int padv = PADV >> !!i;
  249.         // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb
  250.         uint8_t *pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> !!i);
  251.         if( b_end && !b_start )
  252.             height += 4 >> (!!i + h->sh.b_mbaff);
  253.         if( h->sh.b_mbaff )
  254.         {
  255.             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
  256.             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );
  257.         }
  258.         else
  259.         {
  260.             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );
  261.         }
  262.     }
  263. }
  264. void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end )
  265. {
  266.     /* during filtering, 8 extra pixels were filtered on each edge,
  267.      * but up to 3 of the horizontal ones may be wrong.
  268.        we want to expand border from the last filtered pixel */
  269.     int b_start = !mb_y;
  270.     int stride = frame->i_stride[0];
  271.     int width = 16*h->sps->i_mb_width + 8;
  272.     int height = b_end ? (16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff) + 16 : 16;
  273.     int padh = PADH - 4;
  274.     int padv = PADV - 8;
  275.     int i;
  276.     for( i = 1; i < 4; i++ )
  277.     {
  278.         // buffer: 8 luma, to match the hpel filter
  279.         uint8_t *pix = frame->filtered[i] + (16*mb_y - (8 << h->sh.b_mbaff)) * stride - 4;
  280.         if( h->sh.b_mbaff )
  281.         {
  282.             plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );
  283.             plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );
  284.         }
  285.         else
  286.         {
  287.             plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );
  288.         }
  289.     }
  290. }
  291. void x264_frame_expand_border_lowres( x264_frame_t *frame )
  292. {
  293.     int i;
  294.     for( i = 0; i < 4; i++ )
  295.         plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_width_lowres, frame->i_lines_lowres, PADH, PADV, 1, 1 );
  296. }
  297. void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
  298. {
  299.     int i, y;
  300.     for( i = 0; i < frame->i_plane; i++ )
  301.     {
  302.         int i_subsample = i ? 1 : 0;
  303.         int i_width = h->param.i_width >> i_subsample;
  304.         int i_height = h->param.i_height >> i_subsample;
  305.         int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;
  306.         int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;
  307.         if( i_padx )
  308.         {
  309.             for( y = 0; y < i_height; y++ )
  310.                 memset( &frame->plane[i][y*frame->i_stride[i] + i_width],
  311.                          frame->plane[i][y*frame->i_stride[i] + i_width - 1],
  312.                          i_padx );
  313.         }
  314.         if( i_pady )
  315.         {
  316.             //FIXME interlace? or just let it pad using the wrong field
  317.             for( y = i_height; y < i_height + i_pady; y++ )
  318.                 memcpy( &frame->plane[i][y*frame->i_stride[i]],
  319.                         &frame->plane[i][(i_height-1)*frame->i_stride[i]],
  320.                         i_width + i_padx );
  321.         }
  322.     }
  323. }
  324. /* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of
  325.  * entropy coding, but per 64 coeffs for the purpose of deblocking */
  326. static void munge_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] )
  327. {
  328.     uint32_t (*src)[6] = (uint32_t(*)[6])h->mb.non_zero_count + mb_y * h->sps->i_mb_width;
  329.     int8_t *transform = h->mb.mb_transform_size + mb_y * h->sps->i_mb_width;
  330.     int x, nnz;
  331.     for( x=0; x<h->sps->i_mb_width; x++ )
  332.     {
  333.         memcpy( buf+x, src+x, 16 );
  334.         if( transform[x] )
  335.         {
  336.             nnz = src[x][0] | src[x][1];
  337.             src[x][0] = src[x][1] = ((uint16_t)nnz ? 0x0101 : 0) + (nnz>>16 ? 0x01010000 : 0);
  338.             nnz = src[x][2] | src[x][3];
  339.             src[x][2] = src[x][3] = ((uint16_t)nnz ? 0x0101 : 0) + (nnz>>16 ? 0x01010000 : 0);
  340.         }
  341.     }
  342. }
  343. static void restore_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] )
  344. {
  345.     uint8_t (*dst)[24] = h->mb.non_zero_count + mb_y * h->sps->i_mb_width;
  346.     int x;
  347.     for( x=0; x<h->sps->i_mb_width; x++ )
  348.         memcpy( dst+x, buf+x, 16 );
  349. }
  350. static void munge_cavlc_nnz( x264_t *h, int mb_y, uint8_t (*buf)[16], void (*func)(x264_t*, int, uint8_t (*)[16]) )
  351. {
  352.     func( h, mb_y, buf );
  353.     if( mb_y > 0 )
  354.         func( h, mb_y-1, buf + h->sps->i_mb_width );
  355.     if( h->sh.b_mbaff )
  356.     {
  357.         func( h, mb_y+1, buf + h->sps->i_mb_width * 2 );
  358.         if( mb_y > 0 )
  359.             func( h, mb_y-2, buf + h->sps->i_mb_width * 3 );
  360.     }
  361. }
  362. /* Deblocking filter */
  363. static const uint8_t i_alpha_table[52+12*2] =
  364. {
  365.      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  366.      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  367.      0,  0,  0,  0,  0,  0,  4,  4,  5,  6,
  368.      7,  8,  9, 10, 12, 13, 15, 17, 20, 22,
  369.     25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
  370.     80, 90,101,113,127,144,162,182,203,226,
  371.    255,255,
  372.    255,255,255,255,255,255,255,255,255,255,255,255,
  373. };
  374. static const uint8_t i_beta_table[52+12*2] =
  375. {
  376.      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  377.      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  378.      0,  0,  0,  0,  0,  0,  2,  2,  2,  3,
  379.      3,  3,  3,  4,  4,  4,  6,  6,  7,  7,
  380.      8,  8,  9,  9, 10, 10, 11, 11, 12, 12,
  381.     13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
  382.     18, 18,
  383.     18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
  384. };
  385. static const int8_t i_tc0_table[52+12*2][4] =
  386. {
  387.     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
  388.     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
  389.     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
  390.     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 },
  391.     {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 1 },
  392.     {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 1, 1 }, {-1, 0, 1, 1 }, {-1, 1, 1, 1 },
  393.     {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 },
  394.     {-1, 1, 1, 2 }, {-1, 1, 2, 3 }, {-1, 1, 2, 3 }, {-1, 2, 2, 3 }, {-1, 2, 2, 4 }, {-1, 2, 3, 4 },
  395.     {-1, 2, 3, 4 }, {-1, 3, 3, 5 }, {-1, 3, 4, 6 }, {-1, 3, 4, 6 }, {-1, 4, 5, 7 }, {-1, 4, 5, 8 },
  396.     {-1, 4, 6, 9 }, {-1, 5, 7,10 }, {-1, 6, 8,11 }, {-1, 6, 8,13 }, {-1, 7,10,14 }, {-1, 8,11,16 },
  397.     {-1, 9,12,18 }, {-1,10,13,20 }, {-1,11,15,23 }, {-1,13,17,25 },
  398.     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
  399.     {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 },
  400. };
  401. #define alpha_table(x) i_alpha_table[(x)+12]
  402. #define beta_table(x)  i_beta_table[(x)+12]
  403. #define tc0_table(x)   i_tc0_table[(x)+12]
  404. /* From ffmpeg */
  405. static inline void deblock_luma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
  406. {
  407.     int i, d;
  408.     for( i = 0; i < 4; i++ )
  409.     {
  410.         if( tc0[i] < 0 )
  411.         {
  412.             pix += 4*ystride;
  413.             continue;
  414.         }
  415.         for( d = 0; d < 4; d++ )
  416.         {
  417.             const int p2 = pix[-3*xstride];
  418.             const int p1 = pix[-2*xstride];
  419.             const int p0 = pix[-1*xstride];
  420.             const int q0 = pix[ 0*xstride];
  421.             const int q1 = pix[ 1*xstride];
  422.             const int q2 = pix[ 2*xstride];
  423.             if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
  424.             {
  425.                 int tc = tc0[i];
  426.                 int delta;
  427.                 if( abs( p2 - p0 ) < beta )
  428.                 {
  429.                     pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1) >> 1)) >> 1) - p1, -tc0[i], tc0[i] );
  430.                     tc++;
  431.                 }
  432.                 if( abs( q2 - q0 ) < beta )
  433.                 {
  434.                     pix[ 1*xstride] = q1 + x264_clip3( (( q2 + ((p0 + q0 + 1) >> 1)) >> 1) - q1, -tc0[i], tc0[i] );
  435.                     tc++;
  436.                 }
  437.                 delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
  438.                 pix[-1*xstride] = x264_clip_uint8( p0 + delta );    /* p0' */
  439.                 pix[ 0*xstride] = x264_clip_uint8( q0 - delta );    /* q0' */
  440.             }
  441.             pix += ystride;
  442.         }
  443.     }
  444. }
  445. static void deblock_v_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  446. {
  447.     deblock_luma_c( pix, stride, 1, alpha, beta, tc0 );
  448. }
  449. static void deblock_h_luma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  450. {
  451.     deblock_luma_c( pix, 1, stride, alpha, beta, tc0 );
  452. }
  453. static inline void deblock_chroma_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0 )
  454. {
  455.     int i, d;
  456.     for( i = 0; i < 4; i++ )
  457.     {
  458.         const int tc = tc0[i];
  459.         if( tc <= 0 )
  460.         {
  461.             pix += 2*ystride;
  462.             continue;
  463.         }
  464.         for( d = 0; d < 2; d++ )
  465.         {
  466.             const int p1 = pix[-2*xstride];
  467.             const int p0 = pix[-1*xstride];
  468.             const int q0 = pix[ 0*xstride];
  469.             const int q1 = pix[ 1*xstride];
  470.             if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
  471.             {
  472.                 int delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
  473.                 pix[-1*xstride] = x264_clip_uint8( p0 + delta );    /* p0' */
  474.                 pix[ 0*xstride] = x264_clip_uint8( q0 - delta );    /* q0' */
  475.             }
  476.             pix += ystride;
  477.         }
  478.     }
  479. }
  480. static void deblock_v_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  481. {
  482.     deblock_chroma_c( pix, stride, 1, alpha, beta, tc0 );
  483. }
  484. static void deblock_h_chroma_c( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  485. {
  486.     deblock_chroma_c( pix, 1, stride, alpha, beta, tc0 );
  487. }
  488. static inline void deblock_luma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
  489. {
  490.     int d;
  491.     for( d = 0; d < 16; d++ )
  492.     {
  493.         const int p2 = pix[-3*xstride];
  494.         const int p1 = pix[-2*xstride];
  495.         const int p0 = pix[-1*xstride];
  496.         const int q0 = pix[ 0*xstride];
  497.         const int q1 = pix[ 1*xstride];
  498.         const int q2 = pix[ 2*xstride];
  499.         if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
  500.         {
  501.             if(abs( p0 - q0 ) < ((alpha >> 2) + 2) )
  502.             {
  503.                 if( abs( p2 - p0 ) < beta ) /* p0', p1', p2' */
  504.                 {
  505.                     const int p3 = pix[-4*xstride];
  506.                     pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
  507.                     pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
  508.                     pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
  509.                 }
  510.                 else /* p0' */
  511.                     pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
  512.                 if( abs( q2 - q0 ) < beta ) /* q0', q1', q2' */
  513.                 {
  514.                     const int q3 = pix[3*xstride];
  515.                     pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
  516.                     pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
  517.                     pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
  518.                 }
  519.                 else /* q0' */
  520.                     pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
  521.             }
  522.             else /* p0', q0' */
  523.             {
  524.                 pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
  525.                 pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
  526.             }
  527.         }
  528.         pix += ystride;
  529.     }
  530. }
  531. static void deblock_v_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
  532. {
  533.     deblock_luma_intra_c( pix, stride, 1, alpha, beta );
  534. }
  535. static void deblock_h_luma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
  536. {
  537.     deblock_luma_intra_c( pix, 1, stride, alpha, beta );
  538. }
  539. static inline void deblock_chroma_intra_c( uint8_t *pix, int xstride, int ystride, int alpha, int beta )
  540. {
  541.     int d;
  542.     for( d = 0; d < 8; d++ )
  543.     {
  544.         const int p1 = pix[-2*xstride];
  545.         const int p0 = pix[-1*xstride];
  546.         const int q0 = pix[ 0*xstride];
  547.         const int q1 = pix[ 1*xstride];
  548.         if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta )
  549.         {
  550.             pix[-1*xstride] = (2*p1 + p0 + q1 + 2) >> 2;   /* p0' */
  551.             pix[ 0*xstride] = (2*q1 + q0 + p1 + 2) >> 2;   /* q0' */
  552.         }
  553.         pix += ystride;
  554.     }
  555. }
  556. static void deblock_v_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
  557. {
  558.     deblock_chroma_intra_c( pix, stride, 1, alpha, beta );
  559. }
  560. static void deblock_h_chroma_intra_c( uint8_t *pix, int stride, int alpha, int beta )
  561. {
  562.     deblock_chroma_intra_c( pix, 1, stride, alpha, beta );
  563. }
  564. static inline void deblock_edge( x264_t *h, uint8_t *pix1, uint8_t *pix2, int i_stride, uint8_t bS[4], int i_qp, int b_chroma, x264_deblock_inter_t pf_inter )
  565. {
  566.     const int index_a = i_qp + h->sh.i_alpha_c0_offset;
  567.     const int alpha = alpha_table(index_a);
  568.     const int beta  = beta_table(i_qp + h->sh.i_beta_offset);
  569.     int8_t tc[4];
  570.     if( !alpha || !beta )
  571.         return;
  572.     tc[0] = tc0_table(index_a)[bS[0]] + b_chroma;
  573.     tc[1] = tc0_table(index_a)[bS[1]] + b_chroma;
  574.     tc[2] = tc0_table(index_a)[bS[2]] + b_chroma;
  575.     tc[3] = tc0_table(index_a)[bS[3]] + b_chroma;
  576.     pf_inter( pix1, i_stride, alpha, beta, tc );
  577.     if( b_chroma )
  578.         pf_inter( pix2, i_stride, alpha, beta, tc );
  579. }
  580. static inline void deblock_edge_intra( x264_t *h, uint8_t *pix1, uint8_t *pix2, int i_stride, uint8_t bS[4], int i_qp, int b_chroma, x264_deblock_intra_t pf_intra )
  581. {
  582.     const int alpha = alpha_table(i_qp + h->sh.i_alpha_c0_offset);
  583.     const int beta  = beta_table(i_qp + h->sh.i_beta_offset);
  584.     if( !alpha || !beta )
  585.         return;
  586.     pf_intra( pix1, i_stride, alpha, beta );
  587.     if( b_chroma )
  588.         pf_intra( pix2, i_stride, alpha, beta );
  589. }
  590. void x264_frame_deblock_row( x264_t *h, int mb_y )
  591. {
  592.     const int s8x8 = 2 * h->mb.i_mb_stride;
  593.     const int s4x4 = 4 * h->mb.i_mb_stride;
  594.     const int b_interlaced = h->sh.b_mbaff;
  595.     const int mvy_limit = 4 >> b_interlaced;
  596.     const int qp_thresh = 15 - X264_MIN(h->sh.i_alpha_c0_offset, h->sh.i_beta_offset) - X264_MAX(0, h->param.analyse.i_chroma_qp_offset);
  597.     const int no_sub8x8 = !(h->param.analyse.inter & X264_ANALYSE_PSUB8x8);
  598.     int mb_x;
  599.     int stridey   = h->fdec->i_stride[0];
  600.     int stride2y  = stridey << b_interlaced;
  601.     int strideuv  = h->fdec->i_stride[1];
  602.     int stride2uv = strideuv << b_interlaced;
  603.     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
  604.         munge_cavlc_nnz( h, mb_y, h->mb.nnz_backup, munge_cavlc_nnz_row );
  605.     for( mb_x = 0; mb_x < h->sps->i_mb_width; mb_x += (~b_interlaced | mb_y)&1, mb_y ^= b_interlaced )
  606.     {
  607.         const int mb_xy  = mb_y * h->mb.i_mb_stride + mb_x;
  608.         const int mb_8x8 = 2 * s8x8 * mb_y + 2 * mb_x;
  609.         const int mb_4x4 = 4 * s4x4 * mb_y + 4 * mb_x;
  610.         const int b_8x8_transform = h->mb.mb_transform_size[mb_xy];
  611.         const int i_qp = h->mb.qp[mb_xy];
  612.         int i_edge_end = (h->mb.type[mb_xy] == P_SKIP) ? 1 : 4;
  613.         uint8_t *pixy = h->fdec->plane[0] + 16*mb_y*stridey  + 16*mb_x;
  614.         uint8_t *pixu = h->fdec->plane[1] +  8*mb_y*strideuv +  8*mb_x;
  615.         uint8_t *pixv = h->fdec->plane[2] +  8*mb_y*strideuv +  8*mb_x;
  616.         if( b_interlaced && (mb_y&1) )
  617.         {
  618.             pixy -= 15*stridey;
  619.             pixu -=  7*strideuv;
  620.             pixv -=  7*strideuv;
  621.         }
  622.         x264_prefetch_fenc( h, h->fdec, mb_x, mb_y );
  623.         if( i_qp <= qp_thresh )
  624.             i_edge_end = 1;
  625.         #define FILTER_DIR(intra, i_dir)
  626.         {
  627.             /* Y plane */
  628.             i_qpn= h->mb.qp[mbn_xy];
  629.             if( i_dir == 0 )
  630.             {
  631.                 /* vertical edge */
  632.                 deblock_edge##intra( h, pixy + 4*i_edge, NULL,
  633.                               stride2y, bS, (i_qp+i_qpn+1) >> 1, 0,
  634.                               h->loopf.deblock_h_luma##intra );
  635.                 if( !(i_edge & 1) )
  636.                 {
  637.                     /* U/V planes */
  638.                     int i_qpc = (h->chroma_qp_table[i_qp] + h->chroma_qp_table[i_qpn] + 1) >> 1;
  639.                     deblock_edge##intra( h, pixu + 2*i_edge, pixv + 2*i_edge,
  640.                                   stride2uv, bS, i_qpc, 1,
  641.                                   h->loopf.deblock_h_chroma##intra );
  642.                 }
  643.             }
  644.             else
  645.             {
  646.                 /* horizontal edge */
  647.                 deblock_edge##intra( h, pixy + 4*i_edge*stride2y, NULL,
  648.                               stride2y, bS, (i_qp+i_qpn+1) >> 1, 0,
  649.                               h->loopf.deblock_v_luma##intra );
  650.                 /* U/V planes */
  651.                 if( !(i_edge & 1) )
  652.                 {
  653.                     int i_qpc = (h->chroma_qp_table[i_qp] + h->chroma_qp_table[i_qpn] + 1) >> 1;
  654.                     deblock_edge##intra( h, pixu + 2*i_edge*stride2uv, pixv + 2*i_edge*stride2uv,
  655.                                   stride2uv, bS, i_qpc, 1,
  656.                                   h->loopf.deblock_v_chroma##intra );
  657.                 }
  658.             }
  659.         }
  660.         #define DEBLOCK_STRENGTH(i_dir)
  661.         {
  662.             /* *** Get bS for each 4px for the current edge *** */
  663.             if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )
  664.                 *(uint32_t*)bS = 0x03030303;
  665.             else
  666.             {
  667.                 *(uint32_t*)bS = 0x00000000;
  668.                 for( i = 0; i < 4; i++ )
  669.                 {
  670.                     int x  = i_dir == 0 ? i_edge : i;
  671.                     int y  = i_dir == 0 ? i      : i_edge;
  672.                     int xn = i_dir == 0 ? (x - 1)&0x03 : x;
  673.                     int yn = i_dir == 0 ? y : (y - 1)&0x03;
  674.                     if( h->mb.non_zero_count[mb_xy][x+y*4] != 0 ||
  675.                         h->mb.non_zero_count[mbn_xy][xn+yn*4] != 0 )
  676.                         bS[i] = 2;
  677.                     else if(!(i_edge&no_sub8x8))
  678.                     {
  679.                         if((i&no_sub8x8) && bS[i-1] != 2)
  680.                             bS[i] = bS[i-1];
  681.                         else
  682.                         {
  683.                             /* FIXME: A given frame may occupy more than one position in
  684.                              * the reference list. So we should compare the frame numbers,
  685.                              * not the indices in the ref list.
  686.                              * No harm yet, as we don't generate that case.*/
  687.                             int i8p= mb_8x8+(x>>1)+(y>>1)*s8x8;
  688.                             int i8q= mbn_8x8+(xn>>1)+(yn>>1)*s8x8;
  689.                             int i4p= mb_4x4+x+y*s4x4;
  690.                             int i4q= mbn_4x4+xn+yn*s4x4;
  691.                             if((h->mb.ref[0][i8p] != h->mb.ref[0][i8q] ||
  692.                                 abs( h->mb.mv[0][i4p][0] - h->mb.mv[0][i4q][0] ) >= 4 ||
  693.                                 abs( h->mb.mv[0][i4p][1] - h->mb.mv[0][i4q][1] ) >= mvy_limit ) ||
  694.                                (h->sh.i_type == SLICE_TYPE_B &&
  695.                                (h->mb.ref[1][i8p] != h->mb.ref[1][i8q] ||
  696.                                 abs( h->mb.mv[1][i4p][0] - h->mb.mv[1][i4q][0] ) >= 4 ||
  697.                                 abs( h->mb.mv[1][i4p][1] - h->mb.mv[1][i4q][1] ) >= mvy_limit )))
  698.                             {
  699.                                 bS[i] = 1;
  700.                             }
  701.                         }
  702.                     }
  703.                 }
  704.             }
  705.         }
  706.         /* i_dir == 0 -> vertical edge
  707.          * i_dir == 1 -> horizontal edge */
  708.         #define DEBLOCK_DIR(i_dir)
  709.         {
  710.             int i_edge = (i_dir ? (mb_y <= b_interlaced) : (mb_x == 0));
  711.             int i_qpn, i, mbn_xy, mbn_8x8, mbn_4x4;
  712.             ALIGNED_4( uint8_t bS[4] );  /* filtering strength */
  713.             if( i_edge )
  714.                 i_edge+= b_8x8_transform;
  715.             else
  716.             {
  717.                 mbn_xy  = i_dir == 0 ? mb_xy  - 1 : mb_xy - h->mb.i_mb_stride;
  718.                 mbn_8x8 = i_dir == 0 ? mb_8x8 - 2 : mb_8x8 - 2 * s8x8;
  719.                 mbn_4x4 = i_dir == 0 ? mb_4x4 - 4 : mb_4x4 - 4 * s4x4;
  720.                 if( b_interlaced && i_dir == 1 )
  721.                 {
  722.                     mbn_xy -= h->mb.i_mb_stride;
  723.                     mbn_8x8 -= 2 * s8x8;
  724.                     mbn_4x4 -= 4 * s4x4;
  725.                 }
  726.                 else if( IS_INTRA( h->mb.type[mb_xy] ) || IS_INTRA( h->mb.type[mbn_xy]) )
  727.                 {
  728.                     FILTER_DIR( _intra, i_dir );
  729.                     goto end##i_dir;
  730.                 }
  731.                 DEBLOCK_STRENGTH(i_dir);
  732.                 if( *(uint32_t*)bS )
  733.                     FILTER_DIR( , i_dir);
  734.                 end##i_dir:
  735.                 i_edge += b_8x8_transform+1;
  736.             }
  737.             mbn_xy  = mb_xy;
  738.             mbn_8x8 = mb_8x8;
  739.             mbn_4x4 = mb_4x4;
  740.             for( ; i_edge < i_edge_end; i_edge+=b_8x8_transform+1 )
  741.             {
  742.                 DEBLOCK_STRENGTH(i_dir);
  743.                 if( *(uint32_t*)bS )
  744.                     FILTER_DIR( , i_dir);
  745.             }
  746.         }
  747.         DEBLOCK_DIR(0);
  748.         DEBLOCK_DIR(1);
  749.     }
  750.     if( !h->pps->b_cabac && h->pps->b_transform_8x8_mode )
  751.         munge_cavlc_nnz( h, mb_y, h->mb.nnz_backup, restore_cavlc_nnz_row );
  752. }
  753. void x264_frame_deblock( x264_t *h )
  754. {
  755.     int mb_y;
  756.     for( mb_y = 0; mb_y < h->sps->i_mb_height; mb_y += 1 + h->sh.b_mbaff )
  757.         x264_frame_deblock_row( h, mb_y );
  758. }
  759. #ifdef HAVE_MMX
  760. void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
  761. void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
  762. void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
  763. void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
  764. void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
  765. void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
  766. void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
  767. void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta );
  768. #ifdef ARCH_X86
  769. void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
  770. void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
  771. void x264_deblock_h_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
  772. void x264_deblock_v8_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta );
  773. static void x264_deblock_v_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  774. {
  775.     x264_deblock_v8_luma_mmxext( pix,   stride, alpha, beta, tc0   );
  776.     x264_deblock_v8_luma_mmxext( pix+8, stride, alpha, beta, tc0+2 );
  777. }
  778. static void x264_deblock_v_luma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
  779. {
  780.     x264_deblock_v8_luma_intra_mmxext( pix,   stride, alpha, beta );
  781.     x264_deblock_v8_luma_intra_mmxext( pix+8, stride, alpha, beta );
  782. }
  783. #endif
  784. #endif
  785. #ifdef ARCH_PPC
  786. void x264_deblock_v_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
  787. void x264_deblock_h_luma_altivec( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
  788. #endif // ARCH_PPC
  789. #ifdef HAVE_ARMV6
  790. void x264_deblock_v_luma_neon( uint8_t *, int, int, int, int8_t * );
  791. void x264_deblock_h_luma_neon( uint8_t *, int, int, int, int8_t * );
  792. void x264_deblock_v_chroma_neon( uint8_t *, int, int, int, int8_t * );
  793. void x264_deblock_h_chroma_neon( uint8_t *, int, int, int, int8_t * );
  794. #endif
  795. void x264_deblock_init( int cpu, x264_deblock_function_t *pf )
  796. {
  797.     pf->deblock_v_luma = deblock_v_luma_c;
  798.     pf->deblock_h_luma = deblock_h_luma_c;
  799.     pf->deblock_v_chroma = deblock_v_chroma_c;
  800.     pf->deblock_h_chroma = deblock_h_chroma_c;
  801.     pf->deblock_v_luma_intra = deblock_v_luma_intra_c;
  802.     pf->deblock_h_luma_intra = deblock_h_luma_intra_c;
  803.     pf->deblock_v_chroma_intra = deblock_v_chroma_intra_c;
  804.     pf->deblock_h_chroma_intra = deblock_h_chroma_intra_c;
  805. #ifdef HAVE_MMX
  806.     if( cpu&X264_CPU_MMXEXT )
  807.     {
  808.         pf->deblock_v_chroma = x264_deblock_v_chroma_mmxext;
  809.         pf->deblock_h_chroma = x264_deblock_h_chroma_mmxext;
  810.         pf->deblock_v_chroma_intra = x264_deblock_v_chroma_intra_mmxext;
  811.         pf->deblock_h_chroma_intra = x264_deblock_h_chroma_intra_mmxext;
  812. #ifdef ARCH_X86
  813.         pf->deblock_v_luma = x264_deblock_v_luma_mmxext;
  814.         pf->deblock_h_luma = x264_deblock_h_luma_mmxext;
  815.         pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_mmxext;
  816.         pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_mmxext;
  817. #endif
  818.         if( (cpu&X264_CPU_SSE2) && !(cpu&X264_CPU_STACK_MOD4) )
  819.         {
  820.             pf->deblock_v_luma = x264_deblock_v_luma_sse2;
  821.             pf->deblock_h_luma = x264_deblock_h_luma_sse2;
  822.             pf->deblock_v_luma_intra = x264_deblock_v_luma_intra_sse2;
  823.             pf->deblock_h_luma_intra = x264_deblock_h_luma_intra_sse2;
  824.         }
  825.     }
  826. #endif
  827. #ifdef ARCH_PPC
  828.     if( cpu&X264_CPU_ALTIVEC )
  829.     {
  830.         pf->deblock_v_luma = x264_deblock_v_luma_altivec;
  831.         pf->deblock_h_luma = x264_deblock_h_luma_altivec;
  832.    }
  833. #endif // ARCH_PPC
  834. #ifdef HAVE_ARMV6
  835.    if( cpu&X264_CPU_NEON )
  836.    {
  837.         pf->deblock_v_luma   = x264_deblock_v_luma_neon;
  838.         pf->deblock_h_luma   = x264_deblock_h_luma_neon;
  839.         pf->deblock_v_chroma = x264_deblock_v_chroma_neon;
  840.         pf->deblock_h_chroma = x264_deblock_h_chroma_neon;
  841.    }
  842. #endif
  843. }
  844. /* threading */
  845. void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed )
  846. {
  847.     x264_pthread_mutex_lock( &frame->mutex );
  848.     frame->i_lines_completed = i_lines_completed;
  849.     x264_pthread_cond_broadcast( &frame->cv );
  850.     x264_pthread_mutex_unlock( &frame->mutex );
  851. }
  852. void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed )
  853. {
  854.     x264_pthread_mutex_lock( &frame->mutex );
  855.     while( frame->i_lines_completed < i_lines_completed )
  856.         x264_pthread_cond_wait( &frame->cv, &frame->mutex );
  857.     x264_pthread_mutex_unlock( &frame->mutex );
  858. }
  859. /* list operators */
  860. void x264_frame_push( x264_frame_t **list, x264_frame_t *frame )
  861. {
  862.     int i = 0;
  863.     while( list[i] ) i++;
  864.     list[i] = frame;
  865. }
  866. x264_frame_t *x264_frame_pop( x264_frame_t **list )
  867. {
  868.     x264_frame_t *frame;
  869.     int i = 0;
  870.     assert( list[0] );
  871.     while( list[i+1] ) i++;
  872.     frame = list[i];
  873.     list[i] = NULL;
  874.     return frame;
  875. }
  876. void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame )
  877. {
  878.     int i = 0;
  879.     while( list[i] ) i++;
  880.     while( i-- )
  881.         list[i+1] = list[i];
  882.     list[0] = frame;
  883. }
  884. x264_frame_t *x264_frame_shift( x264_frame_t **list )
  885. {
  886.     x264_frame_t *frame = list[0];
  887.     int i;
  888.     for( i = 0; list[i]; i++ )
  889.         list[i] = list[i+1];
  890.     assert(frame);
  891.     return frame;
  892. }
  893. void x264_frame_push_unused( x264_t *h, x264_frame_t *frame )
  894. {
  895.     assert( frame->i_reference_count > 0 );
  896.     frame->i_reference_count--;
  897.     if( frame->i_reference_count == 0 )
  898.         x264_frame_push( h->frames.unused[frame->b_fdec], frame );
  899. }
  900. x264_frame_t *x264_frame_pop_unused( x264_t *h, int b_fdec )
  901. {
  902.     x264_frame_t *frame;
  903.     if( h->frames.unused[b_fdec][0] )
  904.         frame = x264_frame_pop( h->frames.unused[b_fdec] );
  905.     else
  906.         frame = x264_frame_new( h, b_fdec );
  907.     if( !frame )
  908.         return NULL;
  909.     frame->b_last_minigop_bframe = 0;
  910.     frame->i_reference_count = 1;
  911.     frame->b_intra_calculated = 0;
  912.     return frame;
  913. }
  914. void x264_frame_sort( x264_frame_t **list, int b_dts )
  915. {
  916.     int i, b_ok;
  917.     do {
  918.         b_ok = 1;
  919.         for( i = 0; list[i+1]; i++ )
  920.         {
  921.             int dtype = list[i]->i_type - list[i+1]->i_type;
  922.             int dtime = list[i]->i_frame - list[i+1]->i_frame;
  923.             int swap = b_dts ? dtype > 0 || ( dtype == 0 && dtime > 0 )
  924.                              : dtime > 0;
  925.             if( swap )
  926.             {
  927.                 XCHG( x264_frame_t*, list[i], list[i+1] );
  928.                 b_ok = 0;
  929.             }
  930.         }
  931.     } while( !b_ok );
  932. }
  933. void x264_frame_delete_list( x264_frame_t **list )
  934. {
  935.     int i = 0;
  936.     while( list[i] )
  937.         x264_frame_delete( list[i++] );
  938.     x264_free( list );
  939. }
  940. int x264_synch_frame_list_init( x264_synch_frame_list_t *slist, int max_size )
  941. {
  942.     if( max_size < 0 )
  943.         return -1;
  944.     slist->i_max_size = max_size;
  945.     slist->i_size = 0;
  946.     CHECKED_MALLOCZERO( slist->list, (max_size+1) * sizeof(x264_frame_t*) );
  947.     if( x264_pthread_mutex_init( &slist->mutex, NULL ) ||
  948.         x264_pthread_cond_init( &slist->cv_fill, NULL ) ||
  949.         x264_pthread_cond_init( &slist->cv_empty, NULL ) )
  950.         return -1;
  951.     return 0;
  952. fail:
  953.     return -1;
  954. }
  955. void x264_synch_frame_list_delete( x264_synch_frame_list_t *slist )
  956. {
  957.     x264_pthread_mutex_destroy( &slist->mutex );
  958.     x264_pthread_cond_destroy( &slist->cv_fill );
  959.     x264_pthread_cond_destroy( &slist->cv_empty );
  960.     x264_frame_delete_list( slist->list );
  961. }
  962. void x264_synch_frame_list_push( x264_synch_frame_list_t *slist, x264_frame_t *frame )
  963. {
  964.     x264_pthread_mutex_lock( &slist->mutex );
  965.     while( slist->i_size == slist->i_max_size )
  966.         x264_pthread_cond_wait( &slist->cv_empty, &slist->mutex );
  967.     slist->list[ slist->i_size++ ] = frame;
  968.     x264_pthread_mutex_unlock( &slist->mutex );
  969.     x264_pthread_cond_broadcast( &slist->cv_fill );
  970. }