mc.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:17k
源码类别:

Audio

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * mc.c: h264 encoder library (Motion Compensation)
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 Laurent Aimar
  5.  * $Id: mc.c,v 1.1 2004/06/03 19:27:07 fenrir Exp $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *
  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.
  13.  *
  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.
  18.  *
  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.  *****************************************************************************/
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include "common.h"
  26. #include "clip1.h"
  27. #ifdef HAVE_MMXEXT
  28. #include "i386/mc.h"
  29. #endif
  30. #ifdef ARCH_PPC
  31. #include "ppc/mc.h"
  32. #endif
  33. static inline int x264_tapfilter( uint8_t *pix, int i_pix_next )
  34. {
  35.     return pix[-2*i_pix_next] - 5*pix[-1*i_pix_next] + 20*(pix[0] + pix[1*i_pix_next]) - 5*pix[ 2*i_pix_next] + pix[ 3*i_pix_next];
  36. }
  37. static inline int x264_tapfilter1( uint8_t *pix )
  38. {
  39.     return pix[-2] - 5*pix[-1] + 20*(pix[0] + pix[1]) - 5*pix[ 2] + pix[ 3];
  40. }
  41. static inline void pixel_avg( uint8_t *dst,  int i_dst_stride,
  42.                               uint8_t *src1, int i_src1_stride,
  43.                               uint8_t *src2, int i_src2_stride,
  44.                               int i_width, int i_height )
  45. {
  46.     int x, y;
  47.     for( y = 0; y < i_height; y++ )
  48.     {
  49.         for( x = 0; x < i_width; x++ )
  50.         {
  51.             dst[x] = ( src1[x] + src2[x] + 1 ) >> 1;
  52.         }
  53.         dst  += i_dst_stride;
  54.         src1 += i_src1_stride;
  55.         src2 += i_src2_stride;
  56.     }
  57. }
  58. static inline void pixel_avg_wxh( uint8_t *dst, int i_dst, uint8_t *src, int i_src, int width, int height )
  59. {
  60.     int x, y;
  61.     for( y = 0; y < height; y++ )
  62.     {
  63.         for( x = 0; x < width; x++ )
  64.         {
  65.             dst[x] = ( dst[x] + src[x] + 1 ) >> 1;
  66.         }
  67.         dst += i_dst;
  68.         src += i_src;
  69.     }
  70. }
  71. #define PIXEL_AVG_C( name, width, height ) 
  72. static void name( uint8_t *pix1, int i_stride_pix1, 
  73.                   uint8_t *pix2, int i_stride_pix2 ) 
  74.     pixel_avg_wxh( pix1, i_stride_pix1, pix2, i_stride_pix2, width, height ); 
  75. }
  76. PIXEL_AVG_C( pixel_avg_16x16, 16, 16 )
  77. PIXEL_AVG_C( pixel_avg_16x8,  16, 8 )
  78. PIXEL_AVG_C( pixel_avg_8x16,  8, 16 )
  79. PIXEL_AVG_C( pixel_avg_8x8,   8, 8 )
  80. PIXEL_AVG_C( pixel_avg_8x4,   8, 4 )
  81. PIXEL_AVG_C( pixel_avg_4x8,   4, 8 )
  82. PIXEL_AVG_C( pixel_avg_4x4,   4, 4 )
  83. PIXEL_AVG_C( pixel_avg_4x2,   4, 2 )
  84. PIXEL_AVG_C( pixel_avg_2x4,   2, 4 )
  85. PIXEL_AVG_C( pixel_avg_2x2,   2, 2 )
  86. /* Implicit weighted bipred only:
  87.  * assumes log2_denom = 5, offset = 0, weight1 + weight2 = 64 */
  88. #define op_scale2(x) dst[x] = x264_clip_uint8( (dst[x]*i_weight1 + src[x]*i_weight2 + (1<<5)) >> 6 )
  89. static inline void pixel_avg_weight_wxh( uint8_t *dst, int i_dst, uint8_t *src, int i_src, int width, int height, int i_weight1 ){
  90.     int y;
  91.     const int i_weight2 = 64 - i_weight1;
  92.     for(y=0; y<height; y++, dst += i_dst, src += i_src){
  93.         op_scale2(0);
  94.         op_scale2(1);
  95.         if(width==2) continue;
  96.         op_scale2(2);
  97.         op_scale2(3);
  98.         if(width==4) continue;
  99.         op_scale2(4);
  100.         op_scale2(5);
  101.         op_scale2(6);
  102.         op_scale2(7);
  103.         if(width==8) continue;
  104.         op_scale2(8);
  105.         op_scale2(9);
  106.         op_scale2(10);
  107.         op_scale2(11);
  108.         op_scale2(12);
  109.         op_scale2(13);
  110.         op_scale2(14);
  111.         op_scale2(15);
  112.     }
  113. }
  114. #define PIXEL_AVG_WEIGHT_C( width, height ) 
  115. static void pixel_avg_weight_##width##x##height( 
  116.                 uint8_t *pix1, int i_stride_pix1, 
  117.                 uint8_t *pix2, int i_stride_pix2, int i_weight1 ) 
  118.     pixel_avg_weight_wxh( pix1, i_stride_pix1, pix2, i_stride_pix2, width, height, i_weight1 ); 
  119. }
  120. PIXEL_AVG_WEIGHT_C(16,16)
  121. PIXEL_AVG_WEIGHT_C(16,8)
  122. PIXEL_AVG_WEIGHT_C(8,16)
  123. PIXEL_AVG_WEIGHT_C(8,8)
  124. PIXEL_AVG_WEIGHT_C(8,4)
  125. PIXEL_AVG_WEIGHT_C(4,8)
  126. PIXEL_AVG_WEIGHT_C(4,4)
  127. PIXEL_AVG_WEIGHT_C(4,2)
  128. PIXEL_AVG_WEIGHT_C(2,4)
  129. PIXEL_AVG_WEIGHT_C(2,2)
  130. #undef op_scale2
  131. #undef PIXEL_AVG_WEIGHT_C
  132. typedef void (*pf_mc_t)(uint8_t *src, int i_src_stride, uint8_t *dst, int i_dst_stride, int i_width, int i_height );
  133. static void mc_copy( uint8_t *src, int i_src_stride, uint8_t *dst, int i_dst_stride, int i_width, int i_height )
  134. {
  135.     int y;
  136.     for( y = 0; y < i_height; y++ )
  137.     {
  138.         memcpy( dst, src, i_width );
  139.         src += i_src_stride;
  140.         dst += i_dst_stride;
  141.     }
  142. }
  143. static inline void mc_hh( uint8_t *src, int i_src_stride, uint8_t *dst, int i_dst_stride, int i_width, int i_height )
  144. {
  145.     int x, y;
  146.     for( y = 0; y < i_height; y++ )
  147.     {
  148.         for( x = 0; x < i_width; x++ )
  149.         {
  150.             dst[x] = x264_mc_clip1( ( x264_tapfilter1( &src[x] ) + 16 ) >> 5 );
  151.         }
  152.         src += i_src_stride;
  153.         dst += i_dst_stride;
  154.     }
  155. }
  156. static inline void mc_hv( uint8_t *src, int i_src_stride, uint8_t *dst, int i_dst_stride, int i_width, int i_height )
  157. {
  158.     int x, y;
  159.     for( y = 0; y < i_height; y++ )
  160.     {
  161.         for( x = 0; x < i_width; x++ )
  162.         {
  163.             dst[x] = x264_mc_clip1( ( x264_tapfilter( &src[x], i_src_stride ) + 16 ) >> 5 );
  164.         }
  165.         src += i_src_stride;
  166.         dst += i_dst_stride;
  167.     }
  168. }
  169. static inline void mc_hc( uint8_t *src, int i_src_stride, uint8_t *dst, int i_dst_stride, int i_width, int i_height )
  170. {
  171.     uint8_t *out;
  172.     uint8_t *pix;
  173.     int x, y;
  174.     for( x = 0; x < i_width; x++ )
  175.     {
  176.         int tap[6];
  177.         pix = &src[x];
  178.         out = &dst[x];
  179.         tap[0] = x264_tapfilter1( &pix[-2*i_src_stride] );
  180.         tap[1] = x264_tapfilter1( &pix[-1*i_src_stride] );
  181.         tap[2] = x264_tapfilter1( &pix[ 0*i_src_stride] );
  182.         tap[3] = x264_tapfilter1( &pix[ 1*i_src_stride] );
  183.         tap[4] = x264_tapfilter1( &pix[ 2*i_src_stride] );
  184.         for( y = 0; y < i_height; y++ )
  185.         {
  186.             tap[5] = x264_tapfilter1( &pix[ 3*i_src_stride] );
  187.             *out = x264_mc_clip1( ( tap[0] - 5*tap[1] + 20 * tap[2] + 20 * tap[3] -5*tap[4] + tap[5] + 512 ) >> 10 );
  188.             /* Next line */
  189.             pix += i_src_stride;
  190.             out += i_dst_stride;
  191.             tap[0] = tap[1];
  192.             tap[1] = tap[2];
  193.             tap[2] = tap[3];
  194.             tap[3] = tap[4];
  195.             tap[4] = tap[5];
  196.         }
  197.     }
  198. }
  199. static void mc_luma( uint8_t *src[4], int i_src_stride,
  200.                      uint8_t *dst,    int i_dst_stride,
  201.                      int mvx,int mvy,
  202.                      int i_width, int i_height )
  203. {
  204.     uint8_t *src1, *src2;
  205.     int correction = (mvx&1) && (mvy&1) && ((mvx&2) ^ (mvy&2));
  206.     int hpel1x = mvx>>1;
  207.     int hpel1y = (mvy+1-correction)>>1;
  208.     int filter1 = (hpel1x & 1) + ( (hpel1y & 1) << 1 );
  209.     src1 = src[filter1] + (hpel1y >> 1) * i_src_stride + (hpel1x >> 1);
  210.     if ( (mvx|mvy) & 1 ) /* qpel interpolation needed */
  211.     {
  212.         int hpel2x = (mvx+1)>>1;
  213.         int hpel2y = (mvy+correction)>>1;
  214.         int filter2 = (hpel2x & 1) + ( (hpel2y & 1) <<1 );
  215.         src2 = src[filter2] + (hpel2y >> 1) * i_src_stride + (hpel2x >> 1);
  216.     
  217.         pixel_avg( dst, i_dst_stride, src1, i_src_stride,
  218.                    src2, i_src_stride, i_width, i_height );
  219.     }
  220.     else
  221.     {
  222.         mc_copy( src1, i_src_stride, dst, i_dst_stride, i_width, i_height );
  223.     }
  224. }
  225. static uint8_t *get_ref( uint8_t *src[4], int i_src_stride,
  226.                          uint8_t *dst,    int * i_dst_stride,
  227.                          int mvx,int mvy,
  228.                          int i_width, int i_height )
  229. {
  230.     uint8_t *src1, *src2;
  231.     int correction = (mvx&1) && (mvy&1) && ((mvx&2) ^ (mvy&2));
  232.     int hpel1x = mvx>>1;
  233.     int hpel1y = (mvy+1-correction)>>1;
  234.     int filter1 = (hpel1x & 1) + ( (hpel1y & 1) << 1 );
  235.     src1 = src[filter1] + (hpel1y >> 1) * i_src_stride + (hpel1x >> 1);
  236.     if ( (mvx|mvy) & 1 ) /* qpel interpolation needed */
  237.     {
  238.         int hpel2x = (mvx+1)>>1;
  239.         int hpel2y = (mvy+correction)>>1;
  240.         int filter2 = (hpel2x & 1) + ( (hpel2y & 1) <<1 );
  241.         src2 = src[filter2] + (hpel2y >> 1) * i_src_stride + (hpel2x >> 1);
  242.     
  243.         pixel_avg( dst, *i_dst_stride, src1, i_src_stride,
  244.                    src2, i_src_stride, i_width, i_height );
  245.         return dst;
  246.     }
  247.     else
  248.     {
  249.         *i_dst_stride = i_src_stride;
  250.         return src1;
  251.     }
  252. }
  253. /* full chroma mc (ie until 1/8 pixel)*/
  254. static void motion_compensation_chroma( uint8_t *src, int i_src_stride,
  255.                                         uint8_t *dst, int i_dst_stride,
  256.                                         int mvx, int mvy,
  257.                                         int i_width, int i_height )
  258. {
  259.     uint8_t *srcp;
  260.     int x, y;
  261.     const int d8x = mvx&0x07;
  262.     const int d8y = mvy&0x07;
  263.     const int cA = (8-d8x)*(8-d8y);
  264.     const int cB = d8x    *(8-d8y);
  265.     const int cC = (8-d8x)*d8y;
  266.     const int cD = d8x    *d8y;
  267.     src  += (mvy >> 3) * i_src_stride + (mvx >> 3);
  268.     srcp = &src[i_src_stride];
  269.     for( y = 0; y < i_height; y++ )
  270.     {
  271.         for( x = 0; x < i_width; x++ )
  272.         {
  273.             dst[x] = ( cA*src[x]  + cB*src[x+1] +
  274.                        cC*srcp[x] + cD*srcp[x+1] + 32 ) >> 6;
  275.         }
  276.         dst  += i_dst_stride;
  277.         src   = srcp;
  278.         srcp += i_src_stride;
  279.     }
  280. }
  281. #ifdef HAVE_MMXEXT
  282. static void motion_compensation_chroma_mmxext( uint8_t *src, int i_src_stride,
  283.                                         uint8_t *dst, int i_dst_stride,
  284.                                         int mvx, int mvy,
  285.                                         int i_width, int i_height )
  286. {
  287.     if (i_width == 2) {
  288.         motion_compensation_chroma(src, i_src_stride, dst, i_dst_stride,
  289.                                    mvx, mvy, i_width, i_height);
  290.     } else {
  291.         const int d8x = mvx&0x07;
  292.         const int d8y = mvy&0x07;
  293.         
  294.         src  += (mvy >> 3) * i_src_stride + (mvx >> 3);
  295.         
  296.         x264_mc_chroma_mmxext( src, i_src_stride, dst, i_dst_stride,
  297.                                d8x, d8y, i_width, i_height );
  298.     }
  299. }
  300. #endif
  301. #define MC_COPY(W) 
  302. static void mc_copy_w##W( uint8_t *dst, int i_dst, uint8_t *src, int i_src, int i_height ) 
  303.     mc_copy( src, i_src, dst, i_dst, W, i_height ); 
  304. }
  305. MC_COPY( 16 )
  306. MC_COPY( 8 )
  307. MC_COPY( 4 )
  308. void x264_mc_init( int cpu, x264_mc_functions_t *pf )
  309. {
  310.     pf->mc_luma   = mc_luma;
  311.     pf->get_ref   = get_ref;
  312.     pf->mc_chroma = motion_compensation_chroma;
  313.     pf->avg[PIXEL_16x16]= pixel_avg_16x16;
  314.     pf->avg[PIXEL_16x8] = pixel_avg_16x8;
  315.     pf->avg[PIXEL_8x16] = pixel_avg_8x16;
  316.     pf->avg[PIXEL_8x8]  = pixel_avg_8x8;
  317.     pf->avg[PIXEL_8x4]  = pixel_avg_8x4;
  318.     pf->avg[PIXEL_4x8]  = pixel_avg_4x8;
  319.     pf->avg[PIXEL_4x4]  = pixel_avg_4x4;
  320.     pf->avg[PIXEL_4x2]  = pixel_avg_4x2;
  321.     pf->avg[PIXEL_2x4]  = pixel_avg_2x4;
  322.     pf->avg[PIXEL_2x2]  = pixel_avg_2x2;
  323.     
  324.     pf->avg_weight[PIXEL_16x16]= pixel_avg_weight_16x16;
  325.     pf->avg_weight[PIXEL_16x8] = pixel_avg_weight_16x8;
  326.     pf->avg_weight[PIXEL_8x16] = pixel_avg_weight_8x16;
  327.     pf->avg_weight[PIXEL_8x8]  = pixel_avg_weight_8x8;
  328.     pf->avg_weight[PIXEL_8x4]  = pixel_avg_weight_8x4;
  329.     pf->avg_weight[PIXEL_4x8]  = pixel_avg_weight_4x8;
  330.     pf->avg_weight[PIXEL_4x4]  = pixel_avg_weight_4x4;
  331.     pf->avg_weight[PIXEL_4x2]  = pixel_avg_weight_4x2;
  332.     pf->avg_weight[PIXEL_2x4]  = pixel_avg_weight_2x4;
  333.     pf->avg_weight[PIXEL_2x2]  = pixel_avg_weight_2x2;
  334.     pf->copy[PIXEL_16x16] = mc_copy_w16;
  335.     pf->copy[PIXEL_8x8]   = mc_copy_w8;
  336.     pf->copy[PIXEL_4x4]   = mc_copy_w4;
  337. #ifdef HAVE_MMXEXT
  338.     if( cpu&X264_CPU_MMXEXT ) {
  339.         x264_mc_mmxext_init( pf );
  340.         pf->mc_chroma = motion_compensation_chroma_mmxext;
  341.     }
  342. #endif
  343. #ifdef HAVE_SSE2
  344.     if( cpu&X264_CPU_SSE2 )
  345.         x264_mc_sse2_init( pf );
  346. #endif
  347. #ifdef ARCH_PPC
  348.     if( cpu&X264_CPU_ALTIVEC )
  349.         x264_mc_altivec_init( pf );
  350. #endif
  351. }
  352. extern void x264_horizontal_filter_mmxext( uint8_t *dst, int i_dst_stride,
  353.                                            uint8_t *src, int i_src_stride,
  354.                                            int i_width, int i_height );
  355. extern void x264_center_filter_mmxext( uint8_t *dst1, int i_dst1_stride,
  356.                                        uint8_t *dst2, int i_dst2_stride,
  357.                                        uint8_t *src, int i_src_stride,
  358.                                        int i_width, int i_height );
  359. void x264_frame_filter( int cpu, x264_frame_t *frame )
  360. {
  361.     const int x_inc = 16, y_inc = 16;
  362.     const int stride = frame->i_stride[0];
  363.     int x, y;
  364.     pf_mc_t int_h = mc_hh;
  365.     pf_mc_t int_v = mc_hv;
  366.     pf_mc_t int_hv = mc_hc;
  367. #ifdef HAVE_MMXEXT
  368.     if ( cpu & X264_CPU_MMXEXT )
  369.     {
  370.         x264_horizontal_filter_mmxext(frame->filtered[1] - 8 * stride - 8, stride,
  371.             frame->plane[0] - 8 * stride - 8, stride,
  372.             stride - 48, frame->i_lines[0] + 16);
  373.         x264_center_filter_mmxext(frame->filtered[2] - 8 * stride - 8, stride,
  374.             frame->filtered[3] - 8 * stride - 8, stride,
  375.             frame->plane[0] - 8 * stride - 8, stride,
  376.             stride - 48, frame->i_lines[0] + 16);
  377.     }
  378.     else
  379. #endif
  380.     {
  381.         for( y = -8; y < frame->i_lines[0]+8; y += y_inc )
  382.         {
  383.             uint8_t *p_in = frame->plane[0] + y * stride - 8;
  384.             uint8_t *p_h  = frame->filtered[1] + y * stride - 8;
  385.             uint8_t *p_v  = frame->filtered[2] + y * stride - 8;
  386.             uint8_t *p_hv = frame->filtered[3] + y * stride - 8;
  387.             for( x = -8; x < stride - 64 + 8; x += x_inc )
  388.             {
  389.                 int_h(  p_in, stride, p_h,  stride, x_inc, y_inc );
  390.                 int_v(  p_in, stride, p_v,  stride, x_inc, y_inc );
  391.                 int_hv( p_in, stride, p_hv, stride, x_inc, y_inc );
  392.                 p_h += x_inc;
  393.                 p_v += x_inc;
  394.                 p_hv += x_inc;
  395.                 p_in += x_inc;
  396.             }
  397.         }
  398.     }
  399.     /* generate integral image:
  400.      * each entry in frame->integral is the sum of all luma samples above and
  401.      * to the left of its location (inclusive).
  402.      * this allows us to calculate the DC of any rectangle by looking only
  403.      * at the corner entries.
  404.      * individual entries will overflow 16 bits, but that's ok:
  405.      * we only need the differences between entries, and those will be correct
  406.      * as long as we don't try to evaluate a rectangle bigger than 16x16.
  407.      * likewise, we don't really have to init the edges to 0, leaving garbage
  408.      * there wouldn't affect the results.*/
  409.     if( frame->integral )
  410.     {
  411.         memset( frame->integral - 32 * stride - 32, 0, stride * sizeof(uint16_t) );
  412.         for( y = -31; y < frame->i_lines[0] + 32; y++ )
  413.         {
  414.             uint8_t  *ref  = frame->plane[0] + y * stride - 32;
  415.             uint16_t *line = frame->integral + y * stride - 32;
  416.             uint16_t v = line[0] = 0;
  417.             for( x = 1; x < stride; x++ )
  418.                 line[x] = v += ref[x] + line[x-stride] - line[x-stride-1];
  419.         }
  420.     }
  421. }
  422. void x264_frame_init_lowres( int cpu, x264_frame_t *frame )
  423. {
  424.     // FIXME: tapfilter?
  425.     const int i_stride = frame->i_stride[0];
  426.     const int i_stride2 = frame->i_stride_lowres;
  427.     const int i_width2 = i_stride2 - 64;
  428.     int x, y, i;
  429.     for( y = 0; y < frame->i_lines_lowres - 1; y++ )
  430.     {
  431.         uint8_t *src0 = &frame->plane[0][2*y*i_stride];
  432.         uint8_t *src1 = src0+i_stride;
  433.         uint8_t *src2 = src1+i_stride;
  434.         uint8_t *dst0 = &frame->lowres[0][y*i_stride2];
  435.         uint8_t *dsth = &frame->lowres[1][y*i_stride2];
  436.         uint8_t *dstv = &frame->lowres[2][y*i_stride2];
  437.         uint8_t *dstc = &frame->lowres[3][y*i_stride2];
  438.         for( x = 0; x < i_width2 - 1; x++ )
  439.         {
  440.             dst0[x] = (src0[2*x  ] + src0[2*x+1] + src1[2*x  ] + src1[2*x+1] + 2) >> 2;
  441.             dsth[x] = (src0[2*x+1] + src0[2*x+2] + src1[2*x+1] + src1[2*x+2] + 2) >> 2;
  442.             dstv[x] = (src1[2*x  ] + src1[2*x+1] + src2[2*x  ] + src2[2*x+1] + 2) >> 2;
  443.             dstc[x] = (src1[2*x+1] + src1[2*x+2] + src2[2*x+1] + src2[2*x+2] + 2) >> 2;
  444.         }
  445.         dst0[x] = (src0[2*x  ] + src0[2*x+1] + src1[2*x  ] + src1[2*x+1] + 2) >> 2;
  446.         dstv[x] = (src1[2*x  ] + src1[2*x+1] + src2[2*x  ] + src2[2*x+1] + 2) >> 2;
  447.         dsth[x] = (src0[2*x+1] + src1[2*x+1] + 1) >> 1;
  448.         dstc[x] = (src1[2*x+1] + src2[2*x+1] + 1) >> 1;
  449.     }
  450.     for( i = 0; i < 4; i++ )
  451.         memcpy( &frame->lowres[i][y*i_stride2], &frame->lowres[i][(y-1)*i_stride2], i_width2 );
  452.     for( y = 0; y < 16; y++ )
  453.         for( x = 0; x < 16; x++ )
  454.             frame->i_cost_est[x][y] = -1;
  455.     x264_frame_expand_border_lowres( frame );
  456. }