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

Audio

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * predict.c: h264 encoder
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 Laurent Aimar
  5.  * $Id: predict.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 "common/common.h"
  24. #include "common/clip1.h"
  25. #include "predict.h"
  26. extern void predict_16x16_v_mmx( uint8_t *src );
  27. extern void predict_16x16_dc_core_mmxext( uint8_t *src, int i_dc_left );
  28. extern void predict_16x16_dc_top_mmxext( uint8_t *src );
  29. extern void predict_16x16_p_core_mmxext( uint8_t *src, int i00, int b, int c );
  30. extern void predict_8x8c_p_core_mmxext( uint8_t *src, int i00, int b, int c );
  31. extern void predict_8x8c_dc_core_mmxext( uint8_t *src, int s2, int s3 );
  32. extern void predict_8x8c_v_mmx( uint8_t *src );
  33. extern void predict_8x8_v_mmxext( uint8_t *src, int i_neighbors );
  34. extern void predict_8x8_ddl_mmxext( uint8_t *src, int i_neighbors );
  35. extern void predict_8x8_ddl_sse2( uint8_t *src, int i_neighbors );
  36. extern void predict_8x8_ddr_sse2( uint8_t *src, int i_neighbors );
  37. extern void predict_8x8_vl_sse2( uint8_t *src, int i_neighbors );
  38. extern void predict_8x8_vr_core_mmxext( uint8_t *src, int i_neighbors, uint16_t ltt0 );
  39. extern void predict_8x8_dc_core_mmxext( uint8_t *src, int i_neighbors, uint8_t *pix_left );
  40. extern void predict_4x4_ddl_mmxext( uint8_t *src );
  41. extern void predict_4x4_vl_mmxext( uint8_t *src );
  42. static void predict_16x16_p( uint8_t *src )
  43. {
  44.     int a, b, c, i;
  45.     int H = 0;
  46.     int V = 0;
  47.     int i00;
  48.     for( i = 1; i <= 8; i++ )
  49.     {
  50.         H += i * ( src[7+i - FDEC_STRIDE ]  - src[7-i - FDEC_STRIDE ] );
  51.         V += i * ( src[(7+i)*FDEC_STRIDE -1] - src[(7-i)*FDEC_STRIDE -1] );
  52.     }
  53.     a = 16 * ( src[15*FDEC_STRIDE -1] + src[15 - FDEC_STRIDE] );
  54.     b = ( 5 * H + 32 ) >> 6;
  55.     c = ( 5 * V + 32 ) >> 6;
  56.     i00 = a - b * 7 - c * 7 + 16;
  57.     predict_16x16_p_core_mmxext( src, i00, b, c );
  58. }
  59. static void predict_8x8c_p( uint8_t *src )
  60. {
  61.     int a, b, c, i;
  62.     int H = 0;
  63.     int V = 0;
  64.     int i00;
  65.     for( i = 1; i <= 4; i++ )
  66.     {
  67.         H += i * ( src[3+i - FDEC_STRIDE] - src[3-i - FDEC_STRIDE] );
  68.         V += i * ( src[(3+i)*FDEC_STRIDE -1] - src[(3-i)*FDEC_STRIDE -1] );
  69.     }
  70.     a = 16 * ( src[7*FDEC_STRIDE -1] + src[7 - FDEC_STRIDE] );
  71.     b = ( 17 * H + 16 ) >> 5;
  72.     c = ( 17 * V + 16 ) >> 5;
  73.     i00 = a -3*b -3*c + 16;
  74.     predict_8x8c_p_core_mmxext( src, i00, b, c );
  75. }
  76. static void predict_16x16_dc( uint8_t *src )
  77. {
  78.     uint32_t dc=16;
  79.     int i;
  80.     for( i = 0; i < 16; i+=2 )
  81.     {
  82.         dc += src[-1 + i * FDEC_STRIDE];
  83.         dc += src[-1 + (i+1) * FDEC_STRIDE];
  84.     }
  85.     predict_16x16_dc_core_mmxext( src, dc );
  86. }
  87. static void predict_8x8c_dc( uint8_t *src )
  88. {
  89.     int s2 = 4
  90.        + src[-1 + 0*FDEC_STRIDE]
  91.        + src[-1 + 1*FDEC_STRIDE]
  92.        + src[-1 + 2*FDEC_STRIDE]
  93.        + src[-1 + 3*FDEC_STRIDE];
  94.     int s3 = 2
  95.        + src[-1 + 4*FDEC_STRIDE]
  96.        + src[-1 + 5*FDEC_STRIDE]
  97.        + src[-1 + 6*FDEC_STRIDE]
  98.        + src[-1 + 7*FDEC_STRIDE];
  99.     predict_8x8c_dc_core_mmxext( src, s2, s3 );
  100. }
  101. #define SRC(x,y) src[(x)+(y)*FDEC_STRIDE]
  102. static void predict_8x8_dc( uint8_t *src, int i_neighbor )
  103. {
  104.     uint8_t l[10];
  105.     l[0] = i_neighbor&MB_TOPLEFT ? SRC(-1,-1) : SRC(-1,0);
  106.     l[1] = SRC(-1,0);
  107.     l[2] = SRC(-1,1);
  108.     l[3] = SRC(-1,2);
  109.     l[4] = SRC(-1,3);
  110.     l[5] = SRC(-1,4);
  111.     l[6] = SRC(-1,5);
  112.     l[7] = SRC(-1,6);
  113.     l[8] =
  114.     l[9] = SRC(-1,7);
  115.     predict_8x8_dc_core_mmxext( src, i_neighbor, l+1 );
  116. }
  117. #ifdef ARCH_X86_64
  118. static void predict_16x16_h( uint8_t *src )
  119. {
  120.     int y;
  121.     for( y = 0; y < 16; y++ )
  122.     {
  123.         const uint64_t v = 0x0101010101010101ULL * src[-1];
  124.         uint64_t *p = (uint64_t*)src;
  125.         p[0] = p[1] = v;
  126.         src += FDEC_STRIDE;
  127.     }
  128. }
  129. static void predict_8x8c_h( uint8_t *src )
  130. {
  131.     int y;
  132.     for( y = 0; y < 8; y++ )
  133.     {
  134.         *(uint64_t*)src = 0x0101010101010101ULL * src[-1];
  135.         src += FDEC_STRIDE;
  136.     }
  137. }
  138. static void predict_16x16_dc_left( uint8_t *src )
  139. {
  140.     uint32_t s = 0;
  141.     uint64_t dc; 
  142.     int y;
  143.     
  144.     for( y = 0; y < 16; y++ )
  145.     {
  146.         s += src[-1 + y * FDEC_STRIDE];
  147.     }   
  148.     dc = (( s + 8 ) >> 4) * 0x0101010101010101ULL;
  149.     
  150.     for( y = 0; y < 16; y++ )
  151.     {
  152.         uint64_t *p = (uint64_t*)src;
  153.         p[0] = p[1] = dc;
  154.         src += FDEC_STRIDE;
  155.     }
  156. }
  157. static void predict_8x8c_dc_left( uint8_t *src )
  158. {
  159.     int y;
  160.     uint32_t s0 = 0, s1 = 0;
  161.     uint64_t dc0, dc1;
  162.     for( y = 0; y < 4; y++ )
  163.     {
  164.         s0 += src[y * FDEC_STRIDE     - 1];
  165.         s1 += src[(y+4) * FDEC_STRIDE - 1];
  166.     }
  167.     dc0 = (( s0 + 2 ) >> 2) * 0x0101010101010101ULL;
  168.     dc1 = (( s1 + 2 ) >> 2) * 0x0101010101010101ULL;
  169.     for( y = 0; y < 4; y++ )
  170.     {
  171.         *(uint64_t*)src = dc0;
  172.         src += FDEC_STRIDE;
  173.     }
  174.     for( y = 0; y < 4; y++ )
  175.     {
  176.         *(uint64_t*)src = dc1;
  177.         src += FDEC_STRIDE;
  178.     }
  179. }
  180. static void predict_8x8c_dc_top( uint8_t *src )
  181. {
  182.     int y, x;
  183.     uint32_t s0 = 0, s1 = 0;
  184.     uint64_t dc;
  185.     for( x = 0; x < 4; x++ )
  186.     {
  187.         s0 += src[x     - FDEC_STRIDE];
  188.         s1 += src[x + 4 - FDEC_STRIDE];
  189.     }
  190.     dc = (( s0 + 2 ) >> 2) * 0x01010101
  191.        + (( s1 + 2 ) >> 2) * 0x0101010100000000ULL;
  192.     for( y = 0; y < 8; y++ )
  193.     {
  194.         *(uint64_t*)src = dc;
  195.         src += FDEC_STRIDE;
  196.     }
  197. }
  198. #endif
  199. /* Diagonals */
  200. #define PREDICT_4x4_LOAD_LEFT 
  201.     const int l0 = src[-1+0*FDEC_STRIDE];   
  202.     const int l1 = src[-1+1*FDEC_STRIDE];   
  203.     const int l2 = src[-1+2*FDEC_STRIDE];   
  204.     UNUSED const int l3 = src[-1+3*FDEC_STRIDE];
  205. #define PREDICT_4x4_LOAD_TOP 
  206.     const int t0 = src[0-1*FDEC_STRIDE];   
  207.     const int t1 = src[1-1*FDEC_STRIDE];   
  208.     const int t2 = src[2-1*FDEC_STRIDE];   
  209.     UNUSED const int t3 = src[3-1*FDEC_STRIDE];
  210. #define PREDICT_4x4_LOAD_TOP_RIGHT 
  211.     const int t4 = src[4-1*FDEC_STRIDE];   
  212.     const int t5 = src[5-1*FDEC_STRIDE];   
  213.     const int t6 = src[6-1*FDEC_STRIDE];   
  214.     UNUSED const int t7 = src[7-1*FDEC_STRIDE];
  215. #define F1(a,b)   (((a)+(b)+1)>>1)
  216. #define F2(a,b,c) (((a)+2*(b)+(c)+2)>>2)
  217. #ifdef ARCH_X86_64 // slower on x86
  218. #if 0
  219. static void predict_4x4_ddl( uint8_t *src )
  220. {
  221.     PREDICT_4x4_LOAD_TOP
  222.     PREDICT_4x4_LOAD_TOP_RIGHT
  223.     uint32_t vec = (F2(t3,t4,t5)<< 0)
  224.                  + (F2(t4,t5,t6)<< 8)
  225.                  + (F2(t5,t6,t7)<<16)
  226.                  + (F2(t6,t7,t7)<<24);
  227.     *(uint32_t*)&src[3*FDEC_STRIDE] = vec;
  228.     *(uint32_t*)&src[2*FDEC_STRIDE] = vec = (vec<<8) + F2(t2,t3,t4);
  229.     *(uint32_t*)&src[1*FDEC_STRIDE] = vec = (vec<<8) + F2(t1,t2,t3);
  230.     *(uint32_t*)&src[0*FDEC_STRIDE] = vec = (vec<<8) + F2(t0,t1,t2);
  231. }
  232. #endif
  233. static void predict_4x4_ddr( uint8_t *src )
  234. {
  235.     const int lt = src[-1-FDEC_STRIDE];
  236.     PREDICT_4x4_LOAD_LEFT
  237.     PREDICT_4x4_LOAD_TOP
  238.     uint32_t vec = (F2(l0,lt,t0)<< 0)
  239.                  + (F2(lt,t0,t1)<< 8)
  240.                  + (F2(t0,t1,t2)<<16)
  241.                  + (F2(t1,t2,t3)<<24);
  242.     *(uint32_t*)&src[0*FDEC_STRIDE] = vec;
  243.     *(uint32_t*)&src[1*FDEC_STRIDE] = vec = (vec<<8) + F2(l1,l0,lt);
  244.     *(uint32_t*)&src[2*FDEC_STRIDE] = vec = (vec<<8) + F2(l2,l1,l0);
  245.     *(uint32_t*)&src[3*FDEC_STRIDE] = vec = (vec<<8) + F2(l3,l2,l1);
  246. }
  247. static void predict_4x4_vr( uint8_t *src )
  248. {
  249.     const int lt = src[-1-FDEC_STRIDE];
  250.     PREDICT_4x4_LOAD_LEFT
  251.     PREDICT_4x4_LOAD_TOP
  252.     const int ltt0 = lt + t0 + 1;
  253.     const int t0t1 = t0 + t1 + 1;
  254.     const int t1t2 = t1 + t2 + 1;
  255.     const int t2t3 = t2 + t3 + 1;
  256.     const int l0lt = l0 + lt + 1;
  257.     const int l1l0 = l1 + l0 + 1;
  258.     const int l2l1 = l2 + l1 + 1;
  259.     src[0*FDEC_STRIDE+0]=
  260.     src[2*FDEC_STRIDE+1]= ltt0 >> 1;
  261.     src[0*FDEC_STRIDE+1]=
  262.     src[2*FDEC_STRIDE+2]= t0t1 >> 1;
  263.     src[0*FDEC_STRIDE+2]=
  264.     src[2*FDEC_STRIDE+3]= t1t2 >> 1;
  265.     src[0*FDEC_STRIDE+3]= t2t3 >> 1;
  266.     src[1*FDEC_STRIDE+0]=
  267.     src[3*FDEC_STRIDE+1]= (l0lt + ltt0) >> 2;
  268.     src[1*FDEC_STRIDE+1]=
  269.     src[3*FDEC_STRIDE+2]= (ltt0 + t0t1) >> 2;
  270.     src[1*FDEC_STRIDE+2]=
  271.     src[3*FDEC_STRIDE+3]= (t0t1 + t1t2) >> 2;
  272.     src[1*FDEC_STRIDE+3]= (t1t2 + t2t3) >> 2;
  273.     src[2*FDEC_STRIDE+0]= (l1l0 + l0lt) >> 2;
  274.     src[3*FDEC_STRIDE+0]= (l2l1 + l1l0) >> 2;
  275. }
  276. static void predict_4x4_hd( uint8_t *src )
  277. {
  278.     const int lt= src[-1-1*FDEC_STRIDE];
  279.     PREDICT_4x4_LOAD_LEFT
  280.     PREDICT_4x4_LOAD_TOP
  281.     const int ltt0 = lt + t0 + 1;
  282.     const int t0t1 = t0 + t1 + 1;
  283.     const int t1t2 = t1 + t2 + 1;
  284.     const int l0lt = l0 + lt + 1;
  285.     const int l1l0 = l1 + l0 + 1;
  286.     const int l2l1 = l2 + l1 + 1;
  287.     const int l3l2 = l3 + l2 + 1;
  288.     src[0*FDEC_STRIDE+0]=
  289.     src[1*FDEC_STRIDE+2]= l0lt >> 1;
  290.     src[0*FDEC_STRIDE+1]=
  291.     src[1*FDEC_STRIDE+3]= (l0lt + ltt0) >> 2;
  292.     src[0*FDEC_STRIDE+2]= (ltt0 + t0t1) >> 2;
  293.     src[0*FDEC_STRIDE+3]= (t0t1 + t1t2) >> 2;
  294.     src[1*FDEC_STRIDE+0]=
  295.     src[2*FDEC_STRIDE+2]= l1l0 >> 1;
  296.     src[1*FDEC_STRIDE+1]=
  297.     src[2*FDEC_STRIDE+3]= (l0lt + l1l0) >> 2;
  298.     src[2*FDEC_STRIDE+0]=
  299.     src[3*FDEC_STRIDE+2]= l2l1 >> 1;
  300.     src[2*FDEC_STRIDE+1]=
  301.     src[3*FDEC_STRIDE+3]= (l1l0 + l2l1) >> 2;
  302.     src[3*FDEC_STRIDE+0]= l3l2 >> 1;
  303.     src[3*FDEC_STRIDE+1]= (l2l1 + l3l2) >> 2;
  304. }
  305. #if 0
  306. static void predict_4x4_vl( uint8_t *src )
  307. {
  308.     PREDICT_4x4_LOAD_TOP
  309.     PREDICT_4x4_LOAD_TOP_RIGHT
  310.     const int t0t1 = t0 + t1 + 1;
  311.     const int t1t2 = t1 + t2 + 1;
  312.     const int t2t3 = t2 + t3 + 1;
  313.     const int t3t4 = t3 + t4 + 1;
  314.     const int t4t5 = t4 + t5 + 1;
  315.     const int t5t6 = t5 + t6 + 1;
  316.     src[0*FDEC_STRIDE+0]= t0t1 >> 1;
  317.     src[0*FDEC_STRIDE+1]=
  318.     src[2*FDEC_STRIDE+0]= t1t2 >> 1;
  319.     src[0*FDEC_STRIDE+2]=
  320.     src[2*FDEC_STRIDE+1]= t2t3 >> 1;
  321.     src[0*FDEC_STRIDE+3]=
  322.     src[2*FDEC_STRIDE+2]= t3t4 >> 1;
  323.     src[2*FDEC_STRIDE+3]= t4t5 >> 1;
  324.     src[1*FDEC_STRIDE+0]= (t0t1 + t1t2) >> 2;
  325.     src[1*FDEC_STRIDE+1]=
  326.     src[3*FDEC_STRIDE+0]= (t1t2 + t2t3) >> 2;
  327.     src[1*FDEC_STRIDE+2]=
  328.     src[3*FDEC_STRIDE+1]= (t2t3 + t3t4) >> 2;
  329.     src[1*FDEC_STRIDE+3]=
  330.     src[3*FDEC_STRIDE+2]= (t3t4 + t4t5) >> 2;
  331.     src[3*FDEC_STRIDE+3]= (t4t5 + t5t6) >> 2;
  332. }
  333. #endif
  334. static void predict_4x4_hu( uint8_t *src )
  335. {
  336.     PREDICT_4x4_LOAD_LEFT
  337.     const int l1l0 = l1 + l0 + 1;
  338.     const int l2l1 = l2 + l1 + 1;
  339.     const int l3l2 = l3 + l2 + 1;
  340.     src[0*FDEC_STRIDE+0]= l1l0 >> 1;
  341.     src[0*FDEC_STRIDE+1]= (l1l0 + l2l1) >> 2;
  342.     src[0*FDEC_STRIDE+2]=
  343.     src[1*FDEC_STRIDE+0]= l2l1 >> 1;
  344.     src[0*FDEC_STRIDE+3]=
  345.     src[1*FDEC_STRIDE+1]= (l2l1 + l3l2) >> 2;
  346.     src[1*FDEC_STRIDE+2]=
  347.     src[2*FDEC_STRIDE+0]= l3l2 >> 1;
  348.     src[1*FDEC_STRIDE+3]=
  349.     src[2*FDEC_STRIDE+1]= (l2 + 3*l3 + 2) >> 2;
  350.     src[2*FDEC_STRIDE+3]=
  351.     src[3*FDEC_STRIDE+1]=
  352.     src[3*FDEC_STRIDE+0]=
  353.     src[2*FDEC_STRIDE+2]=
  354.     src[3*FDEC_STRIDE+2]=
  355.     src[3*FDEC_STRIDE+3]= l3;
  356. }
  357. #endif
  358. /****************************************************************************
  359.  * 8x8 prediction for intra luma block
  360.  ****************************************************************************/
  361. #define PL(y) 
  362.     const int l##y = (SRC(-1,y-1) + 2*SRC(-1,y) + SRC(-1,y+1) + 2) >> 2;
  363. #define PREDICT_8x8_LOAD_LEFT(have_tl) 
  364.     const int l0 = ((have_tl || (i_neighbor&MB_TOPLEFT) ? SRC(-1,-1) : SRC(-1,0)) 
  365.                      + 2*SRC(-1,0) + SRC(-1,1) + 2) >> 2; 
  366.     PL(1) PL(2) PL(3) PL(4) PL(5) PL(6) 
  367.     UNUSED const int l7 = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2;
  368. #define PT(x) 
  369.     const int t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2;
  370. #define PREDICT_8x8_LOAD_TOP(have_tl) 
  371.     const int t0 = ((have_tl || (i_neighbor&MB_TOPLEFT) ? SRC(-1,-1) : SRC(0,-1)) 
  372.                      + 2*SRC(0,-1) + SRC(1,-1) + 2) >> 2; 
  373.     PT(1) PT(2) PT(3) PT(4) PT(5) PT(6) 
  374.     UNUSED const int t7 = ((i_neighbor&MB_TOPRIGHT ? SRC(8,-1) : SRC(7,-1)) 
  375.                      + 2*SRC(7,-1) + SRC(6,-1) + 2) >> 2; 
  376. #define PTR(x) 
  377.     t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2;
  378. #define PREDICT_8x8_LOAD_TOPRIGHT 
  379.     int t8, t9, t10, t11, t12, t13, t14, t15; 
  380.     if(i_neighbor&MB_TOPRIGHT) { 
  381.         PTR(8) PTR(9) PTR(10) PTR(11) PTR(12) PTR(13) PTR(14) 
  382.         t15 = (SRC(14,-1) + 3*SRC(15,-1) + 2) >> 2; 
  383.     } else t8=t9=t10=t11=t12=t13=t14=t15= SRC(7,-1);
  384. #define PREDICT_8x8_LOAD_TOPLEFT 
  385.     const int lt = (SRC(-1,0) + 2*SRC(-1,-1) + SRC(0,-1) + 2) >> 2;
  386. #define PREDICT_8x8_DC(v) 
  387.     int y; 
  388.     for( y = 0; y < 8; y++ ) { 
  389.         ((uint32_t*)src)[0] = 
  390.         ((uint32_t*)src)[1] = v; 
  391.         src += FDEC_STRIDE; 
  392.     }
  393. #define SRC4(x,y) *(uint32_t*)&SRC(x,y)
  394. #if 0
  395. static void predict_8x8_ddl( uint8_t *src, int i_neighbor )
  396. {
  397.     PREDICT_8x8_LOAD_TOP(0)
  398.     uint32_t vec0, vec1;
  399.     int t8b;
  400.     if(i_neighbor&MB_TOPRIGHT)
  401.     {
  402.         PREDICT_8x8_LOAD_TOPRIGHT
  403.         vec1 = (F2(t14,t15,t15)<<24)
  404.              + (F2(t13,t14,t15)<<16)
  405.              + (F2(t12,t13,t14)<< 8)
  406.              + (F2(t11,t12,t13)<< 0);
  407.         vec0 = (F2(t10,t11,t12)<<24)
  408.              + (F2( t9,t10,t11)<<16)
  409.              + (F2( t8, t9,t10)<< 8)
  410.              + (F2( t7, t8, t9)<< 0);
  411.         t8b = t8;
  412.     }
  413.     else
  414.     {
  415.         t8b = SRC(7,-1);
  416.         vec1 = t8b * 0x01010101;
  417.         vec0 = (vec1&0xffffff00) + F2(t7,t8b,t8b);
  418.     }
  419.     SRC4(4,7) = vec1;
  420.     SRC4(4,3) =
  421.     SRC4(0,7) = vec0;
  422.     SRC4(4,6) = vec1 = (vec1<<8) + (vec0>>24);
  423.     SRC4(4,2) =
  424.     SRC4(0,6) = vec0 = (vec0<<8) + F2(t6,t7,t8b);
  425.     SRC4(4,5) = vec1 = (vec1<<8) + (vec0>>24);
  426.     SRC4(4,1) =
  427.     SRC4(0,5) = vec0 = (vec0<<8) + F2(t5,t6,t7);
  428.     SRC4(4,4) = vec1 = (vec1<<8) + (vec0>>24);
  429.     SRC4(4,0) =
  430.     SRC4(0,4) = vec0 = (vec0<<8) + F2(t4,t5,t6);
  431.     SRC4(0,3) = vec0 = (vec0<<8) + F2(t3,t4,t5);
  432.     SRC4(0,2) = vec0 = (vec0<<8) + F2(t2,t3,t4);
  433.     SRC4(0,1) = vec0 = (vec0<<8) + F2(t1,t2,t3);
  434.     SRC4(0,0) = vec0 = (vec0<<8) + F2(t0,t1,t2);
  435. }
  436. #endif
  437. static void predict_8x8_ddr( uint8_t *src, int i_neighbor )
  438. {
  439.     PREDICT_8x8_LOAD_TOP(1)
  440.     PREDICT_8x8_LOAD_LEFT(1)
  441.     PREDICT_8x8_LOAD_TOPLEFT
  442.     uint32_t vec0, vec1;
  443.     vec1 = (F2(t7,t6,t5)<<24)
  444.          + (F2(t6,t5,t4)<<16)
  445.          + (F2(t5,t4,t3)<< 8)
  446.          + (F2(t4,t3,t2)<< 0);
  447.     vec0 = (F2(t3,t2,t1)<<24)
  448.          + (F2(t2,t1,t0)<<16)
  449.          + (F2(t1,t0,lt)<< 8)
  450.          + (F2(t0,lt,l0)<< 0);
  451.     SRC4(4,0) = vec1;
  452.     SRC4(0,0) =
  453.     SRC4(4,4) = vec0;
  454.     SRC4(4,1) = vec1 = (vec1<<8) + (vec0>>24);
  455.     SRC4(0,1) =
  456.     SRC4(4,5) = vec0 = (vec0<<8) + F2(lt,l0,l1);
  457.     SRC4(4,2) = vec1 = (vec1<<8) + (vec0>>24);
  458.     SRC4(0,2) =
  459.     SRC4(4,6) = vec0 = (vec0<<8) + F2(l0,l1,l2);
  460.     SRC4(4,3) = vec1 = (vec1<<8) + (vec0>>24);
  461.     SRC4(0,3) =
  462.     SRC4(4,7) = vec0 = (vec0<<8) + F2(l1,l2,l3);
  463.     SRC4(0,4) = vec0 = (vec0<<8) + F2(l2,l3,l4);
  464.     SRC4(0,5) = vec0 = (vec0<<8) + F2(l3,l4,l5);
  465.     SRC4(0,6) = vec0 = (vec0<<8) + F2(l4,l5,l6);
  466.     SRC4(0,7) = vec0 = (vec0<<8) + F2(l5,l6,l7);
  467. }
  468. #ifdef ARCH_X86_64
  469. static void predict_8x8_vr_mmxext( uint8_t *src, int i_neighbor )
  470. {
  471.     PREDICT_8x8_LOAD_TOPLEFT
  472.     const int t0 = F2(SRC(-1,-1), SRC(0,-1), SRC(1,-1));
  473.     predict_8x8_vr_core_mmxext( src, i_neighbor, lt+(t0<<8) );
  474.     {
  475.         PREDICT_8x8_LOAD_LEFT(1)
  476.         SRC(0,1)=SRC(1,3)=SRC(2,5)=SRC(3,7)= (l0 + 2*lt + t0 + 2) >> 2;
  477.         SRC(0,2)=SRC(1,4)=SRC(2,6)= (l1 + 2*l0 + lt + 2) >> 2;
  478.         SRC(0,3)=SRC(1,5)=SRC(2,7)= (l2 + 2*l1 + l0 + 2) >> 2;
  479.         SRC(0,4)=SRC(1,6)= (l3 + 2*l2 + l1 + 2) >> 2;
  480.         SRC(0,5)=SRC(1,7)= (l4 + 2*l3 + l2 + 2) >> 2;
  481.         SRC(0,6)= (l5 + 2*l4 + l3 + 2) >> 2;
  482.         SRC(0,7)= (l6 + 2*l5 + l4 + 2) >> 2;
  483.     }
  484. }
  485. #endif
  486. /****************************************************************************
  487.  * Exported functions:
  488.  ****************************************************************************/
  489. void x264_predict_16x16_init_mmxext( x264_predict_t pf[7] )
  490. {
  491.     pf[I_PRED_16x16_V]       = predict_16x16_v_mmx;
  492.     pf[I_PRED_16x16_DC]      = predict_16x16_dc;
  493.     pf[I_PRED_16x16_DC_TOP]  = predict_16x16_dc_top_mmxext;
  494.     pf[I_PRED_16x16_P]       = predict_16x16_p;
  495. #ifdef ARCH_X86_64
  496.     pf[I_PRED_16x16_H]       = predict_16x16_h;
  497.     pf[I_PRED_16x16_DC_LEFT] = predict_16x16_dc_left;
  498. #endif
  499. }
  500. void x264_predict_8x8c_init_mmxext( x264_predict_t pf[7] )
  501. {
  502.     pf[I_PRED_CHROMA_V]       = predict_8x8c_v_mmx;
  503.     pf[I_PRED_CHROMA_P]       = predict_8x8c_p;
  504.     pf[I_PRED_CHROMA_DC]      = predict_8x8c_dc;
  505. #ifdef ARCH_X86_64
  506.     pf[I_PRED_CHROMA_H]       = predict_8x8c_h;
  507.     pf[I_PRED_CHROMA_DC_LEFT] = predict_8x8c_dc_left;
  508.     pf[I_PRED_CHROMA_DC_TOP]  = predict_8x8c_dc_top;
  509. #endif
  510. }
  511. void x264_predict_8x8_init_mmxext( x264_predict8x8_t pf[12] )
  512. {
  513.     pf[I_PRED_8x8_V]   = predict_8x8_v_mmxext;
  514.     pf[I_PRED_8x8_DC]  = predict_8x8_dc;
  515.     pf[I_PRED_8x8_DDR] = predict_8x8_ddr;
  516. #ifdef ARCH_X86_64 // x86 not written yet
  517.     pf[I_PRED_8x8_DDL] = predict_8x8_ddl_mmxext;
  518.     pf[I_PRED_8x8_VR]  = predict_8x8_vr_mmxext;
  519. #endif
  520. }
  521. void x264_predict_8x8_init_sse2( x264_predict8x8_t pf[12] )
  522. {
  523. #ifdef ARCH_X86_64 // x86 not written yet
  524.     pf[I_PRED_8x8_DDL] = predict_8x8_ddl_sse2;
  525.     pf[I_PRED_8x8_DDR] = predict_8x8_ddr_sse2;
  526.     pf[I_PRED_8x8_VL]  = predict_8x8_vl_sse2;
  527. #endif
  528. }
  529. void x264_predict_4x4_init_mmxext( x264_predict_t pf[12] )
  530. {
  531. #ifdef ARCH_X86_64 // x86 not written yet
  532.     pf[I_PRED_4x4_DDL] = predict_4x4_ddl_mmxext;
  533.     pf[I_PRED_4x4_VL]  = predict_4x4_vl_mmxext;
  534. #endif
  535. #ifdef ARCH_X86_64 // slower on x86
  536.     pf[I_PRED_4x4_DDR] = predict_4x4_ddr;
  537.     pf[I_PRED_4x4_VR]  = predict_4x4_vr;
  538.     pf[I_PRED_4x4_HD]  = predict_4x4_hd;
  539.     pf[I_PRED_4x4_HU]  = predict_4x4_hu;
  540. #endif
  541. }