文章目录
基本概念
- 视频输入设备(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");
}
else
{
SAMPLE_PRT("my_vio exit abnormally!\n");
}
return s32Ret;
}
- 运行结果:
二、实现多路VPSS分别进行裁剪、锐化、缩放、旋转的任务
#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;
}
图像处理结果:(原图、裁剪、旋转90、缩放)
三、实现VO与VPSS绑定,测试VO的旋转、缩放功能,并输出VO设备的像素、帧率信息
#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;
}
图像处理结果(旋转90度+缩放):
终端运行输出结果:
总结
海思的mpp/sample还是很实用的。。。。(。-_-。)
- 关于缩放:如果只用vpss缩放,vo输出图像会自动适应显示器的大小;
- 关于缩放:vo设置显示的分辨率才能让显示变成对应的分辨率;