jl3276

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276  发布于  2016-09-10 10:56:54
采纳率 0%
8个问答
14122

hi3520D的VI部分我的理解

 

[i=s] 本帖最后由 jl3276 于 2017-3-22 16:21 编辑 [/i]

[code]/*****

  • function : star vi according to product type
  • if vi input is hd, we will start sub-chn for cvbs preview ***/ HI_S32 SAMPLE_COMM_VI_Start(SAMPLE_VI_MODE_E enViMode, VIDEO_NORM_E enNorm) { VI_DEV ViDev; VI_CHN ViChn, ViChn_Sub; HI_S32 i; HI_S32 s32Ret; SAMPLE_VI_PARAM_S stViParam; SIZE_S stMainTargetSize;//SIZE_S定义尺寸信息结构体 SIZE_S stSubTargetSize; RECT_S stCapRect;//RECT_S定义矩形区域信息结构体。 /enViMode = SAMPLE_VI_MODE_4_D1;enNorm = VIDEO_ENCODING_MODE_PAL;/ /* get parameter from Sample_Vi_Mode ***/ s32Ret = SAMPLE_COMM_VI_Mode2Param(enViMode, &stViParam);//根据enViMode模式设置stViParam参数 if (HI_SUCCESS !=s32Ret) { SAMPLE_PRT("vi get param failed!\n"); return HI_FAILURE; } s32Ret = SAMPLE_COMM_VI_Mode2Size(enViMode, enNorm, &stCapRect, &stMainTargetSize);//get vi parameter, according to vi type if (HI_SUCCESS !=s32Ret) { SAMPLE_PRT("vi get size failed!\n"); return HI_FAILURE; }

    / Start AD / s32Ret = SAMPLE_COMM_VI_ADStart(enViMode, enNorm); if (HI_SUCCESS !=s32Ret) { SAMPLE_PRT("Start AD failed!\n"); return HI_FAILURE; }

    / Start VI Dev / for(i=0; i<stViParam.s32ViDevCnt; i++) { ViDev = i * stViParam.s32ViDevInterval; s32Ret = SAMPLE_COMM_VI_StartDev(ViDev, enViMode); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("SAMPLE_COMM_VI_StartDev failed with %#x\n", s32Ret); return HI_FAILURE; } }

    / Start VI Chn / for(i=0; i<stViParam.s32ViChnCnt; i++) { ViChn = i * stViParam.s32ViChnInterval;//s32ViChnInterval的含义

    s32Ret = SAMPLE_COMM_VI_StartChn(ViChn, &stCapRect, &stMainTargetSize, enViMode, VI_CHN_SET_NORMAL);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("call SAMPLE_COMM_VI_StarChn failed with %#x\n", s32Ret);
        return HI_FAILURE;
    } 
    /* HD mode, we will start vi sub-chn */
    if (HI_TRUE == SAMPLE_COMM_VI_IsHd(enViMode))
    {
        ViChn_Sub = SUBCHN(ViChn);
        s32Ret = SAMPLE_COMM_VI_GetSubChnSize(ViChn_Sub, enNorm, &stSubTargetSize);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("SAMPLE_COMM_VI_GetSubChnSize(%d) failed!\n", ViChn_Sub);
            return HI_FAILURE;
        }
        s32Ret = SAMPLE_COMM_VI_StartChn(ViChn_Sub, &stCapRect, &stSubTargetSize,enViMode, VI_CHN_SET_NORMAL);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("SAMPLE_COMM_VI_StartChn (Sub_Chn-%d) failed!\n", ViChn_Sub);
            return HI_FAILURE;
        }
    }

    }

    return HI_SUCCESS; }[/code]

hi3520D的VI部分我的理解: http://ebaina.com/bbs/thread-12613-1-1.html hi3520D的VPSS部分我的理解: http://ebaina.com/bbs/thread-12618-1-1.html hi3520D的VO部分我的理解: http://www.ebaina.com/bbs/thread-12619-1-1.html 如有问题欢迎加群讨论: 学习交流群:375323762

我来回答
回答41个
时间排序
认可量排序

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-10 10:57:57
认可0
本帖最后由 jl3276 于 2016-9-10 11:09 编辑

上面是根据产品类型启动vi的函数代码,这个函数首先调用了下面的函数,也就是第17行的SAMPLE_COMM_VI_Mode2Param,作用是根据enViMode模式设置stViParam参数
其中我的项目中的enViMode设置为了SAMPLE_VI_MODE_4_D1,所以case执行的是
case SAMPLE_VI_MODE_4_D1:
            pstViParam->s32ViDevCnt = 1;//可以看出,由于只需要四路所以,只用了一个vi设设备
            pstViParam->s32ViDevInterval = 1;//设备间隔是1,也就是没有间隔,这个参数是为了多个设备的时候循环遍历的时候用到的,这只用一个设备实质上只循环一次。
            pstViParam->s32ViChnCnt = 4;//每个设备对应4个通道也就是说可以采集4路摄像头数据
            pstViParam->s32ViChnInterval = 1;//用于后面循环处理的
                        break;
[code]
HI_S32 SAMPLE_COMM_VI_Mode2Param(SAMPLE_VI_MODE_E enViMode, SAMPLE_VI_PARAM_S *pstViParam)
{
    switch (enViMode)
    {
        case SAMPLE_VI_MODE_1_D1:
                case SAMPLE_VI_MODE_1_D1Cif:
            pstViParam->s32ViDevCnt = 1;
            pstViParam->s32ViDevInterval = 1;
            pstViParam->s32ViChnCnt = 1;
            pstViParam->s32ViChnInterval = 1;
            break;
        case SAMPLE_VI_MODE_16_D1:
            pstViParam->s32ViDevCnt = 4;
            pstViParam->s32ViDevInterval = 2;
            pstViParam->s32ViChnCnt = 16;
            pstViParam->s32ViChnInterval = 1;
            break;
        case SAMPLE_VI_MODE_16_960H:
            pstViParam->s32ViDevCnt = 4;
            pstViParam->s32ViDevInterval = 2;
            pstViParam->s32ViChnCnt = 16;
            pstViParam->s32ViChnInterval = 1;
            break;
        case SAMPLE_VI_MODE_4_720P:
            pstViParam->s32ViDevCnt = 4;
            pstViParam->s32ViDevInterval = 2;
            pstViParam->s32ViChnCnt = 4;
            pstViParam->s32ViChnInterval = 4;
            break;
        
        case SAMPLE_VI_MODE_4_1080P:
            pstViParam->s32ViDevCnt = 4;
            pstViParam->s32ViDevInterval = 2;
            pstViParam->s32ViChnCnt = 4;
            pstViParam->s32ViChnInterval = 4;            
            break;
        case SAMPLE_VI_MODE_1_1080P:   
            pstViParam->s32ViDevCnt = 1;
            pstViParam->s32ViDevInterval = 1;
            pstViParam->s32ViChnCnt = 1;
            pstViParam->s32ViChnInterval = 1;
            break;

        /*For Hi3521*/
                case SAMPLE_VI_MODE_8_D1:
            pstViParam->s32ViDevCnt = 2;
            pstViParam->s32ViDevInterval = 1;
            pstViParam->s32ViChnCnt = 8;
            pstViParam->s32ViChnInterval = 1;       
                        break;
                case SAMPLE_VI_MODE_1_720P:
            pstViParam->s32ViDevCnt = 1;
            pstViParam->s32ViDevInterval = 1;
            pstViParam->s32ViChnCnt = 1;
            pstViParam->s32ViChnInterval = 1;       
                        break;
                case SAMPLE_VI_MODE_16_Cif:
        case SAMPLE_VI_MODE_16_2Cif:
                case SAMPLE_VI_MODE_16_D1Cif:
            pstViParam->s32ViDevCnt = 4;
            pstViParam->s32ViDevInterval = 1;
            pstViParam->s32ViChnCnt = 16;
            pstViParam->s32ViChnInterval = 1;       
                        break;
        case SAMPLE_VI_MODE_4_D1:
            pstViParam->s32ViDevCnt = 1;
            pstViParam->s32ViDevInterval = 1;
            pstViParam->s32ViChnCnt = 4;
            pstViParam->s32ViChnInterval = 1;       
                        break;
        case SAMPLE_VI_MODE_8_2Cif:
        case SAMPLE_VI_MODE_8_D1Cif:
            pstViParam->s32ViDevCnt = 2;
            pstViParam->s32ViDevInterval = 1;
            pstViParam->s32ViChnCnt = 8;
            pstViParam->s32ViChnInterval = 1;       
                        break;  
        default:
            SAMPLE_PRT("ViMode invaild!\n");
            return HI_FAILURE;
    }
    return HI_SUCCESS;
}[/code]

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-10 11:08:25
认可0
本帖最后由 jl3276 于 2016-9-10 11:13 编辑

然后23行调用了这个函数:
s32Ret = SAMPLE_COMM_VI_Mode2Size(enViMode, enNorm, &stCapRect, &stMainTargetSize);//get vi parameter, according to vi type
根据vi类型获取vi参数,代码贴在下面:
[code]/*****************************************************************************
* function : get vi parameter, according to vi type
*****************************************************************************/
HI_S32 SAMPLE_COMM_VI_Mode2Size(SAMPLE_VI_MODE_E enViMode, VIDEO_NORM_E enNorm, RECT_S *pstCapRect, SIZE_S *pstDestSize)
{
    pstCapRect->s32X = 0;
    pstCapRect->s32Y = 0;
    switch (enViMode)
    {
        case SAMPLE_VI_MODE_1_D1:
        case SAMPLE_VI_MODE_16_D1:
                case SAMPLE_VI_MODE_8_D1:
            pstDestSize->u32Width = D1_WIDTH;
            pstDestSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            pstCapRect->u32Width = D1_WIDTH;
            pstCapRect->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            break;
        case SAMPLE_VI_MODE_16_960H:
            pstDestSize->u32Width = 960;
            pstDestSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            pstCapRect->u32Width = 960;
            pstCapRect->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            break;
        case SAMPLE_VI_MODE_4_720P:
                case SAMPLE_VI_MODE_1_720P:       
            pstDestSize->u32Width = 1280;
                       
            pstDestSize->u32Height = 720;
            pstCapRect->u32Width = 1280;
            pstCapRect->u32Height = 720;
            break;
        case SAMPLE_VI_MODE_4_1080P:
        case SAMPLE_VI_MODE_1_1080P:
            pstDestSize->u32Width = 1920;
            pstDestSize->u32Height = 1080;
            pstCapRect->u32Width = 1920;
            pstCapRect->u32Height = 1080;
            break;
                /*For Hi3521*/
                case SAMPLE_VI_MODE_16_2Cif:
                    pstDestSize->u32Width = D1_WIDTH / 2;
            pstDestSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            pstCapRect->u32Width = D1_WIDTH;
            pstCapRect->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
                        break;
        /*For Hi3520A*/
                case SAMPLE_VI_MODE_16_Cif:
                    pstDestSize->u32Width = D1_WIDTH /2 ;
            pstDestSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?288:240;
            pstCapRect->u32Width = D1_WIDTH;
            pstCapRect->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
                        break;
        case SAMPLE_VI_MODE_4_D1:
            pstDestSize->u32Width = D1_WIDTH;
            pstDestSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            pstCapRect->u32Width = D1_WIDTH;
            pstCapRect->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            break;
        case SAMPLE_VI_MODE_8_2Cif:
                    pstDestSize->u32Width = D1_WIDTH / 2;
            pstDestSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            pstCapRect->u32Width = D1_WIDTH;
            pstCapRect->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
                        break;
        default:
            SAMPLE_PRT("vi mode invaild!\n");
            return HI_FAILURE;
    }
   
    return HI_SUCCESS;
}
[/code]

可以看出,前两个函数参数是输入型的,后面两个实质上是通过指针输出结构体配置的,
根据我们的配置,选择的是
case SAMPLE_VI_MODE_4_D1:
            pstDestSize->u32Width = D1_WIDTH;
            pstDestSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            pstCapRect->u32Width = D1_WIDTH;
            pstCapRect->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            break;
这个匹配的.
然而实质上我接的是4路960H 的摄像头所以我把它改为了
case SAMPLE_VI_MODE_4_D1:
            pstDestSize->u32Width = 960;//D1_WIDTH;
            pstDestSize->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            pstCapRect->u32Width = 960;//D1_WIDTH;
            pstCapRect->u32Height = (VIDEO_ENCODING_MODE_PAL==enNorm)?576:480;
            break;

rafael_wl

0个粉丝

12

问答

0

专栏

7

资料

rafael_wl 2016-09-10 12:40:24
认可0
我喜欢你头像中的妹子 ,接上贴,AD 的driver也要改成960H

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-10 18:12:40
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=37530&ptid=12613]rafael_wl 发表于 2016-9-10 12:40[/url]
我喜欢你头像中的妹子 ,接上贴,AD 的driver也要改成960H[/quote]

嘿嘿谢谢,我继续更新~~

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-10 18:14:41
认可0
本帖最后由 jl3276 于 2016-9-10 18:22 编辑

然后第31行调用了 s32Ret = SAMPLE_COMM_VI_ADStart(enViMode, enNorm);这个函数,这个函数 的定义贴在下面:
[code]/*****************************************************************************
* function : get vi parameter, according to vi type
*****************************************************************************/
HI_S32 SAMPLE_COMM_VI_ADStart(SAMPLE_VI_MODE_E enViMode, VIDEO_NORM_E enNorm)
{
    VI_WORK_MODE_E enWorkMode;
    HI_S32 s32Ret;
   
    switch (enViMode)
    {
        case SAMPLE_VI_MODE_1_D1:
                case SAMPLE_VI_MODE_1_D1Cif:
            enWorkMode = VI_WORK_MODE_4Multiplex;
            s32Ret = SAMPLE_AD_CfgV_D1(enNorm, enWorkMode);
            if (s32Ret != HI_SUCCESS)
            {
                SAMPLE_PRT("SAMPLE_TW2865_CfgV failed with %#x!\n",\
                        s32Ret);
                return HI_FAILURE;
            }
            break;
        case SAMPLE_VI_MODE_16_D1:
                case SAMPLE_VI_MODE_8_D1:
        case SAMPLE_VI_MODE_4_D1:
        case SAMPLE_VI_MODE_16_Cif:
                case SAMPLE_VI_MODE_16_2Cif:
        case SAMPLE_VI_MODE_8_2Cif:
        case SAMPLE_VI_MODE_8_D1Cif:
                case SAMPLE_VI_MODE_16_D1Cif:
            enWorkMode = VI_WORK_MODE_4Multiplex;
            s32Ret = SAMPLE_AD_CfgV_D1(enNorm, enWorkMode);
            if (s32Ret != HI_SUCCESS)
            {
                SAMPLE_PRT("SAMPLE_TW2865_CfgV failed with %#x!\n",\
                        s32Ret);
                return HI_FAILURE;
            }
            break;
        case SAMPLE_VI_MODE_16_960H:
            enWorkMode = VI_WORK_MODE_4Multiplex;
            s32Ret = SAMPLE_AD_CfgV_960H(enNorm, enWorkMode);
            if (s32Ret != HI_SUCCESS)
            {
                SAMPLE_PRT("SAMPLE_TW2960_CfgV failed with %#x!\n",\
                        s32Ret);
                return HI_FAILURE;
            }
            break;
        case SAMPLE_VI_MODE_4_720P:
                case SAMPLE_VI_MODE_1_720P:
            break;
        case SAMPLE_VI_MODE_4_1080P:
        case SAMPLE_VI_MODE_1_1080P:
            break;
        default:
            SAMPLE_PRT("AD not support!\n");
            return HI_FAILURE;
    }
   
    return HI_SUCCESS;
}[/code]

----------------------------------------------------------------------------------------------
我们先来看这个结构体
VI_WORK_MODE_E
【说明】
定义视频设备的复合工作模式。
【定义】
typedef enum hiVI_WORK_MODE_E
{
VI_WORK_MODE_1Multiplex = 0,
VI_WORK_MODE_2Multiplex,
VI_WORK_MODE_4Multiplex,
VI_WORK_MODE_BUTT
} VI_WORK_MODE_E;
【成员】
成员名称 描述
VI_WORK_MODE_1Multiplex 1 路复合工作模式。
VI_WORK_MODE_2Multiplex 2 路复合工作模式,输入数据的协议必须为
标准 BT656 协议。
VI_WORK_MODE_4Multiplex 4 路复合工作模式,输入数据的协议必须为
标准 BT656 协议。
【注意事项】
当该项设为 2 路或 4 路复合工作模式时,设备输入的协议必须是 BT656 协议。 1 路复
合工作模式没有限制。
【相关数据类型及接口】
z VI_DEV_ATTR_S
z HI_MPI_VI_SetDevAttr
------------------------------------------------------------------------------------------------------------
根据我的输入,会进入下面的分支:
        case SAMPLE_VI_MODE_4_D1:
        case SAMPLE_VI_MODE_16_Cif:
        case SAMPLE_VI_MODE_16_2Cif:
        case SAMPLE_VI_MODE_8_2Cif:
        case SAMPLE_VI_MODE_8_D1Cif:
        case SAMPLE_VI_MODE_16_D1Cif:
            enWorkMode = VI_WORK_MODE_4Multiplex;
            s32Ret = SAMPLE_AD_CfgV_D1(enNorm, enWorkMode);
            if (s32Ret != HI_SUCCESS)
            {
                SAMPLE_PRT("SAMPLE_TW2865_CfgV failed with %#x!\n",\
                        s32Ret);
                return HI_FAILURE;
            }
            break;
这里面又调用了SAMPLE_AD_CfgV_D1这个函数,所以下面我把这个函数的源代码贴出来:
[code]HI_S32 SAMPLE_AD_CfgV_D1(VIDEO_NORM_E enVideoMode,VI_WORK_MODE_E enWorkMode)
{
        return 0;
#ifdef DEMO
    return SAMPLE_CX26828_CfgV(enVideoMode, 0, enWorkMode);
#else
    return SAMPLE_TW2865_CfgV(enVideoMode, enWorkMode);
#endif
   
}[/code]
那么问题来了,怎么看是否有DEMO这个宏定义呢?我只好两个都进去改了

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-10 18:29:22
认可0
进去发现代码好复杂,完全搞不懂,不过我发现 与这个函数SAMPLE_AD_CfgV_D1(enNorm, enWorkMode);相似的一个函数,那就是
SAMPLE_AD_CfgV_960H,把他们的代码贴出来
[code]HI_S32 SAMPLE_AD_CfgV_D1(VIDEO_NORM_E enVideoMode,VI_WORK_MODE_E enWorkMode)
{
        return 0;
#ifdef DEMO
    return SAMPLE_CX26828_CfgV(enVideoMode, 0, enWorkMode);
#else
    return SAMPLE_TW2865_CfgV(enVideoMode, enWorkMode);
#endif
   
}

HI_S32 SAMPLE_AD_CfgV_960H(VIDEO_NORM_E enVideoMode,VI_WORK_MODE_E enWorkMode)
{
#ifdef DEMO
    return SAMPLE_CX26828_CfgV(enVideoMode, 1, enWorkMode);
#else
    return SAMPLE_TW2960_CfgV(enVideoMode, enWorkMode);
#endif
}[/code]
既然他们只是D1和960H的区别,那么直接改成这个函数不就可以了吗?我先试试,可以回头告诉大家~

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-10 18:35:11
认可0
本帖最后由 jl3276 于 2016-9-10 18:58 编辑

然后继续回来看SAMPLE_COMM_VI_Start这个函数下面的部分,启动完AD之后是启动VI设备,我把代码贴上来
[code]/*** Start VI Dev ***/
    for(i=0; i     {
        ViDev = i * stViParam.s32ViDevInterval;
        s32Ret = SAMPLE_COMM_VI_StartDev(ViDev, enViMode);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("SAMPLE_COMM_VI_StartDev failed with %#x\n", s32Ret);
            return HI_FAILURE;
        }
    }[/code]
现在出现了stViParam.s32ViDevInterval这个成员变量了,作用就是前面我说的,用于循环的时候控制设备号的间隔的,由于我这里stViParam.s32ViDevCnt为1,故只循环一次,故ViDev =0;后面调用了SAMPLE_COMM_VI_StartDev这个函数我把代码继续给大家贴出来看:
[code]/*****************************************************************************
* function : star vi dev (cfg vi_dev_attr; set_dev_cfg; enable dev)
*****************************************************************************/
HI_S32 SAMPLE_COMM_VI_StartDev(VI_DEV ViDev, SAMPLE_VI_MODE_E enViMode)
{
    HI_S32 s32Ret;
    VI_DEV_ATTR_S    stViDevAttr;//VI_DEV_ATTR_S:定义视频输入设备的属性。
    memset(&stViDevAttr,0,sizeof(stViDevAttr));

    switch (enViMode)
    {
        case SAMPLE_VI_MODE_1_D1:
                case SAMPLE_VI_MODE_1_D1Cif:
            memcpy(&stViDevAttr,&DEV_ATTR_BT656D1_4MUX,sizeof(stViDevAttr));
            SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr);
            break;
        case SAMPLE_VI_MODE_16_D1:
                case SAMPLE_VI_MODE_8_D1:
        case SAMPLE_VI_MODE_4_D1:
        case SAMPLE_VI_MODE_16_Cif:
                case SAMPLE_VI_MODE_16_2Cif:
        case SAMPLE_VI_MODE_8_2Cif:
        case SAMPLE_VI_MODE_8_D1Cif:
                case SAMPLE_VI_MODE_16_D1Cif:
            memcpy(&stViDevAttr,&DEV_ATTR_BT656D1_4MUX,sizeof(stViDevAttr));
            SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr);
            break;
        case SAMPLE_VI_MODE_16_960H:
            memcpy(&stViDevAttr,&DEV_ATTR_BT656D1_4MUX,sizeof(stViDevAttr));
            SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr);
            break;
        case SAMPLE_VI_MODE_4_720P:
                case SAMPLE_VI_MODE_1_720P:
            memcpy(&stViDevAttr,&DEV_ATTR_7441_BT1120_720P,sizeof(stViDevAttr));
            SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr);
            break;
        case SAMPLE_VI_MODE_4_1080P:
        case SAMPLE_VI_MODE_1_1080P:
            memcpy(&stViDevAttr,&DEV_ATTR_7441_BT1120_1080P,sizeof(stViDevAttr));
            SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr);
            break;
        default:
            SAMPLE_PRT("vi input type[%d] is invalid!\n", enViMode);
            return HI_FAILURE;
    }

#ifdef DEMO
    stViDevAttr.bDataRev = HI_TRUE;
#else
    stViDevAttr.bDataRev = HI_FALSE;
#endif
   
    s32Ret = HI_MPI_VI_SetDevAttr(ViDev, &stViDevAttr);
    if (s32Ret != HI_SUCCESS)
    {
        SAMPLE_PRT("HI_MPI_VI_SetDevAttr failed with %#x!\n", s32Ret);
        return HI_FAILURE;
    }

    s32Ret = HI_MPI_VI_EnableDev(ViDev);
    if (s32Ret != HI_SUCCESS)
    {
        SAMPLE_PRT("HI_MPI_VI_EnableDev failed with %#x!\n", s32Ret);
        return HI_FAILURE;
    }

    return HI_SUCCESS;
}[/code]

根据我们的设置,进入了下面的分支
            case SAMPLE_VI_MODE_4_D1:
        case SAMPLE_VI_MODE_16_Cif:
        case SAMPLE_VI_MODE_16_2Cif:
        case SAMPLE_VI_MODE_8_2Cif:
        case SAMPLE_VI_MODE_8_D1Cif:
        case SAMPLE_VI_MODE_16_D1Cif:
            memcpy(&stViDevAttr,&DEV_ATTR_BT656D1_4MUX,sizeof(stViDevAttr));
            SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr);
            break;

----------------------------------------------------------------------------------------------------
memcpy(&stViDevAttr,&DEV_ATTR_BT656D1_4MUX,sizeof(stViDevAttr));这句是一个拷贝赋值,其中DEV_ATTR_BT656D1_4MUX 这个结构体变量定义如下
VI_DEV_ATTR_S DEV_ATTR_BT656D1_4MUX =
{
    /*接口模式*/
    VI_MODE_BT656,
    /*1、2、4路工作模式*/
    VI_WORK_MODE_4Multiplex,
    /* r_mask    g_mask    b_mask*/
    {0xFF000000,    0x0},
    /*逐行or隔行输入*/
    VI_SCAN_INTERLACED,
    /*AdChnId*/
    {-1, -1, -1, -1}
};


然后呢,后面这句SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr);把他代码贴出来看看
[code]/*****************************************************************************
* function : set vi mask.
*****************************************************************************/
HI_VOID SAMPLE_COMM_VI_SetMask(VI_DEV ViDev, VI_DEV_ATTR_S *pstDevAttr)
{
    switch (ViDev % 4)
    {
        case 0:
            pstDevAttr->au32CompMask[0] = 0xFF000000;
            if (VI_MODE_BT1120_STANDARD == pstDevAttr->enIntfMode)
            {
                pstDevAttr->au32CompMask[1] = 0x00FF0000;
            }
            else if (VI_MODE_BT1120_INTERLEAVED == pstDevAttr->enIntfMode)
            {
                pstDevAttr->au32CompMask[1] = 0x0;
            }
            break;
        case 1:
            pstDevAttr->au32CompMask[0] = 0xFF0000;
            if (VI_MODE_BT1120_INTERLEAVED == pstDevAttr->enIntfMode)
            {
                pstDevAttr->au32CompMask[1] = 0x0;
            }
            break;
        case 2:
            pstDevAttr->au32CompMask[0] = 0xFF00;
            if (VI_MODE_BT1120_STANDARD == pstDevAttr->enIntfMode)
            {
                pstDevAttr->au32CompMask[1] = 0xFF;
            }
            else if (VI_MODE_BT1120_INTERLEAVED == pstDevAttr->enIntfMode)
            {
                pstDevAttr->au32CompMask[1] = 0x0;
            }

            #if HICHIP == HI3531_V100
                #ifndef HI_FPGA
                    if ((VI_MODE_BT1120_STANDARD != pstDevAttr->enIntfMode)
                        && (VI_MODE_BT1120_INTERLEAVED != pstDevAttr->enIntfMode))
                    {
                        /* 3531的ASIC板是两个BT1120口出16D1,此时dev2/6要设成dev1/5的MASK */
                        pstDevAttr->au32CompMask[0] = 0xFF0000;
                    }
                #endif
            #endif
            
            break;
        case 3:
            pstDevAttr->au32CompMask[0] = 0xFF;
            if (VI_MODE_BT1120_INTERLEAVED == pstDevAttr->enIntfMode)
            {
                pstDevAttr->au32CompMask[1] = 0x0;
            }
            break;
        default:
            HI_ASSERT(0);
    }
}[/code]

我们用的ViDev =0所以进入这个分支:
case 0:
            pstDevAttr->au32CompMask[0] = 0xFF000000;
            if (VI_MODE_BT1120_STANDARD == pstDevAttr->enIntfMode)
            {
                pstDevAttr->au32CompMask[1] = 0x00FF0000;
            }
            else if (VI_MODE_BT1120_INTERLEAVED == pstDevAttr->enIntfMode)
            {
                pstDevAttr->au32CompMask[1] = 0x0;
            }
            break;

由于 拷贝赋值的时候enIntfMode设置为了VI_MODE_BT656,所以实际上面的分支语句只执行了这样一句话:
pstDevAttr->au32CompMask[0] = 0xFF000000;而实际上这句话也是多余的,因为拷贝赋值的时候已经把au32CompMask[2] 这个成员变量设置成   {0xFF000000,    0x0},了
------------------------------------------------------------------------------------
我们顺便把这个结构体类型的定义也贴出来
VI_DEV_ATTR_S
【说明】
定义视频输入设备的属性。
【定义】
typedef struct hiVI_DEV_ATTR_S
{
VI_INTF_MODE_E enIntfMode;
VI_WORK_MODE_E enWorkMode;
HI_U32 au32CompMask[2];
VI_SCAN_MODE_E enScanMode;
HI_S32 s32AdChnId[4];
/*BT601和DC模式时以下必配,其它模式时无效*/
VI_DATA_YUV_SEQ_E enDataSeq;
VI_SYNC_CFG_S stSynCfg;
VI_DATA_PATH_E enDataPath;
VI_DATA_TYPE_E enInputDataType;
HI_BOOL bDataRev;
} VI_DEV_ATTR_S;
【成员】
成员名称 描述
enIntfMode 接口模式。
enWorkMode 1、 2、 4 路复合工作模式。
au32CompMask[2] 分量掩码配置。当
enIntfMode=VI_MODE_BT1120_STANDARD 时,需要配置 Y
和 C 的分量掩码,其他模式时只需配置单分量掩码。
enScanMode 输入扫描模式 (逐行、隔行)。
s32AdChnId[4] 取值范围[-1, 3],推荐统一设置为默认值-1.
enDataSeq 输入数据顺序 (仅支持 yuv 格式), BT601 和 DC 模式时必须配
置,其它模式时无效。
HiMPP 媒体处理软件
开发参考 3 视频输入
文档版本 10 (2013-04-03) 海思专有和保密信息
版权所有 © 深圳市海思半导体有限公司 3-111
成员名称 描述
stSynCfg 同步时序配置, BT601 和 DC 模式时必须配置,其它模式时无
效。
enDataPath 输入数据通路配置,不带 ISP 的 Sensor 输入时,配置为 ISP 通
路;带 ISP 的 Sensor 或者 AD 输入时,配置为 BYPASS 通路
( VI 内置 ISP 将 Disable); RAW Data 一般仅在 Debug 时使
用,用于捕获 Sensor 输入的原始数据。
enInputDataType 输入数据类型, Sensor 输入一般为 RGB, AD 输入一般为
YUV。
bDataRev 该成员只对 Hi3520D/Hi3515A、 Hi3518 有效。因为走线约束等
硬件原因,有可能出现 AD/Sensor 的数据线与 VI 数据线连接数
据高低位反接,比如, AD_DATA0 与 VIU_DATA7 连接,
AD_DATA7 与 VIU_DATA0 连接,以此类推。。当 AD/Sensor
管脚与 VI 管脚正向连接时,取 bDataRev= HI_FALSE;当反向
连接时,取 bDataRev= HI_TRUE。
【注意事项】
z 当 s32AdChnId设为-1 值时, MPP 将默认检测第 i 个 AdId,且不允许重复检测相
同的 AdId,即 s32AdChnId 数组不允许设置为{-1, 0, 2, 3},因为 s32AdChnId[0]
的值-1 转换后为 0,这与 s32AdChnId[1]的值 0 相冲突。
z 当 enWorkMode 设为 1 路复合模式时, s32AdChnId[0]必须设为-1 或 0;当
enWorkMode 设为 2 路复合模式时, s32AdChnId[0]、 s32AdChnId[1]的值只能取{-
1, 0, 1}。
z 推荐统一将该数组的值都设为-1(即默认绑定关系下的通道按顺序检测{0, 1,
2, 3}的 AdId)。
【相关数据类型及接口】
HI_MPI_VI_SetDevAttr

----------------------------------------------------------------------------------

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-10 19:02:54
认可0
本帖最后由 jl3276 于 2016-9-10 19:27 编辑

继续回到SAMPLE_COMM_VI_Start这个函数看看还需要执行什么,上面我们分析了Start VI Dev ,接着分析Start VI Chn 部分的代码,继续先把代码贴出来:
[code]/*** Start VI Chn ***/
    for(i=0; i     {
        ViChn = i * stViParam.s32ViChnInterval;//s32ViChnInterval的含义
        
        s32Ret = SAMPLE_COMM_VI_StartChn(ViChn, &stCapRect, &stMainTargetSize, enViMode, VI_CHN_SET_NORMAL);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("call SAMPLE_COMM_VI_StarChn failed with %#x\n", s32Ret);
            return HI_FAILURE;
        }
        /* HD mode, we will start vi sub-chn */
        if (HI_TRUE == SAMPLE_COMM_VI_IsHd(enViMode))
        {
            ViChn_Sub = SUBCHN(ViChn);
            s32Ret = SAMPLE_COMM_VI_GetSubChnSize(ViChn_Sub, enNorm, &stSubTargetSize);
            if (HI_SUCCESS != s32Ret)
            {
                SAMPLE_PRT("SAMPLE_COMM_VI_GetSubChnSize(%d) failed!\n", ViChn_Sub);
                return HI_FAILURE;
            }
            s32Ret = SAMPLE_COMM_VI_StartChn(ViChn_Sub, &stCapRect, &stSubTargetSize,enViMode, VI_CHN_SET_NORMAL);
            if (HI_SUCCESS != s32Ret)
            {
                SAMPLE_PRT("SAMPLE_COMM_VI_StartChn (Sub_Chn-%d) failed!\n", ViChn_Sub);
                return HI_FAILURE;
            }
        }
    }

    return HI_SUCCESS;[/code]
你是否还记得,前面我们把stViParam.s32ViChnCnt设置为4,stViParam.s32ViChnInterval设置为了1,所以我们循环4次开启0-3号通道;然后对HD(720P或者1080p)输入还需要再进行其他的设置,显然我们的情况不是,所以只需要看调用的        s32Ret = SAMPLE_COMM_VI_StartChn(ViChn, &stCapRect, &stMainTargetSize, enViMode, VI_CHN_SET_NORMAL);
这个函数就好喽,继续把代码贴出来:
[code]/*****************************************************************************
* function : star vi chn
*****************************************************************************/
HI_S32 SAMPLE_COMM_VI_StartChn(VI_CHN ViChn, RECT_S *pstCapRect, SIZE_S *pstTarSize,
    SAMPLE_VI_MODE_E enViMode, SAMPLE_VI_CHN_SET_E enViChnSet)
{
    HI_S32 s32Ret;
    VI_CHN_ATTR_S stChnAttr;

    /* step  5: config & start vicap dev */
    memcpy(&stChnAttr.stCapRect, pstCapRect, sizeof(RECT_S));
    if (SAMPLE_VI_MODE_16_Cif == enViMode)
    {
        stChnAttr.enCapSel = VI_CAPSEL_BOTTOM;
    }
    else
    {
        stChnAttr.enCapSel = VI_CAPSEL_BOTH;//enCapSel 帧场选择,只用于隔行模式,建议捕获单场时选择捕获底场。逐行模式时,该项必须设置为 VI_CAPSEL_BOTH...这里不是很懂
    }
    /* to show scale. this is a sample only, we want to show dist_size = D1 only */
    stChnAttr.stDestSize.u32Width = pstTarSize->u32Width;
    stChnAttr.stDestSize.u32Height = pstTarSize->u32Height;
    stChnAttr.enPixFormat = SAMPLE_PIXEL_FORMAT;   /* sp420 or sp422 */
    stChnAttr.bMirror = (VI_CHN_SET_MIRROR == enViChnSet)?HI_TRUE:HI_FALSE;
    stChnAttr.bFlip = (VI_CHN_SET_FILP == enViChnSet)?HI_TRUE:HI_FALSE;

    stChnAttr.bChromaResample = HI_FALSE;//是否进行色度重采样。
    stChnAttr.s32SrcFrameRate = -1;//原始帧率,不能小于-1;建议设置为与对接 camera 一致的值
    stChnAttr.s32FrameRate = -1;//目标帧率,必须小于或等于原始帧率,同时不能小于-1;原始帧率与目标帧率要么同时为-1,要么都不为-1,两者都为-1 时表示不进行帧率控制。

    s32Ret = HI_MPI_VI_SetChnAttr(ViChn, &stChnAttr);//设置 VI 通道属性。
    if (s32Ret != HI_SUCCESS)
    {
        SAMPLE_PRT("failed with %#x!\n", s32Ret);
        return HI_FAILURE;
    }
   
    s32Ret = HI_MPI_VI_EnableChn(ViChn);//启用 VI 通道。
    if (s32Ret != HI_SUCCESS)
    {
        SAMPLE_PRT("failed with %#x!\n", s32Ret);
        return HI_FAILURE;
    }

    return HI_SUCCESS;
}
[/code]
我们先分析输入参数
由于在前面已经调用了s32Ret = SAMPLE_COMM_VI_Mode2Size(enViMode, enNorm, &stCapRect, &stMainTargetSize);//get vi parameter, according to vi type
这个函数返回的结果是
stCapRect.s32X = 0;
stCapRect.s32Y = 0;
stCapRect.u32Width = 960;
stCapRect.u32Height = 576;
stMainTargetSize.u32Width = 960;
stMainTargetSize.u32Height =576;
总体上就是先根据分辨率,帧率等设置通道属性结构体,然后设置VI通道属性,最后启用VI通道。循环四次后VI四个通道都被设置而且被启用了~
stChnAttr.enCapSel = VI_CAPSEL_BOTH;这句话还是不理解,不知道是否需要修改

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-10 19:28:36
认可0
今天就先到这里明天继续~明天见

jl3276

0个粉丝

8

问答

0

专栏

0

资料

jl3276 2016-09-11 09:58:13
认可0
下面就要进入到vpss部分了,因为题目没法再编辑了所以重新开了一个帖子,链接提供给大家
[url]http://www.ebaina.com/bbs/thread-12618-1-1.html[/url]

zcc246

0个粉丝

1

问答

0

专栏

0

资料

zcc246 2016-09-12 22:28:32
认可0
学习了  最近也在做这个  要做720p的  AD那里不知道怎么写了

Cybers

0个粉丝

0

问答

0

专栏

0

资料

Cybers 2016-09-16 09:46:17
认可0
学习了,,,谢谢楼主!!!

fenglin1994

0个粉丝

14

问答

0

专栏

3

资料

fenglin1994 2016-09-23 16:39:37
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=37554&ptid=12613]jl3276 发表于 2016-9-11 09:58[/url]
下面就要进入到vpss部分了,因为题目没法再编辑了所以重新开了一个帖子,链接提供给大家
http://www.ebain ...[/quote]

楼主能给一份1918的驱动吗  我的照着你这个改得 直接运行是黑屏的 怀疑是驱动的问题

pumeisc

1个粉丝

13

问答

0

专栏

0

资料

pumeisc 2016-10-08 15:47:50
认可0
学习了,非常感谢

chuxian

0个粉丝

7

问答

0

专栏

0

资料

chuxian 2016-10-14 19:01:23
认可0
非常感谢楼主,学习了:lol

feiyashan

0个粉丝

11

问答

0

专栏

0

资料

feiyashan 2016-12-28 08:43:30
认可0
谢谢楼主的分析,对初学者很有用

applepen

0个粉丝

11

问答

0

专栏

11

资料

applepen 2017-03-04 15:40:36
认可0
谢谢楼主的分析, 请问有关于VENC部分的理解吗,呵呵

tomeker

0个粉丝

0

问答

0

专栏

0

资料

tomeker 2017-04-06 17:30:15
认可0
很好,新手学习好教程。。

randyhsd

0个粉丝

3

问答

0

专栏

2

资料

randyhsd 2017-04-07 09:40:53
认可0
Hisilicon Media Memory Zone Manager
hi3520D_base: module license 'Proprietary' taints kernel.
Disabling lock debugging due to kernel taint
Hisilicon UMAP device driver interface: v3.00
load sys.ko for Hi3520D...OK!
Load tde.ko ...OK!
load venc.ko for Hi3520D...OK!
load group.ko for Hi3520D...OK!
load chnl.ko for Hi3520D...OK!
load h264e.ko for Hi3520D...OK!
load rc.ko for Hi3520D...OK!
load jpege.ko for Hi3520D...OK!
load viu.ko for Hi3520D...OK!
load vou.ko ....OK!
load vpss.ko ....OK!
load vda.ko ....OK!
load region.ko ....OK!
load vdec.ko ....OK
load vhd firmware.ko OK
load hdmi.ko ....OK!
Load jpeg6b.ko success.         (SDK_VERSION:[jpeg6bv1.0] Build Time:[Jul 30 2013, 17:13:35])
tw2865 0x50 ID:0xc8!!!
tw2865 0x50 set to PAL mode ok!
# cd ..
# ./sample_vio 7
[SAMPLE_COMM_SYS_CalcPicVbBlkSize]-167: w:768, u32AlignWidth:64
tw2865 open
tw2865 0x50 set to PAL mode ok!
tw2865 0x50 set to 4d1 mode ok
tw2865 close
start vo SD1.
u32Width:720, u32Square:1
start vo HD0.
u32Width:1920, u32Square:1
HDMI start success.
start vo SD0: wbc from hd0
u32Width:720, u32Square:1
please choose preview mode, press 'q' to exit this sample.
        0) 1 preview
        1) 4 preview
        2) 8 preview
        q) quit

我看了 sample/vio 里的 SAMPLE_VIO_8_D1 复制了 改了一个SAMPLE_VIO_4_D1
    SAMPLE_VI_MODE_E enViMode = SAMPLE_VI_MODE_4_D1;
    HI_U32 u32ViChnCnt = 4;
    HI_S32 s32VpssGrpCnt = 4;
应用能运行 但是摄像头图像出不来:'(
我用i2c_write i2c_read 查看tw2866 的状态寄存器了  是有视频的
研究了好几天都搞不定 请问楼主哪里有问题呢

randyhsd

0个粉丝

3

问答

0

专栏

2

资料

randyhsd 2017-04-07 09:42:58
认可0
哦 对了 我用SD0 输出的 我可以随意改过背景颜色   就是没有摄像头图像
3520 给tw2866 的54M有  tw2866 输出108M也是有的
加载中···
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区