> 海思多媒体(MPP)开发(2)——视频输入(VI)- 易百纳技术社区-权威的AI物联网嵌入式开发平台
Loading...
海思多媒体(MPP)开发(2)——视频输入(VI)
南宫醉 发布于 07/31 11:54 浏览 79

前言:

海思多媒体处理平台(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 通道绑定关系

设计是:

  1. 将通道0,1,分别绑定到dev0 的way0,和way1,
  2. 将通道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路输出,接入一个摄像头的效果如下:

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

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

相关推荐:

*本文仅代表作者观点,不代表易百纳技术社区立场。系作者授权易百纳技术社区发表,未经许可不得转载。

点赞10
收藏6
分享

精彩评论

内容存在敏感词
确定要删除此文章、专栏、评论吗?
确定
取消

详细的问题描述有助于平台快速解决问题

屏幕截图
问题描述