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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * mc-c.c: h264 encoder library (Motion Compensation)
  3.  *****************************************************************************
  4.  * Copyright (C) 2009 x264 project
  5.  *
  6.  * Authors: David Conrad <lessen42@gmail.com>
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  21.  *****************************************************************************/
  22. #include "common/common.h"
  23. #include "mc.h"
  24. void x264_prefetch_ref_arm( uint8_t *, int, int );
  25. void x264_prefetch_fenc_arm( uint8_t *, int, uint8_t *, int, int );
  26. void *x264_memcpy_aligned_neon( void * dst, const void * src, size_t n );
  27. void x264_memzero_aligned_neon( void *dst, size_t n );
  28. void x264_pixel_avg_16x16_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int, int );
  29. void x264_pixel_avg_16x8_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int, int );
  30. void x264_pixel_avg_8x16_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int, int );
  31. void x264_pixel_avg_8x8_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int, int );
  32. void x264_pixel_avg_8x4_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int, int );
  33. void x264_pixel_avg_4x8_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int, int );
  34. void x264_pixel_avg_4x4_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int, int );
  35. void x264_pixel_avg_4x2_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int, int );
  36. void x264_pixel_avg2_w4_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int );
  37. void x264_pixel_avg2_w8_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int );
  38. void x264_pixel_avg2_w16_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int );
  39. void x264_pixel_avg2_w20_neon( uint8_t *, int, uint8_t *, int, uint8_t *, int );
  40. void x264_mc_copy_w4_neon( uint8_t *, int, uint8_t *, int, int );
  41. void x264_mc_copy_w8_neon( uint8_t *, int, uint8_t *, int, int );
  42. void x264_mc_copy_w16_neon( uint8_t *, int, uint8_t *, int, int );
  43. void x264_mc_copy_w16_aligned_neon( uint8_t *, int, uint8_t *, int, int );
  44. void x264_mc_chroma_neon( uint8_t *, int, uint8_t *, int, int, int, int, int );
  45. void x264_frame_init_lowres_core_neon( uint8_t *, uint8_t *, uint8_t *, uint8_t *, uint8_t *, int, int, int, int);
  46. static void (* const x264_pixel_avg_wtab_neon[6])( uint8_t *, int, uint8_t *, int, uint8_t *, int ) =
  47. {
  48.     NULL,
  49.     x264_pixel_avg2_w4_neon,
  50.     x264_pixel_avg2_w8_neon,
  51.     x264_pixel_avg2_w16_neon,   // no slower than w12, so no point in a separate function
  52.     x264_pixel_avg2_w16_neon,
  53.     x264_pixel_avg2_w20_neon,
  54. };
  55. static void (* const x264_mc_copy_wtab_neon[5])( uint8_t *, int, uint8_t *, int, int ) =
  56. {
  57.     NULL,
  58.     x264_mc_copy_w4_neon,
  59.     x264_mc_copy_w8_neon,
  60.     NULL,
  61.     x264_mc_copy_w16_neon,
  62. };
  63. static const int hpel_ref0[16] = {0,1,1,1,0,1,1,1,2,3,3,3,0,1,1,1};
  64. static const int hpel_ref1[16] = {0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2};
  65. static void mc_luma_neon( uint8_t *dst,    int i_dst_stride,
  66.                           uint8_t *src[4], int i_src_stride,
  67.                           int mvx, int mvy,
  68.                           int i_width, int i_height )
  69. {
  70.     int qpel_idx = ((mvy&3)<<2) + (mvx&3);
  71.     int offset = (mvy>>2)*i_src_stride + (mvx>>2);
  72.     uint8_t *src1 = src[hpel_ref0[qpel_idx]] + offset;
  73.     if ( (mvy&3) == 3 )             // explict if() to force conditional add
  74.         src1 += i_src_stride;
  75.     if( qpel_idx & 5 ) /* qpel interpolation needed */
  76.     {
  77.         uint8_t *src2 = src[hpel_ref1[qpel_idx]] + offset + ((mvx&3) == 3);
  78.         x264_pixel_avg_wtab_neon[i_width>>2](
  79.                 dst, i_dst_stride, src1, i_src_stride,
  80.                 src2, i_height );
  81.     }
  82.     else
  83.     {
  84.         x264_mc_copy_wtab_neon[i_width>>2](
  85.                 dst, i_dst_stride, src1, i_src_stride, i_height );
  86.     }
  87. }
  88. static uint8_t *get_ref_neon( uint8_t *dst,   int *i_dst_stride,
  89.                               uint8_t *src[4], int i_src_stride,
  90.                               int mvx, int mvy,
  91.                               int i_width, int i_height )
  92. {
  93.     int qpel_idx = ((mvy&3)<<2) + (mvx&3);
  94.     int offset = (mvy>>2)*i_src_stride + (mvx>>2);
  95.     uint8_t *src1 = src[hpel_ref0[qpel_idx]] + offset;
  96.     if ( (mvy&3) == 3 )             // explict if() to force conditional add
  97.         src1 += i_src_stride;
  98.     if( qpel_idx & 5 ) /* qpel interpolation needed */
  99.     {
  100.         uint8_t *src2 = src[hpel_ref1[qpel_idx]] + offset + ((mvx&3) == 3);
  101.         x264_pixel_avg_wtab_neon[i_width>>2](
  102.                 dst, *i_dst_stride, src1, i_src_stride,
  103.                 src2, i_height );
  104.         return dst;
  105.     }
  106.     else
  107.     {
  108.         *i_dst_stride = i_src_stride;
  109.         return src1;
  110.     }
  111. }
  112. void x264_hpel_filter_v_neon( uint8_t *, uint8_t *, int16_t *, int, int );
  113. void x264_hpel_filter_c_neon( uint8_t *, int16_t *, int );
  114. void x264_hpel_filter_h_neon( uint8_t *, uint8_t *, int );
  115. static void hpel_filter_neon( uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, uint8_t *src,
  116.                               int stride, int width, int height, int16_t *buf )
  117. {
  118.     int realign = (intptr_t)src & 15;
  119.     src -= realign;
  120.     dstv -= realign;
  121.     dstc -= realign;
  122.     dsth -= realign;
  123.     width += realign;
  124.     while( height-- )
  125.     {
  126.         x264_hpel_filter_v_neon( dstv, src, buf+8, stride, width );
  127.         x264_hpel_filter_c_neon( dstc, buf+8, width );
  128.         x264_hpel_filter_h_neon( dsth, src, width );
  129.         dsth += stride;
  130.         dstv += stride;
  131.         dstc += stride;
  132.         src  += stride;
  133.     }
  134. }
  135. void x264_mc_init_arm( int cpu, x264_mc_functions_t *pf )
  136. {
  137.     if( !(cpu&X264_CPU_ARMV6) )
  138.         return;
  139.     pf->prefetch_fenc = x264_prefetch_fenc_arm;
  140.     pf->prefetch_ref  = x264_prefetch_ref_arm;
  141.     if( !(cpu&X264_CPU_NEON) )
  142.         return;
  143.     pf->copy_16x16_unaligned = x264_mc_copy_w16_neon;
  144.     pf->copy[PIXEL_16x16] = x264_mc_copy_w16_aligned_neon;
  145.     pf->copy[PIXEL_8x8]   = x264_mc_copy_w8_neon;
  146.     pf->copy[PIXEL_4x4]   = x264_mc_copy_w4_neon;
  147.     pf->avg[PIXEL_16x16] = x264_pixel_avg_16x16_neon;
  148.     pf->avg[PIXEL_16x8]  = x264_pixel_avg_16x8_neon;
  149.     pf->avg[PIXEL_8x16]  = x264_pixel_avg_8x16_neon;
  150.     pf->avg[PIXEL_8x8]   = x264_pixel_avg_8x8_neon;
  151.     pf->avg[PIXEL_8x4]   = x264_pixel_avg_8x4_neon;
  152.     pf->avg[PIXEL_4x8]   = x264_pixel_avg_4x8_neon;
  153.     pf->avg[PIXEL_4x4]   = x264_pixel_avg_4x4_neon;
  154.     pf->avg[PIXEL_4x2]   = x264_pixel_avg_4x2_neon;
  155.     pf->memcpy_aligned  = x264_memcpy_aligned_neon;
  156.     pf->memzero_aligned = x264_memzero_aligned_neon;
  157.     pf->mc_chroma = x264_mc_chroma_neon;
  158.     pf->mc_luma = mc_luma_neon;
  159.     pf->get_ref = get_ref_neon;
  160.     pf->hpel_filter = hpel_filter_neon;
  161.     pf->frame_init_lowres_core = x264_frame_init_lowres_core_neon;
  162. }