IPP简介、移植文档 --- 移植入Android

IPP简介、移植文档

 

什么是IPP (Intel Integrated Performance Primitives)

 

IPPIntel Integrated Performance Primitives” ( Intel IPP )是一套跨平台的软件函数库,他提供了广泛的多媒体功能:音频解码器(例如: H263 、 MPEG-4 )、图像处理 (JPEG) 、信号处理、语音压缩(例如: G723 、 GSM 、 AMR )和加密机制。

 

官网网站:http://software.intel.com/en-us/articles/intel-software-evaluation-center/

 

针对LinuxIPP2个版本

 

1. Intel IPP for the Linux OS on IA-32 architecture (including low power Intel(R) architecture)

 

2. Intel IPP for the Linux OS on Intel(R) 64 architecture

 

目前android x86使用的是 version 7.0 32bit

 

 

IPP静态库和动态库 以及 线程库和非线程库

  • Intel IPP提供了现成的函数库,用户在使用API时只需包含相应的库然后直接调用即可,这些函数库分为动态库和静态库。在后文提到如何使用这些库。
  • 这些函数库分为线程(Thread)和非线程(non-Thread)两个版本,静态库的线程版本的库名是*_t.a、非线程版本的库名是*_t.a。因为函数库需要调用的基础库在android平台上不完全被实现,所以目前android x86没有办法使用多线程版本,而是使用非线程版本。

一、IPP的基本语法规则

基本数据类型

 

 

 

 

 

 

 

 

 

IPP中基本数据类型的格式是:

IppNN<u|s|f>[c]

其中NN表示此类型的bit长度,us指示是符号型还是无符号型,f表示是float类型,c表明是complex类型。图1-1给出了几种数据类型的示例。

1- IPP 数据类型示例

 

 

 

 

Domain

 

 

 

 

 

 

Intel IPP按函数功能和用途的不同被分为许多小块,每块叫一个domain。每个domain有自己的头文

 

 

 

 

 

 

 

件,静态库,动态库和测试样例。

 

 

 

 

 

 

 

 

 

 

如图1-2所示

 

 

 

 

 

 

 

1-2 IPP domain概况

 

核心函数

 

 

 

 

 

 

Intel IPP中有一些函数执行操作时和具体的domian无关,这些函数叫核心函数。比如获取CPU的类型、特定字节数的指针对齐等。这些函数有他们自己的头文件、静态库和动态库。如图1-3所示

1-3 IPP核心函数库 ippCore

下面是核心函数库中的几个API

•   ippCoreGetCpuType ----------- gets the CPU type

•   ippGetLibVersion --------------- returns the library version

•   ippCoreGetCpuClocks --------- reads the processor clock

 

 

l 函数命名和参数

Intel IPP函数有自己的命名规则

函数的格式如下:

 

ipp<data-domain><name>[_<datatype>][_<descriptor>](<parameters>);

格式中的各个字段分别为:

Data-Domain:代表输入数据类型的字符,现在版本的IPP支持以下的data-domain

Name代表函数执行的操作和算法,格式如下:

 

 <name> = <operation>[_modifier]

 

Operation段代表了基本操作,比如Set, DCTFwd;

Modifier段意味着在函数上的微小改动,比如CToC在函数ippsFFTInv_CToC_32fc代表进行基于复数的快速傅里叶变换,mv在函数ippmMul_mv中代表基于向量的矩阵乘法。

Data Typesdatatypes段格式如下:

<datatype> = <bit_depth><bit_interpretation>

 

相关的参数值为

bit_depth = <1|8|16|32|64>

bit_interpretation = < u|s|f>[c]

u ------------ unsigned integer

s ------------ signed integer

f ------------- floating point

c ------------- complex

 

一个函数可以操作多个对象,如果函数操作的对象都是同一种datatype,则datatype段只能有一个值;

如果函数操作的对象间(源对象和目标对象具有不同的data types,那么各自的datatype按照源对象和目标对象的顺序排列合成一个新的datatype,格式如下:

<datatype> = <src1Datatype>[src2Datatype][dstDatatype]

 

比如,函数ippsDotProd_16s16sc就是将16bitshort型和16bit的复数short型的源向量进行点乘,然后将结果保存在16bit复数short目标向量中。

 

Descriptordescriptor段描述了和操作相关联的数据。为了最小化函数中的分支、消除潜在的且多余的执行,大多数通用函数被分割成独立的原始函数,这些函数的参数就是descriptor

IPP中的descriptor如图1-4所示

 

 

1-4 IPP函数命名中的descriptor字段

 

 

Parametersparameters段就是函数的参数。它的命名有如下规则:

所有指针函数必须以p开头,比如,pPhasepSrcpSeed;指针的指针必须以pp开头,比如,ppState;定义为值得参数必须以小写字符开头,比如,valsrcsrcLen

参数名中新的部分必须以大写字符开头,没有下划线,比如,pSrclenSrcpDlyLine

每个参数的名字指定的它的功能。源目标的参数名就是pSrcsrc,有时候跟着数字或名字,比如pSrc2srcLen。输出参数的参数名就是pDstdst,有时跟数字或名字,比如,pDst1dstLen

 

下面是几个函数名的例子:

•   ippsIIR_32f_I(Ipp32f* pSrcDst, int len, IppsIIRState_32f* pState);

• ippiConvert_8u1u_C1R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, int dstBitOffset, IppiSize roiSize, Ipp8u threshold);

•   ippmSub_vac_32f(const Ipp32f* pSrc, int srcStride0, int srcStride2, Ipp32f val, Ipp32f* pDst, int dstStride0, int dstStride2, int len, int count);

 

 

 

二、IPP API的分类和细节

IPPAPI按作用可以分为四个部分:

•   signal processing

•   image and video processing

•   small martices and realistic rendering

•   cryptography

 

Signal processing

此类函数主要包含在libipps.so中,函数以ipps开头。

1. 内存分配函数

ippsMalloc用来进行内存分配,它是基本函数名,通过与不同的数据类型相组合,有很多种类型的malloc函数,如:

Ipp8u* ippsMalloc_8u(int len);

Ipp16u* ippsMalloc_16u(int len);

等等。

释放内存,使用

void ippsFree(void* ptr);

2. vector初始化函数

复制函数,如:

IppStatus ippsCopy_1u(const Ipp8u* pSrc, int srcBitOffset, Ipp8u* pDst, int dstBitOffset, int len);

IppStatus ippsCopy_8u(const Ipp8u* pSrc, Ipp8u* pDst, int len);

IppStatus ippsCopy_16s(const Ipp16s* pSrc, Ipp16s* pDst, int len);

vector里的数据打包成bitstream:

IppStatus ippsPackBits_32u8u(const Ipp32u* pSrcBit, const int* pSrcBits, int srcLen, Ipp8u* pDst, int dstBitOffset, int* pDstLenBit);

移动数据,如:

IppStatus ippsMove_8u(const Ipp8u* pSrc, Ipp8u* pDst, int len);

IppStatus ippsMove_16s(const Ipp16s* pSrc, Ipp16s* pDst, int len);等。

初始化vector,如:

IppStatus ippsSet_8u(Ipp8u val, Ipp8u* pDst, int len);

IppStatus ippsSet_16s(Ipp16s val, Ipp16s* pDst, int len);

vector置为0:

IppStatus ippsZero_8u(Ipp8u* pDst, int len);

IppStatus ippsZero_16s(Ipp16s* pDst, int len);

3. 数值运算类函数

3.1 逻辑运算

IPP中支持and,or xor的操作,通过区分是两个操作数是vectorvector还是vector与常量,有以下几种类型的逻辑运算:

· AndCComputes the bitwise AND of a scalar value and each element of a vector. 

· AndComputes the bitwise AND of two vectors. 

· OrCComputes the bitwise OR of a scalar value and each element of a vector. 

· OrComputes the bitwise OR of two vectors. 

· XorCComputes the bitwise XOR of a scalar value and each element of a vector. 

· XorComputes the bitwise XOR of two vectors. 

· NotComputes the bitwise NOT of the vector elements. 

· LShiftCShifts bits in vector elements to the left. 

· RShiftCShifts bits in vector elements to the right. 

上面列的每一种基本函数,通过与不通的数据类型相结合,又产生更多的函数,如

IppStatus ippsAndC_8u(const Ipp8u* pSrc, Ipp8u val, Ipp8u* pDst, int len);

    IppStatus ippsAndC_16u(const Ipp16u* pSrc, Ipp16u val, Ipp16u* pDst, int len);

IppStatus ippsRShiftC_8u(const Ipp8u* pSrc, int val, Ipp8u* pDst, int len);

IppStatus ippsRShiftC_16s(const Ipp16s* pSrc, int val, Ipp16s* pDst, int len);

3.2算术运算函数

基本函数名有AddC ,Add ,AddProductC , AddProduct, MulC, Mul, SubC , SubCRev,Sub,DivC,DivCRev,Div,Div_Round,Abs,Sqr,Sqrt,Cubrt,Exp,Ln,10Log10,SumLn,Arctan,Normalize,Cauchy,CauchyD,CauchyDD2。其中C标志与3.1节中的意义相同,表示常量。与数据类型组合后的例子有:

IppStatus ippsAddC_32f(const Ipp32f* pSrc, Ipp32f val, Ipp32f* pDst, int len);

IppStatus ippsAddC_64f(const Ipp64f* pSrc, Ipp64f val, Ipp64f* pDst, int len);

IppStatus ippsAddProduct_32f(const Ipp32f* pSrc1, const Ipp32f* pSrc2, Ipp32f* pSrcDst, int len);

IppStatus ippsAddProduct_64f(const Ipp64f* pSrc1, const Ipp64f* pSrc2, Ipp64f* pSrcDst, int len);

3.3转换函数

转换函数包含的内容有排序、数据类型的转换、vectorJoin操作、提取或构造复数、计算复向量的共轭、笛卡尔坐标与极坐标的转换等。各函数的简介如下:

· SortAscend, SortDescend:升序和降序排序

· SortIndexAscend, SortIndexDescend带索引的排序

· SortRadixAscend, SortRadixDescend使用radix sorting algorithm进行排序。 

· SortRadixIndexAscend, SortRadixIndexDescend间接使用radix sorting algorithm 排序。 

· SwapBytes反转vector里字节序。

· Convert转换vector里数据类型

· Joinvectorfloat数据转换成int型。

· JoinScaledJoin,vector里的数据是带scale参数的。

· SplitScaledJoinScaled进行相反的操作。

· Conj计算共轭向量。

· ConjFlip计算共轭向量,并按相反位置存储。

· Magnitude计算复向量每个元素的大小。

· MagSquared计算复向量每个元素的大小的平方。

· Phase计算复向量每个元素的相角。

· PowerSpectr计算 复向量的power spectrum. 

· Real计算复向量的实数部分。

· Imag计算复向量的虚数部分。

· CartToPolar笛卡尔坐标转极坐标。

· PolarToCart极坐标转笛卡尔坐标。

· Flipvector里元素倒序存放。

3.4 统计类函数 

该类函数主要是是计算vector里的最大值、最小值、平均值和方差等。

· Max: 返回最大值。

· Sum:计算元素之和。

· MaxIndx: 返回最大元素及索引。

· Mean:返回vector的平均值。

· DotProd:计算两个vector的点积。

3.5字符串操作函数

IPP提供了丰富的函数进行文本操作,既有简单的字符串操作函数,像字符串的相等比较、查找、删除等,也有复杂的使用正则表达式进行的模式匹配。基本函数名有:

· Find, FindRev: 查找子串的第一次出现位置。

· Insert: 在一个字符串中插入字符串。

· Remove: 从字符串中删除指定数目的字符。

· Compare: 比较两个字符串是否相等。

· RegExpFind: 查找符合指定正则表达式的子串。

· RegWxpReplace:按照正则表达式查找并替换子串。

这些基本函数名也可以结合不同的数据类型,如:

IppStatus ippsFind_8u(const Ipp8u* pSrc, int len, const Ipp8u* pFind, int lenFind, int* pIndex);IppStatus ippsFind_Z_8u(const Ipp8u* pSrcZ, const Ipp8u* pFindZ, int* pIndex);

IppStatus ippsFind_16u(const Ipp16u* pSrc, int len, const Ipp16u* pFind, int lenFind, int* pIndex);IppStatus ippsFind_Z_16u(const Ipp16u* pSrc, const Ipp16u* pFind, int* pIndex);

IppStatus ippsRegExpReplace_8u(const Ipp8u* pSrc, int* pSrcLenOffset, Ipp8u* pDst, int* pDstLen, IppRegExpFind* pFind, int* pNumFind, IppRegExpState* pRegExpState, IppRegExpReplaceState* pReplaceState);

3.6 其他函数

IPP提供了其他一些高级函数:

1)信号过滤函数,如

IppStatus ippsConv_32f(const Ipp32f* pSrc1, int src1Len, const Ipp32f* pSrc2, int src2Len, Ipp32f* pDst);

用来计算两向量的卷积。

2)信号变换函数,如FFTFwd_RToPack, FFTFwd_RToPerm, FFTFwd_RToCCS等函数用来进行快速傅立叶变换。

3)数据压缩函数,如

ippsVLCEncodeBlock_16s1u (const Ipp16s* pSrc, int srcLen, Ipp8u** ppDst, int* pDstBitsOffset, const IppsVLCEncodeSpec_32s* pVLCSpec);

对数据进行VLC编码,

IppStatus ippsEncodeHuff_8u(const Ipp8u* pSrc, int srcLen, Ipp8u* pDst, int* pDstLen, IppHuffState_8u* pHuffState);

进行Huffman编码。

4)Speech coding和 Audio coding.

 

image and video processing

此类函数主要包含在libippi.so中,函数以ippi开头。

1. 内存分配函数

这部分使用的内存分配函数原型为:

Ipp<datatype>* ippiMalloc_<mod>(int widthPixels, int heightPixels, int* pStepBytes);

除了可以与不同的datatype结合外,还有不同的mode8u_C1,8u_AC4, 322sc_AC3等等。A就代表alpha通道,C跟上后面的数字表示通道个数。

释放内存,使用

void ippiFree(void* ptr);

2. Image数据的交换与初始化

Convert:将像素数据类型转换为另一类型,如

IppStatus ippiConvert_1u8u_C1R(const Ipp8u* pSrc, int srcStep, int srcBitOffset, Ipp8u* pDst, int dstStep, IppiSize roiSize);

Set:初始化Image像素为一固定值,如

IppStatus ippiConvert_1u8u_C1R(const Ipp8u* pSrc, int srcStep, int srcBitOffset, Ipp8u* pDst, int dstStep, IppiSize roiSize);

Copy:在两个buffer之间复制像素,如

IppStatus ippiCopy_<mod>(const Ipp<datatype>* pSrc, int srcStep, Ipp<datatype>* pDst, int dstStep, IppiSize roiSize);

Transpose:对图像进行转置操作,如IppStatus ippiTranspose_<mod>(const Ipp<datatype>* pSrc, int srcStep, Ipp<datatype>* pDst, int dstStep, IppiSize roiSize);

3. 图像的数据运算函数

3.1 算法运算函数

这部分函数与ipps中的数据运算类似,只是ipps是对象是一维的vector,这部分的运算对象 是二维的image,主要函数简介如下:

· Add将两个image的像素值相加。

· AddC将一个常量与image中的每个像素值相加。

· MulMultiplies pixel values of two images.

· MulCMultiplies pixel values of an image by a constant.

· SubSubtracts pixel values of two images.

· SubCSubtracts a constant from pixel values of an image.

· DivDivides pixel values of an image by pixel values of another image.

· DivCDivides pixel values of an image by a constant.

· Abs取一个image各像素的绝对值,构造新的image

· AbsDiff计算两image的像素的绝对值差。

· AbsDiffCCalculates absolute difference between image and scalar value.

· SqrSquares pixel values of an image and writes them into the destination image.

· DotProdComputes the dot product of pixel values of two source images.

3.2 逻辑运算函数

主要有如下函数

· AndPerforms a bitwise AND operation between corresponding pixels of two images.

· AndCPerforms a bitwise AND operation of each pixel with a constant.

· OrPerforms bitwise inclusive OR operation between pixels of two source buffers.

· OrC: Performs a bitwise inclusive OR operation between each pixel of a buffer and a constant.

· XorPerforms bitwise exclusive OR operation between pixels of two source buffers.

· XorCPerforms a bitwise exclusive OR operation between each pixel of a buffer and a constant.

· NotPerforms a bitwise NOT operation on each pixel of a source buffer.

· RShiftCShifts bits in pixel values to the right.

· LShiftC: Shifts bits in pixel values to the left.

3.3 alpha构造图像函数

使用两个imagealpha值来从两个image中生成新的image,主要有四类生成类型:

AlphaComp使用两个image中的alpha值来生成image

AlphaCompC使用一个指定的alpha数据生成image

AlphaPremul首先使用一个图像的像素中颜色信息部分乘以本身的alpha值。

AlphaPremulC首先使用一个图像的像素中颜色信息部分乘以一个固定的alpha值。

下面给出几个实例:

IppStatus ippiAlphaComp_<mod>(const Ipp<datatype>* pSrc1, int src1Step, const Ipp<datatype>* pSrc2, int src2Step, Ipp<datatype>* pDst, int dstStep, IppiSize roiSize, IppiAlphaType alphaType);

IppStatus ippiAlphaComp_<mod>(const Ipp<datatype>* pSrc1, int src1Step, const Ipp<datatype>* pSrc2, int src2Step, Ipp<datatype>* pDst, int dstStep, IppiSize roiSize, IppiAlphaType alphaType);

4. 图像颜色转换

4.1 颜色模型的转换

IPP支持丰富的颜色模型,包括RGB,CMYK,YUV,YCbCr,YCCK,PhotoYCC,YCoCg,HSV,HLS,CIE XYZ, CIE LUV CIE Lab等,并提供了它们之间的转换函数,如

RGBToYUVYUVToRGB,RGBToXYZ,RGBToHLS,HLSToRGB,BGRToHLSHLSToBGR等。

对于不同的颜色格式IPP也提供了支持,如BRG, RGB, RGB565,RGB555, YCbCr422, YCbCr420, YCbCr411, YUV planar格式和YUV packet格式等。它们之间的转换函数有:RGBToRGB565, BGRToBGR565, RGB565ToRGB, BGR565ToBGR, YCbCr422, YCbCr422ToYCrCb422YCbCr422ToCbYCr422YCbCr422ToYCbCr420等。

4.2 灰度图像的转换

RGBToGray使用IPP内部固定的转换系统将彩色图像转换成灰度图像。

ColorToGray使用自定义的转换系数将彩色图像转换成灰度图像。.

CFAToRGB使用color filter array (CFA)将灰度图像还原成彩色图像。

DemosaicAHD使用AHD 算法将CFA image转换成彩色图像。

5. 图像线性变换

IPP提供了快速傅立叶变换(FFT), 离散傅立叶变换(DFT),离散余弦变换(DCT)以及小波变换(wavelet transform), 如:

FFTFwdDFTFwd , DCTFwdWTFwd等。

6. 图像压缩

IPP图像压缩使用了JPEG, JPEG2000,JPEG XR的标准。

6.1 JPEG编码

1)颜色转换

这些函数是针对JPEG编码的。彩色图像与灰度图像的转换有:

RGBToY_JPEGConverts an RGB image to gray scale.

BGRToY_JPEGConverts a BGR image to gray scale.

RGBYCrCb之间的转换有:

RGBToYCbCr_JPEGConverts an RGB image to YCbCr color model.

YCbCrToRGB_JPEGConverts an YCbCr image to the RGB color model.

RGB565ToYCbCr_JPEG, RGB555ToYCbCr_JPEGConvert a 16-bit RGB image to YCbCr color model.

等。还有其他类型的一些颜色转换函数,如

CMYKToYCCK_JPEGConverts a CMYK image to the YCCK color model.

YCCKToCMYK_JPEGConverts an YCCK image to the CMYK color model.

2)混合颜色转换

这类函数在进行颜色转换时,还可以进行samplinglevel shift等操作,如

IppStatus ippiRGBToYCbCr444LS_MCU_8u16s_C3P3R(const Ipp8u* pSrcRGB, int srcStep, Ipp16s* pDstMCU[3]);

在完成将RGBYCbCr444转换后,通过level shift将源数据表示范围由[0..255]转换到带符号的[-128..127],同时创建一个444 MCU。其他函数类似,如:

· RGBToYCbCr422LS_MCU Converts RGB images to YCbCr color model and creates 422 MCU. 

· RGBToYCbCr411LS_MCU Converts RGB images to YCbCr color model and creates 411 MCU. 

· BGRToYCbCr444LS_MCU Converts BGR images to YCbCr color model and creates 444 MCU. 

等。

3)无损JPEG压缩

它使用的是Huffman编码,主要函数如下:

· DiffPredFirstRow_JPEG Computes the differences between input sample and predictor for the first line 

· DiffPredRow_JPEG Computes the differences between input sample and predictor for all lines but the first. 

· ReconstructPredFirstRow_JPEG Reconstructs samples from the decoded differences between input samples and predictor for the first line. 

· ReconstructPredRow_JPEG Reconstructs samples from the decoded differences between input samples and predictor for all lines but the first. 

· GetHuffmanStatisticsOne_JPEG Computes Huffman symbol statistics 

· EncodeHuffmanOne_JPEG Performs Huffman encoding of one difference. 

· DecodeHuffmanOne_JPEG Decodes one Huffman coded difference. 

· EncodeHuffmanRow_JPEG : Performs Huffman encoding of one row of differences for each color component in the JPEG scan. 

· DecodeHuffmanRow_JPEGDecodes one row for each color component of Huffman coded differences

4JPEG2000 熵编码与解码

它的函数举例说明如下:

· IppStatus ippiEncodeInitAlloc_JPEG2K(IppiEncodeState_JPEG2K** pState, IppiSize codeBlockMaxSize):初始化熵编码state structure

· IppStatus ippiEncodeFree_JPEG2K(IppiEncodeState_JPEG2K* pState):释放申请有memory

IppStatus ippiEncodeLoadCodeBlock_JPEG2K_32s_C1R:执行编码过程。

· IppStatus ippiDecodeCodeBlock_JPEG2K_1u32s_C1R:解码指定的block.

· IppStatus ippiDecodeCBProgrStep_JPEG2K:执行一步解码的操作。

7. 视频编码

可处理的视频格式包括MPEG-1, MPEG-2, MPEG-4, DV, H.261, H.263, H.264 , AVS, VC-1等。

 

small martices and realistic rendering

此类函数主要包含在libippm.so中,函数以ippm开头。

 

ippm的操作对象

常量、常量数组

向量、向量数组

矩阵、矩阵数组

转置矩阵、转置矩阵数组

 

实用函数

 

Copy:将一个向量拷贝至另一个向量

 

IppStatus ippmCopy_va_32f_SS(const Ipp32f* pSrc, int srcStride0, int srcStride2, Ipp32f* pDst, int dstStride0, int dstStride2, int len, int count);

Extract:提取出ROI部分

IppStatus ippmExtract_v_32f(const Ipp32f* pSrc, int srcStride2, Ipp32f* pDst, int len);

LoadIdentity:初始化单位矩阵

IppStatus ippmLoadIdentity_ma_32f(const Ipp32f* pDst, int dstStride0, int dstStride1, int dstStride2, int width, int height, int count);

Add:将常量和向量或向量和向量相加

IppStatus ippmAdd_vc_32f(const Ipp32f* pSrc, int srcStride2, Ipp32f val, Ipp32f* pDst, int dstStride2, int len);

Sub:从向量减去一个常量 或 从一个常量减去向量 或 向量减向量

 

IppStatus ippmSub_vc_32f(const Ipp32f* pSrc, int srcStride2, Ipp32f val, Ipp32f* pDst, int dstStride2, int len);

 

Mul:向量和常量相乘

 

IppStatus ippmMul_vc_32f(const Ipp32f* pSrc, int srcStride2, Ipp32f val, Ipp32f* pDst, int dstStride2, int len);

 

 

矩阵代数运算

 

Transpose:计算矩阵的转置

 

IppStatus ippmTranspose_m_32f(const Ipp32f* pSrc, int srcStride1, int srcStride2, int width, int height, Ipp32f* pDst, int dstStride1, int dstStride2);

 

Invert:翻转矩阵

 

IppStatus ippmInvert_m_32f(const Ipp32f* pSrc, int srcStride1, int srcStride2, Ipp32f* pBuffer, Ipp32f* pDst, int dstStride1, int dstStride2, int widthHeight);

 

FrobNorm:计算行列式

 

IppStatus ippmFrobNorm_m_32f(const Ipp32f* pSrc, int srcStride1, int srcStride2, int width, int height, Ipp32f* pDst);

 

Mul:矩阵相乘

 

IppStatus ippmMul_mc_32f(const Ipp32f* pSrc, int srcStride1, int srcStride2, Ipp32f val, Ipp32f* pDst, int dstStride1, int dstStride2, int width, int height);

 

Add:矩阵相加

 

IppStatus ippmAdd_mm_32f(const Ipp32f* pSrc1, int src1Stride1, int src1Stride2, const Ipp32f* pSrc2, int src2Stride1, int src2Stride2, Ipp32f* pDst, int dstStride1, int dstStride2, int width, int height);

 

Sub:矩阵相减

 

IppStatus ippmSub_mm_32f(const Ipp32f* pSrc1, int src1Stride1, int src1Stride2, const Ipp32f* pSrc2, int src2Stride1, int src2Stride2, Ipp32f* pDst, int dstStride1, int dstStride2, int width, int height);

 

线性系统函数

 

LUDecomp:将矩阵分解为上三角或下三角矩阵

 

IppStatus ippmLUDecomp_m_32f(const Ipp32f* pSrc, int srcStride1, int srcStride2, int* pDstIndex, Ipp32f* pDst, int dstStride1, int dstStride2, int widthHeight);

 

LUBackSubst:计算矩阵的线性方程

 

IppStatus ippmLUBackSubst_mv_32f(const Ipp32f* pSrc1, int src1Stride1, int src1Stride2, int* pSrcIndex, const Ipp32f* pSrc2, int src2Stride2, Ipp32f* pDst, int dstStride2, int widthHeight);

 

CholeskyDecomp: 将对称矩阵进行Cholesky分解

 

IppStatus ippmCholeskyDecomp_m_32f(const Ipp32f* pSrc, int srcStride1, int srcStride2, Ipp32f* pDst, int dstStride1, int dstStride2, int widthHeight);

 

CholeskyBackSubst:利用Cholesky计算矩阵线性方程

 

IppStatus ippmCholeskyBackSubst_mv_32f(const Ipp32f* pSrc1, int src1Stride1, int src1Stride2, const Ipp32f* pSrc2, int src2Stride2, Ipp32f* pDst, int dstStride2, int widthHeight);

 

最小平方问题

 

QRDecomp:将矩阵进行QR分解

 

IppStatus ippmQRDecomp_m_32f(const Ipp32f* pSrc, int srcStride1, int srcStride2, Ipp32f* pBuffer, Ipp32f* pDst, int dstStride1, int dstStride2, int width, int height);

 

QRBackSubst:解决QR分解矩阵的最小平方问题

 

IppStatus ippmQRBackSubst_mv_32f(const Ipp32f* pSrc1, int src1Stride1, int src1Stride2, Ipp32f* pBuffer, const Ipp32f* pSrc2, int src2Stride2, Ipp32f* pDst, int dstStride2, int width, int height);

 

特征值问题

 

EigenValuesVectorsSym:找出矩阵的特征值和特征向量

 

IppStatus ippmEigenValuesVectorsSym_m_32f (const Ipp32f* pSrc, int srcStride1, int srcStride2, Ipp32f* pBuffer, Ipp32f* pDstVectors, int dstStride1, int dstStride2, Ipp32f* pDstValues, int widthHeight);

 

EigenValuesSym:找出特征值

 

IppStatus ippmEigenValuesSym_m_32f (const Ipp32f* pSrc, int srcStride1, int srcStride2, Ipp32f* pBuffer, Ipp32f* pDstValues, int widthHeight);

 

EigenValuesVectors:找出特征值,左右特征向量

 

IppStatus ippmEigenValuesVectors_m_32f (const Ipp32f* pSrc, int srcStride1, int srcStride2, Ipp32f* pDstVectorsRight, int dstRightStride1, int dstRightStride2, Ipp32f* pDstVectorsLeft, int dstLeftStride1, int dstLeftStride2, Ipp32f* pDstValuesRe, Ipp32f* pDstValuesIm, int widthHeight, Ipp8u* pBuffer);

 

EigenValues:找出特征值

 

IppStatus ippmEigenValues_m_32f (const Ipp32f* pSrc, int srcStride1, int srcStride2, Ipp32f* pDstValuesRe, Ipp32f* pDstValuesIm, int widthHeight, Ipp8u* pBuffer);

 

EigenValuesVectorsGetBufSize:计算函数EigenValuesVectors的buffersize

 

IppStatus ippmEigenValuesVectorsGetBufSize_32f (int widthHeigh, int* pSizeBytes);

 

EigenValuesGetBufSize:计算函数EigenValues的buffersize

 

IppStatus ippmEigenValuesGetBufSize_32f (int widthHeight, int* pSizeBytes);

 

 

2D,3D,4D向量的数学操作

 

Len:计算2D,3D,4D向量的长度

 

IppStatus ippmLen_v2_32f (const Ipp32f* pSrc, Ipp32f* pDst);

 

LenSqr:计算2D,3D,4D向量的平方长度

 

IppStatus ippmLenSqr_v2_32f (const Ipp32f* pSrc, Ipp32f* pDst);

DotProduct:计算2D,3D,4D向量的点乘

 

IppStatus ippmDotProduct_v2_32f (const Ipp32f* pSrc1, const Ipp32f* pSrc2, Ipp32f* pDst);

 

Add:把两个2D,3D,4D向量相加

 

IppStatus ippmAdd_v2_32f (const Ipp32f* pSrc1, const Ipp32f* pSrc2, Ipp32f* pDst);

 

Sub:把两个2D,3D,4D向量相减

 

IppStatus ippmSub_v2_32f (const Ipp32f* pSrc1, const Ipp32f* pSrc2, Ipp32f* pDst);

 

Min:计算两个2D,3D,4D向量最小分量

 

IppStatus ippmMin_v2_32f (const Ipp32f* pSrc1, const Ipp32f* pSrc2, Ipp32f* pDst);

 

Max:计算两个2D,3D,4D向量最大分量

 

IppStatus ippmMax_v2_32f (const Ipp32f* pSrc1, const Ipp32f* pSrc2, Ipp32f* pDst);

 

MulC:将2D,3D,4D向量和常数相乘

 

IppStatus ippmMulC_v2_32f (const Ipp32f* pSrc, Ipp32f scale, Ipp32f* pDst);

 

InterpolationLinear:执行两个2D,3D,4D向量的线性内插

 

IppStatus ippmInterpolationLinear_v2_32f (const Ipp32f* pSrc1, const Ipp32f* pSrc2, Ipp32f scale, Ipp32f* pDst);

 

Normalize:将2D,3D,4D向量标准化

 

IppStatus ippmNormalize_v2_32f (const Ipp32f* pSrc, Ipp32f* pDst);

 

CrossProduct:将2D,3D,4D向量进行叉乘

 

IppStatus ippmCrossProduct_v2_32f (const Ipp32f* pSrc1, const Ipp32f* pSrc2, Ipp32f* pDst);

Invert:将4X4矩阵反转

 

IppStatus ippmInvert_m4_32f (const Ipp32f* pSrc, Ipp32f* pDstDet, Ipp32f* pDst);

Identity:初始化一个4X4单位矩阵

 

IppStatus ippmIdentity_m4_32f (Ipp32f* pDst);

IsIdentity:检查一个4X4矩阵是不是单位矩阵

 

IppStatus ippmIsIdentity_m4_32f (const Ipp32f* pSrc, Ipp32s* pDst);

 

Det:计算一个4X4矩阵的行列式

 

IppStatus ippmDet_m4_32f (const Ipp32f* pSrc, Ipp32f* pDst);

 

 

cryptography

 

支持的对称加密类型

DES/TDES

Rijndael

AES-CCM

AES-GCM

Blowfish

Twofish

RC5*

ARCFour

 

单路Hash原始加密

 

MD5GetSize获取IppsMD5State上下文的大小

 

IppStatus ippsMD5GetSize(int *pSize);

 

MD5Init初始化IppsMD5State

 

IppStatus ippsMD5Init(IppsMD5State* pCtx);

 

MD5Pack,MD5UnpackIppsMD5State打包进一个用户定义的buffer或者从buffer中取出打开

 

IppStatus ippsMD5Pack (const IppsMD5State* pCtx, Ipp8u* pBuffer);

 

MD5DuplicateIppsMD5State上下文拷贝至另一个

 

IppStatus ippsMD5Duplicate(const IppsMD5State* pSrcCtx, IppsMD5State* pDstCtx);

 

MD5MessageDigest生成MD5函数

 

IppStatus ippsMD5MessageDigest(const Ipp8u *pSrcMesg, int mesgLen

Ipp8u *pMD);

 

还提供了SHA1,SHA224,SHA256,SH384和SH512的相关操作

 

公钥加密函数

大数算术

 

Add_BNU:将两个等长的无符号整形大数相加

 

IppStatus ippsAdd_BNU(const Ipp32u *a, const Ipp32u *b, Ipp32u *r, int n, Ipp32u * carry);

 

Sub_BNU:将两个等长的无符号整形大数相减

 

IppStatus ippsSub_BNU(const Ipp32u *a, const Ipp32u *b, Ipp32u *r, int n, Ipp32u * carry);

 

MulOne_BNU:将两个等长的无符号整形大数相乘

 

IppStatus ippsMulOne_BNU(const Ipp32u *a, Ipp32u *r, int n, Ipp32u w, Ipp32u *carry);

 

Mul_BNU4:将两个4*32bit的无符号整形相乘

 

IppStatus ippsMul_BNU4(const Ipp32u *a, const Ipp32u *b, Ipp32u *r);

 

Mul_BNU8:将两个8*32bit的无符号整形相乘

 

IppStatus ippsMul_BNU8(const Ipp32u *a, const Ipp32u *b, Ipp32u *r);

 

Div_64u32u:将一个64bit的无符号整形除以32bit的无符号整形

 

IppStatus ippsDiv_64u32u(Ipp64u a, Ipp32u b, Ipp32u *q, Ipp32u *r);

 

GetOctString_BNU:将一个无符号整形大数转化为一个字符串

 

IppStatus ippsGetOctString_BNU(const Ipp32u* pBNU, int bnuSize, Ipp8u* pOctStr, int strLen);

 

SetOctString_BNU:将一个字符串转化为一个无符号整形大数

 

IppStatus ippsSetOctString_BNU(const Ipp8u* pOctStr, int strLen, Ipp32u* pBNU, int* pBNUsize);

 

Cmp_BN:比较两个大数的大小

 

IppStatus ippsCmp_BN(const IppsBigNumState *pA, const IppsBigNumState *pB, Ipp32u *pRsult);

 

Add_BN:将两个整形大数相加

 

IppStatus ippsCmp_BN(const IppsBigNumState *pA, const IppsBigNumState *pB, Ipp32u *pRsult);

 

Sub_BN:将两个整形大数想减

 

IppStatus ippsSub_BN(IppsBigNumState *a, IppsBigNumState *b, IppsBigNumState * r);

Mul_BN:将两个整形大数相乘

 

IppStatus ippsMul_BN(IppsBigNumState *a, IppsBigNumState *b, IppsBigNumState * r);

 

Div_BN:将两个大数整形相处

 

IppStatus ippsDiv_BN(IppsBigNumState *a, IppsBigNumState *b, IppsBigNumState * q, IppsBigNumState *r);

 

Mod_BN:取模

 

IppStatus ippsMod_BN(IppsBigNumState *a, IppsBigNumState *m, IppsBigNumState * r);

 

RSA算法

 

RSAGetSize:获取IppsRSAState Context的大小

 

IppStatus ippsRSAGetSize(int nBitsN, int nBitsP, IppRSAKeyType flag, int* pSize);

 

RSAInit:初始化IppsRSAState

 

IppStatus ippsRSAInit(int nBitsN, int nBitsP, IppRSAKeyType flag, IppsRSAState* pCtx);

 

RSASetKey:为创建的RSA Context创建key

 

IppStatus ippsRSASetKey(const IppsBigNumState* pBN, IppsRSAKeyTag tag, IppsRSAState* pCtx);

 

RSAGetKey:获取RSA Context中的key

 

IppStatus ippsRSAGetKey(IppsBigNumState* pBN, IppsRSAKeyTag tag, const IppsRSAState* pCtx);

 

RSAEncrypt:执行RSA加密操作

 

IppStatus ippsRSAEncrypt(const IppsBigNumState* pX, IppsBigNumState* pY, IppsRSAState* pCtx);

 

RSADecrypt:执行RSA解密操作

 

IppStatus ippsRSADecrypt(const IppsBigNumState* pX, IppsBigNumState* pY, IppsRSAState* pCtx);

 

基于离散对象的加密

 

DLPGetSize: 获取IppsDLPState context的大小

 

IppStatus ippsDLPGetSize(int peBits, int reBits, int *pSize);

 

DLPInit:初始化IppsDLPState context

 

IppsStatus IppsDLPInit(int peBits, int reBits, IppsDLPState* pCtx);

 

DLPPublicKey:计算DL-basedkey

 

IppStatus ippsDLPPublicKey(const IppsBigNumState* pPrivate, IppsBigNumState* pPublic, IppsDLPState* pCtx);

 

 

PS:在PC上安装完IPP之后,

ippDir/comopser_xe_2011_sp1/Documentation/en_US/ipp/ipp_manual/index.html 中有具体的API介绍,使用时可以参考。(ippDir通常为/opt/intel)

 

三、IPPandroid中的移植和使用

Intel IPP库的下载及安装

步骤一:在网站http://software.intel.com/en-us/articles/intel-software-evaluation-center/下载Intel® Integrated Performance Primitives (Intel® IPP) for Linux*选择32位版本l_ipp_7.0.6.273_ia32.tgz

步骤二: 解压后,进入目录运行install.sh,在ubuntu上安装安装过程使用默认设置。安装完成后ippDir默认为/opt/intel

步骤三: ubuntu上的   ippDir/composer_xe_2011_sp1.8.273/IPP/includeippDir/composer_xe_2011_sp1.8.273/IPP/lib目录及包含的所有文件拷贝android source codeexternal/ipp/下。

 

Android上使用IPP静态库 (以在Camera HAL中调用IPP为例)

步骤一:修改Camera HAL 中的Android.mk

LOCAL_C_INCLUDES += \ 

external/ipp/include 

LOCAL_LDFLAGS:= \ 

                  external /ipp/lib/ia32/libippi_l.a \ 

                 external /ipp/lib/ia32/libipps_l.a \ 

external /ipp/lib/ia32/libippm_l.a \

                  external /ipp/lib/ia32/libippcore_l.a \ 

                  external /ipp/lib/ia32/libippcc_l.a

步骤二:在要使用IPP function的文件中(.c.h)包括头文件<ipp.h>

步骤三: 一定要先调用ippStaticInit()进行静态库的初始化,才能调用IPP其他函数。否则,链接无法通过。比如在CameraHardware.cppstartPreview()时调用ippStaticInit()之后就能直接调用IPP中的function.

 

Android上使用IPP动态库 (以在Camera HAL中调用IPP为例)

步骤一:将IPP.a 重新编译.so

external/ipp/下新建ippxxx.so对应的目录,比如要生成libippi.so,libippcore.so,libippcc.so等,建立目录ippi,ipps,ippcc等。

每个目录下新建init.c,在其中调用ippStaticInit.编辑相应目录下Android.mk,在 LOCAL_SRC_FILES中添加init.c文件,在LOCAL_LDFLAGS添加library.script文件和该so所依赖的.a文件,如

LOCAL_LDFLAGS:= \

         $(LOCAL_PATH)/library.scrip \

          external/composer_xe/ipp/lib/ia32/libippcc_l.a \

          external/composer_xe/ipp/lib/ia32/libippcore_l.a

编辑每个目录下的library.script 文件,在其中加入该库需要导出的函数,比如在ipps/library.script中添加:

EXTERN( ippsCopy_8u )

……

执行编译。

步骤二:调用生成的.so

Android.mkLOCAL_SHARED_LIBRARIES上添加上相应的ippxxxso.

source file  include <ipp.h> 后,就可以直接调用IPP的函数了

 

四、Performance提高程度

Camera中的应用

Camerapreview中加入了IPP,使用IPPAPI---ippiYCbCr422ToBGR565() 取代原有的convert函数进行colorspace的转化。经测试,结果如图4-1,表格中的数据代表处理每帧图片所消耗的时间。

 

 4-1 Camera Preview 加入IPP后 performance对比

 

从图中可以看出,随着机器分辨率的提升,处理每帧图片所耗费的时间就越久;于此同时,使用IPPperformance的提升就越明显。

 

Video PlayBack中的应用

frameworks/base/media/libstagefright/colorconversion/ColorConverter.cpp文件中,使用IPP API --- ippiYCbCr420ToBGR_8u_P3C4R代替原有转换方法。利用现有的两个视频文件进行测试,测试结果:

 

播放视频A时:no ipp每帧的耗时是37msuse ipp18ms

播放视频B时:no ipp每帧的耗时是18msuse ipp9ms

 

但就人眼观察的角度来看,使用IPP时的卡顿现象比no ipp稍微少一点,但是差别不大。

 

posted on 2014-08-15 19:52  mimamo  阅读(7425)  评论(0编辑  收藏  举报

导航