在NVIDIA-Jetson平台上構建智能多媒體服務器


NVIDIA-Jetson平台上構建智能多媒體服務器

Building a Multi-Camera Media Server for AI Processing on the NVIDIA Jetson Platform

媒體服務器提供多媒體一體功能,例如視頻捕獲、處理、流式處理、錄制,在某些情況下,還能夠在某些事件下觸發操作,例如自動拍攝快照。             

要使媒體服務器發揮最佳性能,必須是可擴展的、模塊化的,並且易於與其進程集成。一個典型的例子是通過進程間通信控制媒體服務器的GUI。             

在本文中,將向展示如何在NVIDIA Jetson平台上構建一個簡單的用於人工智能處理的實時多攝像機媒體服務器。將演示如何使用GStreamer守護進程(GstD)、GstInterpipe和NVIDIA DeepStream SDK開發一個可伸縮的健壯原型,以便從多個不同的視頻源捕獲。              除了實現實時的深度學習推斷之外,服務器是完全動態的,因為可以在運行時更改正在處理的多個視頻流的屬性和狀態。             

一個有價值的附加組件是觸發動作的能力,例如拍攝快照或錄制視頻作為對特定事件的響應。圖1顯示了在NVIDIA DeepStream軟件模塊執行一些AI處理之后,視頻流的一個示例快照,其中包含生成的邊界框。稍后描述的示例媒體服務器使用兩個攝像機,但是,復制這兩個視頻流以演示可以添加多個視頻流。

Figure 1. AI media server sample snapshot.
在本文的最后,將了解一組基於GStreamer的工具,以及如何根據特定的多媒體和人工智能需求來擴展。要學習本教程,應該具備GStreamer和DeepStream框架的基本知識。

Why a media server?

在媒體服務器中使用DeepStream為智能媒體產品提供了快速上市解決方案。監視和運動流(如圖2所示)是兩個用例的例子,在這些用例中,可以使用增強了人工智能功能的媒體服務器來分析捕獲的視頻並提取有用的信息。當檢測到異常行為時,服務器可以觸發記錄或快照等事件。

Figure 2: Media server example for sports streaming.

AI media server modules

人工智能媒體服務器模塊             

媒體服務器划分為四個模塊:             

視頻捕獲             

視頻處理與人工智能             

視頻編碼             

其功能,如錄制、流式處理和快照。             

與集成媒體服務器的每個模塊相對應的四個模塊:視頻捕獲、視頻處理和人工智能、視頻編碼和附加功能。

如果使用GStreamer實現媒體服務器,則最終會得到如下代碼示例所示的管道:

v4l2src device=/dev/video1 ! video/x-raw,width=640,height=480 ! videoconvert ! video/x-raw,format=I420,width=640,height=480 ! queue ! tee name=camera0 \

nvarguscamerasrc ! nvvidconv ! video/x-raw,format=I420,width=640,height=480 ! queue ! tee name=camera1 \

camera0. ! video/x-raw,format=I420,width=640,height=480 ! nvvideoconvert ! video/x-raw(memory:NVMM),format=NV12,width=640,height=480 ! nvstreammux0.sink_0 \

camera0. ! video/x-raw,format=I420,width=640,height=480 ! nvvideoconvert ! video/x-raw(memory:NVMM),format=NV12,width=640,height=480 ! nvstreammux0.sink_1 \

camera1. ! video/x-raw,format=I420,width=640,height=480 ! nvvideoconvert ! video/x-raw(memory:NVMM),format=NV12,width=640,height=480 ! nvstreammux0.sink_2 \

camera1. ! video/x-raw,format=I420,width=640,height=480 ! nvvideoconvert ! video/x-raw(memory:NVMM),format=NV12,width=640,height=480 ! nvstreammux0.sink_3 \

nvstreammux name=nvstreammux0 batch-size=4 batched-push-timeout=40000 width=640 height=480 ! queue ! nvinfer batch-size=4 config-file-path=deepstream-models/config_infer_primary_4_cameras.txt ! queue ! nvtracker ll-lib-file=deepstream-models/libnvds_mot_klt.so enable-batch-process=true ! queue ! nvmultistreamtiler width=640 height=480 rows=2 columns=2 ! nvvideoconvert ! nvdsosd ! queue ! tee name=deep \

deep. ! nvvideoconvert ! nvv4l2h264enc insert-sps-pps=true iframeinterval=10 ! tee name=h264 \

deep. ! nvvideoconvert ! nvv4l2h265enc insert-sps-pps=true iframeinterval=10 ! tee name=h265 \

deep. ! nvvideoconvert ! nvv4l2vp9enc ! tee name=vp9 \

deep. ! nvvideoconvert ! video/x-raw,width=640,height=480 ! nvjpegenc ! tee name=jpeg \

h264. ! h264parse ! matroskamux ! filesink name=file location=test-h264-0.mkv \

h265. ! h265parse ! matroskamux ! filesink name=file location=test-h265-0.mkv \

vp9. ! matroskamux ! filesink name=file location=test-vp9-0.mkv \

jpeg. ! filesink name=file location=test-snapshot0.jpg

除了很難閱讀之外,這段代碼對於動態控制模塊連接和管道狀態也不是很簡單。此外,這種方法不可擴展,可能導致代碼復制,更不用說實現簡單原型所需經歷的耗時學習曲線了。以下是如何克服這些問題的方法:             

模塊互連             

模塊控制

Module interconnection

一個更好的實現應該有多個更小的管道,而不是一個非常大的管道。問題是如何連接這些管道。             

RidgeRun的GstInterpipe是一個開源插件,可以解決這個問題。GstInterpipe插件提供了兩個元素interpipesrc和interpipesink。

Module control

媒體服務器的一個理想特性是能夠對正在處理的不同流的狀態和屬性進行某種程度的控制。              RidgeRun的GstD是一個開源項目,是處理GStreamer框架的多線程Linux守護進程。GstD提供了一個類似gst啟動的命令行接口gst client,以及C和Python綁定。簡化了動態管道管理,加快了原型和開發時間。

Building an AI media server in 30 minutes

所有這些都准備好了,現在可以使用這里描述的工具將所有內容放在一個真實的實現中。可以使用DeepStream、基於GStreamer的工具(GstD、GstInterpipe)和硬件加速插件,在Python中為Jetson TX2板創建一個示例媒體服務器。

Prerequisites

要運行AI媒體服務器,需要安裝Jetpack 4.3的Jetson TX2板。此外,演示假設板上連接了兩個攝像頭,一個在MIPI CSI上,一個在USB上。             

按照wiki頁面安裝GStreamer守護進程和GstInterpipe。安裝這些開源項目后,可以按照運行演示wiki頁面中的說明進行操作。

Video capture

在這個模塊中,應用程序通常使用一個或多個攝像頭或捕獲硬件設備,為媒體服務器提供視頻輸入。對於每個用例,考慮接口和硬件制造商來選擇正確的解決方案。              

有多種接口可用於捕獲與Jetson板兼容的視頻。這些選項包括MIPI CSI、USB、SLVS、GMSL和FPD Link。有多家制造商為Jetson平台板提供攝像頭,如索尼、OmniVision和OnSemi。             

有些應用需要使用許多攝像頭。在這種情況下,需要特殊的硬件和軟件。一個例子是D3工程的子板(圖3),連接到Jetson AGX Xavier上,使用RidgeRun的相機驅動程序獲得最多16個FPD Link III工作相機。有關更多信息,請參見演示,RidgeRun D3 NVIDIA Partner Showcase Jetson Xavier多攝像頭AI演示。

Figure 3: D3 Engineering hardware for 16 FPD-Link III cameras on Jetson AGX Xavier.

在這個媒體服務器示例中,使用兩個攝像頭:MIPI CSI和USB攝像頭。以下是USB攝像頭的捕獲管道:              client.pipeline_create('camera0', 'v4l2src device=/dev/video0 ! \ video/x-raw,format=YUY2,width=1280,height=720 ! \interpipesink name=camera0 forward-events=true forward-eos=true sync=false')

client對象是用於控制媒體服務器管道的GstD客戶端實例。             

使用管道名稱和描述為參數的管道創建命令。這個camera0管道使用v4l2src元素從USB攝像機捕獲,在本例中,設備屬性設置為/dev/video0。此屬性必須根據每個板中的視頻設備排列進行設置。通過名為camera0的interpipesink實例使USB攝像頭捕獲可用。             

現在,考慮一下用於從CSI MIPI相機捕獲的camera1管道:

client.pipeline_create('camera1', 'nvarguscamerasrc ! nvvidconv ! video/x-raw,format=I420,width=1280,height=720 ! queue ! interpipesink name=camera1 forward-events=true forward-eos=true sync=false')

要從該傳感器捕獲,請使用nvarguscamerasrc元素,NVIDIA視頻捕獲專有元素下面使用libargus。CSI MIPI camera視頻流通過名為camera1的interpipesink實例提供。

Video processing and AI

視頻處理塊由兩個功能單元組成。一個負責調整和修改捕獲的視頻緩沖區(視頻處理)的屬性,另一個負責將原始流數據轉換為可操作的視野(人工智能處理)。             

視頻處理             

通常,原始攝像機視頻流需要一些格式更改才能被其模塊使用。這些更改可能與幀速率、分辨率、顏色空間或用於分配緩沖區的內存類型有關。             

要執行這些操作,可以利用NVIDIA的硬件加速GStreamer元素。例如,考慮camera0_rgba_nvmm和camera1_rgba_nvmm管道,各自監聽各自的相機。nvvideoconvert元素用於同時執行顏色空間、內存轉換和內存:

client.pipeline_create('camera0_rgba_nvmm', 'interpipesrc listen-to=camera0 ! video/x-raw,format=YUY2,width=1280,height=720 ! videoconvert ! video/x-raw,format=NV12,width=1280,height=720 ! nvvideoconvert ! video/x-raw(memory:NVMM),format=RGBA,width=1280,height=720 ! queue ! interpipesink name=camera0_rgba_nvmm forward-events=true forward-eos=true sync=false caps=video/x-raw(memory:NVMM), format=RGBA, width=1280, height=720, pixel-aspect-ratio=1/1,interlace-mode=progressive,framerate=30/1')

已處理的視頻流由名為camera0_rgba_nvmm和camera1_rgba_nvmm的管道間接收器實例提供。             

人工智能處理             

AI處理模塊完全依賴於DeepStream SDK中提供的一組基於GStreamer的工具。提供了一個可操作的洞察級別,涉及對原始數據(在媒體服務器的情況下,來自攝像機的視頻緩沖區)的分析和GPU上的后續處理。可以通過DeepStream訪問的一些功能包括:             

流聚合和批處理             

基於時態相關的推理用於檢測、分類和分割             

目標跟蹤參考實現             

用於突出顯示對象和文本覆蓋的屏幕顯示API             

參考媒體服務器示例,interpipesrc元素偵聽攝像機處理的視頻流,並將其轉換為運行批處理機制的nvreammux元素的四個輸入。盡管在這個示例媒體服務器中僅使用兩個攝像機,但可以將輸入復制到nvreammux以演示可以使用更多攝像機。             

mux元素的輸出進入nvinfer實例和其可用的DeepStream元素,最終到達interpipesink實例,該實例向媒體服務器的下一個階段提供包含推斷信息的視頻幀。

client.pipeline_create('deepstream', '\

interpipesrc listen-to=camera0_rgba_nvmm ! nvstreammux0.sink_0 \

interpipesrc listen-to=camera0_rgba_nvmm ! nvstreammux0.sink_1 \

interpipesrc listen-to=camera1_rgba_nvmm ! nvstreammux0.sink_2 \

interpipesrc listen-to=camera1_rgba_nvmm ! nvstreammux0.sink_3 \

nvstreammux name=nvstreammux0 batch-size=4 batched-push-timeout=40000 width=1280 height=720 ! queue ! nvinfer batch-size=4 config-file-path=../deepstream-models/config_infer_primary_4_cameras.txt ! queue ! \

nvtracker ll-lib-file=../deepstream-models/libnvds_mot_klt.so enable-batch-process=true ! queue ! nvmultistreamtiler width=1280 height=720 rows=2 columns=2 ! nvvideoconvert ! nvdsosd ! queue ! \

interpipesink name=deep forward-events=true forward-eos=true sync=false')

Video encoding

在這一點上,有一個包含(或不包含)人工智能信息的視頻緩沖流。對於其模塊(如錄制、流式處理或拍攝快照),需要數據壓縮以避免不可管理的文件大小問題、網絡過載和其一些問題。當嵌入式系統的可用硬件資源有限且功耗是關鍵競爭因素時,這些問題尤其重要。             

編碼和解碼是一種資源密集型操作。當接收到重要的數據流時,這可能會導致處理瓶頸。這個限制可以通過使用基於硬件的編碼器和解碼器(編解碼器)來解決。NVIDIA提供了硬件編解碼器,可以在專門的硬件上加速編碼和解碼,從而為其任務卸載CPU和GPU單元。             

正在構建的媒體服務器描述了兩種不同的視頻編碼格式(H.264和VP9)選項和一種圖像編碼(JPEG)選項。             

下面的代碼示例顯示了H.264、VP9和JPEG的這種編碼管道的實現:

client.pipeline_create('h264', 'interpipesrc name=h264_src format=time listen-to=deep ! video/x-raw(memory:NVMM),format=RGBA,width=1280,height=720 ! nvvideoconvert ! nvv4l2h264enc ! interpipesink name=h264_sink forward-events=true forward-eos=true sync=false async=false enable-last-sample=false drop=true')

 

client.pipeline_create('vp9', 'interpipesrc name=vp9_src format=time listen-to=deep ! nvvideoconvert ! nvv4l2vp9enc max-perf=true ! interpipesink name=vp9_sink forward-events=true forward-eos=true sync=false async=false enable-last-sample=false drop=true')     

 

client.pipeline_create('jpeg', 'interpipesrc name=src format=time listen-to=deep ! nvvideoconvert ! video/x-raw,format=I420,width=1280,height=720 ! nvjpegenc ! interpipesink name=jpeg forward-events=true forward-eos=true sync=false async=false enable-last-sample=false drop=true')

前面描述的管道處理DeepStream模塊的輸出。通過nvvideoconvert將緩沖區轉換為適合編碼器的顏色空間,並使用nv4l2h264enc、nv4l2vp9enc和nvjpegenc(硬件加速)元素壓縮數據。最后,通過管道將編碼的緩沖區傳遞給以下媒體服務器模塊使用的interpipesink實例。             

vp9管道中,nv4l2vp9enc元素的屬性max perf設置為true。這將啟用編碼器的高性能模式,並且在使用高分辨率和幀速率時非常有用。但是,啟用此屬性會導致功耗增加,這需要在移動系統上加以考慮。

Additional features

最后一個階段可以稱為最終產品模塊。可以生成視頻記錄、通過網絡發起視頻流,或者簡單地從照相機生成其中一個視頻流的快照。所有選項都包括在DeepStream模塊中完成的先前AI處理。             

同樣,每個管道都有一個listen to屬性設置到每個對應的編碼流。兩個視頻錄制管道都使用Matroska容器來生成生成的文件。             

H264錄音

client.pipeline_create('record_h264', 'interpipesrc format=time allow-renegotiation=false listen-to=h264_sink ! h264parse ! matroskamux ! filesink name=filesink_record_h264')

H.264管道的情況下,需要h264parse元素使編碼塊的輸出適應matroskamux接受的內容。             

VP9錄制

client.pipeline_create('record_vp9', 'interpipesrc format=time listen-to=vp9_sink ! matroskamux ! filesink name=filesink_record_vp9')

同樣,VP9也被打包到Matroska容器中。另一方面,不需要解析器。             

快照

client.pipeline_create('snapshot', 'interpipesrc format=time listen-to=jpeg num-buffers=1 ! filesink name=filesink_snapshot')

快照管道使用num buffers屬性僅接受啟用快照數據路徑后通過interpipesrc實例的第一個緩沖區。捕獲第一個緩沖區后,會自動發送一個流結束(EOS事件,以避免用更新的事件覆蓋所需的緩沖區)。             

網絡流媒體             

流協議(UDP、TCP、RTSP和WebRTC)的實際選擇取決於用例場景需求和參數,如延遲、質量、安全性和成本等。             

WebRTC和RTSP是最常用的流媒體解決方案,GStreamer支持這兩種協議。為了加快開發速度,RidgeRun提供了GstWebRTC和GstRtspSink插件等產品。GstWebRTC用於將管道轉換為與WebRTC兼容的端點,而GstRtspSink則加速原型制作並促進集成。

AI media server dynamics

在前面的章節中,展示了AI媒體服務器實現的一些細節。現在,將探索如何控制這些模塊,並利用GstInterpipes更改連接。             

要播放管道,請使用命令pipeline\u play,並將管道名稱用作參數。例如,要從兩個攝像機開始捕獲,並在媒體服務器中啟動視頻處理和DeepStream管道,請使用以下代碼示例:

client.pipeline_play('camera0')

client.pipeline_play('camera1')

client.pipeline_play('camera0_rgba_nvmm')

client.pipeline_play('camera1_rgba_nvmm')

client.pipeline_play('deepstream')

記錄             

要開始錄制,首先需要設置文件的寫入位置。為此,請使用element\u set命令設置filelink元素的location屬性,如下所示:

client.element_set('record_vp9', 'filesink', 'location', 'test_record_vp9_0.mkv')

該位置可以設置為絕對路徑,也可以像前面的示例一樣設置為相對路徑。在位置設置為相對路徑的情況下,文件將寫入GtsD啟動的目錄。             

現在可以播放編碼和錄制管道以開始錄制過程。例如,以下命令開始錄制vp9:

client.pipeline_play('vp9')   

client.pipeline_play('record_vp9')

要停止錄制,請將EOS事件發送到編碼器管道以允許編碼器正確完成,等待管道完成對任何緩沖數據的處理,然后停止編碼和錄制管道:

client.event_eos('vp9')

client.bus_filter('vp9', 'eos')

client.bus_read('vp9')                

client.pipeline_stop('vp9')   

client.pipeline_stop('record_vp9')

在某些情況下,更改編碼器視頻源會很有用。例如,如果要從相機輸出(無對象檢測)而不是DeepStream輸出中錄制一個常規視頻流,這將非常有用。GstInterpipes允許執行此動態更改。             

使用element_set命令將編碼管道的listen to屬性更改為提供要錄制的視頻流的interpipesink的名稱。例如,要僅錄制camera1輸出,請連接到該相機的視頻處理管道interpipesink,如下所示:

client.element_set('vp9', 'vp9_src', 'listen-to', 'camera0_rgba_nvmm')

然后,按照設置所需文件名和播放編碼和錄制管道的相同步驟啟動該過程

client.element_set('record_vp9', 'filesink', 'location', 'test_record_vp9_1.mkv')                      

client.pipeline_play('vp9')   

client.pipeline_play('record_vp9')

快照             

拍攝快照與前面描述的錄制類似。要拍攝快照,必須設置快照的寫入位置。然后可以啟動編碼和快照管道。

client.element_set('snapshot', 'filesink', 'location', 'test_snapshot_0.jpeg')

client.pipeline_play('jpeg')

client.pipeline_play('snapshot')

與記錄連接更改類似,快照源也可以更改。例如,這將允許拍攝單個相機捕獲的快照。只需更改JPEG管道interpipesrc listen to屬性

client.element_set('jpeg', 'jpeg_src', 'listen-to', 'camera0_rgba_nvmm')

復雜的場景             

GtsD的靈活性允許媒體服務器根據AI模塊檢測到的事件觸發操作。例如,檢測到危險區域中的人員可能會觸發媒體服務器中的信號。自定義應用程序可以監聽這些類型的事件,並使用這些信息觸發媒體服務器中的操作,例如拍攝快照,甚至在媒體服務器域之外執行進一步的操作。

總結             

現在已經學會了創建一個媒體服務器解決方案,可以從多個攝像頭捕獲視頻,通過人工智能處理應用一些基本級別的圖像識別,並生成一個文件(視頻或照片),而無需從Gstreamer和Glib學習曲線導出麻煩。在開發過程中,了解了一些工具(GstD、GstInterPipe),這些工具可以為設計帶來靈活性和動態性,允許對媒體服務器中的幾個數據處理分支進行運行時控制。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM