Article Directory
- basic concept
- 1. Sensor data acquisition and output sensor resolution, pixel format, frame rate and other information
- 2. Realize the tasks of cropping, sharpening, zooming, and rotating by multi-channel VPSS respectively
- 3. Realize the binding between VO and VPSS, test the rotation and zoom functions of VO, and output the pixel and frame rate information of VO equipment
- Summarize
basic concept
- Video input device (DEV)
- Video input physical PIPE
- The PIPE of the video input virtual PIPE
VI includes the relevant processing functions of the ISP, mainly to perform pipeline processing on the image data, and output the YUV image format to the channel - Video input physical channel (PHY_CHN)
- Extended channel (EXT_CHN)
The extended channel is an extension of the physical channel, and the extended channel has the functions of zooming, cropping, and fisheye correction
In the vi module of the hisi platform, there is a relationship of sensor -> dev -> pipe -> phy_chn -> ext_chn
1. Sensor data acquisition and output sensor resolution, pixel format, frame rate and other information
- Code:
#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");
}
else
{
SAMPLE_PRT("my_vio exit abnormally!\n");
}
return s32Ret;
}
- operation result:
2. Realize the tasks of cropping, sharpening, zooming, and rotating by multi-channel VPSS respectively
#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 MY_SAMPLE_COMM_VPSS_Start(VPSS_GRP VpssGrp, HI_BOOL* pabChnEnable, VPSS_GRP_ATTR_S* pstVpssGrpAttr, VPSS_CHN_ATTR_S* pastVpssChnAttr,
VPSS_CROP_INFO_S* pstCropInfo, ROTATION_E enRotation)
{
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;
}
/***********************************************
sharpen锐化
************************************************/
VPSS_GRP_SHARPEN_ATTR_S stGrpSharpenAttr;
s32Ret = HI_MPI_VPSS_GetGrpSharpen(VpssGrp, &stGrpSharpenAttr);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_GetGrpSharpen failed with %#x\n", s32Ret);
return HI_FAILURE;
}
stGrpSharpenAttr.bEnable = HI_TRUE; //其他都是默认值?应该
s32Ret = HI_MPI_VPSS_SetGrpSharpen(VpssGrp, &stGrpSharpenAttr);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_SetGrpSharpen failed with %#x\n", 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;
}
// if(VpssChn == 0) chn0是原图
if(VpssChn == 1)
{
// chn1做裁剪
s32Ret = HI_MPI_VPSS_SetChnCrop(VpssGrp, VpssChn, pstCropInfo);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_SetChnCrop failed with %#x\n", s32Ret);
return HI_FAILURE;
}
}
if(VpssChn == 2)
{
// chn2做旋转
s32Ret = HI_MPI_VPSS_SetChnRotation (VpssGrp, VpssChn, enRotation);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_SetChnRotation failed with %#x\n", s32Ret);
return HI_FAILURE;
}
}
if(VpssChn == 3)
{
// chn3做缩放
// 这里输出视频到HDMI后,没有黑边,但是像素明显变了
pastVpssChnAttr[VpssChn].u32Width = 256;//此处设置所需的图片像素大小
pastVpssChnAttr[VpssChn].u32Height = 256;
s32Ret = HI_MPI_VPSS_SetChnAttr(VpssGrp, VpssChn, &pastVpssChnAttr[VpssChn]);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_SetChnAttr chn[%d] failed with %#x\n", VpssChn, 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;
}
HI_S32 MY_SAMPLE_VIPO(VO_INTF_TYPE_E enVoIntfType)
{
HI_S32 s32Ret = HI_SUCCESS;
VI_DEV ViDev0 = 0;
VI_PIPE ViPipe0 = 0;
VI_CHN ViChn = 0;
HI_S32 s32ViCnt = 1;
VPSS_GRP VpssGrp0 = 0;
VPSS_CHN VpssChn[4] = {
VPSS_CHN0, VPSS_CHN1, VPSS_CHN2, VPSS_CHN3};
VPSS_GRP_ATTR_S stVpssGrpAttr = {
0};
VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_PHY_CHN_NUM];
HI_BOOL abChnEnable[VPSS_MAX_PHY_CHN_NUM] = {
0};
VO_DEV VoDev = SAMPLE_VO_DEV_DHD0;
VO_CHN VoChn = 0;
VO_INTF_SYNC_E g_enIntfSync = VO_OUTPUT_1024x768_60;
HI_U32 g_u32DisBufLen = 3;
PIC_SIZE_E enPicSize = PIC_1080P;
WDR_MODE_E enWDRMode = WDR_MODE_NONE;
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_ONLINE;
SIZE_S stSize;
HI_U32 u32BlkSize;
VB_CONFIG_S stVbConf;
SAMPLE_VI_CONFIG_S stViConfig;
SAMPLE_VO_CONFIG_S stVoConfig;
SAMPLE_PRT("VPSS_MAX_PHY_CHN_NUM is %d!\n", VPSS_MAX_PHY_CHN_NUM);
/************************************************
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;
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;
/************************************************
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;
}
/************************************************
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, 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;
}
/************************************************
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;
}
/************************************************
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;
HI_S32 i;
for(i = 0; i < VPSS_MAX_PHY_CHN_NUM; i++)
{
abChnEnable[i] = HI_TRUE;
stVpssChnAttr[i].u32Width = stSize.u32Width;
stVpssChnAttr[i].u32Height = stSize.u32Height;
stVpssChnAttr[i].enChnMode = VPSS_CHN_MODE_USER;
stVpssChnAttr[i].enCompressMode = enCompressMode;
stVpssChnAttr[i].enDynamicRange = enDynamicRange;
stVpssChnAttr[i].enPixelFormat = enPixFormat;
stVpssChnAttr[i].enVideoFormat = enVideoFormat;
stVpssChnAttr[i].stFrameRate.s32SrcFrameRate = -1;
stVpssChnAttr[i].stFrameRate.s32DstFrameRate = -1;
stVpssChnAttr[i].u32Depth = 1;
stVpssChnAttr[i].bMirror = HI_FALSE;
stVpssChnAttr[i].bFlip = HI_FALSE;
stVpssChnAttr[i].stAspectRatio.enMode = ASPECT_RATIO_NONE;
}
/***********************************************
Crop裁剪
************************************************/
VPSS_CROP_INFO_S stCropInfo;
stCropInfo.bEnable = HI_TRUE;
stCropInfo.enCropCoordinate = VPSS_CROP_ABS_COOR; //绝对坐标模式
stCropInfo.stCropRect.s32X = 0;
stCropInfo.stCropRect.s32Y = 0;
stCropInfo.stCropRect.u32Width = 1000;
stCropInfo.stCropRect.u32Height = 1000;
/***********************************************
旋转
************************************************/
ROTATION_E enRotation = ROTATION_90;
s32Ret = MY_SAMPLE_COMM_VPSS_Start(VpssGrp0, abChnEnable, &stVpssGrpAttr, stVpssChnAttr, &stCropInfo, enRotation);
//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;
}
/************************************************
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;
}
/************************************************
step 8: VO bind VPSS
*************************************************/
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 EXIT1;
}
printf("The original image now displayed, press any key to view the cropped image\n");
getchar();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[0], stVoConfig.VoDev, VoChn);
s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp0, VpssChn[1], stVoConfig.VoDev, VoChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VPSS_Bind_VO Grp0 failed with %d!\n", s32Ret);
goto EXIT1;
}
printf("The cropped image now displayed, press any key to view the rotated image\n");
getchar();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[1], stVoConfig.VoDev, VoChn);
s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp0, VpssChn[2], stVoConfig.VoDev, VoChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VPSS_Bind_VO Grp0 failed with %d!\n", s32Ret);
goto EXIT1;
}
printf("The rotated image now displayed, press any key to view the zoomed image\n");
getchar();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[2], stVoConfig.VoDev, VoChn);
s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp0, VpssChn[3], stVoConfig.VoDev, VoChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VPSS_Bind_VO Grp0 failed with %d!\n", s32Ret);
goto EXIT1;
}
printf("The zoomed image now displayed, press any key to stop\n");
getchar();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[3], stVoConfig.VoDev, VoChn);
// PAUSE();
// SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[1], stVoConfig.VoDev, VoChn);
EXIT1:
SAMPLE_COMM_VO_StopVO(&stVoConfig);
EXIT2:
SAMPLE_COMM_VPSS_Stop(VpssGrp0, abChnEnable);
EXIT3:
SAMPLE_COMM_VI_StopVi(&stViConfig);
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_VIPO(enVoIntfType);
if (HI_SUCCESS == s32Ret)
{
SAMPLE_PRT("my_vipo exit success!\n");
}
else
{
SAMPLE_PRT("my_vipo exit abnormally!\n");
}
return s32Ret;
}
Image processing results: (original image, cropped, rotated 90, zoomed)
3. Realize the binding between VO and VPSS, test the rotation and zoom functions of VO, and output the pixel and frame rate information of VO equipment
#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 MY_SAMPLE_COMM_VPSS_Start(VPSS_GRP VpssGrp, HI_BOOL* pabChnEnable, VPSS_GRP_ATTR_S* pstVpssGrpAttr, VPSS_CHN_ATTR_S* pastVpssChnAttr,
VPSS_CROP_INFO_S* pstCropInfo, ROTATION_E enRotation)
{
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;
}
/***********************************************
sharpen锐化
************************************************/
VPSS_GRP_SHARPEN_ATTR_S stGrpSharpenAttr;
s32Ret = HI_MPI_VPSS_GetGrpSharpen(VpssGrp, &stGrpSharpenAttr);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_GetGrpSharpen failed with %#x\n", s32Ret);
return HI_FAILURE;
}
stGrpSharpenAttr.bEnable = HI_TRUE; //其他都是默认值?应该
s32Ret = HI_MPI_VPSS_SetGrpSharpen(VpssGrp, &stGrpSharpenAttr);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_SetGrpSharpen failed with %#x\n", 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;
}
// if(VpssChn == 0) chn0是原图
if(VpssChn == 1)
{
// chn1做裁剪
s32Ret = HI_MPI_VPSS_SetChnCrop(VpssGrp, VpssChn, pstCropInfo);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_SetChnCrop failed with %#x\n", s32Ret);
return HI_FAILURE;
}
}
if(VpssChn == 2)
{
// chn2做旋转
s32Ret = HI_MPI_VPSS_SetChnRotation (VpssGrp, VpssChn, enRotation);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_SetChnRotation failed with %#x\n", s32Ret);
return HI_FAILURE;
}
}
if(VpssChn == 3)
{
// chn3做缩放
// 这里输出视频到HDMI后,没有黑边,但是像素明显变了
pastVpssChnAttr[VpssChn].u32Width = 512;//此处设置所需的图片像素大小
pastVpssChnAttr[VpssChn].u32Height = 512;
s32Ret = HI_MPI_VPSS_SetChnAttr(VpssGrp, VpssChn, &pastVpssChnAttr[VpssChn]);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VPSS_SetChnAttr chn[%d] failed with %#x\n", VpssChn, 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;
}
HI_S32 MY_SAMPLE_COMM_VO_StartVO(SAMPLE_VO_CONFIG_S *pstVoConfig)
{
RECT_S stDefDispRect = {
0, 0, 1920, 1080};
SIZE_S stDefImageSize = {
1920, 1080};
/*******************************************
* VO device VoDev# information declaration.
********************************************/
VO_DEV VoDev = 0;
VO_LAYER VoLayer = 0;
SAMPLE_VO_MODE_E enVoMode = 0;
VO_INTF_TYPE_E enVoIntfType = VO_INTF_HDMI;
VO_INTF_SYNC_E enIntfSync = VO_OUTPUT_1080P30;
DYNAMIC_RANGE_E enDstDyRg = DYNAMIC_RANGE_SDR8;
VO_PART_MODE_E enVoPartMode = VO_PART_MODE_SINGLE;
VO_PUB_ATTR_S stVoPubAttr = {
0};
VO_VIDEO_LAYER_ATTR_S stLayerAttr = {
0};
HI_S32 s32Ret = HI_SUCCESS;
if (NULL == pstVoConfig)
{
SAMPLE_PRT("Error:argument can not be NULL\n");
return HI_FAILURE;
}
VoDev = pstVoConfig->VoDev;
VoLayer = pstVoConfig->VoDev;
enVoMode = pstVoConfig->enVoMode;
enVoIntfType = pstVoConfig->enVoIntfType;
enIntfSync = pstVoConfig->enIntfSync;
enDstDyRg = pstVoConfig->enDstDynamicRange;
enVoPartMode = pstVoConfig->enVoPartMode;
/********************************
* Set and start VO device VoDev#.
*********************************/
stVoPubAttr.enIntfType = enVoIntfType;
stVoPubAttr.enIntfSync = enIntfSync;
stVoPubAttr.u32BgColor = pstVoConfig->u32BgColor;
s32Ret = SAMPLE_COMM_VO_StartDev(VoDev, &stVoPubAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VO_StartDev failed!\n");
return s32Ret;
}
/******************************
* Set and start layer VoDev#.
********************************/
s32Ret = SAMPLE_COMM_VO_GetWH(stVoPubAttr.enIntfSync,
&stLayerAttr.stDispRect.u32Width, &stLayerAttr.stDispRect.u32Height,
&stLayerAttr.u32DispFrmRt);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VO_GetWH failed!\n");
SAMPLE_COMM_VO_StopDev(VoDev);
return s32Ret;
}
stLayerAttr.bClusterMode = HI_FALSE;
stLayerAttr.bDoubleFrame = HI_FALSE;
stLayerAttr.enPixFormat = pstVoConfig->enPixFormat;
stLayerAttr.stDispRect.s32X = 0;
stLayerAttr.stDispRect.s32Y = 0;
/******************************
// Set display rectangle if changed.
********************************/
if (0 != memcmp(&pstVoConfig->stDispRect, &stDefDispRect, sizeof(RECT_S)))
{
stLayerAttr.stDispRect = pstVoConfig->stDispRect;
}
stLayerAttr.stImageSize.u32Width = stLayerAttr.stDispRect.u32Width;
stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height;
stLayerAttr.stImageSize.u32Width = stLayerAttr.stDispRect.u32Width;
stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height;
/******************************
//Set image size if changed.
********************************/
if (0 != memcmp(&pstVoConfig->stImageSize, &stDefImageSize, sizeof(SIZE_S)))
{
stLayerAttr.stImageSize = pstVoConfig->stImageSize;
}
stLayerAttr.enDstDynamicRange = pstVoConfig->enDstDynamicRange;
if (pstVoConfig->u32DisBufLen)
{
s32Ret = HI_MPI_VO_SetDisplayBufLen(VoLayer, pstVoConfig->u32DisBufLen);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VO_SetDisplayBufLen failed with %#x!\n",s32Ret);
SAMPLE_COMM_VO_StopDev(VoDev);
return s32Ret;
}
}
if (VO_PART_MODE_MULTI == enVoPartMode)
{
s32Ret = HI_MPI_VO_SetVideoLayerPartitionMode(VoLayer, enVoPartMode);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VO_SetVideoLayerPartitionMode failed!\n");
SAMPLE_COMM_VO_StopDev(VoDev);
return s32Ret;
}
}
/**************zoom***********************/
stLayerAttr.stDispRect.u32Width = 256;
stLayerAttr.stDispRect.u32Height = 256;
stLayerAttr.stImageSize.u32Width = stLayerAttr.stDispRect.u32Width;
stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height;
SAMPLE_PRT("==============================================\n");
SAMPLE_PRT("The display resolution of VO is (%d x %d)\n", stLayerAttr.stDispRect.u32Width, stLayerAttr.stDispRect.u32Width);
SAMPLE_PRT("The video display frame rate is %d\n", stLayerAttr.u32DispFrmRt);
SAMPLE_PRT("==============================================\n");
s32Ret = HI_MPI_VO_SetVideoLayerAttr(VoLayer, &stLayerAttr);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VO_SetVideoLayerAttr failed with %#x!\n", s32Ret);
SAMPLE_COMM_VO_StopDev(VoDev);
return HI_FAILURE;
}
s32Ret = HI_MPI_VO_EnableVideoLayer(VoLayer);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT(" HI_MPI_VO_EnableVideoLayerfailed with %#x!\n", s32Ret);
SAMPLE_COMM_VO_StopDev(VoDev);
return HI_FAILURE;
}
/******************************
* start vo channels.
********************************/
s32Ret = SAMPLE_COMM_VO_StartChn(VoLayer, enVoMode);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VO_StartChn failed!\n");
SAMPLE_COMM_VO_StopLayer(VoLayer);
SAMPLE_COMM_VO_StopDev(VoDev);
return s32Ret;
}
/**************set rotation****************/
s32Ret = HI_MPI_VO_SetChnRotation(VoLayer, 0, ROTATION_90);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VO_SetChnRotation failed with %#x!\n", s32Ret);
return s32Ret;
}
/******************************
* Start hdmi device.
* Note : do this after vo device started.
********************************/
if(VO_INTF_HDMI == enVoIntfType)
{
SAMPLE_COMM_VO_HdmiStartByDyRg(enIntfSync, enDstDyRg);
}
return HI_SUCCESS;
}
HI_S32 MY_SAMPLE_VIPO(VO_INTF_TYPE_E enVoIntfType)
{
HI_S32 s32Ret = HI_SUCCESS;
VI_DEV ViDev0 = 0;
VI_PIPE ViPipe0 = 0;
VI_CHN ViChn = 0;
HI_S32 s32ViCnt = 1;
VPSS_GRP VpssGrp0 = 0;
VPSS_CHN VpssChn[4] = {
VPSS_CHN0, VPSS_CHN1, VPSS_CHN2, VPSS_CHN3};
VPSS_GRP_ATTR_S stVpssGrpAttr = {
0};
VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_PHY_CHN_NUM];
HI_BOOL abChnEnable[VPSS_MAX_PHY_CHN_NUM] = {
0};
VO_DEV VoDev = SAMPLE_VO_DEV_DHD0;
VO_CHN VoChn = 0;
VO_INTF_SYNC_E g_enIntfSync = VO_OUTPUT_1024x768_60;
HI_U32 g_u32DisBufLen = 3;
PIC_SIZE_E enPicSize = PIC_1080P;
WDR_MODE_E enWDRMode = WDR_MODE_NONE;
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_ONLINE;
SIZE_S stSize;
HI_U32 u32BlkSize;
VB_CONFIG_S stVbConf;
SAMPLE_VI_CONFIG_S stViConfig;
SAMPLE_VO_CONFIG_S stVoConfig;
SAMPLE_PRT("VPSS_MAX_PHY_CHN_NUM is %d!\n", VPSS_MAX_PHY_CHN_NUM);
/************************************************
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;
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;
/************************************************
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;
}
/************************************************
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, 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;
}
/************************************************
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;
}
/************************************************
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;
HI_S32 i;
for(i = 0; i < VPSS_MAX_PHY_CHN_NUM; i++)
{
abChnEnable[i] = HI_TRUE;
stVpssChnAttr[i].u32Width = stSize.u32Width;
stVpssChnAttr[i].u32Height = stSize.u32Height;
stVpssChnAttr[i].enChnMode = VPSS_CHN_MODE_USER;
stVpssChnAttr[i].enCompressMode = enCompressMode;
stVpssChnAttr[i].enDynamicRange = enDynamicRange;
stVpssChnAttr[i].enPixelFormat = enPixFormat;
stVpssChnAttr[i].enVideoFormat = enVideoFormat;
stVpssChnAttr[i].stFrameRate.s32SrcFrameRate = -1;
stVpssChnAttr[i].stFrameRate.s32DstFrameRate = -1;
stVpssChnAttr[i].u32Depth = 1;
stVpssChnAttr[i].bMirror = HI_FALSE;
stVpssChnAttr[i].bFlip = HI_FALSE;
stVpssChnAttr[i].stAspectRatio.enMode = ASPECT_RATIO_NONE;
}
/***********************************************
Crop裁剪
************************************************/
VPSS_CROP_INFO_S stCropInfo;
stCropInfo.bEnable = HI_TRUE;
stCropInfo.enCropCoordinate = VPSS_CROP_ABS_COOR; //绝对坐标模式
stCropInfo.stCropRect.s32X = 0;
stCropInfo.stCropRect.s32Y = 0;
stCropInfo.stCropRect.u32Width = 1000;
stCropInfo.stCropRect.u32Height = 1000;
/***********************************************
旋转
************************************************/
ROTATION_E enRotation = ROTATION_90;
s32Ret = MY_SAMPLE_COMM_VPSS_Start(VpssGrp0, abChnEnable, &stVpssGrpAttr, stVpssChnAttr, &stCropInfo, enRotation);
//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;
}
/************************************************
step 6: VI bind VPSS, for total parallel, no need bind
*************************************************/
/************************************************
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 = MY_SAMPLE_COMM_VO_StartVO(&stVoConfig);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VO_StartVO failed with %d!\n", s32Ret);
goto EXIT1;
}
/************************************************
step 8: VO bind VPSS
*************************************************/
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 EXIT1;
}
printf("The original image now displayed, press any key to view the cropped image\n");
getchar();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[0], stVoConfig.VoDev, VoChn);
s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp0, VpssChn[1], stVoConfig.VoDev, VoChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VPSS_Bind_VO Grp0 failed with %d!\n", s32Ret);
goto EXIT1;
}
printf("The cropped image now displayed, press any key to view the rotated image\n");
getchar();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[1], stVoConfig.VoDev, VoChn);
s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp0, VpssChn[2], stVoConfig.VoDev, VoChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VPSS_Bind_VO Grp0 failed with %d!\n", s32Ret);
goto EXIT1;
}
printf("The rotated image now displayed, press any key to view the zoomed image\n");
getchar();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[2], stVoConfig.VoDev, VoChn);
s32Ret = SAMPLE_COMM_VPSS_Bind_VO(VpssGrp0, VpssChn[3], stVoConfig.VoDev, VoChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("SAMPLE_COMM_VPSS_Bind_VO Grp0 failed with %d!\n", s32Ret);
goto EXIT1;
}
printf("The zoomed image now displayed, press any key to stop\n");
getchar();
SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[3], stVoConfig.VoDev, VoChn);
// PAUSE();
// SAMPLE_COMM_VPSS_UnBind_VO(VpssGrp0, VpssChn[1], stVoConfig.VoDev, VoChn);
EXIT1:
SAMPLE_COMM_VO_StopVO(&stVoConfig);
EXIT2:
SAMPLE_COMM_VPSS_Stop(VpssGrp0, abChnEnable);
EXIT3:
SAMPLE_COMM_VI_StopVi(&stViConfig);
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_VIPO(enVoIntfType);
if (HI_SUCCESS == s32Ret)
{
SAMPLE_PRT("my_vipo exit success!\n");
}
else
{
SAMPLE_PRT("my_vipo exit abnormally!\n");
}
return s32Ret;
}
Image processing results (rotate 90 degrees + scale):
The output of the terminal operation:
Summarize
HiSilicon's mpp/sample is still very practical. . . . (.-_-.)
- About scaling: if only vpss is used to scale, the vo output image will automatically adapt to the size of the display;
- About scaling: vo sets the resolution of the display to make the display the corresponding resolution;