目錄
1.1 基本數據類型
1.2 domain
1.3 核心函數
1.4 函數的命名和參數
2.1.1 內存分配函數
2.1.2 vector初始化函數
2.1.3 數值運算類函數
2.2 Image and video processing
2.2.1 內存分配函數
2.2.2 image數據的交換與初始化
2.2.3 圖像的數據運算函數
2.2.4 圖像顏色轉換
2.2.5 圖像線性變換
2.2.6 圖像壓縮
2.2.7 視頻編碼
2.3 Small martices and realistic rendering
2.3.1 ippm的操作對象
2.3.2 實用函數
2.3.3 矩陣代數運算
2.3.4 線性系統函數
2.3.5 最小平方問題
2.3.6 特征值問題
2.3.7 多維向量的數學操作
2.4 Cryptography
2.4.1 支持的對稱加密類型
2.4.2 單路Hash原始加密
2.4.3 公鑰加密函數
2.4.3.1 大數運算
2.4.3.2 RSA算法
2.4.3.3 基於離散對象的加密
3.1 IntelIPP庫的下載及安裝
4.1 在camera中的應用
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 數據類型示例
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
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按作用可以分為四個部分:
• signal processing
• image and video processing
• small martices and realistic rendering
• cryptography
此類函數主要包含在libipps.so中,函數以ipps開頭。
ippsMalloc用來進行內存分配,它是基本函數名,通過與不同的數據類型相組合,有很多種類型的malloc函數,如:
Ipp8u* ippsMalloc_8u(int len);
Ipp16u* ippsMalloc_16u(int len);
等等。
釋放內存,使用
void ippsFree(void* ptr);
復制函數,如:
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.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.
此類函數主要包含在libippi.so中,函數以ippi開頭。
這部分使用的內存分配函數原型為:
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);
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.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.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轉換成彩色圖像。
IPP提供了快速傅立葉變換(FFT), 離散傅立葉變換(DFT),離散余弦變換(DCT)以及小波變換(wavelet transform), 如:
FFTFwd,DFTFwd , DCTFwd, WTFwd等。
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:執行一步解碼的操作。
可處理的視頻格式包括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開頭。
常量、常量數組
向量、向量數組
矩陣、矩陣數組
轉置矩陣、轉置矩陣數組
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);
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);
DES/TDES
Rijndael
AES-CCM
AES-GCM
Blowfish
Twofish
RC5*
ARCFour
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的相關操作
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);
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-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)。
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的函數了。
在Camera的preview中加入了IPP,使用IPP的API---ippiYCbCr422ToBGR565() 取代原有的convert函數進行colorspace的轉化。經測試,結果如圖4-1,表格中的數據代表處理每幀圖片所消耗的時間。
圖 4-1 Camera Preview 加入IPP后 performance對比
從圖中可以看出,隨着機器分辨率的提升,處理每幀圖片所耗費的時間就越久;於此同時,使用IPP后performance的提升就越明顯。
在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稍微少一點,但是差別不大。