Hi3559 MPP Learning Record (2)


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

insert image description here

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:
    insert image description here

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)
insert image description here


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):
insert image description here

The output of the terminal operation:
insert image description here


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;

Guess you like

Origin blog.csdn.net/weixin_49513223/article/details/130515056