2026年8月24日

回憶之異質雙核心平台通訊機制

前言:

這篇也是一篇回憶,但跟前面主題無關,因為覺得有趣,因此單獨寫一篇。

緣起:

研究所時,這應該是教授一開始希望我做的方向,但要做什麼不明,最終找不到題目,也是差不多看了一年左右。

異質雙核心平台:

當時手機熱門,TI(德州儀器)推出了平價版本的手機開發板OMAP5912,我們Lab買了幾塊,並以此申請教育經費在系上採購幾十塊給學生上課教學實習用。
學期後,教育部還有審查委員來查看我們這門實習課成果,我為此實做了好幾個專題掛給學生
,用於展示😂
當時有趣的是,我其中一個專題是用OMAP5912 Linux + DSPGateway,按照範例寫最基本的DSP Timer,DSP端倒數計時10秒,然後透過DSP Gateway回傳timeout,Linux端顯示倒數結束。
其中一個評審委員是成大的教授,看到當下問我,OMAP5912有幾種通訊機制,我跟教授說,有2種,TI有一套,Linux有開源一套。
教授回我說,嘿嘿嘿...不對,有3套。第三套是我Lab做的。😄
看得出,這位應該是主要的技術委員,他開心,審查就順利結束。😆

何謂異質雙核心平台是什麼?為何多半用於手機?
在手機上,通常會有單獨一顆CPU專門用於通話時的音訊編碼/解碼,這顆CPU在Nokia與TI那個年代,通常是DSP,DSP強項是快速傅立葉變換,關於傅立葉轉換,我一直學不會😂
因此分工上,主系統運作在ARM9(當時還是ARM9),通話時的音訊處理在DSP。
因為2顆CPU不同性質,因此稱為異質雙核心平台。

延伸一點,後來的手機SoC從ARM + DSP變成ARM + ARM,但第二顆ARM延續DSP作用,一樣是用於音訊編碼/解碼,但TI自此跌落手機SoC神壇,因為TI特色與強項是DSP。

異質雙核心平台有個特色,和雙CPU系統不同在於,雙CPU系統通常是多核心或者多Socket,CPU完全相同,設計完全一致,雙CPU甚至可能會要求型號完全一樣,因此在OS裡面,通常當作相同東西處理,也就共用Cache,甚至Interrupt都在OS共同處理。
但異質雙核心平台不同,異質雙核心平台的DSP端,有自己的OS(TI提供的稱為DSP/BIOS),和ARM端有一塊共用的Cache,其他都是各自獨立的,因此,兩端通訊,主要透過互相觸發對方的Interrupt和在Cache上面收放資料進行通訊。

延伸一點,當時Nokia與TI雖然緊密合作,但TI提供了自己的DSP/BIOS以及自己的通訊Driver - DSP/BIOS Link,而Nokia則開發/維護/實做開源的DSP Gateway。

好,終於把異質雙核心平台介紹完了。

異質平台的起源:

在Paper survey過程中,主軸在異質平台的通訊,於是一路溯源,猜猜看ARM + DSP這種異質平台最早可以追朔出什麼?
這種異質通用CPU + DSP的組合,可以追溯到魚雷系統開發,想想很合理,魚雷其實就是麥克風音頻分析與自動化控制,而音頻處理一直是DSP的強項,因此異質通用CPU + DSP的組合,最早出現在魚雷系統上。
Paper年份在後來PC普及後,我還記得小時候電腦沒有音效卡,當時要買「聲霸卡」這種音效卡,而在
音效卡剛出現的那些時間,則開始出現很多PC + 音效卡的Paper,為何呢?
因為
音效卡本質上也是DSP,對於當時的Windows來說,PC + 音效卡的驅動程式,其實就是異質平台的通訊驅動程式。
差別只在於,早期是硬體間用介面卡互連的子系統(subsystem),OMAP平台則是兩顆CPU做在一起,只透過Cache和Interrupt互連。

現在筆電、手機很常見,音效都沒有卡了,直接做到SoC裡面了,或者有像I2S這樣的界面可以接,連接標準和驅動程式都有了,但在這些東西裡面,其實都帶有很高深的技術,換個場景,就會用在意想不到的地方。


2026年8月23日

回憶之無線MANET與P2P、UPnP

前言:

延續上一篇。

P2P:

相信很多人都用過BT和eMule,不論哪一種,用的都是P2P,正如上一篇簡單提到的,P2P的核心邏輯是,我把我的檔案清單分享給別人,或者分享給檔案清單伺服器,別人就能知道我的檔案清單,那麼當需要的檔案我有的時候,就能夠從我這裡下載。
如果這個檔案同時很多人有,那麼就能同時跟很多人下載同一個檔案的分段,就能快速
下載。
而BT和eMule的差異主要是,eMule把自己的檔案清單分享到檔案清單伺服器,必須要連接著這台檔案清單伺服器;BT則是有DHT,DHT每個人維護一個BT用戶(節點)清單,透過torrent的資訊檔案,提供分享檔案的來源在哪,然後透過DHT詢問其他BT用戶(節點)誰有檔案,同時下載,不需要連接檔案清單伺服器。

MANET 與 P2P:

MANET和P2P因為都有自適應與自我組織的去中心化特性,因此P2P overlay MANET是個常見的組合。
很多Paper都會提到在MANET上面疊加P2P網路以提供檔案服務之類的。

所以其實有沒有發現,不論是MANET還是P2P,兩個的分享機制是相同的,差異只是分享的資訊是什麼,以及分享後的用途不同而已,在MANET中,分享的是路由表,處理的是跳點路由的路徑,而在P2P分享的是檔案資源清單,處理的是誰需要什麼檔案,檔案在哪裡。
所以通常MANET在底層,P2P在上層,兩者相同邏輯,層級不同,處理的Resource不同。
有沒有可能兩者合併?
嗯...這也是當時構想的方向,但兩者的資料屬性和用途差異太大,我後來覺得不太行,的確有Paper提過,但Paper的內容實際上還是2層,上面一樣是P2P,下面一樣是MANET。

UPnP:

UPnP相信很多人都聽過,但好像好一陣子沒聽到UPnP這東西了,UPnP也差不多是那個時代的技術之一。
UPnP的核心設計跟智慧家庭有關,因此它主要出現在MediaCenter和智能家電那個年代。
UPnP的作用是這樣的,它把裝置分為2種角色,控制器和被控制器,最典型的例子,印表機是被控制器,遙控器是控制器
所有裝置都要用制式的XML內容,先描述自己是控制器還是被控制器,再描述自己具備什麼服務(功能)。
例如:
我是印表機,我是被控制器,我提供的服務有彩色文件列印、黑白文件列印,我的IP,我的Port。
我是DVD播放機,我是被控制器,我提供的服務有DVD影片播放、影片快轉、影片倒轉、彈出托盤,我的IP,我的Port。
我是遙控器,我是控制端,我提供的服務有我能控制DVD播放機、控制電視機。

UPnP還提供了Discovery之類的探索功能,裝置會廣播自己的上述XML描述,然後別人就能根據UPnP廣播知道網路上有哪些UPnP裝置提供哪些服務。

P2P 與 UPnP:

既然P2P提供分享檔案清單,UPnP提供裝置服務資訊,那是否能把P2P和UPnP結合? 用P2P的方式分享UPnP的服務資訊?
對的,這就是進階的P2P服務探索功能,以P2P方式分享各個UPnP裝置資訊,就能做到動態的知道網路上有哪些服務裝置。

MANET + P2P 與 UPnP:

正如上面提到的,MANET 與 P2P 同質性很高,都具有自適應性、自組織性、去中心化能力,而UPnP有服務探索能力,能夠提供出裝置資訊,那麼MANET + P2P + UPnP會如何?
對的,當時有Paper提出這樣的美好願景,手拿著PocketPC進入辦公室,不用連線WiFi,直接透過MANET + P2P + UPnP,PocketPC就能知道有印表機、有鍵盤、有滑鼠、有螢幕,以及這些裝置的功能和作用。

想像:

有沒有一種可能,我們將 MANET + P2P 搭配像是 UPnP 這樣的Service Discovery功能,提供無人載具具備的「能力」,那麼,就能做到自適應、自組織多台無人載具自行組合與協調?
當然,我相信實際使用應該更單純,直接把功能硬編碼,在開機前就先設置好全部的組成功能,甚至制式化的根據特定配置預先定義好,說不定更簡單還方便。


回憶之無線網路MESH - MANET

前言:

這篇開始,會有幾篇以回憶的方式,把之前研究所時候的一個方向,無線網路電力路由的構想進行介紹。

緣起:

還記得研究所時,當時我問教授題目方向時,教授跟我說,讓我天馬行空想,那時F-22剛出現,號稱能夠共享數據鍊,於是異想天開跟教授提了無線網路的P2P,就這樣看了一年,後來沒做這方向,只有survey,這個方向最後的構想,就是無線網路電力路由,我想可以用回憶方式介紹技術。

MANET 與 MESH:

現在MESH WiFi已經很常見了,因此應該很容易解釋了。
簡單的說,所謂的MESH或MANET,指的是多個無線網路節點在一個區域內,當我們要從A地點傳資料給B地點,可是A和B地點太遠,無法直接透過一個WiFi AP通訊時,中間可以有多個WiFi AP,以接力轉傳的方式。例如,從A地點經過WiFi 1 → WiFi 2 → B地點,反過來也一樣,從B地點經過WiFi 2 → WiFi 1 → A地點進行資料傳輸,這種中間透過多個無線網路節點轉傳資料的方式,就是MESH或MANET。

MANET的Paper起源可以追溯到美國DARPA研究機構的兩種東西。
一種是越戰時,戰車或人員感測器以空投方式灑在戰場上,這些感測器因為隨機散佈而且範圍大,因此透過MANET這種跳點轉傳的形式傳遞感測器資料。
另一種是子母彈,但炸彈投出在高空打開灑出的一堆子彈頭,每個都是一個感測器,這些感測器之間同樣透過MANET方式轉傳感測器資料。
這兩種研究結果,一個延伸出颱風/颶風的投落送,一個延伸出動物棲息地的環境偵測。

我念研究所當時,SensorNetwork(WSN)(感測網路)很熱門,很多實驗室在做感測網路和802.15.4,號稱這是未來的重要發展,「感測網路」,又是Wireless,很自然就有人研究把MANET做在WSN上面。

MANET原理 - 網路路由:

MANET之所以稱為跳點路由,很直觀的看,它就是資料傳輸時的節點轉送機制,而在TCP/IP與網際網路中,路由轉送發展已久,有設定網路的都會聽過設定Gateway,IT通常都會學到靜態路由和動態路由。
網路概論都會提到常見的路由協定有RIP和OSPF,然後提到RIP是固定路由,OSPF則能根據路由器狀態,例如路由器的流量、CPU使用率之類的資訊,動態決定路徑。

我們把無線拿掉,單看資料轉發這件事,就會發現,其實MESH、MANET就是把OSPF、RIP這樣的路由協定做在Wireless上。
我們可以由此知道MANET第一個組成關鍵路由表

MANET原理 - P2P與MANET:

一個有趣的問題,為何看P2P會看到MANET?
這就跟MANET第二個組成關鍵有關了。
P2P常見的BT和eMule,曾經是非常獨特的設計,就算到現在也是自成一個特別的體系。
在P2P中一個核心邏輯是,每個人(節點)都有自己的檔案清單,這個清單內列出了我共享的檔案有哪些。
接著,每個人都會把自己的檔案清單分享給別人,或者分享給清單伺服器,每個人透過詢問能夠知道哪些檔案在哪裡
MANET把路由表以檔案清單的形式分享給其他節點,這讓每個無線節點,都會有一份自己維護的路由清單,裡面列出的是,要到哪個目的地,可以透過誰到達
可以想像,MANET等於是用P2P的方式分享路由表,然後透過維護路由表了解要傳資料給誰,要透過誰。

MANET原理 - 主流協定AODV、OLSR(、DSDV):

上面提到每個人都有自己的路由表,並透過詢問方式得知別人的路由資訊,如何詢問得知?

一般透過廣播,也就是大家自己用喊的。
A: 我是A,誰聽得到,回答我。
B: 我聽到了,A你可以連我。
C: 我聽到了,A你可以連我,另外,我可以連到D,你可以透過我連D。
於是A的路由表就有

Target 經由
C 直連
B 直連
D C

這種透過廣播方式,維護自己路由表的作法,就是DSDV,也是最簡易的版本。
AODV和OLSR是當時的2種主流路線:

  • AODV方向是,每個人不維護路由表,只在要傳輸時詢問。
  • OLSR方向是,每個人透過廣播方式告訴別人自己的路由表,大家各自維護一份路由表,但因為廣播會造成網路風暴或者Wireless訊號佔線,因此OLSR用了演算法降低網路風暴/Wireless佔線的影響。

白話的說,兩種方向,一種是平時不維護路由表,要傳資料時才問,一種是平時維護路由表,但會增加網路廣播影響。(細節不確定,這沒有仔細看)

沒有好壞,各有優缺點,平時維護路由表,要傳資料時直接就能傳,但可能遇到路由資料過時之類的問題,平時不維護,能省下維護路由表的負載,包括定時收發路由資料,但當要傳資料時,要先詢問路由狀態,會拖慢反應時間。
而目前常見的MESH WiFi多半是AODV,原因是,MESH WiFi幾乎都是固定放置不會移動的,因此只在第一次傳送時要詢問出路由,之後不用再問,能節省路由維護的負載。

目前與AI說的發展:

OLSRv2最後一次Release是在2018年,AODV也差不多2018年前後,顯然已經不是新技術了。
我詢問AI後,AI說近期學術Paper開始結合GPS之類的資訊,變成所謂的地理路由,根據GPS資訊或者相對位置,預測或選擇路由方式。
我自己的認知是,套用OSPF的概念,也就是把多個路由資訊進行加權評分,例如典型的WiFi信號強度,現在改成相對物理距離進行判斷,決定出路由路線。

研究所時的構想:

當時的構想跟上面一樣,假設感測節點有插電的,有太陽能的,有純粹電池的。
那麼,可以根據電池電量、是否插電為依據,加上WiFi信號強度當作路由的選擇標準,做動態路由。


2026年7月25日

IPCAMM NVR - Alpha版本0.9.0.0釋出

前言:

IPCAMM NVR寫了好久,我要設定一個里程碑,釋出第一個Alpha版本0.9.0.0。
釋出後,後續NVR的更新重心會放在測試、除錯上,新功能還會有一些,但基本上會收斂整個Scope。
同時,我會準備開始第二階段Dashboard的開發。
IPCAMM NVR可看成是我對於產品開發的全部Know-How,它基本上就是一整套軟體產品的全部內容,因為是Alpha版本還有很多bug,但這整個就是我對產品的完整認知,當然,未來我如果有其他產品開發,也會依循相同模式和設計進行,而這當然也包括第二階段Dashboard。

程式碼:

https://gitlab.com/ipcamm-nvr

說明:

IPCAMM NVR包括的範圍很大。
它的後端由多個Service專案組成,各個Service專案之間共用參照Shared.ooo專案。
它的前端由一個大專案NvrApplication包裹,但內部一樣是多個專案,每個專案都是單獨的前端元件或前端UI元件。

目前版本為 0.9.0.0 Alpha版本,這個版本不能用於正式環境,連測試環境都不能用,原因是它還有大量已知bug和未測試範圍,這個版本要嘗鮮試用,程式碼參考都沒問題。

IPCAMM NVR目前各個專案的README.md都不長,描述也不仔細,因為這整個專案範圍很大,因此我規劃另外建立一個 gitlab page 專門分類描述各個Service和元件的設計、資料結構,便於串接、開源新增功能。

IPCAMM NVR原則上是雙授權,AGPL-3.0 和 商業授權,但商業授權目前我還沒有管道與銷售模式,因此現階段以AGPL-3.0為主,不過,IPCAMM NVR我實做並開源了完整的授權啟用、檢查機制,License Server我還在想要如何開源。
授權檢查使用的 主機碼(Machine-ID) 產生機制、授權檔案的設計與加密簽章機制我也都開源了,只有加密的密鑰和簽章的公私鑰我自己保留了一組用於商業授權時使用,演算法和開源的密鑰、公私鑰都放上去了,可根據需要修改調整。
當然,因為是非強制性的,後端Streammer的appsettings.json有開關能啟用/禁用授權檢查,非常人性化,前端會根據不同設置和授權狀態顯示。

商業授權設計有2種,綁定主機的授權檔案以及綁定USB的USB授權金鑰。
意思是,這版本我實做了USB授權的設計,可以做到插著USB有授權可以使用程式這件事情。

USB金鑰我用樹莓派Pico 1和Pico 2,兩者都能使用,Pico1和Pico2差異只有在SHA256使用軟體還是硬體,其他包括簽章運算都是軟體實做,沒區別。
USB金鑰在Pico很好做,按著BOOTSEL進入燒錄模式,就可以把韌體寫入,接著透過maker工具程式就能把授權上傳上去,就完成了。
當然,這裡要搭配License Server,我整理之後放個Simple版本,把核心API放上去。

這版本在看和使用時會有疑問,FileSubscriber和透過StreamBus的Recorder都能寫錄影檔案,差別在哪? 作用差異是什麼?
FileSubscriber 是用於行車記錄器這樣的使用場景,環境只要單一Streammer即可運作,不用UI。
Recorder 則是正統的 NVR 使用場景,因此主要以服務角度和跨服務使用場景,為典型的微服務架構。

已知Bug:

這版本目前有大量bug,
  • 已知同時開啟RTSP與Onvif Event,Onvif Event斷線會影像到RTSP串流,錄影的瞬斷(小於40ms)會判斷為連續錄影,畫面表現會是灰畫面。
  • EventBus沒測過外部MQTT Server,僅用Streammer內部MQTT Server模式測試。
  • Go2RtcSubscriber還未測試。
  • StreamBus的UDP功能移除,但程式碼保留,測試發現UDP有很多問題,甚至影響到設計(Packet傳輸方式),這個更動影響比較大,而且既有功能已經有NamePipe和TCP,因此UDP功能廢棄(程式碼留著)。
  • AI操作目前Playback還沒測過,預期應該會有bug。
  • WASM版本的影片播放,也就是瀏覽器的影片播放功能目前失能狀態,WebCodecs 在Linux上非常難測試,其他方式牽涉到轉碼(WebRTC / fMP4 <video> tag),還在初期功能測試階段,其他非播放功能的一般UI類,大多能正常使用。
  • Playback和LiveView在一些Camera上面會有灰畫面或者嚴重瞬斷問題。
  • AV1僅簡易測試,尤其未測試AV1硬體解碼與編碼(我手邊電腦不支援AV1硬解/編碼更不用看了)
  • H264/H265未測試轉碼
  • Microsoft SQL Server未測試,僅測試SQLite與PostgreSQL這兩種資料庫
  • 後端Service未測試MacOS和Windows平台

下一步實做:

目前進入Debug階段,僅會進行幾樣開發,其他會轉做Dashboard和測試除錯。
  1. Installer安裝包
  2. Local Linux V4L2支援
  3. Recorder與Gateway支援多Streammer串接
NVR我預計要能支援3種場景:
  1. 傳統NVR場景
  2. 行車紀錄器 與 無人機場景
  3. 雲端場景
行車記錄器和無人機的目標,預計是支援 CSI 和 USB 界面的 Camera模塊,在Linux上也就是 V4L2,另一方面,我目前參考 Kite Ground Control ,它是串 FFMpeg 和 go2rtc,因此我這邊目標是透過介接 V4L2 ,讓像是 Kite Ground Control 這樣的地面站接我,我在轉到 go2rtc ,實現無縫串接進入 Kite Ground Control 工作流。
同時間,我正在survey無人機場景的界面樣式,考慮Dashboard是針對無人機設計,還是針對地圖設計。
雲端場景,我的目標是,把Recorder的RAID (Erasure Coding,簡稱 EC) 實做上去,加上多 Streammer 支援(含轉碼),那應該能做到橫向擴展 Streammer 和 Recorder 的能力,一旦 Streammer 與 Recorder 解耦具備橫向擴充能力之後,基本上應用在雲端和大規模可擴充場景
就沒問題了。

2026年6月28日

IPCAMM NVR - 開發現況

前言:

上一篇提到在開發NVR,到今天2026-06-28,目前推測進度在85%~90%之間,這篇就把目前的開發進展貼出來展示。

近況:

Server端大致上都差不多了,但目前根據前端還會修改。
最近主要在處理Playback和Video Decoder/Rendering的部份,這兩塊比較難處理,Playback部份可能還會改到後端Recorder和Gateway的CMD模式。
目前前端特色是,我實際上實做了Linux/MacOS/Windows的硬體解碼器操作以及各平台的Rendering。
Linux硬體解碼器使用VA-API,Rendering實做3種:

  • vasurface: VA-API的Surface直出,從解碼器-螢幕成像直通,CPU和GPU使用率最低,但會有穩定性問題
  • glrender: 解碼器用VA-API解碼,顯示的部份使用UNO Platform的OpenGL元件,中間是切開的,會有CPU操作,但解碼和成像都是GPU。處理是直接YUV處理。
    skiarender: 解碼器用VA-API解碼,顯示的部份直接是UNO Platform的SkCanvas元件,解碼是GPU,其他都是CPU。處理是RGB(VA-API轉出RGB)。

MacOS硬體解碼器使用Video ToolBox,Rendering實做2種:

  • glrender: 解碼器用Video ToolBox,顯示的部份使用UNO Platform的OpenGL元件,同Linux的glrender,不同的是,MacOS的OpenGL使用OpenGL ES 3.0。處理是直接RGB處理。
  • nsviewrender: 解碼器用Video ToolBox,顯示的部份使用MacOS的原生NSView,NSView上面疊CGImage顯示。處理是直接RGB處理。
這裡可能疑惑,為何MacOS的Rendering都用RGB處理,因為MacOS的Video ToolBox解出後直接是RGB,特殊的是,它讓你指定RGB大小,所以實際上它幫你把YUV->RGB和Resize都處理了,nsviewrender有透過反射方式,直接把畫面大小指定給Decoder API,讓Video ToolBox直接根據視窗大小resize。glrender沒這問題,它本來就是GPU處理,所以原始尺寸給它自己resize。

Windows硬體解碼器使用DXVA2(D3D11),Rendering目前實做1種:

  • glrender: 解碼器用D3D11,顯示部份使用UNO Platform的OpenGL元件,同Linux的glrender。處理是直接YUV處理。

我手上這台Windows的電腦太舊了,Microsoft Media Foundation(後面簡稱MF)沒有硬體解碼器的驅動程式,只有DXVA2(D3D11)的硬體解碼器驅動程式。Windows的硬體解碼器最新的是MF,前一代是D3D11,D3D11前一代是DXVA2,DVXA2前一代是DXVA。目前DXVA已經廢棄,D3D11一般也會叫做DXVA2或DXVA。目前Windows實做有MF和D3D11版本,但MF無法測試,D3D11版本 + glrender正常顯示。至於像是vasurface或是nsviewrender這樣的直出,目前還沒時間處理。

Browser版本,目前有點難產,Browser的硬體解碼器挑硬體,不一定會有,我手邊的電腦Chrome都無法正常驅動WebCodecs的軟解和硬解。我目前找到H265的軟體解碼器可以解,但要Rendering是另一個麻煩點,因為UNO Platform是單一個WebGL Canvas整塊成像,它有自己實做MediaPlayerElement,但原理是專門針對MediaPlayerElement挖空讓<video>顯示,這部份還在嘗試突破。

AI功能,目前AI功能已經實做了,可以參考主要功能Demo影片,目前實做了一個AI對話框,能夠直接跟AI對話,架構設計上,AI串接在後端LLM Gateway Service,LLM Gateway裡面設定要使用的AI Model和OpenAI EndPoint以及API Key,API Key設定在後端,不用擔心前端偷走。
前端應用程式在程式中定義了能夠使用的function calling,包括2種,一種是把function calling當成system prompt,這種專門適用於Gemma Model,另一種是標準的function calling呼叫。
流程上,前端會發送API把具備的function calling註冊到LLM Gateway,之後在AI對話框對話時,AI就能知道有哪些function calling能夠使用,並能呼叫工具操作。
目前NvrApp(前端)包括Camera的列出、放置到LiveView、最大化、頁籤切換、目前有哪些Event,計畫中但還沒完成的,把Camera放置到Playback、跳到指定日期時間、播放。
其中Event(已經完成)比較特別,AI的Event function calling包括2種,一種是目前NvrApp收到的Event,另一種則是NvrApp透過後端API查詢資料庫中的歷史Event。
API Model主要用智譜的GLM-4.7測試,但它的API主要相容Claude的Anthropic API協定,包括有所謂的深度思考,目前實做和測試都OK。

License的設定頁面目前是假資料,其他都是真實能運作的。


Demo影片:

主要功能Demo(Linux平台應用程式):


Linux各Rendering效能比較:


Browser WASM現況:


MacOS Rendering Demo:

Windows Rendering Demo:


開發與測試環境:

開發電腦: 

CPU: AMD Ryzen 5 7530U
GPU: AMD Ryzen 5內顯,4GB VRAM,VA-API支援
GPU硬體編解碼器: MPEG2, VC1, H264, HEVC(H265), JPEG, VP9(不支援AV1)
Memory: DDR4 32GB
作業系統: Debian 13 + MATE Desktop + X-Window + .NET 10(目前到10.0.301)

Linux測試環境(NVR Server):

CPU: Intel Celeron J4105 CPU
GPU: Intel Celeron J4105內顯,VRAM未知
GPU硬體編解碼器: MPEG2, H264, HEVC(H265), JPEG, VP8, VP9(不支援AV1)
Memory: DDR4 4GB
Disk: NVMe 128GB (錄影儲存目前也在這裡面)
作業系統: Debian 13

MacOS測試和編譯環境:

硬體: Mac mini M1 8GB RAM
作業系統: macOS Sequoia 15.7.2

Windows測試和編譯環境:

CPU: Intel Core m7-6Y75 (第六代Intel Core m處理器)
GPU: 
Intel Core m7-6Y75內顯,Intel HD Graphics 515
GPU硬體編解碼器: H264, H265有硬體解碼器(D3D11)
Memory: DDR3 16GB
作業系統: Windows 10


2026年6月1日

IPCAMM NVR - 前導篇

前言:

前面在寫ONVIF Client Lab時提到,在開發ONVIF相關的Side Project,其實就是NVR。
我回看PRD日期,最早大概從2026-03-21開始,也就是3月底左右,到現在2026-06-01,約2個多月的時間,有空閒就開發它,目前推測進度大概70%左右。
因為好一段時間了,雖然還沒有成果,但我想可以先把目前的規劃、實做進行描述。
因為架構比預期大,之後打算用Gitlab Page或Wiki讓AI撰寫系統架構、設計、Models之類的。

發想:

首先,這個NVR預計會是雙授權型式,AGPL與Commercial。
對的,AGPL開源與商用雙授權。
AGPL允許在不改程式碼的情況下,或者開源的情況下可以修改與使用,甚至以安裝方式提供商用服務,唯一要求就是開源。
Commercial,提供商用,但我還沒想清楚到底怎麼商用法。
會特別提的原因是,程式碼是開源的,但上面包括License設計和實做,對的,你沒看錯,程式碼開源還包括License設計與實做在裡面 😆,這在看到時可能覺得疑惑,怎麼要註冊,但是又有程式碼,授權又是AGPL。

我第一份工作就是NVR,負責Linux平台和整合,對NVR有設計的遺憾。
我原本以為自從中國成為監控大國之後,監控產業大概都趴了,在上幾份工作時寫停車場系統才發現,NVR對於公司竟然還是香噴噴的,因此,AI開發計畫中,就有NVR在裡面。

NVR完成後不會是這個Side Project的結束,後面會延續進一步推進Analysis Service以及GIS Service,最終目標是做出Dashboard,能像之前美國國防部記者會時的操作界面,有個地圖(戰場/非戰場)會有圖釘標示哪裡有攻擊(事件),滑鼠移動過去後點擊,會出現當時的影片片段。

當然,無人機這麼熱,不湊熱度說不過去,對吧。

設計規劃:

這次實做花很多時間的原因是,設計的架構比預期大和複雜。

後端系統以微服務設計,分為4部份:

  • Streammer: 接Camera串流、分發串流
  • Recorder: 錄影寫檔案
  • Manager: CRUD服務,REST API和資料管理
  • Gateway: 前端應用程式的對接口,後端接Streammer、Recorder、Manager

微服務的底層設計邏輯是,各自處理各自的事務,所有事務獨立,體現在幾個點:
調Record、查Record Status、Disk Status,都由Recorder處理
Camera介接、串流,都由Streammer處理
DB設定更新、CRUD API,都由Manager處理
和Client對接,Client的Protocol轉換,StreamBus -> WebSocket、gRPC <-> WebSocket、Manager反向代理,都由Gateway處理

主要設計邏輯和核心協定:

微服務(Streammer、Recorder、Manager、Gateway)間透過3個主要協定通訊:

  • gRPC: REST API與WebSocket類的API,Playback的串流都透過gRPC傳輸
  • 自定義的StreamBus Protocol: RTSP串流的訂閱轉發通訊協定
  • MQTT Protocol (EventBus): Event的訂閱轉發協定使用MQTT為基底

各個微服務設計特點:

Streammer:

Streammer主要功能是轉發,包括串流和Event(事件),串流轉發使用StreamBus,Event轉發使用EventBus。
Streammer串流轉發的設計受到Publish/Subscribe設計和mediamtx影響,當然還有AI的建議,Streammer內部使用c#的Channels實做,但額外設計3種對外接口,分別是Named Pipeline、TCP、UDP,Streammer內的串流擴展可直接在內部透過StreamBus實做模塊擴展,Streammer外可以透過TCP、UDP、Named Pipeline串接,Gateway與Recorder就是用外部串接方式和Streammer對接。
Streammer Event轉發使用MQTT為基底,設計上,本身是MQTT Server,也可以用外部MQTT Server,Event則透過MQTT推送到MQTT Server上。
Streammer有gRPC Service服務,主要用於傳入CMD,例如:ReloadCamera,gRPC有Event Trigger API,但Event Trigger透過MQTT注入更方便,兩種都有設計,主要透過MQTT。

Recorder:

Recorder主要功能是錄影寫檔案。
但因為以前整合時吃了太多磁碟IO的虧,Recorder核心設計包括IndexCache、RecCache以及IOWorker。
Recorder包括3個Cache,Playback用的錄影檔案Cache,Index讀寫的LRU Cache,預錄影的RingBuffer Cache。
Recorder在Cache下層寫入磁碟時,會透過IOWorker Pool,IOWorker能在appsettings.json內設定同時的Read IOWorker數量、Write IOWorker數量,所有IO都透過IOWorker Pool動作。
Recorder設定時指定多個實體路徑寫入,透過Consistent Hashing(一致性哈希)平均分散資料到實體路徑內。
保留軟體RAID(Erasure Code)實做設計。

Manager:

Manager提供CRUD,Camera的增/刪/查/找,使用者登入認證都在這裡。前端應用程式的API,主要都是對Manager。有個比較特殊的,ONVIF Discovery是在Manager觸發和搜尋。
目前設定都透過DB儲存,原則上至少支援SQLite和PostgreSQL,Microsoft SQL Server有支援,但問題在於,c# SQL Server的SQLClient目前不完全支援AoT。

Gateway:

Gateway顧名思義,是入口。Client端連入會是透過Gateway,Web版的網站程式也會放在Gateway。
Gateway對Client就2個協定,WebSocket和REST API,REST API主要是反向代理到Manager,其他都透過WebSocket,像是Streammer的StreamBus,StreamBus -> WebSocket,Recorder的gRPC API,WebSocket <-> Recorder gRPC API。

認證有2組:

使用者的認證以及微服務間的認證。
使用者認證就是透過Manager的Auth API進行認證後拿到JWT,然後後續不論是WebSocket或是其他REST API都透過這組JWT。
微服務間的認證,在每個服務的appsettings.json內會有個Internal API Key,要填入相同的密碼,服務間的gRPC會用Internal API Key加密Timestamp後送出,另一端會用Internal API Key解密,並判斷Timestamp是否在一段時間內(是的,每個服務所在的電腦,要對時,我記得會查30秒內吧)。

License設計:

License會以線上登錄序號的方式,登錄註冊後提供license.lic檔案,放入系統中作用。
目前這段細節我還沒想清楚,目前考慮鎖在Streammer就好,但考慮到叢集多電腦微服務運作,我還沒完全想清楚授權怎麼處理。
License預設會有2種,一種是已經完成的license.lic,另一種是USB License Key的形式,不論哪種,核心加密都使用AES + ECDSA簽章。

使用者和群組設計:

DB中,包括幾個跟User有關的Table,包括users, groups, permissions這3個主要的Table以及用於Mapping group和permission的group_permissions Mapping Table。
權限可以概略分2類,1類是NVR操作的使用者權限,一類是MQTT的服務權限。
包括NVR類的:nvr_admin, nvr_power_user, nvr_user, nvr_viewer
以及MQTT類的:mqtt_admin, mqtt_rw, mqtt_ro

權限會對應到group,因此Group包括:
admins, power_users, users, operators, mqtt_services, mqtt_clients

每個使用者都屬於特定1個群組,但群組可以包括多種權限。
直接的體現是,admin這個使用者是admins群組,admins群組的帳號可以同時登入MQTT Server和NVR Client,同樣的道理,
mqtt_services群組的成員,只能登入MQTT Server,NVR Client是不能登入的。

Client設計:

Client應用程式預計為跨平台,會先提供Linux版和網頁版,使用UNO Platform開發。

AI規劃:

設計階段就在想,既然是全新開發NVR,那有沒有什麼新的想法能夠引入?
尤其是AI,既然AI這麼熱門,到底使用者對於AI的想像是什麼? 如何引入?
在和AI討論後,目前想定的設計分2塊,NVR階段的以及Dashboard(中控)階段的。
我對AI之於應用程式的想像是這樣,我要如何如何時,直接跟AI說或對話,AI直接幫我處理,以及AI能夠跟我說發生了什麼事情。
也就是說,延續監控產業的一脈路線,什麼是監控產業的一脈路線?
從最傳統的能錄影 -> 能根據時間調出錄像 -> 有Event -> 能智能的根據Event主動通知

那麼,當進入AI時代後,我對這一脈路線的想定是,Event的通知對象不再是人,而是AI,由AI主動分析Event,並提供給人狀況、建議行為。

因此,我把AI規劃分為低階跟高階,高階放在Dashboard(中控),低階下放在NVR內。
NVR內放的AI,能夠根據文字窗口給與指示,
例如:
給我看第三支Camera目前畫面。
播放第2支Camera昨天下午3:00的錄像。
幫我看看,這兩天有哪些Camera斷線過?

而高階的,則能夠根據Event進行細部推斷,
例如:
目前分析系統偵測到大廳有多人聚集,或者大廳人數眾多。

而兩者差異體現在2塊,1個是AI的智能程度,NVR原則上用的就指令遵循型,能夠提供Live、Playback的自動化操作,而Dashboard(中控)的,就可能需串接雲端,提供目前過往的Event資訊,或者觸發Event時打到雲端AI,讓雲端AI能有完整的Event進行判斷。

我們更白話的說,AI的判斷能力,取決於我們給哪些Event + AI的智能程度,低階的做單純的UI操作,不具備分析,高階的能獲得更多Event訊息,並能深入分析。

目前NVR階段,已能在UNO Platform上面透過按鈕觸發特定連續頁面操作。

Client實做進展:

目前已實做和串接部份,錄影進度條已經能正常顯示,Event能正常顯示,Device清單能正常顯示,錄影狀態串接中。
Device Search功能正常,但UI還需優化,Schedule UI和設定正常。
PTZ能夠功能正常,UI還需優化。
影像部份,Linux版本Live有畫面,但穩定性還有問題。

Client截圖:








2026年5月3日

Dell Wyse 3040 - Debian 13 Read-Only Rootfs設定

 前言:

買了一台二手雷射事務機,因為不帶網路,打算找個小機器當列印伺服器。 列印問題其實不大,但事務機的麻煩是掃描,掃描通常驅動程式要原廠提供,
而事務機基本上只提供x86/x64的驅動程式,不太會有ARM的版本。 很久前我為了這事情我弄了個Intel-Galileo,結果從來沒成功用上那台就壞了, 現在連維修料件都沒庫存了。 不過時代不同了,現在有ThinPC可以買,又有淘寶可以淘,價格今非昔比, 小主機的硬體效能和相容性也和Intel-Galileo不能比,因此找了Dell Wyse 3040。 (Intel-Galileo是Intel Pentium魔改,x86 32-bits,Debian 13不再提供x86 32-bits支援了)

硬體簡介:

Dell Wyse 3040 CPU是Intel Cherry Trail x5 Z-8350,
Intel Cherry Trail x5 Z-8350是手機用的CPU,因此具有一些特色:
  1. 電源是5V
  2. 內嵌Ethernet是Realtek r8168
  3. 界面是SD
    1. 儲存是eMMC
    2. WiFi是特規SDIO WiFi
不過它有標準的USB2.0和USB3.0,可以接USB WiFi。

緣由:

這台的eMMC很慢,存取跟樹莓派差不多速度,這台又是用在列印伺服器,希望斷電可靠度好些。
因此在Debian 13上面設定Read-Only Rootfs,也就是OverlayFS

設定:

按照一般方式安裝和設定Debian 13,接著
# apt install overlayroot






修改 /etc/overlayroot.conf
最後面加上
overlayroot="tmpfs"



PS: 如果希望只有rootfs是read-only,參數用:
overlayroot="tmpfs:recurse=0"

接著修改
/usr/lib/systemd/system/systemd-remount-fs.service

加上如下:
[Service]
Environment=LIBMOUNT_FORCE_MOUNT2=always








再來重新開機就可以了。



2026年4月19日

AI超人之ONVIF Client Lab

前言:

最近興趣在寫這東西,想說這不是老黃曆了嗎,但沒關係,就自己用AI尻尻看。
目前進度約4~5成,還早,但這幾個有趣的過程可以貼。
ONVIF Client完全免費並開發友善的其實就SharpOnvif,最難得的是,作者目前非常熱血,更新頻率很高,支援的ONVIF Profile也非常完整,License是MIT,相當佛。

緣由:

我希望有個AOT-safe、License Free的ONVIF Client,C/C++或c#都可以,結果發現非常難找,C/C++幾乎沒有,原因是ONVIF官方網站與SOAP幾乎都推薦gSOAP,這是正確的,但gSOAP是雙授權,明言GPLv2/Commercial,產生的程式碼也是,要嘛付費給它解鎖,否則就是GPL,這種寫明授權的做法,就是開源商業化。
c#反而友善,Microsoft的svcutil沒有授權問題,但這個有年代了,使用的是依靠反射的WCF和XmlSerializer,設計聰明,但如果AOT-safe會更好。
於是,在繼mediasdk_h264/h265_parser之後,我讓Claude-Code嘗試看看。

成果:

過程:

我讓Claude-Code(GLM-5.1)分析SharpOnvif,然後實際用svcutil產生Reference.cs讓它分析和修改,發現這條路不太對。
接著我讓它用gSOAP Binary透過WDSL產生C/C++程式碼,然後發現,它產生的程式碼全都是GPL,並且官方網站寫明了授權方式。
我詢問WDSL到底是什麼?它跟我說了個xsd.exe工具(咦?)。
然後我想想,AI你為何要改生成的東西,能否自己用xsd工具產生Model,我們自己寫API?
然後我找到xsd.exe和xscgen,讓它分析xsd.exe和xscgen,讓它xscgen執行看看,試看看能不能用WSDL產生出Model,這些Model能不能用?
Claude-Code(GLM-5.1)在嘗試後非常篤定的跟我說,沒問題,Client加上去就可以了,而Client它會寫(儘管我還是讓它參考了SharpOnvif)。
然後它就寫好了。😲

雜談:

上面的過程像是念經😂,其實描述了我最近發現AI的互動方式有些變化(或者說新的用法?),AI分析程式碼的能力和速度遠比人類快得多,這可能是因為AST加上Model更強了的雙重因素,但目前的高階推理模型已經可以根據你給它的需求分析整個程式碼,並且給出它和你需要的部份,並且判斷和抽取出程式碼內容,這已經不是半年前給它一個專案,它給出專案概述和描述分析這麼簡單,而是它已經有能力判斷出這份東西裡面有沒有完成任務需要的內容,而且能夠篤定的跟我說有/沒有,可以/不可以,可行/不可行。
要知道一點,上面列出的,每一個都是一份完整專案和程式碼,資深工程師如果領域內的,要拆解可能也要一些時間,領域外的可能找入口就要2~3天,但AI已經能夠根據你給的需求,分析這個專案程式碼是否有可以用的程式,或者直接執行並分析執行結果,搭配程式碼分析,給出如何做?能否用?😲

AI超人之影像編/解碼器 (H264Parser, H265Parser)

 前言:

最近在寫H264和H265的硬體編碼解碼器程式。
發現在Linux選項不多,只有FFMpeg的libav、GStreamer,但我想找授權乾淨的(無GPL、Library GPL),並且支援VA-API的,於是就試著讓AI寫看看。

成果:


過程:

我要求Claude-Code(GLM-5.1)參考OneVPL(MediaSDK),並要求它直接抄OneVPL(MediaSDK),跟它說,它的授權是MIT,不用擔心,但你盡量不要自己實做,以它寫的為準,做法是,複製它的程式碼後,修剪。
最終完成品,就是成果的程式碼。

我在使用時,還有發現bug,所以我無法保證沒有bug,目前H265解碼時會間歇性出現灰畫面,但我在交叉使用ffplay時有些來源也會這樣,我還無法準確判斷是影像來源問題,還是它實做的有bug,但以完成度、穩定度來說,基本上沒問題。

雜談:

先前看到新聞說Claude Opus能夠參考並實做出程式語言編譯器,GLM-5.1雖然能力差一點,但基本能夠超越Opus的上一代,弱於這一代。
這次讓它直接參考並抄寫、改寫、修改OneVPL(MediaSDK),並且成功重構出mediasdk_h264_parser和mediasdk_h265_parser,以程式碼分析與修改能力而言,我認為能力已經超越我了,因為我自己看和分析,是無法做到的,要知道,OneVPL可以一路追朔到Intel IPP,裡面程式碼龐大且經過多年迭代 + 重構,加上是根據H264, H265 Spec. 實做的,基本上有特殊的Domain專業以及複雜的程式脈絡,但Claude-Code已經能夠分析、拆解,並根據功能抽取和改出需要的程式碼,再組出Library,非常強大。😲