Hi3559 MPP学习记录(2)


基本概念

  • 视频输入设备(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设置显示的分辨率才能让显示变成对应的分辨率;

猜你喜欢

转载自blog.csdn.net/weixin_49513223/article/details/130515056