文章目录
基本概念
- 视频输入设备(DEV)
- 视频输入物理PIPE
- 视频输入虚拟PIPE
VI 的 PIPE 包含了 ISP 的相关处理功能,主要是对图像数据进行流水线处理,输出YUV 图像格式给通道 - 视频输入物理通道(PHY_CHN)
- 扩展通道(EXT_CHN)
扩展通道是物理通道的扩展,扩展通道具备缩放、裁剪、鱼眼矫正功能
在hisi平台vi模块中,存在sensor -> dev -> pipe -> phy_chn -> ext_chn的关系
一、sensor数据获取以及输出sensor分辨率、像素格式、帧率等信息
- 代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "sample_comm.h"
/******************************************************************************
* function : to process abnormal case
******************************************************************************/
void SAMPLE_VIO_HandleSig(HI_S32 signo)
{
//当捕获到异常信号后触发的自定义函数如下,主要是对信号的重新定义以及系统退出资源的释放
if (SIGINT == signo || SIGTERM == signo)
{
SAMPLE_COMM_All_ISP_Stop();
SAMPLE_COMM_SYS_Exit();
printf("\033[0;31mprogram termination abnormally!\033[0;39m\n");
}
exit(-1);
}
HI_S32 SAMPLE_VIO_StartViVo(SAMPLE_VI_CONFIG_S* pstViConfig, SAMPLE_VO_CONFIG_S* pstVoConfig)
{
HI_S32 s32Ret;
s32Ret = SAMPLE_COMM_VI_StartVi(pstViConfig);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("start vi failed!\n");
return s32Ret;
}
s32Ret = SAMPLE_COMM_VO_StartVO(pstVoConfig);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_VIO start VO failed with %#x!\n", s32Ret);
goto EXIT;
}
return s32Ret;
EXIT:
//VO失败了需要把VI一同停止
SAMPLE_COMM_VI_StopVi(pstViConfig);
return s32Ret;
}
HI_S32 SAMPLE_VIO_StopViVo(SAMPLE_VI_CONFIG_S* pstViConfig, SAMPLE_VO_CONFIG_S* pstVoConfig)
{
SAMPLE_COMM_VO_StopVO(pstVoConfig);
SAMPLE_COMM_VI_StopVi(pstViConfig);
return HI_SUCCESS;
}
HI_S32 MY_SAMPLE_VIO(VO_INTF_TYPE_E enVoIntfType)
{
// Embeded isp.
HI_S32 s32Ret; //返回值
VI_DEV ViDev = 0;
VI_PIPE ViPipe = 0;
VI_CHN ViChn = 0;
HI_S32 s32WorkSnsId = 0;
VO_DEV VoDev = SAMPLE_VO_DEV_DHD0;
VO_CHN VoChn = 0;
SIZE_S stSize; //结构体,宽、高
VB_CONFIG_S stVbConf; //视频缓存池属性结构体,
PIC_SIZE_E enPicSize = PIC_3840x2160; //图片分辨率,也就是定义的视频的每一帧的分辨率
HI_U32 u32BlkSize;
SAMPLE_VI_CONFIG_S stViConfig = {
0}; //设置VI模块属性的结构体
SAMPLE_VO_CONFIG_S stVoConfig = {
0}; //设置VO模块属性的结构体
combo_dev_t ComboDev;
DYNAMIC_RANGE_E enDynamicRange = DYNAMIC_RANGE_SDR8; //动态范围
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_ONLINE_VPSS_OFFLINE; //VI PIPE 和 VPSS 组的工作模式
/************************************************
step1: Get all sensors information
*************************************************/
SAMPLE_COMM_VI_GetSensorInfo(&stViConfig);
ComboDev = SAMPLE_COMM_VI_GetComboDevBySensor(stViConfig.astViInfo[s32WorkSnsId].stSnsInfo.enSnsType, s32WorkSnsId);
stViConfig.s32WorkingViNum = 1;
stViConfig.as32WorkingViId[0] = 0;
stViConfig.astViInfo[0].stSnsInfo.MipiDev = ComboDev;
stViConfig.astViInfo[0].stSnsInfo.s32BusId = 0;
stViConfig.astViInfo[0].stDevInfo.ViDev = ViDev;
stViConfig.astViInfo[0].stDevInfo.enWDRMode = WDR_MODE_NONE;
stViConfig.astViInfo[0].stPipeInfo.enMastPipeMode = enMastPipeMode;
stViConfig.astViInfo[0].stPipeInfo.aPipe[0] = ViPipe;
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;
/************************************************
step2: Get input size
*************************************************/
s32Ret = SAMPLE_COMM_VI_GetSizeBySensor(stViConfig.astViInfo[s32WorkSnsId].stSnsInfo.enSnsType, &enPicSize);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VI_GetSizeBySensor failed!\n");
return s32Ret;
}
s32Ret = SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed!\n");
return s32Ret;
}
else
{
SAMPLE_PRT("==============================================\n");
SAMPLE_PRT("The resolution of the sensor is (%d x %d)\n", stSize.u32Width, stSize.u32Height);
SAMPLE_PRT("The pixel format of the sensor is %d\n", enPixFormat);
SAMPLE_PRT("==============================================\n");
}
/************************************************
step3: Init SYS and common VB(视频缓存池处理模块)
*************************************************/
hi_memset(&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, 32);
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);
SAMPLE_COMM_SYS_Exit();
return s32Ret;
}
s32Ret = SAMPLE_COMM_VI_SetParam(&stViConfig);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_COMM_SYS_Exit();
return s32Ret;
}
/************************************************
step4: Init VI and VO
*************************************************/
SAMPLE_COMM_VO_GetDefConfig(&stVoConfig);
s32Ret = SAMPLE_VIO_StartViVo(&stViConfig, &stVoConfig);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_VIO_StartViVo failed witfh %d\n", s32Ret);
goto EXIT;
}
// 获取PipeAttr信息,需要在系统初始化之后,否则报错
VI_PIPE_ATTR_S stPipeAttr;
s32Ret = HI_MPI_VI_GetPipeAttr(0, &stPipeAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VI_GetPipeAttr failed!\n");
SAMPLE_PRT("%x\n",s32Ret); //输出错误码
return s32Ret;
}
else
{
//这里输出了一个-1.......,就是默认值,但是默认值是多少啊?????? 30fps
SAMPLE_PRT("==============================================\n");
HI_U32 rate;
if(stPipeAttr.stFrameRate.s32SrcFrameRate == -1)
{
rate = 30;
}
else
{
rate = stPipeAttr.stFrameRate.s32SrcFrameRate;
}
SAMPLE_PRT("The frame rate of the sensor is %d fps\n", rate);
SAMPLE_PRT("==============================================\n");
}
/************************************************
step5: Bind VI and VO
*************************************************/
s32Ret = SAMPLE_COMM_VI_Bind_VO(ViPipe, ViChn, VoDev, VoChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VI_Bind_VO failed with %#x!\n", s32Ret);
goto EXIT1;
}
PAUSE();
SAMPLE_COMM_VI_UnBind_VO(ViPipe, ViChn, VoDev, VoChn); //解除bind
EXIT1:
SAMPLE_VIO_StopViVo(&stViConfig, &stVoConfig);
EXIT:
SAMPLE_COMM_SYS_Exit();
return s32Ret;
}
/******************************************************************************
* function : main()
* Description : main
******************************************************************************/
int main(int argc, char* argv[])
{
HI_S32 s32Ret = HI_FAILURE;
VO_INTF_TYPE_E enVoIntfType = VO_INTF_HDMI; //输出格式
signal(SIGINT, SAMPLE_VIO_HandleSig);
signal(SIGTERM, SAMPLE_VIO_HandleSig);
s32Ret = MY_SAMPLE_VIO(enVoIntfType);
if (HI_SUCCESS == s32Ret)
{
SAMPLE_PRT("my_vio exit success!\n")