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

IPP简介、移植文档

 

l 什么是IPP (Intel Integrated Performance Primitives)

 

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

 

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

 

l 针对Linux的IPP有2个版本:

 

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

 

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

 

 

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

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

一、IPP的基本语法规则

l 基本数据类型

 

 

 

 

 

 

 

 

 

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

IppNN<u|s|f>[c]

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

图1-1  IPP 数据类型示例

 

 

 

 

l Domain

 

 

 

 

 

 

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

 

 

 

 

 

 

 

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

 

 

 

 

 

 

 

 

 

 

如图1-2所示

 

 

 

 

 

 

 

图1-2 IPP domain概况

 

l 核心函数

 

 

 

 

 

 

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

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

 

 <name> = <operation>[_modifier]

 

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

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

n Data Types:datatypes段格式如下:

<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就是将16bit的short型和16bit的复数short型的源向量进行点乘,然后将结果保存在16bit复数short目标向量中。

 

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

IPP中的descriptor如图1-4所示

 

 

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

 

 

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

u 所有指针函数必须以p开头,比如,pPhase,pSrc,pSeed;指针的指针必须以pp开头,比如,ppState;定义为值得参数必须以小写字符开头,比如,val,src,srcLen。

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

u 每个参数的名字指定的它的功能。源目标的参数名就是pSrc或src,有时候跟着数字或名字,比如pSrc2,srcLen。输出参数的参数名就是pDst或dst,有时跟数字或名字,比如,pDst1,dstLen。

 

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

•   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的分类和细节

IPP的API按作用可以分为四个部分:

•   signal processing

•   image and video processing

•   small martices and realistic rendering

•   cryptography

 

l 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的操作,通过区分是两个操作数是vector与vector还是vector与常量,有以下几种类型的逻辑运算:

· AndC: Computes the bitwise AND of a scalar value and each element of a vector. 

· And: Computes the bitwise AND of two vectors. 

· OrC: Computes the bitwise OR of a scalar value and each element of a vector. 

· Or: Computes the bitwise OR of two vectors. 

· XorC: Computes the bitwise XOR of a scalar value and each element of a vector. 

· Xor: Computes the bitwise XOR of two vectors. 

· Not: Computes the bitwise NOT of the vector elements. 

· LShiftC: Shifts bits in vector elements to the left. 

· RShiftC: Shifts 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转换函数

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

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

· SortIndexAscend, SortIndexDescend: 带索引的排序

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

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

· SwapBytes: 反转vector里字节序。

· Convert: 转换vector里数据类型

· Join: 将vector里float数据转换成int型。

· JoinScaled: 同Join,但vector里的数据是带scale参数的。

· SplitScaled: 与JoinScaled进行相反的操作。

· Conj: 计算共轭向量。

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

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

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

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

· PowerSpectr: 计算 复向量的power spectrum. 

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

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

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

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

· Flip: 将vector里元素倒序存放。

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.

 

l image and video processing

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

1. 内存分配函数

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

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

除了可以与不同的datatype结合外,还有不同的mode:8u_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中的每个像素值相加。

· Mul: Multiplies pixel values of two images.

· MulC: Multiplies pixel values of an image by a constant.

· Sub: Subtracts pixel values of two images.

· SubC: Subtracts a constant from pixel values of an image.

· Div: Divides pixel values of an image by pixel values of another image.

· DivC: Divides pixel values of an image by a constant.

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

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

· AbsDiffC: Calculates absolute difference between image and scalar value.

· Sqr: Squares pixel values of an image and writes them into the destination image.

· DotProd: Computes the dot product of pixel values of two source images.

3.2 逻辑运算函数

主要有如下函数

· And: Performs a bitwise AND operation between corresponding pixels of two images.

· AndC: Performs a bitwise AND operation of each pixel with a constant.

· Or: Performs 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.

· Xor: Performs bitwise exclusive OR operation between pixels of two source buffers.

· XorC: Performs a bitwise exclusive OR operation between each pixel of a buffer and a constant.

· Not: Performs a bitwise NOT operation on each pixel of a source buffer.

· RShiftC: Shifts bits in pixel values to the right.

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

3.3 alpha构造图像函数

使用两个image的alpha值来从两个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等,并提供了它们之间的转换函数,如

RGBToYUV, YUVToRGB,RGBToXYZ,RGBToHLS,HLSToRGB,BGRToHLS, HLSToBGR等。

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

4.2 灰度图像的转换

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

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

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

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

5. 图像线性变换

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

FFTFwd,DFTFwd , DCTFwd, WTFwd等。

6. 图像压缩

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

6.1 JPEG编码

1)颜色转换

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

RGBToY_JPEG:Converts an RGB image to gray scale.

BGRToY_JPEG:Converts a BGR image to gray scale.

RGB与YCrCb之间的转换有:

RGBToYCbCr_JPEG:Converts an RGB image to YCbCr color model.

YCbCrToRGB_JPEG:Converts an YCbCr image to the RGB color model.

RGB565ToYCbCr_JPEG, RGB555ToYCbCr_JPEG:Convert a 16-bit RGB image to YCbCr color model.

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

CMYKToYCCK_JPEG:Converts a CMYK image to the YCCK color model.

YCCKToCMYK_JPEG:Converts an YCCK image to the CMYK color model.

2)混合颜色转换

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

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

在完成将RGB向YCbCr444转换后,通过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_JPEG: Decodes one row for each color component of Huffman coded differences

4)JPEG2000 熵编码与解码

它的函数举例说明如下:

· 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等。

 

l small martices and realistic rendering

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

 

n ippm的操作对象

常量、常量数组

向量、向量数组

矩阵、矩阵数组

转置矩阵、转置矩阵数组

 

n 实用函数

 

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);

 

 

n 矩阵代数运算

 

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);

 

n 线性系统函数

 

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);

 

n 最小平方问题

 

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);

 

n 特征值问题

 

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);

 

 

n 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);

 

 

l cryptography

 

n 支持的对称加密类型

DES/TDES

Rijndael

AES-CCM

AES-GCM

Blowfish

Twofish

RC5*

ARCFour

 

n 单路Hash原始加密

 

MD5GetSize:获取IppsMD5State上下文的大小

 

IppStatus ippsMD5GetSize(int *pSize);

 

MD5Init:初始化IppsMD5State

 

IppStatus ippsMD5Init(IppsMD5State* pCtx);

 

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

 

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

 

MD5Duplicate:将IppsMD5State上下文拷贝至另一个

 

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

 

MD5MessageDigest:生成MD5函数

 

IppStatus ippsMD5MessageDigest(const Ipp8u *pSrcMesg, int mesgLen, 

Ipp8u *pMD);

 

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

 

n 公钥加密函数

u 大数算术

 

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);

 

u 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);

 

u 基于离散对象的加密

 

DLPGetSize: 获取IppsDLPState context的大小

 

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

 

DLPInit:初始化IppsDLPState context

 

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

 

DLPPublicKey:计算DL-based的key

 

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)。

 

三、IPP在android中的移植和使用

l Intel IPP库的下载及安装

n 步骤一:在网站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。

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

n 步骤三: 将ubuntu上的   ippDir/composer_xe_2011_sp1.8.273/IPP/include和ippDir/composer_xe_2011_sp1.8.273/IPP/lib目录及包含的所有文件拷贝到android source code的external/ipp/下。

 

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

n 步骤一:修改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

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

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

 

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

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

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

u 每个目录下新建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

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

EXTERN( ippsCopy_8u )

……

u 执行编译。

n 步骤二:调用生成的.so

u 在Android.mk中LOCAL_SHARED_LIBRARIES上添加上相应的ippxxxso.

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

 

四、Performance提高程度

l 在Camera中的应用

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

 

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

 

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

 

l 在Video PlayBack中的应用

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

 

播放视频A时:no ipp每帧的耗时是37ms,use ipp是18ms;

播放视频B时:no ipp每帧的耗时是18ms,use ipp是9ms。

 

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

 

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

导航