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

Audio

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * mc.c: h264 encoder library (Motion Compensation)
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 Laurent Aimar
  5.  * $Id: mc-c.c,v 1.5 2004/06/18 01:59:58 chenm001 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 <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include "common/common.h"
  27. /* NASM functions */
  28. extern void x264_pixel_avg_w4_mmxext( uint8_t *,  int, uint8_t *, int, uint8_t *, int, int );
  29. extern void x264_pixel_avg_w8_mmxext( uint8_t *,  int, uint8_t *, int, uint8_t *, int, int );
  30. extern void x264_pixel_avg_w16_mmxext( uint8_t *,  int, uint8_t *, int, uint8_t *, int, int );
  31. extern void x264_pixel_avg_w16_sse2( uint8_t *,  int, uint8_t *, int, uint8_t *, int, int );
  32. extern void x264_pixel_avg_weight_4x4_mmxext( uint8_t *, int, uint8_t *, int, int );
  33. extern void x264_pixel_avg_weight_w8_mmxext( uint8_t *, int, uint8_t *, int, int, int );
  34. extern void x264_pixel_avg_weight_w16_mmxext( uint8_t *, int, uint8_t *, int, int, int );
  35. extern void x264_mc_copy_w4_mmxext( uint8_t *, int, uint8_t *, int, int );
  36. extern void x264_mc_copy_w8_mmxext( uint8_t *, int, uint8_t *, int, int );
  37. extern void x264_mc_copy_w16_mmxext( uint8_t *, int, uint8_t *, int, int );
  38. extern void x264_mc_copy_w16_sse2( uint8_t *, int, uint8_t *, int, int );
  39. #define AVG(W,H) 
  40. static void x264_pixel_avg_ ## W ## x ## H ## _mmxext( uint8_t *dst, int i_dst, uint8_t *src, int i_src ) 
  41.     x264_pixel_avg_w ## W ## _mmxext( dst, i_dst, dst, i_dst, src, i_src, H ); 
  42. }
  43. AVG(16,16)
  44. AVG(16,8)
  45. AVG(8,16)
  46. AVG(8,8)
  47. AVG(8,4)
  48. AVG(4,8)
  49. AVG(4,4)
  50. AVG(4,2)
  51. #define AVG_WEIGHT(W,H) 
  52. void x264_pixel_avg_weight_ ## W ## x ## H ## _mmxext( uint8_t *dst, int i_dst, uint8_t *src, int i_src, int i_weight_dst ) 
  53.     x264_pixel_avg_weight_w ## W ## _mmxext( dst, i_dst, src, i_src, i_weight_dst, H ); 
  54. }
  55. AVG_WEIGHT(16,16)
  56. AVG_WEIGHT(16,8)
  57. AVG_WEIGHT(8,16)
  58. AVG_WEIGHT(8,8)
  59. AVG_WEIGHT(8,4)
  60. void mc_luma_mmx( uint8_t *src[4], int i_src_stride,
  61.               uint8_t *dst,    int i_dst_stride,
  62.               int mvx,int mvy,
  63.               int i_width, int i_height )
  64. {
  65.     uint8_t *src1, *src2;
  66.     int correction = (mvx&1) && (mvy&1) && ((mvx&2) ^ (mvy&2));
  67.     int hpel1x = mvx>>1;
  68.     int hpel1y = (mvy+1-correction)>>1;
  69.     int filter1 = (hpel1x & 1) + ( (hpel1y & 1) << 1 );
  70.     src1 = src[filter1] + (hpel1y >> 1) * i_src_stride + (hpel1x >> 1);
  71.     if ( (mvx|mvy) & 1 ) /* qpel interpolation needed */
  72.     {
  73.         int hpel2x = (mvx+1)>>1;
  74.         int hpel2y = (mvy+correction)>>1;
  75.         int filter2 = (hpel2x & 1) + ( (hpel2y & 1) <<1 );
  76.         src2 = src[filter2] + (hpel2y >> 1) * i_src_stride + (hpel2x >> 1);
  77.         switch(i_width) {
  78.         case 4:
  79.             x264_pixel_avg_w4_mmxext( dst, i_dst_stride, src1, i_src_stride,
  80.                           src2, i_src_stride, i_height );
  81.             break;
  82.         case 8:
  83.             x264_pixel_avg_w8_mmxext( dst, i_dst_stride, src1, i_src_stride,
  84.                           src2, i_src_stride, i_height );
  85.             break;
  86.         case 16:
  87.         default:
  88.             x264_pixel_avg_w16_mmxext(dst, i_dst_stride, src1, i_src_stride,
  89.                           src2, i_src_stride, i_height );
  90.         }
  91.     }
  92.     else
  93.     {
  94.         switch(i_width) {
  95.         case 4:
  96.             x264_mc_copy_w4_mmxext( dst, i_dst_stride, src1, i_src_stride, i_height );
  97.             break;
  98.         case 8:
  99.             x264_mc_copy_w8_mmxext( dst, i_dst_stride, src1, i_src_stride, i_height );
  100.             break;
  101.         case 16:
  102.             x264_mc_copy_w16_mmxext( dst, i_dst_stride, src1, i_src_stride, i_height );
  103.             break;
  104.         }
  105.     }
  106. }
  107. uint8_t *get_ref_mmx( uint8_t *src[4], int i_src_stride,
  108.                       uint8_t *dst,   int *i_dst_stride,
  109.                       int mvx,int mvy,
  110.                       int i_width, int i_height )
  111. {
  112.     uint8_t *src1, *src2;
  113.     int correction = (mvx&1) && (mvy&1) && ((mvx&2) ^ (mvy&2));
  114.     int hpel1x = mvx>>1;
  115.     int hpel1y = (mvy+1-correction)>>1;
  116.     int filter1 = (hpel1x & 1) + ( (hpel1y & 1) << 1 );
  117.     src1 = src[filter1] + (hpel1y >> 1) * i_src_stride + (hpel1x >> 1);
  118.     if ( (mvx|mvy) & 1 ) /* qpel interpolation needed */
  119.     {
  120.         int hpel2x = (mvx+1)>>1;
  121.         int hpel2y = (mvy+correction)>>1;
  122.         int filter2 = (hpel2x & 1) + ( (hpel2y & 1) <<1 );
  123.         src2 = src[filter2] + (hpel2y >> 1) * i_src_stride + (hpel2x >> 1);
  124.     
  125.         switch(i_width) {
  126.         case 4:
  127.             x264_pixel_avg_w4_mmxext( dst, *i_dst_stride, src1, i_src_stride,
  128.                           src2, i_src_stride, i_height );
  129.             break;
  130.         case 8:
  131.             x264_pixel_avg_w8_mmxext( dst, *i_dst_stride, src1, i_src_stride,
  132.                           src2, i_src_stride, i_height );
  133.             break;
  134.         case 16:
  135.         default:
  136.             x264_pixel_avg_w16_mmxext(dst, *i_dst_stride, src1, i_src_stride,
  137.                           src2, i_src_stride, i_height );
  138.         }
  139.         return dst;
  140.     }
  141.     else
  142.     {
  143.         *i_dst_stride = i_src_stride;
  144.         return src1;
  145.     }
  146. }
  147. void x264_mc_mmxext_init( x264_mc_functions_t *pf )
  148. {
  149.     pf->mc_luma   = mc_luma_mmx;
  150.     pf->get_ref   = get_ref_mmx;
  151.     pf->avg[PIXEL_16x16] = x264_pixel_avg_16x16_mmxext;
  152.     pf->avg[PIXEL_16x8]  = x264_pixel_avg_16x8_mmxext;
  153.     pf->avg[PIXEL_8x16]  = x264_pixel_avg_8x16_mmxext;
  154.     pf->avg[PIXEL_8x8]   = x264_pixel_avg_8x8_mmxext;
  155.     pf->avg[PIXEL_8x4]   = x264_pixel_avg_8x4_mmxext;
  156.     pf->avg[PIXEL_4x8]   = x264_pixel_avg_4x8_mmxext;
  157.     pf->avg[PIXEL_4x4]   = x264_pixel_avg_4x4_mmxext;
  158.     pf->avg[PIXEL_4x2]   = x264_pixel_avg_4x2_mmxext;
  159.     
  160.     pf->avg_weight[PIXEL_16x16] = x264_pixel_avg_weight_16x16_mmxext;
  161.     pf->avg_weight[PIXEL_16x8]  = x264_pixel_avg_weight_16x8_mmxext;
  162.     pf->avg_weight[PIXEL_8x16]  = x264_pixel_avg_weight_8x16_mmxext;
  163.     pf->avg_weight[PIXEL_8x8]   = x264_pixel_avg_weight_8x8_mmxext;
  164.     pf->avg_weight[PIXEL_8x4]   = x264_pixel_avg_weight_8x4_mmxext;
  165.     pf->avg_weight[PIXEL_4x4]   = x264_pixel_avg_weight_4x4_mmxext;
  166.     // avg_weight_4x8 is rare and 4x2 is not used
  167.     pf->copy[PIXEL_16x16] = x264_mc_copy_w16_mmxext;
  168.     pf->copy[PIXEL_8x8]   = x264_mc_copy_w8_mmxext;
  169.     pf->copy[PIXEL_4x4]   = x264_mc_copy_w4_mmxext;
  170. }
  171. void x264_mc_sse2_init( x264_mc_functions_t *pf )
  172. {
  173.     /* todo: use sse2 */
  174.     pf->mc_luma   = mc_luma_mmx;
  175.     pf->get_ref   = get_ref_mmx;
  176. }