天天看點

[海思]--Hi3516aIVE--基礎簡介:自定義圖像結構

簡介:

     我剛剛接觸海思的時候用的是Hi3518E/Hi3616C 這個時候的IVE例子可以所是沒有的,官方完全沒有給出使用例子。隻在pdf上給出了些許說明。讓那時的我頭痛欲裂。不過現在的IVE已經比較完善了,而且還有基于VS2010的模拟庫,不過這個我從來沒有用過。我通常都是直接在闆子上調的。

     HI3516A 給出的例子已經比較詳細了,不過海思有一些不足,而且我很不喜歡它的那套。是以我是自己再封裝了一層,然後後邊用自己的習慣。這樣在後邊的項目開發中可以提高很大的工作效率的。所謂磨刀不誤砍柴工。那麼這篇部落客要說的就是我現在使用的自己封裝的庫的基礎部分。

自定義圖像結構

     IVE是用來圖像加速處理的,那麼我們必須要有一個圖像結構(海思自帶的是IVE_IMAGE_S),那麼我們現在個基于海思的IVE_IMAGE_S 圖像結構封裝出 自己的圖像結構

//使用者圖像結構
typedef struct __USER_IVE_IMG__
{
    IVE_IMAGE_S iveImg;       ///海思圖像結構
    int width;                ///使用者圖像寬度
    int height;               ///使用者圖像高度
    int    imgMemSize;        ///圖像記憶體大小
    int isCreated;            ///圖像建立标志位
    unsigned char *data;      ///圖像資料指針,指向虛拟位址[0]
    void *pReserve;           ///保留位
}UserIveImg,*PUserIveImg;
           

   根據海思的官方文檔給出的資料,IVE_IMAGE_S具有不同的圖像格式,可以參考文檔《HiIVE API 參考.pdf》,我這裡以u8c3Plannar格式為例來配置設定記憶體

記憶體格式如下圖所示:

[海思]--Hi3516aIVE--基礎簡介:自定義圖像結構

首先我們要确認記憶體大小 memSize = stride[0]*height*3;這裡的stride是width 16bit對齊。

計算公式為 stride = (width + (16 - width%16)%16);

有了上面這些基礎資料,我們就可以配置設定記憶體了,記憶體是使用 HI_MPI_SYS_MmzAlloc_Cached API來配置設定的,也可以使用

HI_MPI_SYS_MmzAlloc Api;兩個的差別,可以檢視一下《HiMPP IPC V2.0 媒體處理軟體開發參考.pdf》文檔,這裡就不多

說了。

//配置設定圖像記憶體 by cached
static int allocUserImg(IVE_IMAGE_S *pImg,IVE_IMAGE_TYPE_E imgType,int width,int height)
{
	int size = 0;
	int ret = 0;
	//判斷輸入指針是否為空
	if(pImg==NULL)
		return HI_FAILURE;

	//配置圖像類型和計算圖像基本資訊
	pImg->enType = imgType;
	pImg->u16Height = (HI_U16)height;
	pImg->u16Width = (HI_U16)width;
	pImg->u16Stride[0] = CALC_STRIDE(pImg,USER_IVE_ALIGN);
	switch(imgType)
	{
	case IVE_IMAGE_TYPE_U8C3_PLANAR:
	{
		size = pImg->u16Stride[0]*pImg->u16Height*3;//3倍的圖像尺寸
		ret = HI_MPI_SYS_MmzAlloc_Cached(&pImg->u32PhyAddr[0], (void**)&pImg->pu8VirAddr[0], NULL, HI_NULL, size);
		HI_CHECK_MPI_SYS_RET(ret,"allocUserImg fail,Error(%#x)\r\n");
		pImg->pu8VirAddr[1] = pImg->pu8VirAddr[0] +pImg->u16Stride[0]*pImg->u16Height;
		pImg->pu8VirAddr[2] = pImg->pu8VirAddr[1] +pImg->u16Stride[0]*pImg->u16Height;
		pImg->u32PhyAddr[1] = pImg->u32PhyAddr[0] +pImg->u16Stride[0]*pImg->u16Height;
		pImg->u32PhyAddr[2] = pImg->u32PhyAddr[1] +pImg->u16Stride[0]*pImg->u16Height;
		pImg->u16Stride[1] = pImg->u16Stride[0];
		pImg->u16Stride[2] = pImg->u16Stride[0];
	}break;
	default:
		break;
	}
}

           

然後再增加兩個函數就可以完成基本需求了,create 和 release 函數

int userIveCreatImg(UserIveImg *pImg,int width,int height,IVE_IMAGE_TYPE_E imgType)
{
	//判斷輸入的指針是否為空
	if(pImg==NULL)
		return HI_FAILURE;

	//假如圖像記憶體已經配置設定,則将原來的圖像記憶體釋放掉
	if(pImg->isCreated==HI_TRUE)
		userIveReleaseImg(pImg);
	//配置設定圖像記憶體
	pImg->imgMemSize = userIveAllocImg(&pImg->iveImg,width,height,imgType);
	pImg->data= pImg->iveImg.pu8VirAddr[0];
	pImg->height = height;
	pImg->width = width;
	pImg->pReserve = NULL;
	pImg->isCreated = HI_TRUE;
	return HI_SUCCESS;
}

int userIveReleaseImg(UserIveImg *pImg)
{
	//判斷輸入的指針是否為空
	if(pImg==NULL)
		return HI_FAILURE;
	if(pImg->isCreated==HI_TRUE)
	{
		//釋放圖像記憶體
		RELEASE_IVE_MEM(pImg->iveImg.u32PhyAddr[0],pImg->iveImg.pu8VirAddr[0]);
	}
	pImg->imgMemSize = 0;
	pImg->data= NULL;
	pImg->height = 0;
	pImg->width = 0;
	pImg->pReserve = NULL;
	pImg->isCreated = HI_FALSE;
}
           

代碼下載下傳請移步到資源下載下傳中心 http://download.csdn.net/download/qq_21193563/10047254

繼續閱讀