首页 > 技术知识 > 正文

前言:

海思多媒体处理平台(MPP)分为:视频输入(VI),视频处理(VPSS),视频编码(VENC),视频解码(VDEC),视频输出(VO)、视频侦测分析(VDA),音频输入(AI),音频输出(AO),音频编码(AENC),音频解码(ADEC),区域管理(REGION)等模块. 这里介绍视频输入模块(VI)。 VI与AD密切相关,AD的输出模式必须与海思的VI先对应,AD的输出才能正确的传输到Hisi设备上,所以有必要的先了解自己使用的ADC的特性。另外VI的操作流程大致可以分为:

0.获取默认参数 1.判断ADC芯片的个数 2.通过IOC_VDEC_GET_INPUT_VIDEO_FMT 获取当前已经插入的摄像头的分辨率信息 3.计算缓存池的大小 4.初始化mpp系统 5.启动ADC设备 6.启动VI功能 7.设置VI通道绑定关系 8.建立VI与VPSS的绑定 说明:

开发板配置:

Hisi:Hi3521A AD :NVP6134C 一个 摄像头:720P,1080P 显示:HDMI总线,1080P屏 (一)基本特性:

(1)NVP6134

Input Formats – 4CH Video Input : CVBS / COMET : Universal 1M, 2M and 3/4/5M NRT Output Formats – Output in BT.656/BT.1120 4:2:2 byte interleave format with37.125/74.25/148.5/297MHz – Support Sync Separate BT.601 Format (CLK/ H,V-SYNC/ 8’bitDATA) Support 2*Video Output Port, Each Port Video Output FormatSelectable

一个6134NVP芯片支持最大至此4路数据的输入,两个8位的输出口,可以单独选择控制,也可以配合成一个16位的口。

(2)Hisi VI Hi3521A 芯片有 2 个 BT.1120 接口,每个 BT.1120 接口依次对应两个 VI 设备,即第一 个 BT.1120 口对应 VI 的 Dev0 和 Dev1,第二个 BT.1120 口对应 VI 的 Dev2 和 Dev3。4 个 VI 设备均支持 1/2/4 路 D1,960H 复合模式输入(BT.656 协议),以及 2 路 720P复合模式。 4 个设备支持 1 路 720P/1080P 高清输入(BT.1120 协议),此时,同一个BT1120 接口的另一个 Dev 不可用,即 DEV0,DEV1 中只能一个可用; DEV2,DEV3 中只能用一个。

我这里使用的是BT.656模式,也就是4个dev都可以单独使用,可以支持1/2/4 路 D1,960H 复合模式输入(BT.656 协议),以及 2 路

(二)自适应输入

自适应输入也就是根据实际的摄像头输入路数和实际接入的摄像头分辨率去申请内存池,去设置输入模式等功能。

要实现自适应输入,可以使用IOC_VDEC_GET_INPUT_VIDEO_FMT 获取视频输入分辨率,输入摄像头个数等信息。

实际操作的机构体是:

typedef struct _nvp6134_input_videofmt { unsigned int inputvideofmt[16]; unsigned int getvideofmt[16]; unsigned int geteqstage[16]; unsigned int getacpdata[16][8]; }nvp6134_input_videofmt;

查询摄像头插入路数及分辨率可以如下实现:

int Check_NVP6134_VideoInputFMT(void) { int fd = -1; int i = 0; int l_s32Ret = 0; nvp6134_input_videofmt stInputFMT; bzero(&stInputFMT,sizeof(nvp6134_input_videofmt)); fd = open(NVP6134_FILE, O_RDWR); if (fd < 0) { printf(“[%s:%d] open nvp6134 (%s) fail\n”, __func__, __LINE__, NVP6134_FILE); return -1; } l_s32Ret = ioctl(fd, IOC_VDEC_GET_INPUT_VIDEO_FMT, &stInputFMT); if(l_s32Ret < 0) { printf(“[%s,%d][l_s32Ret:%d]\n”,__FILE__,__LINE__,l_s32Ret); } close(fd); for(i=0;i<16;i++) { printf(“i=%d videofmt =0x%x \n”,i,stInputFMT.getvideofmt[i]); printf(“i=%d inputvideofmt=0x%x \n\n”,i,stInputFMT.inputvideofmt[i]); } return 0; }
<

getvideofmt 与分辨率的对应关系可以查看NVP6134驱动中的函数

unsigned char nvp6134_vfmt_convert(unsigned char vdsts, unsigned char g_ck_fmt) /*nvp6134b视频模式值转换*/ unsigned char nvp6134_vfmt_convert(unsigned char vdsts, unsigned char g_ck_fmt) { unsigned int ret; switch(vdsts) { case 0x00: ret = 0x01; break; //cvbs ntsc case 0x10: ret = 0x02; break; //cvbs pal case 0x20: ret = 0x04; break; //720p ntsc case 0x21: ret = 0x08; break; //720p pal case 0x22: ret = 0x51; break; //720P@RT ntsc case 0x23: ret = 0x52; break; //720P@RT pal case 0x30: ret = 0x40; break; //1080p ntsc case 0x31: ret = 0x80; break; //1080p pal …. case 0x01: case 0x02: if((g_ck_fmt>>4) == 0x02) ret = 0x91; //AHD @ 3M RT-30P else ret = 0x92; //AHD @ 3M RT-25P break; default: case 0xFF: ret = 0x00; break; //not detects } return ret; }
<

比如执行上面函数得到:

/hi3520/app # ./nvp_6134_input_fmt_check i=0 videofmt =0x0 i=0 inputvideofmt=0x0 i=1 videofmt =0x0 i=1 inputvideofmt=0x0 i=2 videofmt =0x0 i=2 inputvideofmt=0x0 i=3 videofmt =0x12 i=3 inputvideofmt=0x0 ….

可以知道第四路输入的是一个720P的摄像头。然后可以去按照1路720P摄像头输入去初始化Hisi的MPP

(三)基本操作流程 0.获取默认参数

这个不是必须的,只是作为没有检测到摄像头时的一个默认参数使用。

1.判断ADC芯片的个数

一个NVP6134最大只能支持4路摄像头数据输入,但是HI3521A最大可以支持16路摄像头的输入,因此可以同时使用多个ADC芯片作为还是得数据输入。对海思设备,最大应该可以支持4个NVP6134的输入。

2.获取输入摄像头及分辨率

通过IOC_VDEC_GET_INPUT_VIDEO_FMT 获取当前已经插入的摄像头的分辨率信息,这个也就是上面(二)自适应输入中介绍的内容

3.计算缓存池的大小

可以直接使用官方接口SAMPLE_COMM_SYS_CalcPicVbBlkSize 计算

4.初始化mpp系统

可以直接调用SAMPLE_COMM_SYS_Init接口初始化。

5.启动ADC设备

这里需要注意:这里的ADC的设置必须与下面Hisi的VI设置相对应,否则数据不能正常传输。 我这里是设置NVP6134的两个output port 2路复用,每个输出口对应两路数据,总共4路数据,设置如下:

case SAMPLE_VI_MODE_6134_960H_720P_2MUX: { SAMPLE_PRT(“SAMPLE_VI_MODE_6134_960H_720P_2MUX!!!\n”); for(i=0;i<chip_cnt*4;i++) { schnmode.ch = i; schnmode.vformat = video_mode; schnmode.chmode = NVP6134_VI_720P_2530; ioctl(fd, IOC_VDEC_SET_CHNMODE, &schnmode); } for(i=0;i<chip_cnt;i++) { optmode.chipsel = i; optmode.portsel = 2; optmode.portmode = NVP6134_OUTMODE_2MUX_HD; optmode.chid = 0; ioctl(fd, IOC_VDEC_SET_OUTPORTMODE, &optmode); optmode.portsel = 1; optmode.portmode = NVP6134_OUTMODE_2MUX_HD; optmode.chid = 1; ioctl(fd, IOC_VDEC_SET_OUTPORTMODE, &optmode); } SAMPLE_PRT(“[%s:%d] SET OK!!!\n”, __func__, __LINE__); break; }
<

结构体解析:

/** * Argurments : * portsel(port select->6134b[1,2],6134[0,1,2,3],6134C[1,2];) * portmode(port mode select[1mux,2mux,4mux]), * chid(channel id, 1mux[0,1,2,3], 2mux[0,1], 4mux[0]) **/ typedef struct _nvp6134_opt_mode { unsigned char chipsel; unsigned char portsel; unsigned char portmode; unsigned char chid; }nvp6134_opt_mode; 6.启动VI功能

这里设计是使用dev0和dev1,两路复用模式

case SAMPLE_VI_MODE_8_720P: case SAMPLE_VI_MODE_16_720P: case SAMPLE_VI_MODE_8_1080P: case SAMPLE_VI_MODE_4_1080P: case SAMPLE_VI_MODE_2_720P: memcpy(&stViDevAttr,&DEV_ATTR_6114_720P_2MUX_BASE,sizeof(stViDevAttr)); SAMPLE_COMM_VI_SetMask(ViDev,&stViDevAttr); break; default: SAMPLE_PRT(“vi input type[%d] is invalid!\n”, enViMode); return HI_FAILURE;

设备属性如下:

VI_DEV_ATTR_S DEV_ATTR_6114_720P_2MUX_BASE = { /*接口模式*/ VI_MODE_BT656, /*1、2、4路工作模式*/ VI_WORK_MODE_2Multiplex, /* r_mask g_mask b_mask*/ {0xFF000000, 0x0}, /* 双沿输入时必须设置 */ VI_CLK_EDGE_SINGLE_UP, /*AdChnId*/ {-1, -1, -1, -1}, /*enDataSeq, 仅支持YUV格式*/ VI_INPUT_DATA_YVYU, /*同步信息,对应reg手册的如下配置, –bt1120时序无效*/ { /*port_vsync port_vsync_neg port_hsync port_hsync_neg */ VI_VSYNC_FIELD, VI_VSYNC_NEG_HIGH, VI_HSYNC_VALID_SINGNAL,VI_HSYNC_NEG_HIGH,VI_VSYNC_VALID_SINGAL,VI_VSYNC_VALID_NEG_HIGH, /*timing信息,对应reg手册的如下配置*/ /*hsync_hfb hsync_act hsync_hhb*/ {0, 0, 0, /*vsync0_vhb vsync0_act vsync0_hhb*/ 0, 0, 0, /*vsync1_vhb vsync1_act vsync1_hhb*/ 0, 0, 0} }, /*使用内部ISP*/ VI_PATH_BYPASS, /*输入数据类型*/ VI_DATA_TYPE_YUV };
<
7.设置 VI 通道绑定关系

设计是:

将通道0,1,分别绑定到dev0 的way0,和way1, 将通道2,3,分别绑定到dev1 的way0,和way1, 代码实现为: for(i=0,ViChn=0; i<stViParam.s32ViDevCnt; i++) { for(j=0;j<stViParam.s32ViChnCnt/2;j++,ViChn++) { s32Ret = HI_MPI_VI_GetChnBind(ViChn, &stChnBindAttr); stChnBindAttr.ViDev=i; stChnBindAttr.ViWay = ViChn%2; if (HI_ERR_VI_FAILED_NOTBIND == s32Ret) { s32Ret = HI_MPI_VI_BindChn(ViChn, &stChnBindAttr); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT(“call HI_MPI_VI_BindChn failed with %#x\n”, s32Ret); return HI_FAILURE; } } s32Ret = SAMPLE_COMM_VI_StartChn(ViChn, &stCapRect, &stTargetSize, enViMode, VI_CHN_SET_NORMAL); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT(“call SAMPLE_COMM_VI_StarChn failed with %#x\n”, s32Ret); return HI_FAILURE; } } }
<
8.开启VPSS并将VI绑定到VPSS中 /****************************************** step 4: start vpss and vi bind vpss ******************************************/ s32Ret = SAMPLE_COMM_SYS_GetPicSize(enNorm, PIC_HD720, &stSize); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT(“SAMPLE_COMM_SYS_GetPicSize failed!\n”); goto END_4_720P_1; } memset(&stGrpAttr,0,sizeof(VPSS_GRP_ATTR_S)); stGrpAttr.u32MaxW = stSize.u32Width; stGrpAttr.u32MaxH = stSize.u32Height; stGrpAttr.bNrEn = HI_TRUE; stGrpAttr.enDieMode = VPSS_DIE_MODE_NODIE; stGrpAttr.enPixFmt = SAMPLE_PIXEL_FORMAT; s32Ret = SAMPLE_COMM_VPSS_Start(s32VpssGrpCnt, &stSize, VPSS_MAX_CHN_NUM, &stGrpAttr); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT(“Start Vpss failed!\n”); goto END_4_720P_1; } s32Ret = SAMPLE_COMM_VI_BindVpss(enViMode); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT(“Vi bind Vpss failed!\n”); goto END_4_720P_2; }
<

执行结果:

正确初始化和绑定之后,属性如下:

/hi3520/app # cat /proc/umap/vi [VIU] Version: [Hi3521A_MPP_V1.0.3.1 B010 Release], Build Time: [Apr 18 2016, 12:08:26] —–MODULE PARAM————————————————————– detect_err_frame drop_err_frame stop_int_level max_cas_gap 10 0 0 28000 —–VI DEV ATTR————————————————————— Dev IntfM WkM ComMsk0 ComMsk1 CLKM AD0 AD1 AD2 AD3 Seq DPath DType DRev 0 BT656 2Mux ff 0 UP -1 -1 -1 -1 UYVY ByPass YUV N 1 BT656 2Mux ff00 0 UP -1 -1 -1 -1 UYVY ByPass YUV N —–VI HIGH DEV ATTR————————————————————— Dev InputM WkM ComMsk0 ComMsk1 AD0 AD1 AD2 AD3 Seq CombM CompM ClkM Fix FldP DPath DType DRev —–VI PHYCHN ATTR———————————————————— PhyChn CapX CapY CapW CapH DstW DstH CapSel ScanM SkipM Mirror Flip IntEn PixFom SrcRat DstRat 0 0 0 1280 720 1280 720 both P SKIPNON N N Y sp420 -1 -1 1 0 0 1280 720 1280 720 both P SKIPNON N N Y sp420 -1 -1 2 0 0 1280 720 1280 720 both P SKIPNON N N Y sp420 -1 -1 3 0 0 1280 720 1280 720 both P SKIPNON N N Y sp420 -1 -1 —–VI PHYCHN MINOR ATTR———————————————————— PhyChn CapX CapY CapW CapH DstW DstH CapSel ScanM Mirror Flip PixFom MixCap DwScal SrcRat DstRat —–VI PHYCHN STATUS 1———————————————————- PhyChn BindDev Way IntCnt VbFail LosInt TopLos BotLos BufCnt IntT SendT Field Stride 0 0 0 353 0 3 0 2 2 58 24 frm 1280 1 0 1 352 0 3 0 2 2 27 11 frm 1280 2 1 0 352 0 3 0 2 2 34 13 frm 1280 3 1 1 352 0 3 0 2 2 26 11 frm 1280 —–VI PHYCHN STATUS 2——————————————————— PhyChn MaxIntT IntGapT MaxGapT OverCnt LIntCnt ThrCnt AutoDis CasAutD TmgErr ccErrN IntRat 0 58 40009 40021 0 0 1 0 0 0 3 24 1 47 40001 40010 0 0 1 0 0 0 3 25 2 52 40026 40026 0 0 1 0 0 0 3 24 3 55 40004 40086 0 0 1 0 0 0 3 24 —–VI CHN STATUS————————————————————- ViChn bEnUsrP FrmTime FrmRate SendCnt SwLost Depth 0 N 40010 25 350 0 0 1 N 40000 25 349 0 0 2 N 40025 25 349 0 0 3 N 40004 25 349 0 0 —–VI CHN CALL VGS STATUS 1————————————————- ViChn UsrBgnNOk UsrCancel UsrEndOk UsrCbOk CvrBgnNOk CvrCancel CvrEndOk CvrCbOk —–VI CHN CALL VGS STATUS 2————————————————- ViChn OsdBgnNOk OsdCancel OsdEndOk OsdCbOk ScaleNOk SclCancel SclEndOk SclCbOk /hi3520/app #
<

设置4路输出,接入一个摄像头的效果如下:

海思多媒体(MPP)开发(2)——视频输入(VI)

显示屏有点脏,将就看下吧,哈哈~

原文链接:https://blog.csdn.net/li_wen01/article/details/104429216

相关推荐:

海思HI35XX串口调试 海思多媒体(MPP)开发(1)——nvp6134驱动介绍 海思hi3516A-sample的使用1–sensor加载

猜你喜欢