下面隨筆系列將對Hi3559AV100 RFCN實現細節進行解析,整個過程涉及到VI、VDEC、VPSS、VGS、VO、NNIE,其中涉及的內容,大家可以參考之前我寫的部落格:
https://www.cnblogs.com/iFrank/p/14374658.html
基於Hi3559AV100的視訊採集(VDEC-VPSS-VO)整體框圖設計
https://www.cnblogs.com/iFrank/p/14370575.html
基於Hi3559AV100 RFCN實現細節解析-(1)VGS初介紹:
https://www.cnblogs.com/iFrank/p/14465306.html
基於Hi3559AV100的SVP(NNIE)開發整體流程 :
https://www.cnblogs.com/iFrank/p/14377668.html
首先給出整體的RFCN流程圖解,整個RFCN分為3個step,具體如下所示:
在分析RFCN資料流之前,首先了解一下基於Hi3559AV100的NNIE模型,在搭建好SDK等環境後,配置好對應的硬體,在HiLinux上進行測試,具體如下:
1 ~ # ./sample_nnie_main 2 Usage : ./sample_nnie_main <index> 3 index: 4 0) RFCN(VI->VPSS->NNIE->VGS->VO). 5 1) Segnet(Read File). 6 2) FasterRcnnAlexnet(Read File). 7 3) FasterRcnnDoubleRoiPooling(Read File). 8 4) Cnn(Read File). 9 5) SSD(Read File). 10 6) Yolov1(Read File). 11 7) Yolov2(Read File). 12 8) Yolov3(Read File) 13 9) LSTM(Read File) 14 a) Pvanet(Read File).\n")
從中看可以看到RFCN的整個過程VI->VPSS->NNIE->VGS->VO,VI模組繫結了VPSS模組,VI從攝像頭輸入一路視訊,經VPSS分解為兩路,(具體見SAMPLE_SVP_NNIE_Rfcn中step 3-執行緒建立函式SAMPLE_SVP_NNIE_Rfcn_ViToVo),通過如下函式:
1 HI_MPI_VPSS_GetChnFrame( //使用者從通道獲取一幀處理完成的影像。 2 3 s32VpssGrp, 4 5 as32VpssChn[1], 6 7 &stExtFrmInfo, 8 9 s32MilliSec); 10 HI_MPI_VPSS_GetChnFrame( //使用者從通道獲取一幀處理完成的影像。 11 12 s32VpssGrp, 13 14 as32VpssChn[0], 15 16 &stBaseFrmInfo, 17 18 s32MilliSec);
(設定兩路VPSS通道如幀圖片大小等等引數見SAMPLE_COMM_IVE_StartVpss函式)
一路stBaseFrmInfo保持原來的1080P解析度(這個需要看MIPI介面的相機型號來,如:見SAMPLE_COMM_IVE_StartViVpssVencVo函式:
case SONY_IMX277_SLVS_2M_240FPS_12BIT:
*penSize = PIC_1080P;
);
一路stExtFrmInfo轉為PIC_CIF(352x288)解析度(追溯到最初的賦值語句:在SAMPLE_SVP_NNIE_Rfcn函式中:PIC_SIZE_E enSize = PIC_CIF;
經過如下得到VPSS通道對應的圖片大小:
1 SAMPLE_COMM_IVE_StartViVpssVencVo 2 3 aenSize[1] = *penExtPicSize; 4 5 SAMPLE_COMM_IVE_VbInit(aenSize,astSize,VPSS_CHN_NUM); 6 7 SAMPLE_COMM_SYS_GetPicSize(paenSize[i], &pastSize[i]) 8 9 SAMPLE_COMM_SYS_GetPicSize 10 11 { 12 13 switch (enPicSize) 14 15 { 16 17 case PIC_CIF: /* 352 * 288 */ 18 pstSize->u32Width = 352; 19 pstSize->u32Height = 288; break;...... 20 21 } 22 23 }
之後到SAMPLE_SVP_NNIE_Rfcn_Proc函式,具體如下:
1 s32Ret = SAMPLE_SVP_NNIE_Rfcn_Proc( 2 3 pstParam, 4 5 pstSwParam, 6 7 &stExtFrmInfo, 8 9 stBaseFrmInfo.stVFrame.u32Width, 10 11 stBaseFrmInfo.stVFrame.u32Height);
隨後進入加框函式:(即進入VGS視訊圖形子系統)
1 //Draw rect 2 3 s32Ret = SAMPLE_COMM_SVP_NNIE_FillRect( 4 5 &stBaseFrmInfo, //*pstFrmInfo 6 7 &(pstSwParam->stRect), // *pstRect 8 9 0x0000FF00); //u32color
用到了兩個VGS重要引數定義:
VGS_TASK_ATTR_S stVgsTask; //定義 VGS task 的屬性
VGS_ADD_COVER_S stVgsAddCover; //定義 VGS 上 COVER 的配置
下面為定義影像屬性和輸出影像屬性:
1 memcpy( &stVgsTask.stImgIn, 2 pstFrmInfo, 3 sizeof(VIDEO_FRAME_INFO_S)); 4 5 memcpy( &stVgsTask.stImgOut, 6 pstFrmInfo, 7 sizeof(VIDEO_FRAME_INFO_S));
隨後定義 VGS 上 COVER 的配置,設定COVER引數,如顏色設定為0x0000FF00(綠色,這個與之前Hi3519 RFCN執行一致,加綠色的框)
通過memcpy定義任意四邊形 COVER 四個座標點:
1 memcpy( stVgsAddCover.stQuadRangle.stPoint, 2 3 pstRect->astRect[i][j].astPoint, //(pstSwParam->stRect) 4 5 sizeof(pstRect->astRect[i][j].astPoint));
VGS 支援對一幅影像進行遮擋操作,遮擋區域形狀可以是矩形或者任意四邊形, 遮擋區域顏色為純色,支援批量打 COVER。 而在Draw rect函式中,沒有對stBaseFrmInfo資料直接操作,目前認知VGS做COVER任務提交job時,直接將COVER資料送入至VO,隨後加上stBaseFrmInfo的資料:
1 //將視訊影像送入指定輸出通道顯示。 2 3 s32Ret = HI_MPI_VO_SendFrame( 4 5 voLayer, 6 7 voChn, 8 9 &stBaseFrmInfo, 10 11 s32MilliSec);
整體的資料流處理流程如下: