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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * dct.c: h264 encoder library
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2008 x264 project
  5.  *
  6.  * Authors: Loren Merritt <lorenm@u.washington.edu>
  7.  *          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., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. #include "common.h"
  24. #ifdef HAVE_MMX
  25. #   include "x86/dct.h"
  26. #endif
  27. #ifdef ARCH_PPC
  28. #   include "ppc/dct.h"
  29. #endif
  30. #ifdef ARCH_ARM
  31. #   include "arm/dct.h"
  32. #endif
  33. int x264_dct4_weight2_zigzag[2][16];
  34. int x264_dct8_weight2_zigzag[2][64];
  35. /*
  36.  * XXX For all dct dc : input could be equal to output so ...
  37.  */
  38. static void dct4x4dc( int16_t d[4][4] )
  39. {
  40.     int16_t tmp[4][4];
  41.     int s01, s23;
  42.     int d01, d23;
  43.     int i;
  44.     for( i = 0; i < 4; i++ )
  45.     {
  46.         s01 = d[i][0] + d[i][1];
  47.         d01 = d[i][0] - d[i][1];
  48.         s23 = d[i][2] + d[i][3];
  49.         d23 = d[i][2] - d[i][3];
  50.         tmp[0][i] = s01 + s23;
  51.         tmp[1][i] = s01 - s23;
  52.         tmp[2][i] = d01 - d23;
  53.         tmp[3][i] = d01 + d23;
  54.     }
  55.     for( i = 0; i < 4; i++ )
  56.     {
  57.         s01 = tmp[i][0] + tmp[i][1];
  58.         d01 = tmp[i][0] - tmp[i][1];
  59.         s23 = tmp[i][2] + tmp[i][3];
  60.         d23 = tmp[i][2] - tmp[i][3];
  61.         d[i][0] = ( s01 + s23 + 1 ) >> 1;
  62.         d[i][1] = ( s01 - s23 + 1 ) >> 1;
  63.         d[i][2] = ( d01 - d23 + 1 ) >> 1;
  64.         d[i][3] = ( d01 + d23 + 1 ) >> 1;
  65.     }
  66. }
  67. static void idct4x4dc( int16_t d[4][4] )
  68. {
  69.     int16_t tmp[4][4];
  70.     int s01, s23;
  71.     int d01, d23;
  72.     int i;
  73.     for( i = 0; i < 4; i++ )
  74.     {
  75.         s01 = d[i][0] + d[i][1];
  76.         d01 = d[i][0] - d[i][1];
  77.         s23 = d[i][2] + d[i][3];
  78.         d23 = d[i][2] - d[i][3];
  79.         tmp[0][i] = s01 + s23;
  80.         tmp[1][i] = s01 - s23;
  81.         tmp[2][i] = d01 - d23;
  82.         tmp[3][i] = d01 + d23;
  83.     }
  84.     for( i = 0; i < 4; i++ )
  85.     {
  86.         s01 = tmp[i][0] + tmp[i][1];
  87.         d01 = tmp[i][0] - tmp[i][1];
  88.         s23 = tmp[i][2] + tmp[i][3];
  89.         d23 = tmp[i][2] - tmp[i][3];
  90.         d[i][0] = s01 + s23;
  91.         d[i][1] = s01 - s23;
  92.         d[i][2] = d01 - d23;
  93.         d[i][3] = d01 + d23;
  94.     }
  95. }
  96. static inline void pixel_sub_wxh( int16_t *diff, int i_size,
  97.                                   uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
  98. {
  99.     int y, x;
  100.     for( y = 0; y < i_size; y++ )
  101.     {
  102.         for( x = 0; x < i_size; x++ )
  103.         {
  104.             diff[x + y*i_size] = pix1[x] - pix2[x];
  105.         }
  106.         pix1 += i_pix1;
  107.         pix2 += i_pix2;
  108.     }
  109. }
  110. static void sub4x4_dct( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
  111. {
  112.     int16_t d[4][4];
  113.     int16_t tmp[4][4];
  114.     int i;
  115.     pixel_sub_wxh( (int16_t*)d, 4, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );
  116.     for( i = 0; i < 4; i++ )
  117.     {
  118.         const int s03 = d[i][0] + d[i][3];
  119.         const int s12 = d[i][1] + d[i][2];
  120.         const int d03 = d[i][0] - d[i][3];
  121.         const int d12 = d[i][1] - d[i][2];
  122.         tmp[0][i] =   s03 +   s12;
  123.         tmp[1][i] = 2*d03 +   d12;
  124.         tmp[2][i] =   s03 -   s12;
  125.         tmp[3][i] =   d03 - 2*d12;
  126.     }
  127.     for( i = 0; i < 4; i++ )
  128.     {
  129.         const int s03 = tmp[i][0] + tmp[i][3];
  130.         const int s12 = tmp[i][1] + tmp[i][2];
  131.         const int d03 = tmp[i][0] - tmp[i][3];
  132.         const int d12 = tmp[i][1] - tmp[i][2];
  133.         dct[i][0] =   s03 +   s12;
  134.         dct[i][1] = 2*d03 +   d12;
  135.         dct[i][2] =   s03 -   s12;
  136.         dct[i][3] =   d03 - 2*d12;
  137.     }
  138. }
  139. static void sub8x8_dct( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
  140. {
  141.     sub4x4_dct( dct[0], &pix1[0], &pix2[0] );
  142.     sub4x4_dct( dct[1], &pix1[4], &pix2[4] );
  143.     sub4x4_dct( dct[2], &pix1[4*FENC_STRIDE+0], &pix2[4*FDEC_STRIDE+0] );
  144.     sub4x4_dct( dct[3], &pix1[4*FENC_STRIDE+4], &pix2[4*FDEC_STRIDE+4] );
  145. }
  146. static void sub16x16_dct( int16_t dct[16][4][4], uint8_t *pix1, uint8_t *pix2 )
  147. {
  148.     sub8x8_dct( &dct[ 0], &pix1[0], &pix2[0] );
  149.     sub8x8_dct( &dct[ 4], &pix1[8], &pix2[8] );
  150.     sub8x8_dct( &dct[ 8], &pix1[8*FENC_STRIDE+0], &pix2[8*FDEC_STRIDE+0] );
  151.     sub8x8_dct( &dct[12], &pix1[8*FENC_STRIDE+8], &pix2[8*FDEC_STRIDE+8] );
  152. }
  153. static int sub4x4_dct_dc( uint8_t *pix1, uint8_t *pix2 )
  154. {
  155.     int16_t d[4][4];
  156.     int sum = 0;
  157.     pixel_sub_wxh( (int16_t*)d, 4, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );
  158.     sum += d[0][0] + d[0][1] + d[0][2] + d[0][3];
  159.     sum += d[1][0] + d[1][1] + d[1][2] + d[1][3];
  160.     sum += d[2][0] + d[2][1] + d[2][2] + d[2][3];
  161.     sum += d[3][0] + d[3][1] + d[3][2] + d[3][3];
  162.     return sum;
  163. }
  164. static void sub8x8_dct_dc( int16_t dct[2][2], uint8_t *pix1, uint8_t *pix2 )
  165. {
  166.     dct[0][0] = sub4x4_dct_dc( &pix1[0], &pix2[0] );
  167.     dct[0][1] = sub4x4_dct_dc( &pix1[4], &pix2[4] );
  168.     dct[1][0] = sub4x4_dct_dc( &pix1[4*FENC_STRIDE+0], &pix2[4*FDEC_STRIDE+0] );
  169.     dct[1][1] = sub4x4_dct_dc( &pix1[4*FENC_STRIDE+4], &pix2[4*FDEC_STRIDE+4] );
  170. }
  171. static void add4x4_idct( uint8_t *p_dst, int16_t dct[4][4] )
  172. {
  173.     int16_t d[4][4];
  174.     int16_t tmp[4][4];
  175.     int x, y;
  176.     int i;
  177.     for( i = 0; i < 4; i++ )
  178.     {
  179.         const int s02 =  dct[0][i]     +  dct[2][i];
  180.         const int d02 =  dct[0][i]     -  dct[2][i];
  181.         const int s13 =  dct[1][i]     + (dct[3][i]>>1);
  182.         const int d13 = (dct[1][i]>>1) -  dct[3][i];
  183.         tmp[i][0] = s02 + s13;
  184.         tmp[i][1] = d02 + d13;
  185.         tmp[i][2] = d02 - d13;
  186.         tmp[i][3] = s02 - s13;
  187.     }
  188.     for( i = 0; i < 4; i++ )
  189.     {
  190.         const int s02 =  tmp[0][i]     +  tmp[2][i];
  191.         const int d02 =  tmp[0][i]     -  tmp[2][i];
  192.         const int s13 =  tmp[1][i]     + (tmp[3][i]>>1);
  193.         const int d13 = (tmp[1][i]>>1) -  tmp[3][i];
  194.         d[0][i] = ( s02 + s13 + 32 ) >> 6;
  195.         d[1][i] = ( d02 + d13 + 32 ) >> 6;
  196.         d[2][i] = ( d02 - d13 + 32 ) >> 6;
  197.         d[3][i] = ( s02 - s13 + 32 ) >> 6;
  198.     }
  199.     for( y = 0; y < 4; y++ )
  200.     {
  201.         for( x = 0; x < 4; x++ )
  202.         {
  203.             p_dst[x] = x264_clip_uint8( p_dst[x] + d[y][x] );
  204.         }
  205.         p_dst += FDEC_STRIDE;
  206.     }
  207. }
  208. static void add8x8_idct( uint8_t *p_dst, int16_t dct[4][4][4] )
  209. {
  210.     add4x4_idct( &p_dst[0],               dct[0] );
  211.     add4x4_idct( &p_dst[4],               dct[1] );
  212.     add4x4_idct( &p_dst[4*FDEC_STRIDE+0], dct[2] );
  213.     add4x4_idct( &p_dst[4*FDEC_STRIDE+4], dct[3] );
  214. }
  215. static void add16x16_idct( uint8_t *p_dst, int16_t dct[16][4][4] )
  216. {
  217.     add8x8_idct( &p_dst[0],               &dct[0] );
  218.     add8x8_idct( &p_dst[8],               &dct[4] );
  219.     add8x8_idct( &p_dst[8*FDEC_STRIDE+0], &dct[8] );
  220.     add8x8_idct( &p_dst[8*FDEC_STRIDE+8], &dct[12] );
  221. }
  222. /****************************************************************************
  223.  * 8x8 transform:
  224.  ****************************************************************************/
  225. #define DCT8_1D {
  226.     const int s07 = SRC(0) + SRC(7);
  227.     const int s16 = SRC(1) + SRC(6);
  228.     const int s25 = SRC(2) + SRC(5);
  229.     const int s34 = SRC(3) + SRC(4);
  230.     const int a0 = s07 + s34;
  231.     const int a1 = s16 + s25;
  232.     const int a2 = s07 - s34;
  233.     const int a3 = s16 - s25;
  234.     const int d07 = SRC(0) - SRC(7);
  235.     const int d16 = SRC(1) - SRC(6);
  236.     const int d25 = SRC(2) - SRC(5);
  237.     const int d34 = SRC(3) - SRC(4);
  238.     const int a4 = d16 + d25 + (d07 + (d07>>1));
  239.     const int a5 = d07 - d34 - (d25 + (d25>>1));
  240.     const int a6 = d07 + d34 - (d16 + (d16>>1));
  241.     const int a7 = d16 - d25 + (d34 + (d34>>1));
  242.     DST(0) =  a0 + a1     ;
  243.     DST(1) =  a4 + (a7>>2);
  244.     DST(2) =  a2 + (a3>>1);
  245.     DST(3) =  a5 + (a6>>2);
  246.     DST(4) =  a0 - a1     ;
  247.     DST(5) =  a6 - (a5>>2);
  248.     DST(6) = (a2>>1) - a3 ;
  249.     DST(7) = (a4>>2) - a7 ;
  250. }
  251. static void sub8x8_dct8( int16_t dct[8][8], uint8_t *pix1, uint8_t *pix2 )
  252. {
  253.     int i;
  254.     int16_t tmp[8][8];
  255.     pixel_sub_wxh( (int16_t*)tmp, 8, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );
  256. #define SRC(x) tmp[x][i]
  257. #define DST(x) tmp[x][i]
  258.     for( i = 0; i < 8; i++ )
  259.         DCT8_1D
  260. #undef SRC
  261. #undef DST
  262. #define SRC(x) tmp[i][x]
  263. #define DST(x) dct[x][i]
  264.     for( i = 0; i < 8; i++ )
  265.         DCT8_1D
  266. #undef SRC
  267. #undef DST
  268. }
  269. static void sub16x16_dct8( int16_t dct[4][8][8], uint8_t *pix1, uint8_t *pix2 )
  270. {
  271.     sub8x8_dct8( dct[0], &pix1[0],               &pix2[0] );
  272.     sub8x8_dct8( dct[1], &pix1[8],               &pix2[8] );
  273.     sub8x8_dct8( dct[2], &pix1[8*FENC_STRIDE+0], &pix2[8*FDEC_STRIDE+0] );
  274.     sub8x8_dct8( dct[3], &pix1[8*FENC_STRIDE+8], &pix2[8*FDEC_STRIDE+8] );
  275. }
  276. #define IDCT8_1D {
  277.     const int a0 =  SRC(0) + SRC(4);
  278.     const int a2 =  SRC(0) - SRC(4);
  279.     const int a4 = (SRC(2)>>1) - SRC(6);
  280.     const int a6 = (SRC(6)>>1) + SRC(2);
  281.     const int b0 = a0 + a6;
  282.     const int b2 = a2 + a4;
  283.     const int b4 = a2 - a4;
  284.     const int b6 = a0 - a6;
  285.     const int a1 = -SRC(3) + SRC(5) - SRC(7) - (SRC(7)>>1);
  286.     const int a3 =  SRC(1) + SRC(7) - SRC(3) - (SRC(3)>>1);
  287.     const int a5 = -SRC(1) + SRC(7) + SRC(5) + (SRC(5)>>1);
  288.     const int a7 =  SRC(3) + SRC(5) + SRC(1) + (SRC(1)>>1);
  289.     const int b1 = (a7>>2) + a1;
  290.     const int b3 =  a3 + (a5>>2);
  291.     const int b5 = (a3>>2) - a5;
  292.     const int b7 =  a7 - (a1>>2);
  293.     DST(0, b0 + b7);
  294.     DST(1, b2 + b5);
  295.     DST(2, b4 + b3);
  296.     DST(3, b6 + b1);
  297.     DST(4, b6 - b1);
  298.     DST(5, b4 - b3);
  299.     DST(6, b2 - b5);
  300.     DST(7, b0 - b7);
  301. }
  302. static void add8x8_idct8( uint8_t *dst, int16_t dct[8][8] )
  303. {
  304.     int i;
  305.     dct[0][0] += 32; // rounding for the >>6 at the end
  306. #define SRC(x)     dct[x][i]
  307. #define DST(x,rhs) dct[x][i] = (rhs)
  308.     for( i = 0; i < 8; i++ )
  309.         IDCT8_1D
  310. #undef SRC
  311. #undef DST
  312. #define SRC(x)     dct[i][x]
  313. #define DST(x,rhs) dst[i + x*FDEC_STRIDE] = x264_clip_uint8( dst[i + x*FDEC_STRIDE] + ((rhs) >> 6) );
  314.     for( i = 0; i < 8; i++ )
  315.         IDCT8_1D
  316. #undef SRC
  317. #undef DST
  318. }
  319. static void add16x16_idct8( uint8_t *dst, int16_t dct[4][8][8] )
  320. {
  321.     add8x8_idct8( &dst[0],               dct[0] );
  322.     add8x8_idct8( &dst[8],               dct[1] );
  323.     add8x8_idct8( &dst[8*FDEC_STRIDE+0], dct[2] );
  324.     add8x8_idct8( &dst[8*FDEC_STRIDE+8], dct[3] );
  325. }
  326. static void inline add4x4_idct_dc( uint8_t *p_dst, int16_t dc )
  327. {
  328.     int i;
  329.     dc = (dc + 32) >> 6;
  330.     for( i = 0; i < 4; i++, p_dst += FDEC_STRIDE )
  331.     {
  332.         p_dst[0] = x264_clip_uint8( p_dst[0] + dc );
  333.         p_dst[1] = x264_clip_uint8( p_dst[1] + dc );
  334.         p_dst[2] = x264_clip_uint8( p_dst[2] + dc );
  335.         p_dst[3] = x264_clip_uint8( p_dst[3] + dc );
  336.     }
  337. }
  338. static void add8x8_idct_dc( uint8_t *p_dst, int16_t dct[2][2] )
  339. {
  340.     add4x4_idct_dc( &p_dst[0],               dct[0][0] );
  341.     add4x4_idct_dc( &p_dst[4],               dct[0][1] );
  342.     add4x4_idct_dc( &p_dst[4*FDEC_STRIDE+0], dct[1][0] );
  343.     add4x4_idct_dc( &p_dst[4*FDEC_STRIDE+4], dct[1][1] );
  344. }
  345. static void add16x16_idct_dc( uint8_t *p_dst, int16_t dct[4][4] )
  346. {
  347.     int i;
  348.     for( i = 0; i < 4; i++, p_dst += 4*FDEC_STRIDE )
  349.     {
  350.         add4x4_idct_dc( &p_dst[ 0], dct[i][0] );
  351.         add4x4_idct_dc( &p_dst[ 4], dct[i][1] );
  352.         add4x4_idct_dc( &p_dst[ 8], dct[i][2] );
  353.         add4x4_idct_dc( &p_dst[12], dct[i][3] );
  354.     }
  355. }
  356. /****************************************************************************
  357.  * x264_dct_init:
  358.  ****************************************************************************/
  359. void x264_dct_init( int cpu, x264_dct_function_t *dctf )
  360. {
  361.     dctf->sub4x4_dct    = sub4x4_dct;
  362.     dctf->add4x4_idct   = add4x4_idct;
  363.     dctf->sub8x8_dct    = sub8x8_dct;
  364.     dctf->sub8x8_dct_dc = sub8x8_dct_dc;
  365.     dctf->add8x8_idct   = add8x8_idct;
  366.     dctf->add8x8_idct_dc = add8x8_idct_dc;
  367.     dctf->sub16x16_dct  = sub16x16_dct;
  368.     dctf->add16x16_idct = add16x16_idct;
  369.     dctf->add16x16_idct_dc = add16x16_idct_dc;
  370.     dctf->sub8x8_dct8   = sub8x8_dct8;
  371.     dctf->add8x8_idct8  = add8x8_idct8;
  372.     dctf->sub16x16_dct8  = sub16x16_dct8;
  373.     dctf->add16x16_idct8 = add16x16_idct8;
  374.     dctf->dct4x4dc  = dct4x4dc;
  375.     dctf->idct4x4dc = idct4x4dc;
  376. #ifdef HAVE_MMX
  377.     if( cpu&X264_CPU_MMX )
  378.     {
  379.         dctf->sub4x4_dct    = x264_sub4x4_dct_mmx;
  380.         dctf->add4x4_idct   = x264_add4x4_idct_mmx;
  381.         dctf->add8x8_idct_dc = x264_add8x8_idct_dc_mmx;
  382.         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_mmx;
  383.         dctf->dct4x4dc      = x264_dct4x4dc_mmx;
  384.         dctf->idct4x4dc     = x264_idct4x4dc_mmx;
  385.         dctf->sub8x8_dct_dc = x264_sub8x8_dct_dc_mmxext;
  386. #ifndef ARCH_X86_64
  387.         dctf->sub8x8_dct    = x264_sub8x8_dct_mmx;
  388.         dctf->sub16x16_dct  = x264_sub16x16_dct_mmx;
  389.         dctf->add8x8_idct   = x264_add8x8_idct_mmx;
  390.         dctf->add16x16_idct = x264_add16x16_idct_mmx;
  391.         dctf->sub8x8_dct8   = x264_sub8x8_dct8_mmx;
  392.         dctf->sub16x16_dct8 = x264_sub16x16_dct8_mmx;
  393.         dctf->add8x8_idct8  = x264_add8x8_idct8_mmx;
  394.         dctf->add16x16_idct8= x264_add16x16_idct8_mmx;
  395. #endif
  396.     }
  397.     if( cpu&X264_CPU_SSE2 )
  398.     {
  399.         dctf->sub8x8_dct8   = x264_sub8x8_dct8_sse2;
  400.         dctf->sub16x16_dct8 = x264_sub16x16_dct8_sse2;
  401.         dctf->sub8x8_dct_dc = x264_sub8x8_dct_dc_sse2;
  402.         dctf->add8x8_idct8  = x264_add8x8_idct8_sse2;
  403.         dctf->add16x16_idct8= x264_add16x16_idct8_sse2;
  404.         dctf->sub8x8_dct    = x264_sub8x8_dct_sse2;
  405.         dctf->sub16x16_dct  = x264_sub16x16_dct_sse2;
  406.         dctf->add8x8_idct   = x264_add8x8_idct_sse2;
  407.         dctf->add16x16_idct = x264_add16x16_idct_sse2;
  408.         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_sse2;
  409.     }
  410.     if( cpu&X264_CPU_SSSE3 )
  411.     {
  412.         dctf->sub4x4_dct    = x264_sub4x4_dct_ssse3;
  413.         dctf->sub8x8_dct    = x264_sub8x8_dct_ssse3;
  414.         dctf->sub16x16_dct  = x264_sub16x16_dct_ssse3;
  415.         dctf->sub8x8_dct8   = x264_sub8x8_dct8_ssse3;
  416.         dctf->sub16x16_dct8 = x264_sub16x16_dct8_ssse3;
  417.         dctf->add8x8_idct_dc = x264_add8x8_idct_dc_ssse3;
  418.         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_ssse3;
  419.     }
  420.     if( cpu&X264_CPU_SSE4 )
  421.         dctf->add4x4_idct   = x264_add4x4_idct_sse4;
  422. #endif //HAVE_MMX
  423. #ifdef ARCH_PPC
  424.     if( cpu&X264_CPU_ALTIVEC )
  425.     {
  426.         dctf->sub4x4_dct    = x264_sub4x4_dct_altivec;
  427.         dctf->sub8x8_dct    = x264_sub8x8_dct_altivec;
  428.         dctf->sub16x16_dct  = x264_sub16x16_dct_altivec;
  429.         dctf->add4x4_idct   = x264_add4x4_idct_altivec;
  430.         dctf->add8x8_idct   = x264_add8x8_idct_altivec;
  431.         dctf->add16x16_idct = x264_add16x16_idct_altivec;
  432.         dctf->sub8x8_dct8   = x264_sub8x8_dct8_altivec;
  433.         dctf->sub16x16_dct8 = x264_sub16x16_dct8_altivec;
  434.         dctf->add8x8_idct8  = x264_add8x8_idct8_altivec;
  435.         dctf->add16x16_idct8= x264_add16x16_idct8_altivec;
  436.     }
  437. #endif
  438. #ifdef HAVE_ARMV6
  439.     if( cpu&X264_CPU_NEON )
  440.     {
  441.         dctf->sub4x4_dct    = x264_sub4x4_dct_neon;
  442.         dctf->sub8x8_dct    = x264_sub8x8_dct_neon;
  443.         dctf->sub16x16_dct  = x264_sub16x16_dct_neon;
  444.         dctf->add8x8_idct_dc = x264_add8x8_idct_dc_neon;
  445.         dctf->add16x16_idct_dc = x264_add16x16_idct_dc_neon;
  446.         dctf->sub8x8_dct_dc = x264_sub8x8_dct_dc_neon;
  447.         dctf->dct4x4dc      = x264_dct4x4dc_neon;
  448.         dctf->idct4x4dc     = x264_idct4x4dc_neon;
  449.         dctf->add4x4_idct   = x264_add4x4_idct_neon;
  450.         dctf->add8x8_idct   = x264_add8x8_idct_neon;
  451.         dctf->add16x16_idct = x264_add16x16_idct_neon;
  452.         dctf->sub8x8_dct8   = x264_sub8x8_dct8_neon;
  453.         dctf->sub16x16_dct8 = x264_sub16x16_dct8_neon;
  454.         dctf->add8x8_idct8  = x264_add8x8_idct8_neon;
  455.         dctf->add16x16_idct8= x264_add16x16_idct8_neon;
  456.     }
  457. #endif
  458. }
  459. void x264_dct_init_weights( void )
  460. {
  461.     int i, j;
  462.     for( j=0; j<2; j++ )
  463.     {
  464.         for( i=0; i<16; i++ )
  465.             x264_dct4_weight2_zigzag[j][i] = x264_dct4_weight2_tab[ x264_zigzag_scan4[j][i] ];
  466.         for( i=0; i<64; i++ )
  467.             x264_dct8_weight2_zigzag[j][i] = x264_dct8_weight2_tab[ x264_zigzag_scan8[j][i] ];
  468.     }
  469. }
  470. // gcc pessimizes multi-dimensional arrays here, even with constant indices
  471. #define ZIG(i,y,x) level[i] = dct[0][x*8+y];
  472. #define ZIGZAG8_FRAME
  473.     ZIG( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)
  474.     ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)
  475.     ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,4,0) ZIG(11,3,1)
  476.     ZIG(12,2,2) ZIG(13,1,3) ZIG(14,0,4) ZIG(15,0,5)
  477.     ZIG(16,1,4) ZIG(17,2,3) ZIG(18,3,2) ZIG(19,4,1)
  478.     ZIG(20,5,0) ZIG(21,6,0) ZIG(22,5,1) ZIG(23,4,2)
  479.     ZIG(24,3,3) ZIG(25,2,4) ZIG(26,1,5) ZIG(27,0,6)
  480.     ZIG(28,0,7) ZIG(29,1,6) ZIG(30,2,5) ZIG(31,3,4)
  481.     ZIG(32,4,3) ZIG(33,5,2) ZIG(34,6,1) ZIG(35,7,0)
  482.     ZIG(36,7,1) ZIG(37,6,2) ZIG(38,5,3) ZIG(39,4,4)
  483.     ZIG(40,3,5) ZIG(41,2,6) ZIG(42,1,7) ZIG(43,2,7)
  484.     ZIG(44,3,6) ZIG(45,4,5) ZIG(46,5,4) ZIG(47,6,3)
  485.     ZIG(48,7,2) ZIG(49,7,3) ZIG(50,6,4) ZIG(51,5,5)
  486.     ZIG(52,4,6) ZIG(53,3,7) ZIG(54,4,7) ZIG(55,5,6)
  487.     ZIG(56,6,5) ZIG(57,7,4) ZIG(58,7,5) ZIG(59,6,6)
  488.     ZIG(60,5,7) ZIG(61,6,7) ZIG(62,7,6) ZIG(63,7,7)
  489. #define ZIGZAG8_FIELD
  490.     ZIG( 0,0,0) ZIG( 1,1,0) ZIG( 2,2,0) ZIG( 3,0,1)
  491.     ZIG( 4,1,1) ZIG( 5,3,0) ZIG( 6,4,0) ZIG( 7,2,1)
  492.     ZIG( 8,0,2) ZIG( 9,3,1) ZIG(10,5,0) ZIG(11,6,0)
  493.     ZIG(12,7,0) ZIG(13,4,1) ZIG(14,1,2) ZIG(15,0,3)
  494.     ZIG(16,2,2) ZIG(17,5,1) ZIG(18,6,1) ZIG(19,7,1)
  495.     ZIG(20,3,2) ZIG(21,1,3) ZIG(22,0,4) ZIG(23,2,3)
  496.     ZIG(24,4,2) ZIG(25,5,2) ZIG(26,6,2) ZIG(27,7,2)
  497.     ZIG(28,3,3) ZIG(29,1,4) ZIG(30,0,5) ZIG(31,2,4)
  498.     ZIG(32,4,3) ZIG(33,5,3) ZIG(34,6,3) ZIG(35,7,3)
  499.     ZIG(36,3,4) ZIG(37,1,5) ZIG(38,0,6) ZIG(39,2,5)
  500.     ZIG(40,4,4) ZIG(41,5,4) ZIG(42,6,4) ZIG(43,7,4)
  501.     ZIG(44,3,5) ZIG(45,1,6) ZIG(46,2,6) ZIG(47,4,5)
  502.     ZIG(48,5,5) ZIG(49,6,5) ZIG(50,7,5) ZIG(51,3,6)
  503.     ZIG(52,0,7) ZIG(53,1,7) ZIG(54,4,6) ZIG(55,5,6)
  504.     ZIG(56,6,6) ZIG(57,7,6) ZIG(58,2,7) ZIG(59,3,7)
  505.     ZIG(60,4,7) ZIG(61,5,7) ZIG(62,6,7) ZIG(63,7,7)
  506. #define ZIGZAG4_FRAME
  507.     ZIGDC( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)
  508.     ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)
  509.     ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,3,1) ZIG(11,2,2)
  510.     ZIG(12,1,3) ZIG(13,2,3) ZIG(14,3,2) ZIG(15,3,3)
  511. #define ZIGZAG4_FIELD
  512.     ZIGDC( 0,0,0) ZIG( 1,1,0) ZIG( 2,0,1) ZIG( 3,2,0)
  513.     ZIG( 4,3,0) ZIG( 5,1,1) ZIG( 6,2,1) ZIG( 7,3,1)
  514.     ZIG( 8,0,2) ZIG( 9,1,2) ZIG(10,2,2) ZIG(11,3,2)
  515.     ZIG(12,0,3) ZIG(13,1,3) ZIG(14,2,3) ZIG(15,3,3)
  516. static void zigzag_scan_8x8_frame( int16_t level[64], int16_t dct[8][8] )
  517. {
  518.     ZIGZAG8_FRAME
  519. }
  520. static void zigzag_scan_8x8_field( int16_t level[64], int16_t dct[8][8] )
  521. {
  522.     ZIGZAG8_FIELD
  523. }
  524. #undef ZIG
  525. #define ZIG(i,y,x) level[i] = dct[0][x*4+y];
  526. #define ZIGDC(i,y,x) ZIG(i,y,x)
  527. static void zigzag_scan_4x4_frame( int16_t level[16], int16_t dct[4][4] )
  528. {
  529.     ZIGZAG4_FRAME
  530. }
  531. static void zigzag_scan_4x4_field( int16_t level[16], int16_t dct[4][4] )
  532. {
  533.     *(uint32_t*)level = *(uint32_t*)dct;
  534.     ZIG(2,0,1) ZIG(3,2,0) ZIG(4,3,0) ZIG(5,1,1)
  535.     *(uint32_t*)(level+6) = *(uint32_t*)(*dct+6);
  536.     *(uint64_t*)(level+8) = *(uint64_t*)(*dct+8);
  537.     *(uint64_t*)(level+12) = *(uint64_t*)(*dct+12);
  538. }
  539. #undef ZIG
  540. #define ZIG(i,y,x) {
  541.     int oe = x+y*FENC_STRIDE;
  542.     int od = x+y*FDEC_STRIDE;
  543.     level[i] = p_src[oe] - p_dst[od];
  544.     nz |= level[i];
  545. }
  546. #define COPY4x4
  547.     *(uint32_t*)(p_dst+0*FDEC_STRIDE) = *(uint32_t*)(p_src+0*FENC_STRIDE);
  548.     *(uint32_t*)(p_dst+1*FDEC_STRIDE) = *(uint32_t*)(p_src+1*FENC_STRIDE);
  549.     *(uint32_t*)(p_dst+2*FDEC_STRIDE) = *(uint32_t*)(p_src+2*FENC_STRIDE);
  550.     *(uint32_t*)(p_dst+3*FDEC_STRIDE) = *(uint32_t*)(p_src+3*FENC_STRIDE);
  551. #define COPY8x8
  552.     *(uint64_t*)(p_dst+0*FDEC_STRIDE) = *(uint64_t*)(p_src+0*FENC_STRIDE);
  553.     *(uint64_t*)(p_dst+1*FDEC_STRIDE) = *(uint64_t*)(p_src+1*FENC_STRIDE);
  554.     *(uint64_t*)(p_dst+2*FDEC_STRIDE) = *(uint64_t*)(p_src+2*FENC_STRIDE);
  555.     *(uint64_t*)(p_dst+3*FDEC_STRIDE) = *(uint64_t*)(p_src+3*FENC_STRIDE);
  556.     *(uint64_t*)(p_dst+4*FDEC_STRIDE) = *(uint64_t*)(p_src+4*FENC_STRIDE);
  557.     *(uint64_t*)(p_dst+5*FDEC_STRIDE) = *(uint64_t*)(p_src+5*FENC_STRIDE);
  558.     *(uint64_t*)(p_dst+6*FDEC_STRIDE) = *(uint64_t*)(p_src+6*FENC_STRIDE);
  559.     *(uint64_t*)(p_dst+7*FDEC_STRIDE) = *(uint64_t*)(p_src+7*FENC_STRIDE);
  560. static int zigzag_sub_4x4_frame( int16_t level[16], const uint8_t *p_src, uint8_t *p_dst )
  561. {
  562.     int nz = 0;
  563.     ZIGZAG4_FRAME
  564.     COPY4x4
  565.     return !!nz;
  566. }
  567. static int zigzag_sub_4x4_field( int16_t level[16], const uint8_t *p_src, uint8_t *p_dst )
  568. {
  569.     int nz = 0;
  570.     ZIGZAG4_FIELD
  571.     COPY4x4
  572.     return !!nz;
  573. }
  574. #undef ZIGDC
  575. #define ZIGDC(i,y,x) {
  576.     int oe = x+y*FENC_STRIDE;
  577.     int od = x+y*FDEC_STRIDE;
  578.     *dc = p_src[oe] - p_dst[od];
  579.     level[0] = 0;
  580. }
  581. static int zigzag_sub_4x4ac_frame( int16_t level[16], const uint8_t *p_src, uint8_t *p_dst, int16_t *dc )
  582. {
  583.     int nz = 0;
  584.     ZIGZAG4_FRAME
  585.     COPY4x4
  586.     return !!nz;
  587. }
  588. static int zigzag_sub_4x4ac_field( int16_t level[16], const uint8_t *p_src, uint8_t *p_dst, int16_t *dc )
  589. {
  590.     int nz = 0;
  591.     ZIGZAG4_FIELD
  592.     COPY4x4
  593.     return !!nz;
  594. }
  595. static int zigzag_sub_8x8_frame( int16_t level[64], const uint8_t *p_src, uint8_t *p_dst )
  596. {
  597.     int nz = 0;
  598.     ZIGZAG8_FRAME
  599.     COPY8x8
  600.     return !!nz;
  601. }
  602. static int zigzag_sub_8x8_field( int16_t level[64], const uint8_t *p_src, uint8_t *p_dst )
  603. {
  604.     int nz = 0;
  605.     ZIGZAG8_FIELD
  606.     COPY8x8
  607.     return !!nz;
  608. }
  609. #undef ZIG
  610. #undef COPY4x4
  611. static void zigzag_interleave_8x8_cavlc( int16_t *dst, int16_t *src, uint8_t *nnz )
  612. {
  613.     int i,j;
  614.     for( i=0; i<4; i++ )
  615.     {
  616.         int nz = 0;
  617.         for( j=0; j<16; j++ )
  618.         {
  619.             nz |= src[i+j*4];
  620.             dst[i*16+j] = src[i+j*4];
  621.         }
  622.         nnz[(i&1) + (i>>1)*8] = !!nz;
  623.     }
  624. }
  625. void x264_zigzag_init( int cpu, x264_zigzag_function_t *pf, int b_interlaced )
  626. {
  627.     if( b_interlaced )
  628.     {
  629.         pf->scan_8x8   = zigzag_scan_8x8_field;
  630.         pf->scan_4x4   = zigzag_scan_4x4_field;
  631.         pf->sub_8x8    = zigzag_sub_8x8_field;
  632.         pf->sub_4x4    = zigzag_sub_4x4_field;
  633.         pf->sub_4x4ac  = zigzag_sub_4x4ac_field;
  634. #ifdef HAVE_MMX
  635.         if( cpu&X264_CPU_MMXEXT )
  636.             pf->scan_4x4 = x264_zigzag_scan_4x4_field_mmxext;
  637.         if( cpu&X264_CPU_SSSE3 )
  638.         {
  639.             pf->sub_4x4  = x264_zigzag_sub_4x4_field_ssse3;
  640.             pf->sub_4x4ac= x264_zigzag_sub_4x4ac_field_ssse3;
  641.         }
  642. #endif
  643. #ifdef ARCH_PPC
  644.         if( cpu&X264_CPU_ALTIVEC )
  645.             pf->scan_4x4   = x264_zigzag_scan_4x4_field_altivec;
  646. #endif
  647.     }
  648.     else
  649.     {
  650.         pf->scan_8x8   = zigzag_scan_8x8_frame;
  651.         pf->scan_4x4   = zigzag_scan_4x4_frame;
  652.         pf->sub_8x8    = zigzag_sub_8x8_frame;
  653.         pf->sub_4x4    = zigzag_sub_4x4_frame;
  654.         pf->sub_4x4ac  = zigzag_sub_4x4ac_frame;
  655. #ifdef HAVE_MMX
  656.         if( cpu&X264_CPU_MMX )
  657.             pf->scan_4x4 = x264_zigzag_scan_4x4_frame_mmx;
  658.         if( cpu&X264_CPU_MMXEXT )
  659.             pf->scan_8x8 = x264_zigzag_scan_8x8_frame_mmxext;
  660.         if( cpu&X264_CPU_SSE2_IS_FAST )
  661.             pf->scan_8x8 = x264_zigzag_scan_8x8_frame_sse2;
  662.         if( cpu&X264_CPU_SSSE3 )
  663.         {
  664.             pf->sub_4x4  = x264_zigzag_sub_4x4_frame_ssse3;
  665.             pf->sub_4x4ac= x264_zigzag_sub_4x4ac_frame_ssse3;
  666.             pf->scan_8x8 = x264_zigzag_scan_8x8_frame_ssse3;
  667.             if( cpu&X264_CPU_SHUFFLE_IS_FAST )
  668.                 pf->scan_4x4 = x264_zigzag_scan_4x4_frame_ssse3;
  669.         }
  670. #endif
  671. #ifdef ARCH_PPC
  672.         if( cpu&X264_CPU_ALTIVEC )
  673.             pf->scan_4x4   = x264_zigzag_scan_4x4_frame_altivec;
  674. #endif
  675. #ifdef HAVE_ARMV6
  676.         if( cpu&X264_CPU_NEON )
  677.             pf->scan_4x4 = x264_zigzag_scan_4x4_frame_neon;
  678. #endif
  679.     }
  680.     pf->interleave_8x8_cavlc = zigzag_interleave_8x8_cavlc;
  681. #ifdef HAVE_MMX
  682.     if( cpu&X264_CPU_MMX )
  683.         pf->interleave_8x8_cavlc = x264_zigzag_interleave_8x8_cavlc_mmx;
  684.     if( cpu&X264_CPU_SHUFFLE_IS_FAST )
  685.         pf->interleave_8x8_cavlc = x264_zigzag_interleave_8x8_cavlc_sse2;
  686. #endif
  687. }