简介:
我刚刚接触海思的时候用的是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格式为例来分配内存
内存格式如下图所示:
首先我们要确认内存大小 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