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稍微少一點,但是差別不大。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM