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

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: Eric Petit <titer@m0k.org>
  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 <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdint.h>
  27. #include <stdarg.h>
  28. #ifdef SYS_LINUX
  29. #include <altivec.h>
  30. #endif
  31. #include "x264.h"
  32. #include "common/mc.h"
  33. #include "common/clip1.h"
  34. #include "mc.h"
  35. #include "ppccommon.h"
  36. typedef void (*pf_mc_t)( uint8_t *src, int i_src,
  37.                          uint8_t *dst, int i_dst, int i_height );
  38. static inline int x264_tapfilter( uint8_t *pix, int i_pix_next )
  39. {
  40.     return pix[-2*i_pix_next] - 5*pix[-1*i_pix_next] + 20*(pix[0] +
  41.            pix[1*i_pix_next]) - 5*pix[ 2*i_pix_next] +
  42.            pix[ 3*i_pix_next];
  43. }
  44. static inline int x264_tapfilter1( uint8_t *pix )
  45. {
  46.     return pix[-2] - 5*pix[-1] + 20*(pix[0] + pix[1]) - 5*pix[ 2] +
  47.            pix[ 3];
  48. }
  49. /* pixel_avg */
  50. static inline void pixel_avg_w4( uint8_t *dst,  int i_dst,
  51.                                  uint8_t *src1, int i_src1,
  52.                                  uint8_t *src2, int i_src2,
  53.                                  int i_height )
  54. {
  55.     int x, y;
  56.     for( y = 0; y < i_height; y++ )
  57.     {
  58.         for( x = 0; x < 4; x++ )
  59.         {
  60.             dst[x] = ( src1[x] + src2[x] + 1 ) >> 1;
  61.         }
  62.         dst  += i_dst;
  63.         src1 += i_src1;
  64.         src2 += i_src2;
  65.     }
  66. }
  67. static inline void pixel_avg_w8( uint8_t *dst,  int i_dst,
  68.                                  uint8_t *src1, int i_src1,
  69.                                  uint8_t *src2, int i_src2,
  70.                                  int i_height )
  71. {
  72.     /* TODO - optimize */
  73.     pixel_avg_w4( &dst[0], i_dst, &src1[0], i_src1, &src2[0], i_src2,
  74.                   i_height );
  75.     pixel_avg_w4( &dst[4], i_dst, &src1[4], i_src1, &src2[4], i_src2,
  76.                   i_height );
  77. }
  78. static inline void pixel_avg_w16( uint8_t *dst,  int i_dst,
  79.                                   uint8_t *src1, int i_src1,
  80.                                   uint8_t *src2, int i_src2,
  81.                                   int i_height )
  82. {
  83.     int y;
  84.     vec_u8_t src1v, src2v;
  85.     PREP_LOAD;
  86.     PREP_STORE16;
  87.     for( y = 0; y < i_height; y++ )
  88.     {
  89.         VEC_LOAD( src1, src1v, 16, vec_u8_t );
  90.         VEC_LOAD( src2, src2v, 16, vec_u8_t );
  91.         src1v = vec_avg( src1v, src2v );
  92.         VEC_STORE16( src1v, dst );
  93.         dst  += i_dst;
  94.         src1 += i_src1;
  95.         src2 += i_src2;
  96.     }
  97. }
  98. /* mc_copy: plain c */
  99. #define MC_COPY( name, a )                                
  100. static void name( uint8_t *src, int i_src,                
  101.                   uint8_t *dst, int i_dst, int i_height ) 
  102. {                                                         
  103.     int y;                                                
  104.     for( y = 0; y < i_height; y++ )                       
  105.     {                                                     
  106.         memcpy( dst, src, a );                            
  107.         src += i_src;                                     
  108.         dst += i_dst;                                     
  109.     }                                                     
  110. }
  111. MC_COPY( mc_copy_w4,  4  )
  112. MC_COPY( mc_copy_w8,  8  )
  113. MC_COPY( mc_copy_w16, 16 )
  114. void mc_luma_altivec( uint8_t *src[4], int i_src_stride,
  115.                       uint8_t *dst,    int i_dst_stride,
  116.                       int mvx, int mvy,
  117.                       int i_width, int i_height )
  118. {
  119.     uint8_t *src1, *src2;
  120.     
  121.     /* todo : fixme... */
  122.     int correction = (((mvx&3) == 3 && (mvy&3) == 1) || ((mvx&3) == 1 && (mvy&3) == 3)) ? 1:0;
  123.     
  124.     int hpel1x = mvx>>1;
  125.     int hpel1y = (mvy+1-correction)>>1;
  126.     int filter1 = (hpel1x & 1) + ( (hpel1y & 1) << 1 );
  127.     
  128.     
  129.     src1 = src[filter1] + (hpel1y >> 1) * i_src_stride + (hpel1x >> 1);
  130.     
  131.     if ( (mvx|mvy) & 1 ) /* qpel interpolation needed */
  132.     {
  133.         int hpel2x = (mvx+1)>>1;
  134.         int hpel2y = (mvy+correction)>>1;
  135.         int filter2 = (hpel2x & 1) + ( (hpel2y & 1) <<1 );
  136.         
  137.         src2 = src[filter2] + (hpel2y >> 1) * i_src_stride + (hpel2x >> 1);
  138.         
  139.         switch(i_width) {
  140.         case 4:
  141.             pixel_avg_w4( dst, i_dst_stride, src1, i_src_stride,
  142.                           src2, i_src_stride, i_height );
  143.             break;
  144.         case 8:
  145.             pixel_avg_w8( dst, i_dst_stride, src1, i_src_stride,
  146.                           src2, i_src_stride, i_height );
  147.             break;
  148.         case 16:
  149.         default:
  150.             pixel_avg_w16( dst, i_dst_stride, src1, i_src_stride,
  151.                            src2, i_src_stride, i_height );
  152.         }
  153.         
  154.     }
  155.     else
  156.     {
  157.         switch(i_width) {
  158.         case 4:
  159.             mc_copy_w4( src1, i_src_stride, dst, i_dst_stride, i_height );
  160.             break;
  161.         case 8:
  162.             mc_copy_w8( src1, i_src_stride, dst, i_dst_stride, i_height );
  163.             break;
  164.         case 16:
  165.             mc_copy_w16( src1, i_src_stride, dst, i_dst_stride, i_height );
  166.             break;
  167.         }
  168.         
  169.     }
  170. }
  171. uint8_t *get_ref_altivec( uint8_t *src[4], int i_src_stride,
  172.                           uint8_t *dst,    int * i_dst_stride,
  173.                           int mvx, int mvy,
  174.                           int i_width, int i_height )
  175. {
  176.     uint8_t *src1, *src2;
  177.     
  178.     /* todo : fixme... */
  179.     int correction = (((mvx&3) == 3 && (mvy&3) == 1) || ((mvx&3) == 1 && (mvy&3) == 3)) ? 1:0;
  180.     
  181.     int hpel1x = mvx>>1;
  182.     int hpel1y = (mvy+1-correction)>>1;
  183.     int filter1 = (hpel1x & 1) + ( (hpel1y & 1) << 1 );
  184.     
  185.     
  186.     src1 = src[filter1] + (hpel1y >> 1) * i_src_stride + (hpel1x >> 1);
  187.     
  188.     if ( (mvx|mvy) & 1 ) /* qpel interpolation needed */
  189.     {
  190.         int hpel2x = (mvx+1)>>1;
  191.         int hpel2y = (mvy+correction)>>1;
  192.         int filter2 = (hpel2x & 1) + ( (hpel2y & 1) <<1 );
  193.         
  194.         src2 = src[filter2] + (hpel2y >> 1) * i_src_stride + (hpel2x >> 1);
  195.         
  196.         switch(i_width) {
  197.         case 4:
  198.             pixel_avg_w4( dst, *i_dst_stride, src1, i_src_stride,
  199.                           src2, i_src_stride, i_height );
  200.             break;
  201.         case 8:
  202.             pixel_avg_w8( dst, *i_dst_stride, src1, i_src_stride,
  203.                           src2, i_src_stride, i_height );
  204.             break;
  205.         case 16:
  206.         default:
  207.             pixel_avg_w16( dst, *i_dst_stride, src1, i_src_stride,
  208.                           src2, i_src_stride, i_height );
  209.         }
  210.         return dst;
  211.     }
  212.     else
  213.     {
  214.         *i_dst_stride = i_src_stride;
  215.         return src1;
  216.     }
  217. }
  218. static void mc_chroma_c( uint8_t *src, int i_src_stride,
  219.                          uint8_t *dst, int i_dst_stride,
  220.                          int mvx, int mvy,
  221.                          int i_width, int i_height )
  222. {
  223.     uint8_t *srcp;
  224.     int x, y;
  225.     int d8x = mvx & 0x07;
  226.     int d8y = mvy & 0x07;
  227.     DECLARE_ALIGNED( uint16_t, coeff[4], 16 );
  228.     coeff[0] = (8-d8x)*(8-d8y);
  229.     coeff[1] = d8x    *(8-d8y);
  230.     coeff[2] = (8-d8x)*d8y;
  231.     coeff[3] = d8x    *d8y;
  232.     src  += (mvy >> 3) * i_src_stride + (mvx >> 3);
  233.     srcp  = &src[i_src_stride];
  234.     /* TODO: optimize */
  235.     for( y = 0; y < i_height; y++ )
  236.     {
  237.         for( x = 0; x < i_width; x++ )
  238.         {
  239.             dst[x] = ( coeff[0]*src[x]  + coeff[1]*src[x+1] +
  240.                        coeff[2]*srcp[x] + coeff[3]*srcp[x+1] + 32 ) >> 6;
  241.         }
  242.         dst  += i_dst_stride;
  243.         src   = srcp;
  244.         srcp += i_src_stride;
  245.     }
  246. }
  247. #define DO_PROCESS(a) 
  248.         src##a##v_16 = vec_u8_to_u16( src##a##v_8 ); 
  249.         src##a##v_16 = vec_mladd( coeff##a##v, src##a##v_16, zero_u16v ); 
  250.         dstv_16      = vec_add( dstv_16, src##a##v_16 )
  251. static void mc_chroma_altivec_4xh( uint8_t *src, int i_src_stride,
  252.                                    uint8_t *dst, int i_dst_stride,
  253.                                    int mvx, int mvy,
  254.                                    int i_height )
  255. {
  256.     uint8_t *srcp;
  257.     int y;
  258.     int d8x = mvx & 0x07;
  259.     int d8y = mvy & 0x07;
  260.     DECLARE_ALIGNED( uint16_t, coeff[4], 16 );
  261.     coeff[0] = (8-d8x)*(8-d8y);
  262.     coeff[1] = d8x    *(8-d8y);
  263.     coeff[2] = (8-d8x)*d8y;
  264.     coeff[3] = d8x    *d8y;
  265.     src  += (mvy >> 3) * i_src_stride + (mvx >> 3);
  266.     srcp  = &src[i_src_stride];
  267.     
  268.     LOAD_ZERO;
  269.     PREP_LOAD;
  270.     PREP_STORE4;
  271.     vec_u16_t   coeff0v, coeff1v, coeff2v, coeff3v;
  272.     vec_u8_t    src0v_8, src1v_8, src2v_8, src3v_8;
  273.     vec_u16_t   src0v_16, src1v_16, src2v_16, src3v_16;
  274.     vec_u8_t    dstv_8;
  275.     vec_u16_t   dstv_16;
  276.     vec_u8_t    permv;
  277.     vec_u16_t   shiftv;
  278.     vec_u16_t   k32v;
  279.     
  280.     coeff0v = vec_ld( 0, coeff );
  281.     coeff3v = vec_splat( coeff0v, 3 );
  282.     coeff2v = vec_splat( coeff0v, 2 );
  283.     coeff1v = vec_splat( coeff0v, 1 );
  284.     coeff0v = vec_splat( coeff0v, 0 );
  285.     k32v    = vec_sl( vec_splat_u16( 1 ), vec_splat_u16( 5 ) );
  286.     permv   = vec_lvsl( 0, (uint8_t *) 1 );
  287.     shiftv  = vec_splat_u16( 6 );
  288.     VEC_LOAD( src, src2v_8, 5, vec_u8_t );
  289.     src3v_8 = vec_perm( src2v_8, src2v_8, permv );
  290.     for( y = 0; y < i_height; y++ )
  291.     {
  292.         src0v_8 = src2v_8;
  293.         src1v_8 = src3v_8;
  294.         VEC_LOAD( srcp, src2v_8, 5, vec_u8_t );
  295.         src3v_8 = vec_perm( src2v_8, src2v_8, permv );
  296.         dstv_16 = k32v;
  297.         DO_PROCESS( 0 );
  298.         DO_PROCESS( 1 );
  299.         DO_PROCESS( 2 );
  300.         DO_PROCESS( 3 );
  301.         dstv_16 = vec_sr( dstv_16, shiftv );
  302.         dstv_8  = vec_u16_to_u8( dstv_16 );
  303.         VEC_STORE4( dstv_8, dst );
  304.         dst  += i_dst_stride;
  305.         srcp += i_src_stride;
  306.     }
  307. }
  308. static void mc_chroma_altivec_8xh( uint8_t *src, int i_src_stride,
  309.                                    uint8_t *dst, int i_dst_stride,
  310.                                    int mvx, int mvy,
  311.                                    int i_height )
  312. {
  313.     uint8_t *srcp;
  314.     int y;
  315.     int d8x = mvx & 0x07;
  316.     int d8y = mvy & 0x07;
  317.     DECLARE_ALIGNED( uint16_t, coeff[4], 16 );
  318.     coeff[0] = (8-d8x)*(8-d8y);
  319.     coeff[1] = d8x    *(8-d8y);
  320.     coeff[2] = (8-d8x)*d8y;
  321.     coeff[3] = d8x    *d8y;
  322.     src  += (mvy >> 3) * i_src_stride + (mvx >> 3);
  323.     srcp  = &src[i_src_stride];
  324.     
  325.     LOAD_ZERO;
  326.     PREP_LOAD;
  327.     PREP_STORE8;
  328.     vec_u16_t   coeff0v, coeff1v, coeff2v, coeff3v;
  329.     vec_u8_t    src0v_8, src1v_8, src2v_8, src3v_8;
  330.     vec_u16_t   src0v_16, src1v_16, src2v_16, src3v_16;
  331.     vec_u8_t    dstv_8;
  332.     vec_u16_t   dstv_16;
  333.     vec_u8_t    permv;
  334.     vec_u16_t   shiftv;
  335.     vec_u16_t   k32v;
  336.     
  337.     coeff0v = vec_ld( 0, coeff );
  338.     coeff3v = vec_splat( coeff0v, 3 );
  339.     coeff2v = vec_splat( coeff0v, 2 );
  340.     coeff1v = vec_splat( coeff0v, 1 );
  341.     coeff0v = vec_splat( coeff0v, 0 );
  342.     k32v    = vec_sl( vec_splat_u16( 1 ), vec_splat_u16( 5 ) );
  343.     permv   = vec_lvsl( 0, (uint8_t *) 1 );
  344.     shiftv  = vec_splat_u16( 6 );
  345.     VEC_LOAD( src, src2v_8, 9, vec_u8_t );
  346.     src3v_8 = vec_perm( src2v_8, src2v_8, permv );
  347.     for( y = 0; y < i_height; y++ )
  348.     {
  349.         src0v_8 = src2v_8;
  350.         src1v_8 = src3v_8;
  351.         VEC_LOAD( srcp, src2v_8, 9, vec_u8_t );
  352.         src3v_8 = vec_perm( src2v_8, src2v_8, permv );
  353.         dstv_16 = k32v;
  354.         DO_PROCESS( 0 );
  355.         DO_PROCESS( 1 );
  356.         DO_PROCESS( 2 );
  357.         DO_PROCESS( 3 );
  358.         dstv_16 = vec_sr( dstv_16, shiftv );
  359.         dstv_8  = vec_u16_to_u8( dstv_16 );
  360.         VEC_STORE8( dstv_8, dst );
  361.         dst  += i_dst_stride;
  362.         srcp += i_src_stride;
  363.     }
  364. }
  365. static void mc_chroma_altivec( uint8_t *src, int i_src_stride,
  366.                                uint8_t *dst, int i_dst_stride,
  367.                                int mvx, int mvy,
  368.                                int i_width, int i_height )
  369. {
  370.     if( i_width == 8 )
  371.     {
  372.         mc_chroma_altivec_8xh( src, i_src_stride, dst, i_dst_stride,
  373.                                mvx, mvy, i_height );
  374.         return;
  375.     }
  376.     if( i_width == 4 )
  377.     {
  378.         mc_chroma_altivec_4xh( src, i_src_stride, dst, i_dst_stride,
  379.                                mvx, mvy, i_height );
  380.         return;
  381.     }
  382.     mc_chroma_c( src, i_src_stride, dst, i_dst_stride,
  383.                  mvx, mvy, i_width, i_height );
  384. }
  385. void x264_mc_altivec_init( x264_mc_functions_t *pf )
  386. {
  387.     pf->mc_luma   = mc_luma_altivec;
  388.     pf->get_ref   = get_ref_altivec;
  389.     pf->mc_chroma = mc_chroma_altivec;
  390. }