MI Demo使用说明

Version 1.0


1. 目录说明


1.1. 功能说明

由于每个模块只验证本身的话,无法客观的暴露出性能、易用性、模拟用户场景等问题,所以才有串模块的测试用例。在实际使用中,性能测试和模拟用户场景的改动比较多,如下是目录功能的简单说明。

├── feature --------------------------------------------------针对各平台的单元测试用例
│   ├── gfx --------------------------------------------gfx模块测试用例
│   └── disp--------------------------------------------disp模块测试用例
    ……
├── mi_demo
├──── source-------------------------------------------针对各平台的整合测试用例
│   ├──── audio_all_test_case--------------------音频功能测试,包括AO/AI
│   ├──── fb-----------------------------------------Linux framebuffer使用参考
│   ├──── stress_test------------------------------解码显示压力测试demo
│   ├──── vdec-------------------------------------解码显示功能测试demo
│   ├──── dvr --------------------------------------dvr功能测试demo
│   ├──── internal ---------------------------------内部使用模块的封装

1.2. 编译

1.2.1. feature编译

  1. 完整编译project

  2. 根据编译config添加相应支持

    如编译gfx,则在project\configs\defconfigs\xvr_m6_spinand.glibc-9.1.0-squashfs.016a.512.bga2_defconfig添加verify gfx支持,CONFIG_verify_gfx="disable"

  3. 编译

    在sdk\verify\feature目录下make gfx,即会在gfx目录下生成prog文件,可以直接用于测试。

1.2.2. demo编译

先完整编译project

cd $(SDK)/ verify/mi_demo/source;
make vdec;         ///// 最终生成的可执行文件在$(SDK)/ verify/mi_demo/out/demo/app

1.3. 添加新模块的测试用例

1.3.1. 串接新的流程

串接新的流程来验证性能时,在$(SDK)/verify/mi_demo/source目录下创建一个新的目录。

如test,在test目录下创建test.mk文件,在test.mk文件中填写依赖的MI库和本身封装的模块库。

#### 模块封装的依赖库
ST_DEP := common hdmi disp vdec fb
#### MI模块的依赖库
LIBS += -lmi_disp -lmi_hdmi -lmi_disp -lmi_vdec

其它平台的添加方法类似。

1.3.2. 添加新的用例

添加新的解码用例,在$(SDK)/verify/mi_demo/geonosis/vdec/st_main_vdec.c中添加用例描述结构体即可。


2. Demo使用说明


2.1. audio_all_test_case

prog_audio_all_test_case使用说明:

-t: 程序的运行时间(秒数),不指定则会一直运行

-I: 使能AI

-o: AI录音的输出路径

-d: AI的设备ID(Amic[0] Dmic[1] I2S RX[2] Linein[3])

-m:AI的声道模式(Mono[0] Stereo[1] Queue[2])

-c: AI通道数

-v: AI音量参数(Amic 0~21, Dmic 0~4, Linein 0~7)

-s: AI采样率8000/16000/32000/48000

-h: 使能AI Hpf

-g: 使能AI Agc

-e: 使能AI Eq

-n: 使能AI NR

-r: AI 重采样采样率8000/16000/32000/48000

-a: AI 编码类型g711a/g711u/g726_16/g726_24/g726_32/g726_40

-A: 使能AED

-b: 使能AEC

-B:使能Hw loop back AEC

-S: 使能SSL

-F: 使能BF

-M:mic的间距(使能SSL或BF时,必须设置,步长为1cm)

使用参考:

  1. 录音测试

    ./prog_audio_all_test_case -I -t 7 -o ./ -d 0 -c 1 -s 16000 -m 0 -v 20
    
  2. 音频播放

    ./prog_audio_all_test_case -O -i ./16K_16bit_MONO_60s.wav -D 0
    
  3. 重采样测试

    ./prog_audio_all_test_case -O -i ./16K_16bit_MONO_60s.wav -D 0 -R 8000
    

2.2. FB

用例描述 打开/dev/fb0设备,mmap地址出来,在这个地址上写color值,能正常显示color
流程图
期望结果 在显示器上能正常显示画到fb上面的数据

./prog_fb 即可运行。

demo会播1路视频,并画4个半透明框,接上鼠标可以移动。

视频流默认为当前目录1080P25.h264,鼠标图标为当前目录cursor-arrow.dat

注意:默认配置文件project\board\i2m\SSC010A-S01A\config\fbdev.ini,固定放到文件系统/config/fbdev.ini,会配置默认的fb格式,分配内存,layer size等。

FB_BUFFER_LEN为所需内存,单位为Kb,由FB_WIDTH/FB_HEIGHT/FB_HWWIN_FORMAT及UI层数决定。

如宽高是1920x1080,ARGB1555格式,1层UI,则需分配内存为1920x1080x2x1约为4M。

FB_HWWIN_FORMAT值对应如下:

typedef enum
{
    /// Color format RGB555 and Blink.
    E_DRV_FB_GOP_COLOR_RGB555_BLINK    =0,
    /// Color format RGB565.
    E_DRV_FB_GOP_COLOR_RGB565          =1,
    /// Color format ARGB4444.
    E_DRV_FB_GOP_COLOR_ARGB4444        =2,
    /// Color format alpha blink.
    E_DRV_FB_GOP_COLOR_2266            =3,
    /// Color format I8 (256-entry palette).
    E_DRV_FB_GOP_COLOR_I8              =4,
    /// Color format ARGB8888.
    E_DRV_FB_GOP_COLOR_ARGB8888        =5,
    /// Color format ARGB1555.
    E_DRV_FB_GOP_COLOR_ARGB1555        =6,
    /// Color format ABGR8888.  - Andriod format
    E_DRV_FB_GOP_COLOR_ABGR8888        =7,
    /// Color format RGB555/YUV422.
    E_DRV_FB_GOP_COLOR_RGB555YUV422    =8,
    /// Color format YUV422.
    E_DRV_FB_GOP_COLOR_YUV422          =9,
    /// Color format ARGB8888.  - Andriod format
    E_DRV_FB_GOP_COLOR_RGBA5551        =10,
    /// Color format ARGB8888.  - Andriod format
    E_DRV_FB_GOP_COLOR_RGBA4444        =11,

    /// Invalid color format.
    E_DRV_FB_GOP_COLOR_INVALID,
} DRV_FB_GOP_ColorFmt_e;

2.3. stress_test

2.3.1. Demo介绍

stress test demo是新开发一个针对nvr chip做压力测试的demo,可以通过脚本配置需要测试的es流。可以用于码流验证,性能验证,压力测试等。

2.3.2. config文件介绍

prog_stress_test是从config文件读取需要播放的es流信息,所以需要提前将要播放的es加到config中,格式如下

// Index, Type, Width, Height, RefNum, bEsAddHead, Path,

VDEC = 0, h264, 1920, 1080, 1, 1, 1080P30.h264

建议index从0往下递增,对不想测试的部分可以直接注释。path默认路径是demo所在路径,也可以带路径传入,比如 ../nref/1080p\_2ref.h265

2.3.3. Demo使用

Demo有多种使用方法:

  1. #./prog_stress_test configFilePath timing index DispWin

    参数1永远是配置文件路径;参数2为timing,数值参考下面结构体;参数3为要播放的es流index;参数4为播放路数,这个参数可以不带,默认播放1路。

    typedef enum
    {
        E_ST_TIMING_720P_50 = 1,
        E_ST_TIMING_720P_60,
        E_ST_TIMING_1080P_50,
        E_ST_TIMING_1080P_60,
        E_ST_TIMING_1600x1200_60,
        E_ST_TIMING_1440x900_60,
        E_ST_TIMING_1280x1024_60,
        E_ST_TIMING_1024x768_60,
        E_ST_TIMING_1280x800_60,
        E_ST_TIMING_1366x768_60,
        E_ST_TIMING_1680x1050_60,
        E_ST_TIMING_MAX,
    } ST_DispoutTiming_e;
    
  2. #./prog_stress_test configFilePath mix timing index1 index2 index3 ...

    参数2为mix代表混合播放,参数3为timing值,带几个index就播放几路,index可重复。

  3. #./prog_stress_test configFilePath play DispWin timing

    参数2为play代表随机播放,DispWin 为路数,timing可以不带,默认输出1080p60.

    执行后会从config文件里面随机挑出DispWin路来播放,只要不超规格,index也有可能重复。

  4. #./prog_stress_test configFilePath rand1

    压力测试项,timing随机,随机播放116路/全部销毁/随机播放116路。。。,如此循环,间隔时间写死5s;index也是随机,只要不超规格

  5. #./prog_stress_test configFilePath rand2

    压力测试项,先随机播放16路,timing随机,然后每隔5s随机销毁1路,再隔5s随机添加一路,如此循环。

  6. #./prog_stress_test configFilePath rand3

    压力测试项,先随机播放16路,timing随机,然后每隔10s切屏一次,切屏路数1~16路随机,如此循环。

  7. #./prog_stress_test configFilePath loop

    将config中的码流遍历播放一次,timing随机。

2.3.4. 辅助命令

  1. exit

    退出程序,也可以用ctrl+c

  2. sleep [arg]

    调整送流时间间隔,单位ms

  3. drop [arg]

    每隔arg2*arg帧丢掉当前帧一定数据,如果当前帧大小为size,会随机丢掉1size数据量。

    drop 0 则会恢复正常送流。

  4. del [arg]

    删除第arg通道,记得是从1开始数,从左到右,从上往下数

  5. add [arg1] [arg2]

    添加第arg1通道,index为arg2

  6. split [arg1] [arg2]

    切换到arg1分屏,原来为arg2分屏

  7. help

    打印命令用法


2.4. VDEC

2.4.1. 使用说明

prog_vdec与es流放同级目录(es流路径和命令都由demo指定),./prog_vdec运行,

然后键入数字选择要播放的case即可。

1) 1x1080P@30 H264 Decode

2) 1x1080P@30 H265 Decode

3) 1xD1 H264 Decode

4) 1xD1 H265 Decode

5) 4x720P@30 H264 Decode

6) 4x720P@30 H265 Decode

7) 4x1080P@30 H264 Decode

8) 4x1080P@30 H265 Decode

9) 2x1080P@30 H264 + 2x1080P@30 H265 Decode

10) 4xD1 H264 Decode

11) 4xD1 H265 Decode

12) 1x1080P30 H264 + 7xD1 H264 Decode

13) 1x1080P30 H265 + 7xD1 H265 Decode

14) 1x1080P30 H264 + 7xD1 H265 Decode

15) 9xD1 H264 Decode

16) 9xD1 H265 Decode

17) 1x1080P@30 H264 Decode + PIP

18) 1x1080P@30 H264 Decode + 5 x D1 H264 Decode

19) 1x720P@30 H264 Decode + 5 x D1 H264 Decode

20) 1x1080P@25 H264 Decode + 5xVGA(640x480) H264 Decode

21) 16xD1 H264 Decode

22) 16xD1 H265 Decode

23) 4xSIZE(640x360) H264 Decode

24) 1x720P H264 Decode

25) 1x720P H265 Decode

26) 4chn 2592x1944 H264 Decode

27) 4chn 2592x1944 H265 Decode

28) 1x8MP(3840x2160) H264 Decode

29) 1x8MP(3840x2160) H265 Decode

30) 1x4MP(2560x1440) H264 Decode

31) 1x4MP(2560x1440) H265 Decode

32) 1 x 4K@30 H264 Decode (corridor)

33) 3xD1@30 H264 Decode (corridor)

34) 3x720P@30 H264 Decode (corridor)

35) 1x1080P@30 H264 Decode (corridor) 16 win

36) 1 x 4K@30 H265 Decode (corridor)

37) 3xD1@30 H265 Decode (corridor)

38) 3x720P@30 H265 Decode (corridor)

39) 3x1080P@30 H265 Decode (corridor)

40) 1x720P@30 H265 + 3x720P@30 H264

播放后按enter键会出来子选项,可以选择一些功能演示或者退出。

2.4.2. 带参数播放

为了方便验证某些流的问题,也有带参数播放的方法。

  1. 首先默认播放的es流都是有特殊处理的(加了一个头信息),如果是原始流,可以编译前注释一行

    sdk\verify\mi_demo\geonosis\vdec\st_main_vdec.c
    //#define ADD_HEADER_ES
    
  2. 带参数播放要打开一个宏再编译

    #define PLAY_WITH_ARGS
    

参数说明:

参数1:码流路径

参数2:格式 0->h264 1->h265

参数3:宽

参数4:高

参数5:参考帧数量

参数6:播放路数

参数7:显示timing,4是1080p60

比如:

./prog_vdec /mnt/chn0_h264.dat 0 1920 1080 2 4 4

播放一个码流/mnt/chn0_h264.dat,格式为h264,宽为1920,高为1080,参考帧数量为2,播放4路,显示timing为1080p60。

2.4.3. 功能测试

  • PIP

    PIP需要用scl来做缩放,显示在layer1上,对应disp chn 固定为16。

    选case 17 1x1080P@30 H264 Decode + PIP 即可验证PIP功能。

  • 电子放大

    选case1播1路视频,再选sub case 16) zoom即可演示电子放大功能。

    电子放大有两种方式:

    1. 通过disp做crop,但是如果vdec->disp有做过缩小,电子放大清晰度会有影响

    2. 通过vdec做crop,参考MI_VDEC_SetDestCrop,比较推荐这种方式。

  • 抓图

    选case1播1路视频,再选sub case 15) Capture JPEG即可抓图存成jpeg文件,默认抓10张图片。且是抓取的视频大小,如果要抓指定大小图片,可以设置#define CAPTURE_FULL_SIZE 0,默认size是640x360,也可以自己代码里面改成想要的size。

    抓图都需要开启scl;由venc编码成jpeg图片。如果是抓原图,直接vdec->venc即可,如果要抓指定大小,需要scl->venc,vdec到scl的流程由我们内部处理。

  • 切屏

    选择case21播16路视频,然后再选sub case

    1) show 1 channel

    2) show 4 channel

    3) show 9 channel

    4) show 16 channel

    即可切到几分屏。


2.5. DVR

2.5.1. 编译

对于采用不同的AD芯片需要编译不同的demo,驱动部分需要调整。

  • xs9931

    完整编译project后

    cd sdk\verify\mi_demo\source
    make dvr
    get demo from sdk\verify\mi_demo\out\demo\app\prog_dvr
    
  • tp2830

    需要在st_main_dvr.cpp中打开TP2830:#define SUPPORT_TP2830 (1)

  • nvp6158c

    因为6158c驱动走kernel mode,需要st_main_dvr.cpp中设置

    #define USE_USERSENSOR (0)
    

    demo.sh需要添加挂载:

    insmod /config/modules/4.9.227/nvp6158c.ko chmap=5 i2c_slave_id=0x600062
    

    # lane_num=4参数不需要,上面的挂载是设置用2颗6158c,I2C地址分别是0x60,0x62

2.5.2. config配置说明

UseVenc = 1   //暂时用不上,
SensorPad = 0  //使用哪个pad
#ResIndex = 1

UseDisp = 1   //1表示用到DISP模块做输出显示
DispDev0IntfType = 5  //显示类型,5hdmi,参考MI_DISP_Interface_e
DispDev0Width = 1920  //显示输出宽
DispDev0dHeight = 1080 //显示输出高
DispLayer0WinWidth = 1920  //layer宽
DispLayer0WinHeight = 1080  //layer高
DispLayer0WinX = 0
DispLayer0WinY = 0
DispLayer0Width = 1920
DispLayer0Height = 1080

DispPort0Use = 1    //disp chn是否使用,中间数字代表通道号
DispPort0X = 0    //下面4个参数为这个显示通道在layer上的位置信息
DispPort0Y = 0
DispPort0Width = 1920
DispPort0Height = 1080   //这里的设定表示全屏

VifDev = 0         //vif的DEV通道,跟chn是一个概念
vifOutPortId =0    //目前都是0
vifPortCropX=0    //下面四个参数是采集的图像范围
vifPortCropY=0
vifPortCropW=1280
vifPortCropH= 720
vifPortW=1280    //vif输出的宽高信息
vifPortH= 720
vifpixel=14       //vif输出格式14代表E_MI_SYS_PIXEL_FRAME_YUV422_UYVY,参考MI_SYS_PixelFormat_e

HDR = 0         //HDR类型0是关闭,参考MI_VIF_HDRType_e
RunMode = 1Multi //vif的workmodebt656只支持1/2/4 Multi,参考MI_VIF_WorkMode_e
#1Multi/2Multi/4Multi

IspDevId =0 //vif绑定的ISP device
IspInFilePath=NULL //通常InFile用不到
IspInFileW=0
IspInFileH=0
IspInFilePixel=0

IspInFr=30  //isp input frame rate
IspbindType=Frame
#Realtime/Frame
NRLevel = 2    //3D降噪级别0是关闭
IspRotation = 0 //是否旋转 0是不旋转,参考MI_SYS_Rotate_e
IspMirror = 0  //是否水平翻转
IspFlip = 0  //是否垂直翻转
IspInCropX = 0; //下面4个参数代表isp input crop范围
IspInCropY = 0;
IspInCropW = 1280;
IspInCropH = 720;
IqBinPath = NULL

Ispport0Use = 1 //是否使用isp port0
Ispport0PortCropX = 0 //下面4个参数为isp outport范围,通常和input crop一致,缩放一般会由scl做
Ispport0PortCropY = 0
Ispport0PortCropW = 1280
Ispport0PortCropH = 720
Ispport0Pixel=11 //输出格式,11代表E_MI_SYS_PIXEL_FRAME_YUV_SEMIPLANAR_420disp只能吃这种格式
Ispport0EncodeType = 2 //编码格式,2h2643h2654 jpeg

Ispport1Use = 0 // isp port1 设定
Ispport1PortCropX = 0
Ispport1PortCropY = 0
Ispport1PortCropW = 1920
Ispport1PortCropH = 1080
Ispport1Pixel = 11
Ispport1EncodeType = 2
#Ispport1userdepth = 0
#Ispport1depth = 4

SclIspRealtimeUseSclId = 1 //SCL source的4种选择
SclYUVRealtimeUseSclId = 0
SclRdma0UseSclId = 0
SclRotRdmaUseSclId =0

SclRdma0InFilePath =NULL
SclRdma0InFileW=0
SclRdma0InFileH=0
SclRdma0InFilePixel=0

SclRotRdmaInFilePath =NULL
SclRotRdmaInFileW=0
SclRotRdmaFileH=0
SclRotRdmaFilePixel=0

SclRotation= 0 //scl是否做旋转
#0:0, 1:90, 2:180, 3:270

Scl0Use = 1 //SCL有多个port,可以1进多出,这里表示用scl0
Scl0PortCropX = 0  //SCL0 crop范围
Scl0PortCropY = 0
Scl0PortCropW = 1280
Scl0PortCropH = 720
Scl0mirror = 0
Scl0flip = 0
Scl0W = 1920 //SCL0 输出size
Scl0H = 1080 //SCL0 输出size
Scl0Pixel = 11
Scl0BindMod = DISP  //SCL bind到 DISP,也可以bind VENC,看使用情况
Scl0Bindtype = 1    //frame mode,默认工作方式,参考MI_SYS_BindType_e
Scl0EncodeType = 2  //编码格式,2h2643h2654 jpeg
Scl0EncodeFps = 30
#BindType:1 Frame, 4 RealTime
#Encode:2 h264, 3 h265, 4 JPEG
Scl0userdepth = 2
Scl0depth = 4
#Scl0OutPutPath = "/mnt"
#Scl0DumpBuffNum = 1

Scl1Use = 0 // scl1设定,与前面scl0各项代表的意思类同
Scl1PortCropX = 0
Scl1PortCropY = 0
Scl1PortCropW = 0
Scl1PortCropH = 0
Scl1mirror = 0
Scl1flip = 0
Scl1W = 1280
Scl1H = 720
Scl1Pixel = 11
Scl1Bindtype = 1
Scl1EncodeType = 2
#port1OutPutPath = "/mnt"
#port1DumpBuffNum = 1

Scl2Use = 0
Scl2PortCropX = 0
Scl2PortCropY = 0
Scl2PortCropW = 0
Scl2PortCropH = 0
Scl2mirror = 0
Scl2flip = 0
Scl2W = 1920
Scl2H = 1080
Scl2Pixel = 11
Scl2Bindtype = 1
Scl2EncodeType = 2

2.5.3. Demo使用

前提条件,需要sensor的分辨率能对应上,验哪种case就需要把sensor分辨率切到相应分辨率下。N制是30帧,P制是25帧;目前每一路采集对应一个ini文件。比如跑4路1080n,则需要带4个ini:

./prog_dvr bt656frame1080n_ch0port0_disp_4Multi.ini 
bt656frame1080n_ch1port0_disp_4Multi.ini 
bt656frame1080n_ch2port0_disp_4Multi.ini 
bt656frame1080n_ch3port0_disp_4Multi.ini
  • xs9931

    xs9931的driver目前加了6种case(也可以自行扩展),需要demo运行后手动选择使用的设置。

    index 0, Crop(0,0,1280,720), outputsize(1280,720), maxfps 30, minfps 30, ResDesc 1280x720@30fps[1x]
    index 1, Crop(0,0,1920,1080), outputsize(1920,1080), maxfps 30, minfps 30, ResDesc 1920x1080@30fps[1x]
    index 2, Crop(0,0,1280,720), outputsize(1280,720), maxfps 30, minfps 30, ResDesc 1280x720@30fps[2x]
    index 3, Crop(0,0,1920,1080), outputsize(1920,1080), maxfps 30, minfps 30, ResDesc 1920x1080@30fps[2x]
    index 4, Crop(0,0,1280,720), outputsize(1280,720), maxfps 30, minfps 30, ResDesc 1280x720@30fps[4x]
    index 5, Crop(0,0,960,1080), outputsize(960, 1080), maxfps 30, minfps 30, ResDesc 960x1080@30fps[4x]
    

    选择接入xs9931数量(1个或2个)后就可以通过显示屏看到画面。

  • tp2830

    目前只区分6种case:

    0: 1 chn 720p

    1: 1 chn 1080p

    2: 2 chn 720p

    3: 2 chn 1080p

    4: 4 chn 720p

    5: 4 chn 1080p

    然后选择接入tp2830数量,即可正常采集显示。

  • nvp6158c

    12种case,根据需要选择:

    index 0, Crop(0,0,1280,720), outputsize(1280,720), maxfps 30, minfps 3, ResDesc 1280x720@30fps_1Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 1, Crop(0,0,1280,720), outputsize(1280,720), maxfps 25, minfps 3, ResDesc 1280x720@25fps_1Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 2, Crop(0,0,1280,720), outputsize(1280,720), maxfps 30, minfps 3, ResDesc 1280x720@30fps_2Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 3, Crop(0,0,1280,720), outputsize(1280,720), maxfps 25, minfps 3, ResDesc 1280x720@25fps_2Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 4, Crop(0,0,1280,720), outputsize(1280,720), maxfps 30, minfps 3, ResDesc 1280x720@30fps_4Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 5, Crop(0,0,1280,720), outputsize(1280,720), maxfps 25, minfps 3, ResDesc 1280x720@25fps_4Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 6, Crop(0,0,1920,1080), outputsize(1920,1080), maxfps 30, minfps 3, ResDesc 1920x1080@30fps_1Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 7, Crop(0,0,1920,1080), outputsize(1920,1080), maxfps 30, minfps 3, ResDesc 1920x1080@30fps_2Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 8, Crop(0,0,960,1080), outputsize(960,1080), maxfps 30, minfps 3, ResDesc 960x1080@30fps_4Mux
    (ST_SensorModuleInit 2796)exec function pass
    index 9, Crop(0,0,1920,1080), outputsize(1920,1080), maxfps 30, minfps 3, ResDesc 1920x1080@30fps_1Mux_bt1120
    (ST_SensorModuleInit 2796)exec function pass
    index 10, Crop(0,0,1920,1080), outputsize(1920,1080), maxfps 30, minfps 3, ResDesc 1920x1080@30fps_2Mux_bt1120
    (ST_SensorModuleInit 2796)exec function pass
    index 11, Crop(0,0,960,240), outputsize(960,240), maxfps 60, minfps 3, ResDesc 960x240@60i_1Mux
    choice which resolution use, cnt 12
    

    然后就可以正常采集显示。