本帖最后由 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
----------------------------------------------------------------------------------