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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * ppccommon.h: h264 encoder
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 Eric Petit <eric.petit@lapsus.org>
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  19.  *****************************************************************************/
  20. #ifdef HAVE_ALTIVEC_H
  21. #include <altivec.h>
  22. #endif
  23. /***********************************************************************
  24.  * For constant vectors, use parentheses on OS X and braces on Linux
  25.  **********************************************************************/
  26. #if defined(__APPLE__) && __GNUC__ < 4
  27. #define CV(a...) (a)
  28. #else
  29. #define CV(a...) {a}
  30. #endif
  31. /***********************************************************************
  32.  * Vector types
  33.  **********************************************************************/
  34. #define vec_u8_t  vector unsigned char
  35. #define vec_s8_t  vector signed char
  36. #define vec_u16_t vector unsigned short
  37. #define vec_s16_t vector signed short
  38. #define vec_u32_t vector unsigned int
  39. #define vec_s32_t vector signed int
  40. typedef union {
  41.   uint32_t s[4];
  42.   vec_u32_t v;
  43. } vec_u32_u;
  44. typedef union {
  45.   uint16_t s[8];
  46.   vec_u16_t v;
  47. } vec_u16_u;
  48. typedef union {
  49.   int16_t s[8];
  50.   vec_s16_t v;
  51. } vec_s16_u;
  52. typedef union {
  53.   uint8_t s[16];
  54.   vec_u8_t v;
  55. } vec_u8_u;
  56. /***********************************************************************
  57.  * Null vector
  58.  **********************************************************************/
  59. #define LOAD_ZERO const vec_u8_t zerov = vec_splat_u8( 0 )
  60. #define zero_u8v  (vec_u8_t)  zerov
  61. #define zero_s8v  (vec_s8_t)  zerov
  62. #define zero_u16v (vec_u16_t) zerov
  63. #define zero_s16v (vec_s16_t) zerov
  64. #define zero_u32v (vec_u32_t) zerov
  65. #define zero_s32v (vec_s32_t) zerov
  66. /***********************************************************************
  67.  * 8 <-> 16 bits conversions
  68.  **********************************************************************/
  69. #define vec_u8_to_u16_h(v) (vec_u16_t) vec_mergeh( zero_u8v, (vec_u8_t) v )
  70. #define vec_u8_to_u16_l(v) (vec_u16_t) vec_mergel( zero_u8v, (vec_u8_t) v )
  71. #define vec_u8_to_s16_h(v) (vec_s16_t) vec_mergeh( zero_u8v, (vec_u8_t) v )
  72. #define vec_u8_to_s16_l(v) (vec_s16_t) vec_mergel( zero_u8v, (vec_u8_t) v )
  73. #define vec_u8_to_u16(v) vec_u8_to_u16_h(v)
  74. #define vec_u8_to_s16(v) vec_u8_to_s16_h(v)
  75. #define vec_u16_to_u8(v) vec_pack( v, zero_u16v )
  76. #define vec_s16_to_u8(v) vec_packsu( v, zero_s16v )
  77. /***********************************************************************
  78.  * 16 <-> 32 bits conversions
  79.  **********************************************************************/
  80. #define vec_u16_to_u32_h(v) (vec_u32_t) vec_mergeh( zero_u16v, (vec_u16_t) v )
  81. #define vec_u16_to_u32_l(v) (vec_u32_t) vec_mergel( zero_u16v, (vec_u16_t) v )
  82. #define vec_u16_to_s32_h(v) (vec_s32_t) vec_mergeh( zero_u16v, (vec_u16_t) v )
  83. #define vec_u16_to_s32_l(v) (vec_s32_t) vec_mergel( zero_u16v, (vec_u16_t) v )
  84. #define vec_u16_to_u32(v) vec_u16_to_u32_h(v)
  85. #define vec_u16_to_s32(v) vec_u16_to_s32_h(v)
  86. #define vec_u32_to_u16(v) vec_pack( v, zero_u32v )
  87. #define vec_s32_to_u16(v) vec_packsu( v, zero_s32v )
  88. /***********************************************************************
  89.  * PREP_LOAD: declares two vectors required to perform unaligned loads
  90.  * VEC_LOAD:  loads n bytes from u8 * p into vector v of type t where o is from original src offset
  91.  * VEC_LOAD:_G: loads n bytes from u8 * p into vectory v of type t - use when offset is not known
  92.  * VEC_LOAD_OFFSET: as above, but with offset vector known in advance
  93.  **********************************************************************/
  94. #define PREP_LOAD     
  95.     vec_u8_t _hv, _lv
  96. #define PREP_LOAD_SRC( src )              
  97.     vec_u8_t _##src##_ = vec_lvsl(0, src) 
  98. #define VEC_LOAD_G( p, v, n, t )                 
  99.     _hv = vec_ld( 0, p );                        
  100.     v   = (t) vec_lvsl( 0, p );                  
  101.     _lv = vec_ld( n - 1, p );                    
  102.     v   = (t) vec_perm( _hv, _lv, (vec_u8_t) v ) 
  103. #define VEC_LOAD( p, v, n, t, g )                   
  104.     _hv = vec_ld( 0, p );                           
  105.     _lv = vec_ld( n - 1, p );                       
  106.     v = (t) vec_perm( _hv, _lv, (vec_u8_t) _##g##_ )
  107. #define VEC_LOAD_OFFSET( p, v, n, t, o )         
  108.     _hv = vec_ld( 0, p);                         
  109.     _lv = vec_ld( n - 1, p );                    
  110.     v   = (t) vec_perm( _hv, _lv, (vec_u8_t) o )
  111. #define VEC_LOAD_PARTIAL( p, v, n, t, g)               
  112.     _hv = vec_ld( 0, p);                               
  113.     v   = (t) vec_perm( _hv, _hv, (vec_u8_t) _##g##_ )
  114.     
  115. /***********************************************************************
  116.  * PREP_STORE##n: declares required vectors to store n bytes to a
  117.  *                potentially unaligned address
  118.  * VEC_STORE##n:  stores n bytes from vector v to address p
  119.  **********************************************************************/
  120. #define PREP_STORE16 
  121.     vec_u8_t _tmp1v  
  122. #define PREP_STORE16_DST( dst )             
  123.     vec_u8_t _##dst##l_ = vec_lvsl(0, dst); 
  124.     vec_u8_t _##dst##r_ = vec_lvsr(0, dst);
  125. #define VEC_STORE16( v, p, o )                           
  126.     _hv    = vec_ld( 0, p );                             
  127.     _lv    = vec_ld( 15, p );                            
  128.     _tmp1v = vec_perm( _lv, _hv, _##o##l_ );             
  129.     _lv    = vec_perm( (vec_u8_t) v, _tmp1v, _##o##r_ ); 
  130.     vec_st( _lv, 15, (uint8_t *) p );                    
  131.     _hv    = vec_perm( _tmp1v, (vec_u8_t) v, _##o##r_ ); 
  132.     vec_st( _hv, 0, (uint8_t *) p ) 
  133. #define PREP_STORE8 
  134.     vec_u8_t _tmp3v 
  135. #define VEC_STORE8( v, p )                
  136.     _tmp3v = vec_lvsl(0, p);              
  137.     v = vec_perm(v, v, _tmp3v);           
  138.     vec_ste((vec_u32_t)v,0,(uint32_t*)p); 
  139.     vec_ste((vec_u32_t)v,4,(uint32_t*)p)
  140. #define PREP_STORE4                                        
  141.     PREP_STORE16;                                          
  142.     vec_u8_t _tmp2v, _tmp3v;                               
  143.     const vec_u8_t sel =                                   
  144.         (vec_u8_t) CV(-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0)
  145. #define VEC_STORE4( v, p )                      
  146.     _tmp3v = vec_lvsr( 0, p );                  
  147.     v      = vec_perm( v, v, _tmp3v );          
  148.     _lv    = vec_ld( 3, p );                    
  149.     _tmp1v = vec_perm( sel, zero_u8v, _tmp3v ); 
  150.     _lv    = vec_sel( _lv, v, _tmp1v );         
  151.     vec_st( _lv, 3, p );                        
  152.     _hv    = vec_ld( 0, p );                    
  153.     _tmp2v = vec_perm( zero_u8v, sel, _tmp3v ); 
  154.     _hv    = vec_sel( _hv, v, _tmp2v );         
  155.     vec_st( _hv, 0, p )
  156. /***********************************************************************
  157.  * VEC_TRANSPOSE_8
  158.  ***********************************************************************
  159.  * Transposes a 8x8 matrix of s16 vectors
  160.  **********************************************************************/
  161. #define VEC_TRANSPOSE_8(a0,a1,a2,a3,a4,a5,a6,a7,b0,b1,b2,b3,b4,b5,b6,b7) 
  162.     b0 = vec_mergeh( a0, a4 ); 
  163.     b1 = vec_mergel( a0, a4 ); 
  164.     b2 = vec_mergeh( a1, a5 ); 
  165.     b3 = vec_mergel( a1, a5 ); 
  166.     b4 = vec_mergeh( a2, a6 ); 
  167.     b5 = vec_mergel( a2, a6 ); 
  168.     b6 = vec_mergeh( a3, a7 ); 
  169.     b7 = vec_mergel( a3, a7 ); 
  170.     a0 = vec_mergeh( b0, b4 ); 
  171.     a1 = vec_mergel( b0, b4 ); 
  172.     a2 = vec_mergeh( b1, b5 ); 
  173.     a3 = vec_mergel( b1, b5 ); 
  174.     a4 = vec_mergeh( b2, b6 ); 
  175.     a5 = vec_mergel( b2, b6 ); 
  176.     a6 = vec_mergeh( b3, b7 ); 
  177.     a7 = vec_mergel( b3, b7 ); 
  178.     b0 = vec_mergeh( a0, a4 ); 
  179.     b1 = vec_mergel( a0, a4 ); 
  180.     b2 = vec_mergeh( a1, a5 ); 
  181.     b3 = vec_mergel( a1, a5 ); 
  182.     b4 = vec_mergeh( a2, a6 ); 
  183.     b5 = vec_mergel( a2, a6 ); 
  184.     b6 = vec_mergeh( a3, a7 ); 
  185.     b7 = vec_mergel( a3, a7 )
  186. /***********************************************************************
  187.  * VEC_TRANSPOSE_4
  188.  ***********************************************************************
  189.  * Transposes a 4x4 matrix of s16 vectors.
  190.  * Actually source and destination are 8x4. The low elements of the
  191.  * source are discarded and the low elements of the destination mustn't
  192.  * be used.
  193.  **********************************************************************/
  194. #define VEC_TRANSPOSE_4(a0,a1,a2,a3,b0,b1,b2,b3) 
  195.     b0 = vec_mergeh( a0, a0 ); 
  196.     b1 = vec_mergeh( a1, a0 ); 
  197.     b2 = vec_mergeh( a2, a0 ); 
  198.     b3 = vec_mergeh( a3, a0 ); 
  199.     a0 = vec_mergeh( b0, b2 ); 
  200.     a1 = vec_mergel( b0, b2 ); 
  201.     a2 = vec_mergeh( b1, b3 ); 
  202.     a3 = vec_mergel( b1, b3 ); 
  203.     b0 = vec_mergeh( a0, a2 ); 
  204.     b1 = vec_mergel( a0, a2 ); 
  205.     b2 = vec_mergeh( a1, a3 ); 
  206.     b3 = vec_mergel( a1, a3 )
  207. /***********************************************************************
  208.  * VEC_DIFF_H
  209.  ***********************************************************************
  210.  * p1, p2:    u8 *
  211.  * i1, i2, n: int
  212.  * d:         s16v
  213.  *
  214.  * Loads n bytes from p1 and p2, do the diff of the high elements into
  215.  * d, increments p1 and p2 by i1 and i2 into known offset g
  216.  **********************************************************************/
  217. #define PREP_DIFF           
  218.     LOAD_ZERO;              
  219.     PREP_LOAD;              
  220.     vec_s16_t pix1v, pix2v;
  221. #define VEC_DIFF_H(p1,i1,p2,i2,n,d,g)               
  222.     VEC_LOAD_PARTIAL( p1, pix1v, n, vec_s16_t, p1); 
  223.     pix1v = vec_u8_to_s16( pix1v );                 
  224.     VEC_LOAD( p2, pix2v, n, vec_s16_t, g);          
  225.     pix2v = vec_u8_to_s16( pix2v );                 
  226.     d     = vec_sub( pix1v, pix2v );                
  227.     p1   += i1;                                     
  228.     p2   += i2
  229. /***********************************************************************
  230.  * VEC_DIFF_HL
  231.  ***********************************************************************
  232.  * p1, p2: u8 *
  233.  * i1, i2: int
  234.  * dh, dl: s16v
  235.  *
  236.  * Loads 16 bytes from p1 and p2, do the diff of the high elements into
  237.  * dh, the diff of the low elements into dl, increments p1 and p2 by i1
  238.  * and i2
  239.  **********************************************************************/
  240. #define VEC_DIFF_HL(p1,i1,p2,i2,dh,dl)       
  241.     pix1v = (vec_s16_t)vec_ld(0, p1);        
  242.     temp0v = vec_u8_to_s16_h( pix1v );       
  243.     temp1v = vec_u8_to_s16_l( pix1v );       
  244.     VEC_LOAD( p2, pix2v, 16, vec_s16_t, p2); 
  245.     temp2v = vec_u8_to_s16_h( pix2v );       
  246.     temp3v = vec_u8_to_s16_l( pix2v );       
  247.     dh     = vec_sub( temp0v, temp2v );      
  248.     dl     = vec_sub( temp1v, temp3v );      
  249.     p1    += i1;                             
  250.     p2    += i2
  251. /***********************************************************************
  252. * VEC_DIFF_H_8BYTE_ALIGNED
  253. ***********************************************************************
  254. * p1, p2:    u8 *
  255. * i1, i2, n: int
  256. * d:         s16v
  257. *
  258. * Loads n bytes from p1 and p2, do the diff of the high elements into
  259. * d, increments p1 and p2 by i1 and i2
  260. * Slightly faster when we know we are loading/diffing 8bytes which
  261. * are 8 byte aligned. Reduces need for two loads and two vec_lvsl()'s
  262. **********************************************************************/
  263. #define PREP_DIFF_8BYTEALIGNED 
  264. LOAD_ZERO;                     
  265. vec_s16_t pix1v, pix2v;        
  266. vec_u8_t pix1v8, pix2v8;       
  267. vec_u8_t permPix1, permPix2;   
  268. permPix1 = vec_lvsl(0, pix1);  
  269. permPix2 = vec_lvsl(0, pix2);  
  270. #define VEC_DIFF_H_8BYTE_ALIGNED(p1,i1,p2,i2,n,d)     
  271. pix1v8 = vec_perm(vec_ld(0,p1), zero_u8v, permPix1);  
  272. pix2v8 = vec_perm(vec_ld(0, p2), zero_u8v, permPix2); 
  273. pix1v = vec_u8_to_s16( pix1v8 );                      
  274. pix2v = vec_u8_to_s16( pix2v8 );                      
  275. d = vec_sub( pix1v, pix2v);                           
  276. p1 += i1;                                             
  277. p2 += i2;