视频输入 范例

视频输入配置

/*********************************
*函数功能:使能视频输入设备
*输出参数:
*返回值:成功为0 失败非0
*********************************/
HI_S32 enable_VI_dev()
{
    HI_S32 s32Ret;     //返回值
    VI_DEV ViDev = 0;     //VI设备号
    VI_CHN ViChn = 0;     //VI通道号
    VI_DEV_ATTR_S stDevAttr; 
    VI_CHN_ATTR_S stChnAttr; 

    stDevAttr.enIntfMode =VI_MODE_BT1120_STANDARD;         //接口模式
    stDevAttr.enWorkMode = VI_WORK_MODE_1Multiplex;     //124路复合工作模式
    stDevAttr.au32CompMask[0] = 0xFF000000;             //分量掩码
    stDevAttr.au32CompMask[1] = 0xFF0000; 
    stDevAttr. enClkEdge = VI_CLK_EDGE_SINGLE_UP;         //时钟边沿采样模式
    stDevAttr.s32AdChnId[0] = -1;                         //取值范围
    stDevAttr.s32AdChnId[1] = -1; 
    stDevAttr.s32AdChnId[2] = -1;
    stDevAttr.s32AdChnId[3] = -1; 
    s32Ret = HI_MPI_VI_SetDevAttr(ViDev, &stDevAttr);     //设置VI设备属性
    if (s32Ret != HI_SUCCESS) 
    { 
        printf("Set dev attributes failed with error code %#x!
", s32Ret); 
        return HI_FAILURE; 
    } 

    s32Ret = HI_MPI_VI_EnableDev(ViDev);                 //使能VI设备
    if (s32Ret != HI_SUCCESS) 
    { 
        printf("Enable dev failed with error code %#x!
", s32Ret); 
        return HI_FAILURE; 
    } 

    /*配置通道属性*/
    stChnAttr.stCapRest.s32X = 0;                         //捕获区域起始坐标
    stChnAttr.stCapRect.s32Y = 0; 
    stChnAttr.stCapRect.u32Width = 1920;                 //捕获区域宽高
    stChnAttr.stCapRect.u32Height = 1080; 
    stChnAttr.stDestSize.u32Width = 1920;                 //目标图像大小
    stChnAttr.stDestSize.u32Height = 1080; 
    stChnAttr.enCapSel = VI_CAPSEL_BOTH;                 //帧场选择 只用于隔行模式
    stChnAttr.enScanMode = VI_SCAN_PROGRESSIVE;         //输入扫描模式 逐行or隔行
    stChnAttr.enPixFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_422;     //小苏储存格式
    stChnAttr.bMirror = HI_FALSE;                         //是否水平翻转
    stChnAttr.bFlip = HI_FALSE;                         //是否垂直翻转
    stChnAttr.s32SrcFrameRate = -1;                     //原始帧率
    stChnAttr.s32DstFrameRate = -1;                     //目标帧率
    s32Ret = HI_MPI_VI_SetChnAttr(ViChn,&stChnAttr);     //通道属性
    if (s32Ret != HI_SUCCESS) 
    { 
        printf("Set chn attributes failed with error code %#x!
", s32Ret); 
        return HI_FAILURE; 
    } 

    s32Ret = HI_MPI_VI_EnableChn(ViChn);                 //使能通道
    if (s32Ret != HI_SUCCESS) 
    { 
        printf("Enable chn failed with error code %#x!
", s32Ret); 
        return HI_FAILURE; 
    } 

/* now, vi is capturing images, you can do something else ... */ 

    s32Ret = HI_MPI_VI_DisableChn(ViChn);                 //关闭通道
    if (s32Ret != HI_SUCCESS)
    { 
        printf("Disable chn failed with error code %#x!
", s32Ret); 
        return HI_FAILURE; 
    } 

    s32Ret = HI_MPI_VI_DisableDev(ViDev);                 //关闭设备
    if (s32Ret != HI_SUCCESS) 
    { 
        printf("Disable dev failed with error code %#x!
", s32Ret); 
        return HI_FAILURE; 
    }    
}

实例:

HI_S32 vi_create_chn(PIXEL_FORMAT_E pixform, int vi_chn_num)
{
    
    VI_DEV ViDev;
    VI_DEV_ATTR_S stViDevAttr;
    VI_CHN_BIND_ATTR_S stChnBindAttr;
    HI_S32 s32Ret = 0;;
    HI_S32 vi_chn;    
    VI_CHN_ATTR_S stChnAttr,stChnMinorAttr;
    HI_S32 i = 0;
    unsigned char ch=0;
    unsigned char ch_1080p_num=0;
    unsigned char local_channel = 0;
    int vi_chn_num_number ;
    
    memset(&stViDevAttr,0,sizeof(stViDevAttr));
    memcpy(&stViDevAttr,&DEV_ATTR_6114_720P_1MUX_BASE,sizeof(stViDevAttr));

    //设置VI设备属性
    
        if(vi_chn_num == 4)
        {
             vi_chn_num_number = vi_chn_num*2;
        }
        else
        {
             vi_chn_num_number = vi_chn_num;
        }
    for(i=0; i<vi_chn_num_number/4; i++)
    {
        //根据当前的硬件绑定关系,需要开启的VI 设备为DEV2,DEV3
        ViDev =i;
        SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr);

        //modify by yqf 2018.6.21
        stViDevAttr.enClkEdge = VI_CLK_EDGE_DOUBLE;     //时钟边沿模式
        //stViDevAttr.enClkEdge = VI_CLK_EDGE_SINGLE_UP;
/*         s32Ret = HI_MPI_VI_DisableDev(ViDev);
         if (s32Ret != HI_SUCCESS)
         {
             SDKPRINTF("HI_MPI_VI_DiableDev failed with %#x!
", s32Ret);
             return HI_FAILURE;
         }*/
         s32Ret = HI_MPI_VI_SetDevAttr(ViDev, &stViDevAttr);     //设置VI设备属性
        if (s32Ret != HI_SUCCESS)
        {
            SDKPRINTF("HI_MPI_VI_SetDevAttr failed with %#x!
", s32Ret);
            return HI_FAILURE;
        }

        s32Ret = HI_MPI_VI_EnableDev(ViDev);    //启用VI设备
        if (s32Ret != HI_SUCCESS)
        {
            SDKPRINTF("HI_MPI_VI_EnableDev failed with %#x!
", s32Ret);
            return HI_FAILURE;
        }

    }

    // 设置VI通道属性
    for(i=0; i<vi_chn_num; i++)
    {
            vi_chn = channel_adjust[i];

            /* When in the 8x1080p mode, bind chn 2,6,10,14 to way1 is needed */
            //1080P和720P需要修改绑定关系vi通道与vi设备之间的绑定关系
            //if(major_stream[i].width>=1280)
        /*
            {
                if(vi_chn%4 != 0)
                {
                    s32Ret = HI_MPI_VI_GetChnBind(vi_chn, &stChnBindAttr);
                    if(HI_ERR_VI_FAILED_NOTBIND == s32Ret)
                    {
                        stChnBindAttr.ViDev = vi_chn/4;
                          stChnBindAttr.ViWay = 1;
                          s32Ret = HI_MPI_VI_BindChn(vi_chn, &stChnBindAttr);
                          if(HI_SUCCESS != s32Ret)
                          {
                            SDKPRINTF("call HI_MPI_VI_BindChn failed with %#x
", s32Ret);
                             return HI_FAILURE;
                          } 
                    } 
                }
            
            }
        */
            stChnAttr.stCapRect.s32X = 0;     
            stChnAttr.stCapRect.s32Y = 0;
            //获取当前本地通道的索引值
            local_channel = local_chan_index(i);
            stChnAttr.stDestSize.u32Width  = major_stream[local_channel].width;
            stChnAttr.stDestSize.u32Height = major_stream[local_channel].height;
            stChnAttr.enCapSel = VI_CAPSEL_BOTH;

            //modify by yqf 2018.6.21
            if(major_stream[local_channel].width==1280)
            {
                stChnAttr.stCapRect.u32Width = major_stream[local_channel].width;    //*2;
            }
            //else if(major_stream[local_channel].width==960)
            else if(major_stream[local_channel].width < 600)
            {
                stChnAttr.stCapRect.u32Width = major_stream[local_channel].width*2; //*4;
            }
            else 
            {
                stChnAttr.stCapRect.u32Width=major_stream[local_channel].width;
            }
            printf("%d th  origial width  is %d , cap width  is %d!
",i,major_stream[local_channel].width,stChnAttr.stCapRect.u32Width);
            // stChnAttr.stCapRect.u32Width=major_stream[i].width;
            stChnAttr.stCapRect.u32Height = major_stream[local_channel].height;    
            stChnAttr.enPixFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420; 
            stChnAttr.bMirror = HI_FALSE;
            stChnAttr.bFlip = HI_FALSE;

            if(major_stream[local_channel].width == 1920)
            {
                if(major_stream[local_channel].v_norm == VIDEO_FORMAT_NTSC)
                {
                    stChnAttr.s32SrcFrameRate = 30;
                    stChnAttr.s32DstFrameRate= 15;
                }
                else
                {
                    stChnAttr.s32SrcFrameRate = 25;
                    stChnAttr.s32DstFrameRate= 15;
                }
                
            }
            else if(major_stream[local_channel].height == 720)
            {
                if(major_stream[local_channel].v_norm == VIDEO_FORMAT_NTSC)
                {
                    stChnAttr.s32SrcFrameRate = 30;
                    stChnAttr.s32DstFrameRate = 15; //25;
                }
                else
                {
                    stChnAttr.s32SrcFrameRate = 25;
                    stChnAttr.s32DstFrameRate = 15; //25;
                }
            }
            else
            {
                stChnAttr.s32SrcFrameRate = -1;
                stChnAttr.s32DstFrameRate= -1;
            }
        
        if(major_stream[local_channel].height<600)
        {
            stChnAttr.enScanMode=VI_SCAN_INTERLACED;
        }
        else
        {
            
stChnAttr.enScanMode=VI_SCAN_PROGRESSIVE;
        }
        printf("%d th major stream width is %d!
",i,major_stream[i].width);
        //设置通道属性
        s32Ret = HI_MPI_VI_SetChnAttr(vi_chn, &stChnAttr);
        if (s32Ret != HI_SUCCESS)
        {
            SDKPRINTF("vi_chn (%d) failed with %#x!
",vi_chn, s32Ret);
            return HI_FAILURE;
        }
        /*
        if(major_stream[i].width == 1920)
        {
            stChnMinorAttr.stDestSize.u32Width= 960;
               stChnMinorAttr.stDestSize.u32Height= 540;

            stChnMinorAttr.s32SrcFrameRate = 30;
            stChnMinorAttr.s32DstFrameRate = 10;

              s32Ret = HI_MPI_VI_SetChnMinorAttr(vi_chn, &stChnMinorAttr);
            if (HI_SUCCESS != s32Ret)
            {
                SDKPRINTF("call HI_MPI_VI_SetChnMinorAttr failed with %#x
", s32Ret);
                return HI_FAILURE;
            } 
        }
        */
        
        /*        
        if(major_stream[i].width==960)
        {
            
            s32Ret =HI_MPI_VI_SetSkipMode(vi_chn,1);
            if (s32Ret != HI_SUCCESS)
            {
                SDKPRINTF("failed with %#x!
", s32Ret);
                return HI_FAILURE;
            }
            
        }
        else if(major_stream[i].width==1280)
        {
            s32Ret =HI_MPI_VI_SetSkipMode(vi_chn,2);
            if (s32Ret != HI_SUCCESS)
            {
                SDKPRINTF("failed with %#x!
", s32Ret);
                return HI_FAILURE;
            }
        }
        else if(major_stream[i].width==1920)
        {
            s32Ret =HI_MPI_VI_SetSkipMode(vi_chn,0);
            if (s32Ret != HI_SUCCESS)
            {
                SDKPRINTF("failed with %#x!
", s32Ret);
                return HI_FAILURE;
            }
        }
        */
    
    #if 0
        if((major_stream[i].videosize == PIC_720PV1) || if(major_stream[i].videosize == PIC_720PV2))
        {
            if(2 == vi_chn%4)
            {    
                s32Ret = HI_MPI_VI_EnableChn422to420(vi_chn);
                if (s32Ret != HI_SUCCESS)
                {
                    SDKPRINTF("HI_MPI_VI_EnableChn422to420 failed with %#x!
", s32Ret);
                    return HI_FAILURE;
                }        
            }
        }
    #endif
    
        s32Ret = HI_MPI_VI_EnableChn(vi_chn);
        if (s32Ret != HI_SUCCESS)
        {
            SDKPRINTF("failed with %#x!
", s32Ret);
            return HI_FAILURE;
        }

        /*
        if(major_stream[i].width==1280)
        {
            VI_SKIP_MODE_EX_S stModeEx;
            s32Ret = HI_MPI_VI_GetSkipModeEx(vi_chn,&stModeEx);
            stModeEx.bEnable = HI_TRUE;
            stModeEx.u32YMask = 9;
            s32Ret = HI_MPI_VI_SetSkipModeEx(vi_chn,&stModeEx);
            if (s32Ret != HI_SUCCESS)
            {
                SDKPRINTF("failed with %#x!
", s32Ret);
                return HI_FAILURE;
            }
        }else{
                        VI_SKIP_MODE_EX_S stModeEx;
                        s32Ret = HI_MPI_VI_GetSkipModeEx(vi_chn,&stModeEx);
                        stModeEx.bEnable = HI_FALSE;
                stModeEx.u32YMask = 1;
                s32Ret = HI_MPI_VI_SetSkipModeEx(vi_chn,&stModeEx);
                        if (s32Ret != HI_SUCCESS)
                        {
                                SDKPRINTF("failed with %#x!
", s32Ret);
                                return HI_FAILURE;
                        }
        }
        */
    
    }
    
    return HI_SUCCESS;
}
原文地址:https://www.cnblogs.com/qifeng1024/p/13475586.html