節點
一個 Node 是 SiMa.ai Neat 中最小的可組合單元。
節點是 Graph 將其連接在一起的元素:解碼階段、預處理階段、模型階段、後處理階段、來源、接收端和應用程式邊界。
參考資料:
一個節點代表什麼?
一個節點貢獻一個邏輯工作單元,以及建構者需要用來安全地將其整合進去的元資料:
- 執行階段工作,例如解碼、轉換、預處理、推論、後處理或資料匯出行為;
- 輸入/輸出合約,例如預期的媒體類型、張量形狀、資料類型或限制;
- 採用確定性的後端命名方式,因此,
describe()、診斷資訊、指標和探測功能會保持穩定。
主要原則很簡單:
Graph = nodes wired together
Model 是具有模型意識的節點來源。一個 Model 可以直接新增到一個 Graph 中,或者可以提供可重複使用的階段片段,例如預處理、推論和後處理。
預先建置的節點群組
某些常見的模式包含多個低階節點。Neat 將這些節點以預先建置的群組形式呈現,因此使用者不必手動連接每個來源、解碼器、轉換器、佇列或接收器。
將群組視為一個可重複使用的迷你圖:一個具有明確規範的、由多個節點組成的命名集合。
範例:
VideoInputGroup(...):檔案/影片來源 + 解碼路徑。RtspDecodedInput(...):RTSP 來源 + 解碼路徑。- 模型路徑片段:針對已編譯的模型,進行預處理 + 推論 + 解碼/後處理。
#include "neat/runtime.h"
#include "neat/node_groups.h"
simaai::neat::Graph graph;
simaai::neat::nodes::groups::VideoInputGroupOptions vopt;
vopt.path = "/data/sample.mp4";
graph.add(simaai::neat::nodes::groups::VideoInputGroup(vopt));
當形狀為標準,且應用程式中令人感興趣的部分並非內部媒體處理時,請使用預先建置的群組。如果您需要自訂的拓撲結構,請從較低層級的節點自行建置對應的 Graph。
選擇一個節點或群組
在您查閱完整的 API 檔案之前,請先參考這張地圖。
| 任務 | C++ 的起點 | Python 的起點 |
|---|---|---|
| 應用程式推送張量、圖片或樣本。 | nodes::Input("name", options) | pyneat.nodes.input("name", options) |
| 應用程式提取完整的樣本。 | nodes::Output("name", options) | pyneat.nodes.output("name", options) |
| 從檔案中讀取影格。 | nodes::FileInput(...),再加上解碼節點,或者使用 nodes::groups::VideoInputGroup(...)。 | pyneat.nodes.file_input(...),再加上解碼節點,或者使用 pyneat.groups.video_input(...)。 |
| 將一張圖片讀取為來源。 | nodes::StillImageInput(...) | pyneat.nodes.still_image_input(...) |
| 讀取 MIPI/libcamera 相機 | nodes::CameraInput(...) | pyneat.nodes.camera_input(...) |
| 讀取 RTSP 串流。 | nodes::RTSPInput(...)、nodes::groups::RtspEncodedInput(...) 或 nodes::groups::RtspDecodedInput(...)。 | pyneat.nodes.rtsp_input(...)、pyneat.groups.rtsp_encoded_input(...) 或 pyneat.groups.rtsp_decoded_input(...) |
| 讀取 HTTP 多部分 MJPEG 格式。 | nodes::groups::HttpMjpegDecodedInput(...),或用於手動設定畫面的 nodes::HttpSource(...)、MultipartJpegDemux()、JpegParse()。 | pyneat.groups.http_mjpeg_decoded_input(...),或 pyneat.nodes.http_source(...)、pyneat.nodes.multipart_jpeg_demux()、pyneat.nodes.jpeg_parse()。 |
| 解碼圖片 | nodes::ImageDecode() 或 nodes::JpegDecode() | pyneat.nodes.image_decode() 或 pyneat.nodes.jpeg_decode() |
| 解碼已編碼的影片 | nodes::SimaDecode(SimaDecodeOptions{...}) | pyneat.nodes.sima_decode(options) |
| 調整影片的畫質或限制播放速率。 | nodes::VideoScale(), VideoRate(), ImageFreeze() | pyneat.nodes.video_scale(), video_rate(), image_freeze() |
| 建立一個可重複使用的影像輸入路徑。 | nodes::groups::ImageInputGroup(...) | pyneat.groups.image_input(...) |
| 建立一個可重複使用的視訊輸入路徑。 | nodes::groups::VideoInputGroup(...) | pyneat.groups.video_input(...) |
| 傳輸影片訊號 | nodes::groups::VideoSender(...) 或 H.264/UDP 輸出輔助工具。 | pyneat.groups.video_sender(...) 或 H.264/UDP 輸出輔助工具 |
| 傳送中繼資料。 | MetadataSender | pyneat.MetadataSender |
| 呈現偵測結果 | nodes::SimaRender(...) | pyneat.nodes.sima_render(...) |
| 將 logits 轉換為類別索引。 | nodes::SimaArgMax(...) | pyneat.nodes.sima_argmax(...) |
當您需要一個經過測試的片段時,請使用群組。當您需要明確的拓撲結構時,請使用個別節點。對於扇出和扇入,請使用 Graph 輔助工具,例如 graphs::Branch(...) 和 graphs::Combine(...),而不是將拓撲結構隱藏在重複的輸出後面。
nodes::H264Decode(...) 和 pyneat.nodes.h264_decode(...) 已經過時,是相容性包裝函。新的 H.264 解碼圖應使用 SimaDecode,並搭配 SimaDecodeType::H264。
已編碼的解碼路徑
根據您的圖所接收的內容,選擇適當的 API:
| 可供圖使用的輸入資料。 | API | 輸出 |
|---|---|---|
| 已完成、已解析的已編碼存取單元。 | SimaDecode(...) | 原始解碼後的影片 |
| 一個應該保持編碼狀態的 RTSP 串流。 | RtspEncodedInput(...) | 已解析編碼後的存取單元。 |
| 應該要解碼的 RTSP 串流。 | RtspDecodedInput(...) | 原始解碼後的影片 |
SimaDecode 不會連接到 RTSP、解封封包 RTP 或解析基本資料流。當上游階段或應用程式已經提供完整的編碼樣本時,請使用它。
| 已編碼的輸入 | 原生解碼器選項 | 典型的上游路徑 |
|---|---|---|
| H.264/AVC 存取單元 | SimaDecodeType::H264 或 SimaDecodeType::AVC | RTSP H.264 訊號 解封裝和解析,或解析其他 H.264 來源。 |
| H.265/HEVC 存取單元 | SimaDecodeType::H265 或 SimaDecodeType::HEVC | RTSP H.265 進行解封封包和解析,或者解析另一個 H.265 來源。 |
| 單張 JPEG 圖像 | SimaDecodeType::JPEG | JpegParse() 或應用程式提供的已編碼的 JPEG 範例 |
| MJPEG 影格串流 | SimaDecodeType::MJPEG | HTTP 多部分資料流解碼器 + JpegParse(),或 RTSP JPEG 封包解碼器 + JpegParse()。 |
別名會選擇相同的解碼器路徑:H264 等同於 AVC,而 H265 等同於 HEVC。 這些相同的別名可以在 C++ 和 Python 中透過 RtspCodec 和 FormatTag 取得。
H.265 輸入必須使用 8 位元、4:2:0 色度的 HEVC 主要設定檔。 直接的基礎資料流輸入必須進行解析,且必須是 Annex-B 位元組資料流,並且必須對齊存取單元。 其參數集(VPS、SPS 和 PPS)必須在依賴它們的影格之前到達解碼器。 RtspEncodedInput 會處理 RTP 解封裝和用於 RTSP 路徑的 H.265 解析。 不支援主要 10、10 位元、4:2:2 和單色 4:0:0 位元串流。 對於灰階內容,請編碼一個 8 位元 4:2:0 資料流,其 Y 平面包含灰階影像,並且其 U 和 V 樣本使用中性值 128。
在使用資料流之前,請驗證它:
ffprobe -v error -rtsp_transport tcp -select_streams v:0 \
-show_entries stream=codec_name,profile,pix_fmt \
-of default=noprint_wrappers=1 rtsp://camera.example/live
H.265 解碼器需要 codec_name=hevc、profile=Main 和 pix_fmt=yuv420p。
SimaDecodeOptions::raw_output 控制解碼器的即時輸出:
| 價值 | 解碼器輸出 |
|---|---|
true(預設值) | 在 SiMaAI 記憶體中使用原生 NV12 或 I420 格式。對於解碼器的零拷貝輸出,請使用 NV12 格式。 |
false | 已轉換的 video/x-raw(memory:SystemMemory) 輸出,供 CPU 使用。 |
raw_output 與解碼器分開 zero-copy-output。核心功能可讓
zero-copy-output 在解碼器接收時,如果圖可以轉送解碼器的原生 NV12 緩衝區。如果任何後續分支使用無法讀取原生平面佈局的編碼器輸入,則核心會讓解碼器進入,但不會進行零拷貝輸出,因此每個分支都會收到一個打包後的影格。 RunOptions::output_memory
分別控制終端機輸出是否與其後端緩衝區共用ZeroCopy) 或複製到框架擁有的儲存空間中(Owned)。
H.264/H.265 自動偵測功能需要知道解碼器的寬度、高度和幀率。設定 dec_width, dec_height,以及 dec_fps 直接提供,
或透過鍵入的來源提供。 RtspEncodedInput 搭配
source_fps。核心元件在來源幀率未知時,不會預設為 30 FPS。
允許進入會引發明確的 num_buffers 當其低於租賃的
安全下限時,其價值為。離開 num_buffers 「unset」會保留解碼器元素的預設值。
保留 decoder_tuning 設為空白或設定為 auto 適用於一般資料流。請使用
throughput-low-latency 僅適用於未包含 B 影格且僅使用一張參考影格進行編碼的影音串流;該模式會停用已解碼影格的重新排序功能。
nodes::JpegDecode() 以及 pyneat.nodes.jpeg_decode() 是獨立的 CPU/GStreamer
JPEG 解碼節點。將它們用於簡單的 CPU 影像管線。不要將它們用於模型預處理之前的原生 MJPEG 視訊解碼。
對於 RTSP,如果來源的解析度是標準的,請優先使用支援特定編碼器的群組。H.264 仍然是預設設定。明確選擇 H.265 或 HEVC。
保留 RTSP 輸入的編碼格式
使用 RtspEncodedInput(...) 來解封包並解析資料流,而無需對其進行解碼:
simaai::neat::nodes::groups::RtspEncodedInputOptions encoded;
encoded.url = "rtsp://camera.example/live";
encoded.codec = simaai::neat::nodes::groups::RtspCodec::HEVC;
encoded.source_fps = 30;
auto encoded_graph =
simaai::neat::nodes::groups::RtspEncodedInput(encoded);
RtspEncodedInput(...) 在來源解 封包和解析/分幀後停止。
當您的應用程式需要編碼後的樣本時,請使用它,例如將一個已解析的串流分割成解碼圖和視訊輸出圖。對於 H.265,當串流未宣告有效的幀率時,source_fps 會寫入已解析的編碼封包中。
解碼 RTSP 輸入
使用 RtspDecodedInput(...) 來附加 SimaDecode(...),並傳回原始解碼後的影片:
simaai::neat::nodes::groups::RtspDecodedInputOptions decoded;
decoded.url = "rtsp://camera.example/live";
decoded.codec = simaai::neat::nodes::groups::RtspCodec::H265;
decoded.source_fps = 30;
simaai::neat::Graph graph;
graph.add(simaai::neat::nodes::groups::RtspDecodedInput(decoded));
graph.add(simaai::neat::nodes::Output("frames"));
對於 H.265,RtspDecodedInput(...) 會同時針對已解析的 caps 和解碼器 dec-fps 使用 source_fps。當 RTSP caps 不包含有效的幀率時,請設定此值;如果缺少任何一個值,解碼器啟動將會失敗。Neat 不會針對此值探查 RTSP URL。它會宣告來源的幀率,且不會要求進行幀率轉換。若要變更輸出幀率,請啟用 use_videorate,並設定 video_rate_fps。
對於 HTTP 多部分 MJPEG,請使用 HttpMjpegDecodedInput(...)。HTTP 多部分 MJPEG 不是 RTP,因此它使用 HttpSource -> MultipartJpegDemux -> JpegParse -> SimaDecode(MJPEG),而不是 RTSP 解封包。