Hi3559AV100 NNIE RFCN開發:V4L2->VDEC->VPSS->NNIE->VGS->VO系統整體動態除錯實現

流星斬月發表於2021-03-06

  下面隨筆將給出Hi3559AV100 NNIE RFCN開發:V4L2->VDEC->VPSS->NNIE->VGS->VO系統整體動態除錯實現,最終的效果是:USB攝像頭通過板載處理能夠把影像通過HDMI介面輸出,並結合RFCN模型,通過NNIE實現目標檢測,下面給出具體的實現過程。

  板載平臺:BOXER-8410AI

  晶片型號:Hi3559AV100

  相機型號:Logitch c270

  開發環境:VM15.5+ubuntu16.04+Hilinux

  首先給出本篇隨筆涉及之前寫的隨筆,希望大家先提前看一看,因為有些知識你可能不大清楚,看了之後能夠清楚V4L2的實現及更好理解移植過程:

Hi3559AV100外接UVC/MJPEG相機實時採圖設計(一):Linux USB攝像頭驅動分析

https://www.cnblogs.com/iFrank/p/14399421.html

Hi3559AV100外接UVC/MJPEG相機實時採圖設計(二):V4L2介面的實現(以YUV422為例) :

https://www.cnblogs.com/iFrank/p/14403397.html

Hi3559AV100外接UVC/MJPEG相機實時採圖設計(三):V4L2介面通過MPP平臺輸出 :

https://www.cnblogs.com/iFrank/p/14403620.html

Hi3559AV100外接UVC/MJPEG相機實時採圖設計(四):VDEC_Send_Stream執行緒分析

https://www.cnblogs.com/iFrank/p/14485199.html

1、系統框圖及VDEC Chn通道與VPSS Group組的關係

  在實現系統功能前先要確定VDEC的通道數、VPSS Group組的關係,我先給出系統的整體實現圖解:

  為了確定引數,再度分析VPSS上下文關係,使用者可通過 MPI 介面對 GROUP 進行管理。每個 GROUP 僅可與一個輸入源繫結。GROUP 的物理通道兩種工作模式:AUTO 和 USER,兩種模式間可動態切換。AUTO 模式下各通道僅可與一個接收者繫結,主要用於預覽和回放場景下做播放控制。USER 模式下各通道可與多個接收者繫結。需要特別注意的是,USER 模式主要用於對同一通道影像進行多路編碼的場景,此模式下播放控制不生效,因此回放場景下不建議使用 USER 模式。(對於RFCN移植就用到了user模式)

  在移植過程中,用到了VPSS兩個物理通道,對應Hi3559AV100(#define VPSS_MAX_PHY_CHN_NUM 4),對應圖示圖下:

   VPSS 硬體提供多個物理通道,每個通道具縮放、裁剪等 功能。擴充套件通道具備縮放功能,它通過繫結物 理通道,將物理通道輸出作為自己的輸入,把影像縮放成使用者設定的目標解析度輸出,對於本專案,VPSS的輸入源為VDEC,輸出為SVP NNIE,我之前實現的Hi3559AV100外接UVC/MJPEG相機實時採圖設計(三):V4L2介面通過MPP平臺輸出VPSS是接的VO,所有開發過程有不同,實現過程如下圖:

  VDEC模組讀取的視訊檔案需為H.264/H.265/MJPEG的資料檔案,該模組可參考sample_vdec demo編寫,一個通道對應一個視訊檔案。

2、V4L2->VDEC->VPSS->NNIE->VGS->VO實現過程

  BOXER-8410AI-A2-1010 通過外接 UVC/MJPEG USB 攝像頭利用 V4L2 視訊介面讀取一幀 MJPEG 資料,將 MJPEG 資料送入至 VDEC 解碼,經過 VPSS 分兩路圖形,VpssChn[1]送給 NNIE 做神經網路處理,VpssChn[0]一路正常輸出,再通過 VGS 加框,最後 VO-HDMI 輸出。整個流程如下:
  (1)初始化 V4L2 介面,開啟記憶體對映;
  (2)初始化 SYS(SAMPLE_COMM_SYS_Init),必須先於 VDEC,VPSS 等模組;
  (3)初始化 VB or USER VB for VDEC(SAMPLE_COMM_VDEC_InitVBPool);
  (4)開啟 VDEC(SAMPLE_COMM_VDEC_Start);
  (5)開啟 VPSS(SAMPLE_COMM_VPSS_Start);
  (6)開啟 VO(SAMPLE_COMM_VO_StartVO);
  (7)繫結 VDEC 與 VPSS(SAMPLE_COMM_VDEC_Bind_VPSS);
  (8)開啟 VDEC Stream 執行緒(SAMPLE_COMM_VDEC_StartSendStream),時刻從 V4L2 介面取資料;
  (9)Load .wk 模型檔案(SAMPLE_COMM_SVP_NNIE_LoadModel);
  (10)初始化模型引數(SAMPLE_SVP_NNIE_Rfcn_ParamInit);
  (11)開啟 NNIE RFCN 處理執行緒,從 VPSS 取幀資料,經 NNIE 處理,再用 VGS加框;
  (12)開啟 VDEC Stream 執行緒控制指令;
  (13)VDEC Stream 執行緒回收 pthread_join();
  (14)NNIE RFCN 執行緒回收 pthread_join();
  (15)反初始化,結束 V4L2 採集任務等等;
  下面給出具體的移植實現步驟,首先先拋開 V4L2 介面(因為這個之前寫已經封裝好了,移植相對簡單),即先把 V4L2 配置先放一邊,其程式碼主要結合了VDEC、RFCN 及自己編寫的 V4L2。所有的程式碼均在 RFCN 的基礎上進行了修改,這個很大程度節約了時間,且提高了程式正確執行的概率,避免出現莫名其妙的 bug。首先,系統需要完成的是就是 MJPEG->VDEC->VPSS->NNIE->VGS->VO 的各個模組的初始化,step1為 SAMPLE_COMM_IVE_StartViVpssVencVo(SAMPLE_VI_CONFIG_S*pstViConfig,SAMPLE_IVE_SWITCH_S*pstSwitch,PIC_SIZE_E*penExtPicSize),此函式實現(2)-(8), step2 在 RFCN_SVP_NNIE_Rfcn()函式下實現.wk 模型匯入及 NNIE 初始化,step3 完成 NNIE RFCN 執行緒的初始化,step4 完成 VDEC_Stream 執行緒控制和回收及 NNIE 執行緒的回收。
  關於 V4L2 的移植及實現可以參考我之前的隨筆,功能驗證都是正確的。
  最後需要在標頭檔案加上 V4L2 介面的相應定義及初始化,在sample_nnie_main.h 函式下新增標頭檔案:

  #include "sample_comm.h"

  #include <linux/types.h>

  #include <linux/videodev2.h>

  檔案改動位置:

3、除錯遇到問題解決

  在完成MJPEG->VDEC->VPSS->NNIE->VGS->VO函式的初始化之後,最初是簡單的移植了VDEC執行緒開啟執行的三個函式,但是出現了程式卡住的bug,具體如下所示:

  程式碼對應位置:

  因為SAMPLE_COMM_VDEC_CmdCtrl()函式進入了while,卡住了程式,直接將函式位置放到NNIE初始化後面即可,且把函式輸入的引數換成全域性變數即可。

4、結果測試

  系統的硬體連線圖如下所示:

   結果測試如下所示,因為視訊上傳不了,所有以圖片來進行演示,從圖片可以看到,資料通過V4L2->VDEC->VPSS->NNIE->VGS->VO的系統開發後,能夠將攝像頭的資料通過HDMI在螢幕輸出,並且開發的NNIE實現了RFCN目標識別的深度學習模型(紅色框為NNIE處理圖形後VGS加框的效果)。

 

 

 

相關文章