海思3559 sample解析:vio
前言
拿到开发板,编完了平台sample,自然按捺不住要去简单学习测试了。打开最直观相对也比较简单的vio例程做个到手分析和流程梳理吧
测试
一开始自然是最磕磕绊绊的,连上HDMI线,串口登录后运行,屏幕乌漆嘛黑,尝试了几个参数后怀疑是不是线有问题或者哪里配置不对,就打开了snap例程,毕竟显示不了咱保存下来也是一样的看嘛
可惜还是没有半点反应,触发拍照超时,那就只能是sample之前的配置就有问题了呗
完整的分析一下平台搭建后的流程
Makefile
makefile.param文件中首先需要将传感器型号选对,根绝自己所用传感器的型号进行选择(然后加载的时候好像不论加载参数选择哪个都不会报错,在viodemo里都会运行正常)
接下来开始分析vio的sample
整体框架:
vio中的main调用vio中的功能函数,再调用common中的功能函数,再调用mpp中的API,再调用HI3559E内部的硬件单元。
main
先从main函数开始看起:
int main(int argc, char* argv[])
#endif
{HI_S32 s32Ret = HI_FAILURE;HI_S32 s32Index;VO_INTF_TYPE_E enVoIntfType = VO_INTF_HDMI;
首先判断传给执行程序传入的参数个数是否正确,不正确则打印使用说明。
if (argc < 2){SAMPLE_VIO_Usage(argv[0]);return HI_FAILURE;}
设置相应信号处理函数,SIGINT由Interrupt Key产生,
通常是CTRL+C或者Delete,发送给所有ForeGround Group的进程。SIGTERM请求终止进程,Kill命令缺省发送。
#ifdef __HuaweiLite__
#elsesignal(SIGINT, SAMPLE_VIO_HandleSig);signal(SIGTERM, SAMPLE_VIO_HandleSig);
#endifif ((argc > 2) && (1 == atoi(argv[2]))){enVoIntfType = VO_INTF_BT1120;
}
然后开始选择工作模式
switch (s32Index){case 0:s32Ret = SAMPLE_VIO_8K30_PARALLEL(enVoIntfType);break;case 1:s32Ret = SAMPLE_VIO_2X4K60_TotalOnline(enVoIntfType);break;case 2:s32Ret = SAMPLE_VIO_4x4K30_WBC(enVoIntfType);break;case 3:s32Ret = SAMPLE_VIO_4K30_WDR_HDR10(enVoIntfType);break;case 4:s32Ret = SAMPLE_VIO_4K30_LDC_ROTATE(enVoIntfType);break;case 5:s32Ret = SAMPLE_VIO_4K30_FreeRotation(enVoIntfType);break;case 6:s32Ret = SAMPLE_VIO_4K30_LDC_SPREAD(enVoIntfType);break;default:SAMPLE_PRT("the index %d is invaild!\n",s32Index);SAMPLE_VIO_Usage(argv[0]);return HI_FAILURE;}
SAMPLE_VIO_8K30_PARALLEL
以第一种模式8k,30帧为例(摄像头应该没有8k),其他配置都是根据自己实际需求
参数初始化
每个参数的功能均配上了中文备注
HI_S32 s32Ret = HI_SUCCESS;VI_DEV ViDev0 = 0; //VI配置为设备号0VI_PIPE ViPipe0 = 0; //VI配置为物理PIPE号0VI_CHN ViChn = 0; //VI配置通道号0HI_S32 s32ViCnt = 1; //VI配置为单个sensorVPSS_GRP VpssGrp0 = 0; //VPSS GROUP 号0VPSS_CHN VpssChn[4] = {VPSS_CHN0, VPSS_CHN1, VPSS_CHN2, VPSS_CHN3}; //VPSS 通道号VPSS_GRP_ATTR_S stVpssGrpAttr = {0};VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_PHY_CHN_NUM]; //VPSS物理通道属性HI_BOOL abChnEnable[VPSS_MAX_PHY_CHN_NUM] = {0};VO_DEV VoDev = SAMPLE_VO_DEV_DHD0;VO_CHN VoChn = 0; //VO配置视频输出通道号0VO_INTF_SYNC_E g_enIntfSync = VO_OUTPUT_3840x2160_30;HI_U32 g_u32DisBufLen = 3;PIC_SIZE_E enPicSize = PIC_3840x2160;WDR_MODE_E enWDRMode = WDR_MODE_NONE; //WDR 工作模式,分为帧模式、行模式、非WDRDYNAMIC_RANGE_E enDynamicRange = DYNAMIC_RANGE_SDR8; //动态范围,8bit数据的标准动态范围PIXEL_FORMAT_E enPixFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; //像素格式VIDEO_FORMAT_E enVideoFormat = VIDEO_FORMAT_LINEAR; //视频格式,现行存储COMPRESS_MODE_E enCompressMode = COMPRESS_MODE_NONE; //视频压缩数据格式,非压缩VI_VPSS_MODE_E enMastPipeMode = VI_PARALLEL_VPSS_PARALLEL; //定义 VI PIPE 和 VPSS 组的工作模式:VI 并行,VPSS 并行。SIZE_S stSize;HI_U32 u32BlkSize;VB_CONFIG_S stVbConf; //定义视频缓存池属性结构体SAMPLE_VI_CONFIG_S stViConfig;SAMPLE_VO_CONFIG_S stVoConfig;
第一步:获取所有传感器信息,
这个例子中需要一个vi和一个mipi
/************************************************step 1: Get all sensors information, need one vi,and need one mipi --*************************************************/SAMPLE_COMM_VI_GetSensorInfo(&stViConfig);stViConfig.s32WorkingViNum = s32ViCnt;stViConfig.as32WorkingViId[0] = 0;stViConfig.astViInfo[0].stSnsInfo.MipiDev = SAMPLE_COMM_VI_GetComboDevBySensor(stViConfig.astViInfo[0].stSnsInfo.enSnsType, 0);stViConfig.astViInfo[0].stSnsInfo.s32BusId = 0;stViConfig.astViInfo[0].stDevInfo.ViDev = ViDev0;stViConfig.astViInfo[0].stDevInfo.enWDRMode = enWDRMode;stViConfig.astViInfo[0].stPipeInfo.enMastPipeMode = enMastPipeMode; //VI和VPSS均是并行模式stViConfig.astViInfo[0].stPipeInfo.aPipe[0] = ViPipe0;stViConfig.astViInfo[0].stPipeInfo.aPipe[1] = -1;stViConfig.astViInfo[0].stPipeInfo.aPipe[2] = -1;stViConfig.astViInfo[0].stPipeInfo.aPipe[3] = -1;stViConfig.astViInfo[0].stChnInfo.ViChn = ViChn;stViConfig.astViInfo[0].stChnInfo.enPixFormat = enPixFormat;stViConfig.astViInfo[0].stChnInfo.enDynamicRange = enDynamicRange;stViConfig.astViInfo[0].stChnInfo.enVideoFormat = enVideoFormat;stViConfig.astViInfo[0].stChnInfo.enCompressMode = enCompressMode;
SAMPLE_COMM_VI_GetSensorInfo
因为很多sample需要调用同样的配置,所以海思将一些通用的接口都放在SAMPLE_COMM_XXX接口中,这里Sensor配置在下面的注释部分有说明,Hi3559AV100的VI设备最多支持8个,不同的芯片型号支持的不一样,可以具体阅读《HiMPP V4.0 媒体处理软件开发参考》。
跳转进这个函数
HI_VOID SAMPLE_COMM_VI_GetSensorInfo(SAMPLE_VI_CONFIG_S* pstViConfig)
{HI_S32 i;for (i = 0; i < VI_MAX_DEV_NUM; i++){pstViConfig->astViInfo[i].stSnsInfo.s32SnsId = i;pstViConfig->astViInfo[i].stSnsInfo.s32BusId = i;pstViConfig->astViInfo[i].stSnsInfo.MipiDev = i;memset_s(&pstViConfig->astViInfo[i].stSnapInfo, sizeof(SAMPLE_SNAP_INFO_S), 0, sizeof(SAMPLE_SNAP_INFO_S));}pstViConfig->astViInfo[0].stSnsInfo.enSnsType = SENSOR0_TYPE;pstViConfig->astViInfo[1].stSnsInfo.enSnsType = SENSOR1_TYPE;pstViConfig->astViInfo[2].stSnsInfo.enSnsType = SENSOR2_TYPE;pstViConfig->astViInfo[3].stSnsInfo.enSnsType = SENSOR3_TYPE;pstViConfig->astViInfo[4].stSnsInfo.enSnsType = SENSOR4_TYPE;pstViConfig->astViInfo[5].stSnsInfo.enSnsType = SENSOR5_TYPE;pstViConfig->astViInfo[6].stSnsInfo.enSnsType = SENSOR6_TYPE;pstViConfig->astViInfo[7].stSnsInfo.enSnsType = SENSOR7_TYPE;
}
入参结构体hiSAMPLE_VI_CONFIG_S
typedef struct hiSAMPLE_VI_CONFIG_S
{SAMPLE_VI_INFO_S astViInfo[VI_MAX_DEV_NUM];HI_S32 as32WorkingViId[VI_MAX_DEV_NUM];HI_S32 s32WorkingViNum;
} SAMPLE_VI_CONFIG_S;
typedef struct hiSAMPLE_VI_INFO_S
{SAMPLE_SENSOR_INFO_S stSnsInfo;SAMPLE_DEV_INFO_S stDevInfo;SAMPLE_PIPE_INFO_S stPipeInfo;SAMPLE_CHN_INFO_S stChnInfo;SAMPLE_SNAP_INFO_S stSnapInfo;
} SAMPLE_VI_INFO_S;
typedef struct hiSAMPLE_SENSOR_INFO_S
{SAMPLE_SNS_TYPE_E enSnsType;HI_S32 s32SnsId;HI_S32 s32BusId;combo_dev_t MipiDev;
} SAMPLE_SENSOR_INFO_S;
typedef enum hiSAMPLE_SNS_TYPE_E
{SONY_IMX477_MIPI_12M_30FPS_12BIT,SONY_IMX477_MIPI_9M_50FPS_10BIT,SONY_IMX477_MIPI_9M_60FPS_10BIT,SONY_IMX477_MIPI_8M_60FPS_12BIT,SONY_IMX477_MIPI_8M_30FPS_12BIT,SONY_IMX290_MIPI_2M_30FPS_12BIT,SONY_IMX290_MIPI_2M_30FPS_12BIT_WDR3TO1,SONY_IMX334_SLAVE_MIPI_8M_30FPS_12BIT,SONY_IMX334_MIPI_8M_30FPS_12BIT,SONY_IMX334_MIPI_8M_30FPS_12BIT_WDR2TO1,SONY_IMX277_SLVS_8M_120FPS_10BIT,SONY_IMX277_SLVS_8M_30FPS_12BIT,SONY_IMX277_SLVS_8M_60FPS_12BIT,SONY_IMX277_SLVS_12M_30FPS_12BIT,SONY_IMX277_SLVS_2M_240FPS_12BIT,COMSIS_SHARP8K_SLVDS_8K_30FPS_12BIT,SAMPLE_SNS_TYPE_BUTT,
} SAMPLE_SNS_TYPE_E;
再然后就会发现结构体一层套着一层,还是比较复杂的,只能根据具体情况具体做修改了
工作模式的含义可以具体看下表
模式 | VI_CAP 与 VI_PROC | VI_PROC 与 VPSS |
---|---|---|
在线模式 | VI_CAP 与 VI_PROC 之间在线数据流传输,此模式下 VI_CAP不会写出 RAW 数据到 DDR,而是直接把数据流送给VI_PROC。 | VI_PROC 与 VPSS 之间的在线数据流传输,在此模式下 VI_PROC不会写出 YUV 数据到 DDR,而是直接把数据流送给 VPSS |
离线模式 | VI_CAP 写出 RAW 数据到DDR,然后 VI_PROC 从 DDR读取 RAW 数据进行后处理。 | VI_PROC 写出 YUV 数据到DDR,然后 VPSS 从 DDR 读取YUV 数据进行后处理。 |
并行模式 | 当对接大数据量的时序,例如8K@30fps 时,需要 VI_CAP 与两个 VI_PROC 处于并行模式,VI_CAP 直接把一帧数据送给两个 VI_PROC 并行处理 | 当对接大数据量的时序,例如8K@30fps 时,需要 VI_CAP 与两个 VI_PROC 处于并行模式,同时两个 VPSS 也分别与VI_PROC 处于并行模式,VI_CAP 直接把一帧数据送给两个 VI_PROC 并行处理,再给VPSS 并行处理。 |
第二步 :获取输入大小
/************************************************step 2: Get input size*************************************************/s32Ret = SAMPLE_COMM_VI_GetSizeBySensor(stViConfig.astViInfo[0].stSnsInfo.enSnsType, &enPicSize);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_VI_GetSizeBySensor failed with %d!\n", s32Ret);return s32Ret;}s32Ret = SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed with %d!\n", s32Ret);return s32Ret;}
主要涉及两个重要函数
HI_S32 SAMPLE_COMM_VI_GetSizeBySensor(SAMPLE_SNS_TYPE_E enMode, PIC_SIZE_E* penSize)
该函数主要switch了入参1enMode,从而对参数2penSize赋值
HI_S32 SAMPLE_COMM_SYS_GetPicSize(PIC_SIZE_E enPicSize, SIZE_S* pstSize)
该函数则又根据赋值好的的enPicSize进行switch再对结构体pstSize的高和宽进行赋值
第三步:初始化系统并对VB进行配置
/************************************************step3: Init SYS and common VB*************************************************/memset_s(&stVbConf, sizeof(VB_CONFIG_S), 0, sizeof(VB_CONFIG_S));stVbConf.u32MaxPoolCnt = 2;u32BlkSize = COMMON_GetPicBufferSize(stSize.u32Width, stSize.u32Height, SAMPLE_PIXEL_FORMAT, DATA_BITWIDTH_10, COMPRESS_MODE_SEG, DEFAULT_ALIGN);stVbConf.astCommPool[0].u64BlkSize = u32BlkSize;stVbConf.astCommPool[0].u32BlkCnt = 10;u32BlkSize = VI_GetRawBufferSize(stSize.u32Width, stSize.u32Height, PIXEL_FORMAT_RGB_BAYER_16BPP, COMPRESS_MODE_NONE, DEFAULT_ALIGN);stVbConf.astCommPool[1].u64BlkSize = u32BlkSize;stVbConf.astCommPool[1].u32BlkCnt = 4;s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("system init failed with %d!\n", s32Ret);goto EXIT;}s32Ret = SAMPLE_COMM_VI_SetParam(&stViConfig);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_VI_SetParam failed with %d!\n", s32Ret);goto EXIT;}
这两步会根据不同Sensor类型的图片大小分配缓存,这里配置VI写出RAW的缓存块为4块,YUV缓存块10块,可以在下面的最后几行赋值看到10和4,数据结构u32BlkCnt可以在MIPP媒体软件开发参考里面查到(u16)。
COMMON_GetPicBufferSize一般 linear 格式的 YUV 缓存池的大小计算函数
VI_GetRawBufferSize是VI 写出的 Raw 数据缓存池大小的计算函数
在启动各个模块之前自然必须要对MPP系统进行初始化。
跳转进初始化函数,应该是为了防止其它进程已经使用MPP需要对其进行去初始化,然后根据之前VB的配置进行设置MPP 视频缓存池属性,初始化 MPP 视频缓存池,初始化 MPP 系统。分别对应了下面的三个函数
HI_S32 SAMPLE_COMM_SYS_Init(VB_CONFIG_S* pstVbConfig)
{HI_S32 s32Ret = HI_FAILURE;HI_MPI_SYS_Exit();HI_MPI_VB_Exit();if (NULL == pstVbConfig){SAMPLE_PRT("input parameter is null, it is invaild!\n");return HI_FAILURE;}s32Ret = HI_MPI_VB_SetConfig(pstVbConfig);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("HI_MPI_VB_SetConf failed!\n");return HI_FAILURE;}s32Ret = HI_MPI_VB_Init();if (HI_SUCCESS != s32Ret){SAMPLE_PRT("HI_MPI_VB_Init failed!\n");return HI_FAILURE;}s32Ret = HI_MPI_SYS_Init();if (HI_SUCCESS != s32Ret){SAMPLE_PRT("HI_MPI_SYS_Init failed!\n");return HI_FAILURE;}return HI_SUCCESS;
}
函数SAMPLE_COMM_VI_SetParam主要操作了内部函数用以获取 VI,VPSS 的工作模式。设置 VI,VPSS 工作模式
第四步:启动vi
启动VI模块需要先启动MIPI,接口根据hi_mipi驱动进行控制,根据VI的配置进行VI模块的参数设置以及创建,还需要启动ISP,ISP这块又涉及到许多内容,包括调试图像、可以使用自定义3A库开发等等。
/************************************************step 4: start VI*************************************************/s32Ret = SAMPLE_COMM_VI_StartVi(&stViConfig);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_VI_StartVi failed with %d!\n", s32Ret);goto EXIT3;}
第五步:启动vpss
/************************************************step 5: start VPSS, need one grp*************************************************/stVpssGrpAttr.u32MaxW = stSize.u32Width;stVpssGrpAttr.u32MaxH = stSize.u32Height;stVpssGrpAttr.enPixelFormat = enPixFormat;stVpssGrpAttr.enDynamicRange = enDynamicRange;stVpssGrpAttr.stFrameRate.s32SrcFrameRate = -1;stVpssGrpAttr.stFrameRate.s32DstFrameRate = -1;abChnEnable[0] = HI_TRUE;stVpssChnAttr[0].u32Width = stSize.u32Width;stVpssChnAttr[0].u32Height = stSize.u32Height;stVpssChnAttr[0].enChnMode = VPSS_CHN_MODE_USER;stVpssChnAttr[0].enCompressMode = enCompressMode;stVpssChnAttr[0].enDynamicRange = enDynamicRange;stVpssChnAttr[0].enPixelFormat = enPixFormat;stVpssChnAttr[0].enVideoFormat = enVideoFormat;stVpssChnAttr[0].stFrameRate.s32SrcFrameRate = -1;stVpssChnAttr[0].stFrameRate.s32DstFrameRate = -1;stVpssChnAttr[0].u32Depth = 1;stVpssChnAttr[0].bMirror = HI_TRUE; //镜像使能stVpssChnAttr[0].bFlip = HI_TRUE; //翻转使能stVpssChnAttr[0].stAspectRatio.enMode = ASPECT_RATIO_NONE;s32Ret = SAMPLE_COMM_VPSS_Start(VpssGrp0, abChnEnable, &stVpssGrpAttr, stVpssChnAttr);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_VPSS_Start Grp0 failed with %d!\n", s32Ret);goto EXIT2;}
SAMPLE_COMM_VPSS_Start内部主要调用四个函数,起到了创建vpss group, 配置通道属性, 启用通道 ,启用vpss group的作用
/*****************************************************************************
* function : start vpss grp.
创建vpss group 配置通道属性 启用通道 启用vpss group
*****************************************************************************/
HI_S32 SAMPLE_COMM_VPSS_Start(VPSS_GRP VpssGrp, HI_BOOL* pabChnEnable, VPSS_GRP_ATTR_S* pstVpssGrpAttr, VPSS_CHN_ATTR_S* pastVpssChnAttr)
{VPSS_CHN VpssChn;HI_S32 s32Ret;HI_S32 j;s32Ret = HI_MPI_VPSS_CreateGrp(VpssGrp, pstVpssGrpAttr);if (s32Ret != HI_SUCCESS){SAMPLE_PRT("HI_MPI_VPSS_CreateGrp(grp:%d) failed with %#x!\n", VpssGrp, s32Ret);return HI_FAILURE;}for (j = 0; j < VPSS_MAX_PHY_CHN_NUM; j++){if(HI_TRUE == pabChnEnable[j]){VpssChn = j;s32Ret = HI_MPI_VPSS_SetChnAttr(VpssGrp, VpssChn, &pastVpssChnAttr[VpssChn]);if (s32Ret != HI_SUCCESS){SAMPLE_PRT("HI_MPI_VPSS_SetChnAttr failed with %#x\n", s32Ret);return HI_FAILURE;}s32Ret = HI_MPI_VPSS_EnableChn(VpssGrp, VpssChn);if (s32Ret != HI_SUCCESS){SAMPLE_PRT("HI_MPI_VPSS_EnableChn failed with %#x\n", s32Ret);return HI_FAILURE;}}}s32Ret = HI_MPI_VPSS_StartGrp(VpssGrp);if (s32Ret != HI_SUCCESS){SAMPLE_PRT("HI_MPI_VPSS_StartGrp failed with %#x\n", s32Ret);return HI_FAILURE;}return HI_SUCCESS;
}
/* Group Settings*描述 :创建一个 VPSS GROUP*参数 :VpssGrp VPSS GROUP 号。取值范围:[0, VPSS_MAX_GRP_NUM)。 输入* pstGrpAttr VPSS GROUP 属性指针。 输入*返回值:成功返回0,非0参考错误码*注意 :* 不支持重复创建。* 当 VPSS 工作在 VI_PARALLEL_VPSS_PARALLEL 模式时,只有 GROUP0 可以被创建。* 当 Hi3559AV100 VPSS 的 GROUP0 和 GROUP4 都工作VI_ONLINE_VPSS_ONLINE 模式时,只有 GROUP0 和 GROUP4 可以被创建。* 当Hi3519AV100/Hi3516CV500/Hi3516AV300/Hi3516DV300/Hi3556V200/Hi3559V200/Hi3516EV200 VPSS 的 GROUP0 工作 VI_ONLINE_VPSS_ONLINE 模式时,只有GROUP0 可以被创建。* */HI_S32 HI_MPI_VPSS_CreateGrp(VPSS_GRP VpssGrp, const VPSS_GRP_ATTR_S *pstGrpAttr);
/* Chn Settings *描述 :设置 VPSS 通道属性。*参数 :VpssGrp VPSS GROUP 号。取值范围:[0, VPSS_MAX_GRP_NUM) 输入* VpssChn VPSS 通道号。取值范围:[0, VPSS_MAX_PHY_CHN_NUM) 输入* pstGrpAttr VPSS 通道属性。 输入 *返回值:成功返回0,失败参考错误码*注意 :GROUP 必须已创建。扩展通道不支持此接口。通道做任意角度旋转、LDC、Spread 处理或者其绑定的扩展通道开启了鱼眼校正时不支持通道尺寸动态改变。Hi3556V200/Hi3559V200 VPSS 输入图像宽度在(3360, 3840]范围内通道 0 不支持压缩输出。
*/
HI_S32 HI_MPI_VPSS_SetChnAttr(VPSS_GRP VpssGrp, VPSS_CHN VpssChn, const VPSS_CHN_ATTR_S *pstChnAttr);
/* *描述 :启用 VPSS 通道。*参数 :VpssGrp VPSS GROUP 号。取值范围:[0, VPSS_MAX_GRP_NUM) 输入* VpssChn VPSS 通道号。取值范围:[0, VPSS_MAX_CHN_NUM) 输入*返回值:成功返回0,失败参考错误码*注意 :多次使能返回成功。GROUP 必须已创建。Hi3516EV200 通道 0 低延时 buffer 卷绕开启时,若通道 0 写出 bufferSize 大于卷绕bufferSize,接口返回错误码 HI_ERR_VPSS_SIZE_NOT_ENOUGH。若支持扩展通道,扩展通道必须保证此通道绑定的源物理通道已经使能,否则返回失败错误码。*/
HI_S32 HI_MPI_VPSS_EnableChn(VPSS_GRP VpssGrp, VPSS_CHN VpssChn);
/* *描述 :启用 VPSS GROUP*参数 :VpssGrp VPSS GROUP 号。取值范围:[0, VPSS_MAX_GRP_NUM) 输入*返回值:成功返回0,非0参考错误码*注意 :GROUP 必须已创建。* 重复调用该函数设置同一个组返回成功*/
HI_S32 HI_MPI_VPSS_StartGrp(VPSS_GRP VpssGrp);
第六步:vi绑定vpss
都是在线模式,就不需要绑定了
/******************************************step 6: VI bind VPSS, for total online, no need bind*************************************************/
第七步:启动vo
/*step 7: start V0*************************************************/SAMPLE_COMM_VO_GetDefConfig(&stVoConfig);stVoConfig.VoDev = VoDev;stVoConfig.enVoIntfType = enVoIntfType;stVoConfig.enIntfSync = g_enIntfSync;stVoConfig.enPicSize = enPicSize;stVoConfig.u32DisBufLen = g_u32DisBufLen;stVoConfig.enDstDynamicRange = enDynamicRange;stVoConfig.enVoMode = VO_MODE_1MUX;s32Ret = SAMPLE_COMM_VO_StartVO(&stVoConfig);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_VO_StartVO failed with %d!\n", s32Ret);goto EXIT1;}
SAMPLE_COMM_VO_GetDefConfig为vo的基本配置,允许立即使用vo
SAMPLE_COMM_VO_StartVO主要含4个内部函数,分别有VO和VoDev的信息声明,设置并启动,如果改变的话设置显示矩形。打开VO通道的功能
第八步:vi绑定vpss绑定vo
/************************************************step 8: VI bind VPSS bind VO*************************************************/s32Ret = SAMPLE_COMM_VI_Bind_VPSS(ViPipe0, ViChn, VpssGrp0);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_VI_Bind_VPSS failed with %d!\n", s32Ret);goto EXIT1;}s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp0, VpssChn[0], stVoConfig.VoDev, VoChn);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_VPSS_Bind_VO Grp0 failed with %d!\n", s32Ret);goto EXIT0;}
SAMPLE_COMM_VI_Bind_VPSS包含数据源3个参数接收者3个参数,分别是vi和vpss,调用数据源到数据接收者绑定接口。
SAMPLE_COMM_VPSS_Bind_VO包含数据源3个参数接收者3个参数,分别是vpss和vo,也是调用数据源到数据接收者绑定接口。
都调用的同一个函数
/* *描述 :数据源到数据接收者绑定接口。*参数 :pstSrcChn 源通道指针。 输入* :pstDestChn 目的通道指针。 输入*返回值:0成功,非0参考错误码*注意 :太多了参考手册吧p62*/
HI_S32 HI_MPI_SYS_Bind(const MPP_CHN_S *pstSrcChn, const MPP_CHN_S *pstDestChn);
不同异常进行资源释放的处理。
PAUSE();// SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp1, VpssChn[0], stVoConfig.VoDev, VoChn[0]);
//EXIT1:SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[0], stVoConfig.VoDev, VoChn[0]);
EXIT2:SAMPLE_COMM_VO_StopVO(&stVoConfig);
EXIT3:SAMPLE_COMM_VPSS_Stop(VpssGrp1, abChnEnable);
EXIT4:SAMPLE_COMM_VPSS_Stop(VpssGrp0, abChnEnable);
EXIT5:SAMPLE_COMM_VI_StopVi(&stViConfig);
EXIT:SAMPLE_COMM_SYS_Exit();
显示可能存在的问题:
1.显示器无法显示的问题
解决办法:vio中关于分辨率部分修改为1080p60fps
sample里只更改参数的初始化这一行就可以了,如果自己需要手动修改
不建议更改common里面的函数,直接SAMPLE_COMM_VO_GetDefConfig配置后单独配置下面参数就可以
2.显示器显示图像是倒立的
.bMirror参数为视频镜像,.bFlip参数为视频倒立 TRUE改为FALSE即可
位于结构体
typedef struct hiVPSS_CHN_ATTR_S {VPSS_CHN_MODE_E enChnMode; /* RW; Vpss channel's work mode. *//* RW; Range: Hi3559AV100 = [64, 16384] | Hi3519AV100 = [64, 8192] | Hi3516CV500 = [64, 8192] |Hi3516AV300 = [64, 8192] | Hi3516DV300 = [64, 8192] | Hi3556V200 = [64, 8192] | Hi3559V200 = [64, 8192] |Hi3516EV200 = [64, 4096]; Width of target image. */HI_U32 u32Width;/* RW; Range: Hi3559AV100 = [64, 16384] | Hi3519AV100 = [64, 8192] | Hi3516CV500 = [64, 8192] |Hi3516AV300 = [64, 8192] | Hi3516DV300 = [64, 8192] | Hi3556V200 = [64, 8192] | Hi3559V200 = [64, 8192] |Hi3516EV200 = [64, 4096]; Height of target image. */HI_U32 u32Height;VIDEO_FORMAT_E enVideoFormat; /* RW; Video format of target image. */PIXEL_FORMAT_E enPixelFormat; /* RW; Pixel format of target image. */DYNAMIC_RANGE_E enDynamicRange; /* RW; DynamicRange of target image. */COMPRESS_MODE_E enCompressMode; /* RW; Compression mode of the output. */FRAME_RATE_CTRL_S stFrameRate; /* Frame rate control info */HI_BOOL bMirror; /* RW; Mirror enable. */HI_BOOL bFlip; /* RW; Flip enable. */HI_U32 u32Depth; /* RW; Range: [0, 8]; User get list depth. */ASPECT_RATIO_S stAspectRatio; /* Aspect Ratio info. */
} VPSS_CHN_ATTR_S;
最后,万万没想到,不光配置有问题,线也有问题,也是醉啦,不过还好万里长征第一步迈出去啦!
海思3559 sample解析:vio相关推荐
- 海思3559移植yolov3
此人博客上有完整教程: https://blog.csdn.net/avideointerfaces/article/category/8762084 海思3559移植yolov3 海思AI芯片(Hi ...
- 海思3559 人脸识别
https://github.com/hanson-young/nniefacelib nniefacelib是一个在海思35xx系列芯片上运行的人脸算法库,目前集成了mobilefacenet和re ...
- 海思3559与全志a83t比较
全志 a838t 8核 cpu0主频 1800000m,cpu7 480000m 满负荷运行 1608000m 海思开发板运行 第一次 opencv 运行图像处理 全志开发板需要35ms 海思355 ...
- 海思3559:百兆网口的配置
前言 海思3559的开发板网口是默认支持千兆/百兆的,这里的自适应,是从RJ45出来后和PC侧的自适应,而实际上3559对于网口的设置,默认都是RGMII模式,除了对应的软件配置,硬件部分需要通过 ...
- 海思3559编译live555
1.找到live555最新的安装包http://www.live555.com/liveMedia/public/ 下载live555-latest.tar.gz 2.安装live555,必须先安装o ...
- 海思3559万能平台搭建:DDR移植的一些问题
前言: 开发板是绝对无误的硬件环境,但是我们平时的开发肯定会接触自己搭建的硬件环境,难免会有这样那样的小问题,这里给出一次DDR的调试过程 问题描述 海思3559开发板可以用默认配置表格生成的 ...
- 海思3559万能平台搭建:串口编程
前言 平常的工作使用中,总是免不了要和串口打交道,协议的收发也经常通过串口来实现,海思3559下的串口和标准的linux下串口大同小异,可以参考之前zynq的串口编程,也可以直接阅读本文 使能串口 ...
- 海思3559开发常识储备:相关名词全解
前言 接连啃了两个sample,还是觉得笼笼统统模模糊糊,没有达到想要的一目了然的程度,那就再整理整理资料,补些硬货吧 图像和像素格式 颜色: (1)颜色是主观还是客观存在? 颜色的本质是光 ...
- 海思3559A sample的整体架构
sample的整体架构 1.sample的整体架构: sample中有很多个例程,所以有很多个main函数,common是通用性的主题函数,我们分析的是sample_venc 2.基本的架构是:ven ...
最新文章
- 阿里内部禁用Executors创建线程池,为什么?
- LCD控制器与帧率、刷新率的关系分析
- B+树(加强版多路平衡查找树)
- SQL server CASE WHEN
- 在Docker官网上浏览版本号
- easyUi load方法重新加载表单的数据
- 数据加载中,请稍等......
- size ar objdump readelf binutils
- 【数字电子技术课程设计】多功能数字电子钟的设计
- MBR20200CT-ASEMI肖特基二极管MBR20200CT
- 如何调试ajax 和php
- 计算机绘图如何设置精度2007,excel2007饼图百分比精确度如何设置
- react服务端渲染技术
- 【信息系统项目管理师】第十四章 信息文档管理和配置管理(考点汇总篇)
- FT6206在STM32上的调试记录
- PHP获取客户端真实 IP 地址
- 初学者如何从零学习人工智能?看完你就懂了
- 安装升级Exchange Server 2010 SP1补丁
- 计算身体质量指数BMI
- ssh连接服务器失败解决记录