一. 概述
此篇文章為 eIQ 系列的延伸應用,相信各位已經對於 NXP 所開發的 eIQ 機器學習開發環境 有一定程度上的認識了 !! 若尚未理解的夥伴,請點選上述連結溫習一下 !! 所謂的 eIQ NNStreamer 是利用 GStreamer 插件的方式,讓用戶可以快速實現機器學習的一種應用方式。為了加深 NNStreamer 與 GStreamer 差異與用法,本系列會簡單探討 GStreamer 的應用方式 ; 並利用 NXP i.MX8M Plus並搭配一台 WebCAM (I-family If008D) 來完成實作。
如下圖文章架構圖所示,本系列是隸屬於 機器學習開發環境 eIQ 之 應用層 (Application Layer) 中,本篇將介紹“GStreamer 快速使用介紹”。
若新讀者欲理解更多人工智慧、機器學習以及深度學習的資訊,可點選查閱下方博文
大大通精彩博文 【ATU Book-i.MX8系列】博文索引
eIQ NNStreamer 系列博文-文章架構示意圖
二. GStreamer 介紹
GStreamer 是一個跨平台的多媒體框架。工程師可以透過此框架達成各種多媒體應用,比如音訊回放、影片播放、串流媒體、鏡頭解析等等,並支援多種 Windows、Linux、Android、IOS 等熱門作業系統。
其設計理念是以 管道(Pipeline) 的方式來對每一個 元素(Element) 或 插件(Plugins) 進行串聯 ; 如下圖所述,若要透過 GStreamer 來解析一個 視頻檔案(mp4) 的話,基本的動作流程就是載入檔案、解析檔案、再分別解析音訊與視訊,最後將資訊傳送至 autoaudiosink 之中,就可以播放視頻了 !! 這整個流程就是所謂的 Pipeline 概念,以一種流水方式,一項接一項的進行操作 ; 其中淺藍色的區塊稱作元素(Element),通常是指一項動作或一個功能。而深藍色的區塊是稱作 Pad ,泛指一個接口的意思 ; 且接收端稱作 sink ,發送端稱作 src 。
GStreamer Pipeline示意圖
原始出處 : 什么是Gstreamer?
GStreamer Pipeline 的實現方式相當直覺 !! 僅需要開啟終端機輸入下方的 Command Line 即可實現 !!
$ gst-launch-1.0 filesrc location=<mp4> ! \
oggdemux name=demux ! queue ! vorbisdec ! autoaudiosink \
demux. ! queue ! theoradec ! videoconvert ! autovideosink
PS : oggdemux 已被命名為 demux ,後續直接用此名引用即可。
再來,可以快速地探討一下 GStreamer 是如何溝通的。如下圖所示,可以看出 Bus 提供了許多數據傳遞的方式,像是由元素向應用程式發出消息,就稱作 Messages,或是從應用程式向元素發出消息,就稱作 Events 。其中 events 與 quries 的差異是取得訊息的不同,而後者是屬於像查詢時間、文件大小等這類資訊。
GStreamer Pipeline 應用之示意圖
原始出處 : 什么是Gstreamer?
然而, GStreamer 是一套具有豐富資源的框架(Framework),能夠提供數種 插件(Plugins)、工具(Tool)、應用程式(Media Application) 等豐富資源提供給工程師使用。其中最基礎就是各種插件的應用,也就是上述所提及的,讀取檔案的 filesrc 或是解析檔案的 oggdemuxer 皆屬於插件的一種。 如下圖所示,插件大致上可以分為六種類型 ; 依序為 協定(Protocols) 、 來源(Sources) 、格式(Formats) 、 解編碼(Codecs) 、 輸出(Sink) 、 濾波器(Filter) 等等。
GStreamer 框架示意圖
三. GStreamer 插件
因 GStreamer 提供插件過於豐富,以下列出幾個比較常用的 Plugins 介紹 …. 其中表格中的 Package 是指插件的所應用的資料庫。
(1) Video Decoder Plugins
(2) Video Encoder Plugins
(3) Video Sink Plugins
(4) Demux Plugins
視訊解碼至 raw 格式的相關插件,如下 :
(5) Mux Plugins
從 raw 格式編碼至其他影音格式的相關插件,如下 :
(6) i.MX Proprietary Plugins
NXP 所提供的相關插件,包含 VPU 的解碼與編碼、以及 GPU 的轉換格式之應用 :
(7) Audio Plugins
聲音與音訊相關的插件,如下 :
(8) Image Plugins
影像格式相關的插件,如下 :
(9) Network Plugins
網路相關的插件,如下 :
四. 透過 GStreamer 啟用網路攝像頭(WebCAM)
(1) 測試環境
目前使用 WPI 所研發的 OP-Killer 開發板 (NXP i.MX8M Plus) 並搭配一台 WebCAM (I-family If008D) 進行實際測試。
本篇文章將帶領讀者操作 GStreamer 的指令來解析網路攝像頭中的 YUV 與 H264 格式,並應用 i.MX8 獨有的硬體加速晶片 VPU( Video Processing Units) 作影像串流解碼 !! 一起動手探討吧!!
必要環境 :
- OP-Killer EVM 或 NXP i.MX8M Plus 開發板 x 1
- UVC / WebCAM x 1
- Screen X 1
視頻處理單元(VPU) 規格 :
(2) 檢查裝置
請先確認 裝置(Device) 或 網路攝像頭(Webcam) 是否正確連接至開發板。
代碼展示 :
$ v4l2-ctl --list-devices
執行結果展示 :
(3) 檢查裝置規格
請先確認 裝置(Device) 或 網路攝像頭(Webcam) 的規格。
代碼展示 :
$ v4l2-ctl -d /dev/video{*} --list-formats-ext
執行結果展示 :
如下圖所示,此裝置有三種規格 ; 分別為 MJPG \ H264 \ YUYV。
(4) 檢查是否支援 VPU
請列用下列代碼,來檢查確認平台端是否有支援 VPU Encoder / Decoder。
代碼展示 :
$ gst-inspect-1.0 | grep -ie vpu -ie gpu -ie dec
執行結果展示 :
(5) 使用 GStreamer 驅動網路攝像頭
1. 快速啟用
實測結果展示(任選一行指令) :
$ gst-launch-1.0 v4l2src device=/dev/video3 ! waylandsink
2. 解析 YUV 格式
請觀察以下兩種解析度所對應的 FPS 禎數,分別為 1280x720 與 640x480 。此次實測結果,可以發現 640x480 的解析度能夠來到 FPS 禎數約 24 張的表現。遠大於前者的表現,因此對於用 CPU 運行來解碼而言,由此可證 ; 在處理 640x480 的解析度時,會呈現較好地性能表現。
實測結果展示( 1280x720 ) :
$ gst-launch-1.0 v4l2src device=/dev/video3 ! \
'video/x-raw,format=YUY2,width=1280,height=720,pixel-aspect-ratio=1/1,framerate=30/1' ! fpsdisplaysink
實測結果展示( 640x480 ) :
$ gst-launch-1.0 v4l2src device=/dev/video3 ! \
'video/x-raw,format=YUY2,width=640,height=480,pixel-aspect-ratio=1/1,framerate=30/1' ! fpsdisplaysink
3. 解析264 格式
請觀察以下三種解析度所對應的 FPS 禎數,分別為 1920x1080、1280x720、640x480 。
從實測結果可以發現 1920x1080 的解析度能夠達到 FPS 禎數約 24 張的表現。720p 的解析度仍保有 15 張的表現,則 480p 的解析度剩下僅僅 6 張的表現。但因作者尚未熟讀 VPU 的硬體架構,目前僅能實驗的數據來作參考,故藉由 VPU 硬體來作視訊解碼的方式,在處理 1920x1080 的解析度時,會呈現較好地性能表現。
實測結果展示( 640x480 ) :
$ gst-launch-1.0 v4l2src device=/dev/video3 -v ! \
'video/x-h264, width=640, height=480, pixel-aspect-ratio=1/1, framerate=30/1' ! \
queue ! h264parse ! vpudec ! queue ! imxvideoconvert_g2d ! queue ! fpsdisplaysink
# 選項 -v 可以顯示 log 資訊至終端機上
實測結果展示( 1280x720 ) :
$ gst-launch-1.0 v4l2src device=/dev/video3 -v ! \
'video/x-h264, width=1280, height=720, pixel-aspect-ratio=1/1, framerate=30/1' ! \
queue ! h264parse ! vpudec ! queue ! imxvideoconvert_g2d ! queue ! fpsdisplaysink
實測結果展示( 1920x1080 ) :
$ gst-launch-1.0 v4l2src device=/dev/video3 -v ! \
'video/x-h264, width=1920, height=1080, pixel-aspect-ratio=1/1, framerate=30/1' ! \
queue ! h264parse ! vpudec ! queue ! imxvideoconvert_g2d ! queue ! fpsdisplaysink
PS : 此攝像頭雖有支援解析度 2560x1440 的格式,但執行平台端中會有資料流的錯誤訊息。導致無法順利運行。
五. 結語
根據上述實驗得知,能透過 GStreamer Framework 或 Pipeline 指令操作來改善網路攝像頭或 MIPI 攝像頭的每幀處理速度。此文章以 OP-Killer EVM 開發板搭配 I-Family IF-008D 攝像頭來驗證透過 GStreamer 在 YUV 與 H.264 的處理速度。其中發現由 CPU 軟體解碼的 YUV 格式,效能表現是遠慢於透過 VPU 解碼的 H.264 格式的表現,且可以達到解析度 1920x1080@fps 25 的不錯成績。若有興趣的讀者能更加鑽研 GStreamer 的應用,對於影像串流、影音處理都是必學習的一堂課 !! 接下來,就要將 GStreamer 的概念結合至 eIQ NNStreamer 中,敬請期待下一篇博文 !!
六. 參考文件
[1] 官方文件 - i.MX8 GStreamer User Guide
[2] 第三方資源 - GStreamer 維基百科
[3] 第三方資源 - 什么是Gstreamer?
如有任何相關 eIQ NNStreamer 技術問題,歡迎至博文底下留言提問 !!
接下來還會分享更多 eIQ NNStreamer 的技術文章 !!敬請期待 【ATU Book-i.MX8 系列 - eIQ NNStreamer】 !!
評論