張緒紅,黃 睿
(1. 廣東技術師范大學 自動化學院, 廣州 510665; 2. 廣東第二師范學院 計算機科學系, 廣州 510303)
隨著科技的發展,人工智能與物聯網技術已廣泛應用于各個領域,人臉識別、車聯網等技術趨于成熟,對視頻采集、監控的技術要求越來越高。然而,這些實時應用場景往往由于網絡傳輸的時延而影響云端的計算效率。在此背景下,邊緣計算的架構得到了越來越多的關注。邊緣計算將計算部署在離終端更近的邊緣平臺,可以避免集中式云計算中心的網絡延遲,提供更具實時性和短周期的計算,更好地滿足物聯網推動下爆發式的計算需求。本文特別針對大數據量的視頻采集、視頻監控等實時傳輸場景,研究高效穩定的嵌入式視頻傳輸方案,實現邊緣平臺的實時視頻數據采集操作。
具體而言,影響邊緣平臺服務器性能的有處理器、硬盤、內存等硬件因素和服務器架構、網絡傳輸協議等軟件因素,而服務器架構是主要的軟件影響因素。目前基于Linux內核的模型架構一般有傳統I/O模型、SELECT模型、POLL模型和EPOLL模型等[1-4]。傳統I/O模型包括阻塞I/O和非阻塞I/O,該模型主要用于短連接和即時信息交互等場景。SELECT模型通過一組有限的文件描述符集合和時間值(Timeval)結構來等待并處理I/O事件,并通過遍歷監聽池來判斷事件源,從而完成事件下行操作[5]。POLL模型是在SELECT模型的基礎上,對最大監聽數和響應方法進行優化,事件上報后不需要進行遍歷操作,直接調用事件注冊時綁定的處理函數。
本文設計的傳輸方案首先在嵌入式終端實現攝像頭驅動,進行圖像采集,然后進行Socket網絡服務器搭建,建立圖像傳輸協議,最后對客戶端接收到的圖像進行實時顯示。在數據量小且連接數單一的情況下,上述各模型均能滿足需求。隨著連接數和圖像數據量的增大,服務器系統調度頻繁,前兩類模型效率較低,將難以滿足工程所需。POLL模型處理相對較好,但資源占用帶寬高,所以,需要在POLL模型的基礎上進行模型優化,以提高系統性能的效果。
基于Linux內核的嵌入式產品中,通常會掛載多種外部設備,為確保各個設備的穩定運行,系統需要實時監測各設備的運行狀態。傳統的阻塞I/O主要采用忙等的方式來獲取事件的狀態,實現簡單但占用系統資源多。而SELECT在事件發生后不能直接判斷上報的事件是由哪一個文件產生,需要耗費時間和資源對監聽池的所有事件進行遍歷來判斷事件源。EPOLL模型是在POLL模型基礎上進行優化,使監控的文件數量為無窮大,且事件發生后就直接調用該事件綁定的回調函數,從而直接進行下行操作。
為了使設計的視頻監控系統更高效地運行,本文基于EPOLL架構,分別建立圖像采集、圖像傳輸、視頻通訊、播放顯示等4個子系統,各個子系統之間相互通信,從而達到實時視頻監控的效果,并最終基于Intel、ARM平臺下完成圖像傳輸。
EPOLL機制是基于傳統的SELECT、POLL機制產生的,并在Linux2.6內核以后的版本進行了實現。EPOLL支持對管道、先進先出(FIFO)、套接字、可移植操作系統(POSIX)消息隊列、終端、設備等監聽處理,其主要優點如下:
(1) 進程進行文件監控的數量沒有上限。該機制所支持的最大文件描述符上限,主要依賴于運行設備的內存容量,呈正相關,遠大于SELECT的1 024條。
(2) 事件響應快速。當事件發生時,不需要再重新遍歷監聽池里所有注冊的事件,而是直接找到上報事件的回調函數,及時進行事件處理。
(3) 快速訪問內核空間。通過內存映射(mmap)機制將內核空間映射到用戶空間,應用程序直接對內存進行讀寫操作,可以及時對設備進行數據交互。
傳統EPOLL模型使用比較簡單,主要分為3個步驟:創建EPOLL監聽池、添加要監聽的事件、等待事件上報。EPOLL模型如圖1所示,實現步驟如下:
步驟1創建EPOLL監聽池。epoll_create()函數用于創建EPOLL監聽池,該函數創建的監聽數量不限,返回值是一個文件描述符。
步驟2添加要監聽的事件。epoll_ctl()函數可以對監聽文件屬性進行設置。部分參數說明如下[6]:
EPOLL_CTL_ADD,注冊新事件到監聽池中。
EPOLL_CTL_MOD,修改已注冊的監聽事件。
EPOLL_CTL_DEL,從監聽池中刪除事件。
EPOLLLT,水平觸發模式。當監聽池事件處于就緒態時,EPOLL將一直上報該事件。
EPOLLET,邊緣觸發模式,包括上升沿觸發和下降沿觸發。
步驟3等待事件上報。epoll_wait()函數用于等待事件上報,當發生事件上報時,EPOLL機制會調用注冊事件時的處理函數。

圖1 EPOLL模型
傳統EPOLL模型是通過epoll_ctl()函數對事件進行注冊,該函數主要依賴struct epoll_event結構體進行事件描述,該結構體內容如圖2所示。

圖2 Epoll_event結構體關系圖
從圖可以得知,epoll_event結構體成員data是一個union聯合體。雖然使用*ptr可以指向用戶定義的處理函數(*為指針結構),fd可以保存事件的文件描述符,但是union聯合體只能選擇一種成員方式進行使用,因此,需要對EPOLL模型進行優化,如圖3所示。
首先,實現自定義結構體struct event_ext,包含事件描述符fd;事件狀態epolled;事件類型events;事件上報時對應的處理函數*handler;附加參數*arg。
其次,通過union聯合體成員*pt指向自定義結構體struct event_ext,完成EPOLL監聽池事件注冊。當發生事件上報時,可以根據*pt指向的自定義結構體,找到對應的處理函數,從而實現事件下行操作。

圖3 Epoll_event結構體優化
本文基于EPOLL機制分別建立圖像采集、圖像傳輸、視頻通信、顯示等子系統,該系統功能結構圖如圖4所示。

圖4 系統功能結構圖
圖像采集子系統主要功能是對圖像進行采集,包括初始化攝像頭、設置圖像采集格式、圖像的保存等功能。
圖像傳輸子系統用于建立圖像傳輸協議,使服務端和客戶端按照既定的協議完成通信,確保圖像數據傳輸完整。
視頻通信子系統用于建立客戶端與服務器的網絡連接,對接收到的數據進行解析,提供圖像數據接口給顯示子系統。
顯示子系統用于實時顯示攝像頭采集到的圖像,同時也顯示圖像幀格式、圖像尺寸、傳輸速率等基本內容。
視頻監控是嵌入式Linux的一個重要應用場合,合理高效的進行圖像采集是廣大學者研究的重點[7]。目前基于Linux操作系統下,比較流行的攝像頭軟件架構是V4L2(video for linux 2)架構,該架構通過一系列的回調函數來使應用程序具有發現設備和操作設備的功能,譬如設置攝像頭的頻率、視頻壓縮格式等圖像基本參數,其軟件架構如圖5所示。

圖5 V4L2軟件架構
圖5詳細界紹了基于V4L2攝像頭軟件架構,該架構下圖像采集步驟如下:
步驟1初始化攝像頭。
步驟2獲取驅動信息;通過文件接口的調用,使用VIDIOC_QUERYCAP參數可以查看驅動信息。
步驟3設置圖像格式;v4l2_format結構體用于設置攝像頭的視頻捕捉格式和幀格式等信息。
步驟4申請圖像緩沖區;v4l2_requestbuffers結構體用于設置緩沖區數據格式和映射關系。
步驟5將內核空間中的圖像緩沖區映射到用戶空間;結構體v4l2_buffer設置緩沖區的存儲類型,使用mmap建立映射關系。
步驟6圖像緩沖入隊列;映射好的緩沖區通過使用VIDIOC_QBUF參數,進行緩沖入隊列操作。
步驟7注冊事件到EPOLL。當采集事件發生后,EPOLL會自動調用事件處理函數,從而完成采集事件的下行操作。
通過圖像采集子系統完成攝像頭的采集,下一步就需要將圖像進行傳輸。傳輸層采用面向連接的TCP協議,注冊事件到EPOLL后,收到客戶端的網絡包請求時會作出相應的事件處理。Socket編程主要進行以下幾步: 創建套接字; 初始化要綁定的地址,并使用bind進行綁定; 進行端口監聽; 等待連接; 數據交互。
建立網絡連接后,需要定義服務端與客戶端的通信協議,傳輸的基本內容包含幀的格式和圖像內容。一條完整的通訊協議分別由協議頭、協議長度和數據內容3部分組成,如圖6所示。

圖6 網絡傳輸協議
圖6表明,協議頭由3個字節組成,分別包含請求ID(8bit)、數據類型type(3bit)、數據格式subs(5bit)和數據長度len(8bit)。協議幀長度由4個字節組成。剩下為圖像數據。協議數據頭定義見表1。

表1 協議頭定義
當監聽到客戶端的請求幀時,首先,事件處理函數對該請求幀協議頭進行解析,從而獲取請求幀ID,然后將需要返回的內容按照傳輸協議進行封裝,最后發送給客戶端完成了視頻的傳輸。
通過上述步驟完成了采集子系統和傳輸子系統,為了讓客戶端與服務器進行穩定的數據傳輸,需要設計面向連接的通信子系統,該系統工作流程設計如下。
(1) 初始化網絡協議,采用面向連接的TCP協議。
(2) 創建工作線程,主要用于圖像請求及數據解析。
(3) 圖像獲取,根據傳輸子系統的通信協議,對服務器返回一幀的數據進行解析,從而獲取一幀的圖像數據。
(4) 創建顯示接口,該接口用于將解析的一幀圖像數據,傳遞給圖像顯示子系統。
該系統通過線程來發送構造的圖像請求,并對接收到的數據幀進行解析,將解析出來的圖像提交給圖像顯示子系統。
嵌入式Linux支持多種圖形界面(GUI),常用的有Qt[8]、GTK+[9]、miniGUI等[10-11]。Qt是面向對象的跨平臺C++圖形開發框架,模塊化程度高。GTK+是嵌入式Linux下主流的圖形界面開發工具,支持LGPL開發協議,主要采用C語言進行編程。miniGUI是面向嵌入式系統圖形界面開發工具,1.6.10版本后重定義為商用嵌入式GUI系統[12-13]。
顯示子系統主要完成的是圖像顯示功能,相比上述3種程序框架,GTK+開發相對簡單,可以顯著節省開發時間,讓編程人員可以將更多精力集中在項目的核心部分上,故顯示子系統采用GTK+框架進行開發。顯示子系統主要包括以下兩個窗體:
(1) 網絡連接窗體。通過獲取用戶輸入的IP地址和端口號來進行TCP連接,如連接成功,則跳轉到圖像顯示窗體界面[14]。窗體設計如下:
① 創建垂直布局容器,用于定義窗體的整體布局方式,存放后續所有的控件。
② 創建水平布局容器,并繪制登錄圖片。
③ 創建水平布局容器,分別繪制服務器IP地址和端口標簽,以及對應的編輯框。
④ 創建水平布局容器,創建“確定”“取消”按鈕,并分別聯按鈕點擊事件connect_handler和gtk_main_quit。該窗體最終效果如圖7所示。

圖7 網絡連接窗體
(2) 圖像顯示窗體。跳轉到圖像顯示窗體后,通過調用通信子系統來獲取圖像接口,并將圖像、幀格式、尺寸、速率等信息進行實時顯示。窗體設計流程如下:
① 判斷是否連接上服務器,如連接上則獲取服務器IP地址和端口地址,否則報錯。
② 創建圖像顯示區域和功能顯示區域,功能顯示區主要包含圖像幀格式、圖像尺寸、傳輸速率等信息[15]。
③ 將解析的圖像在圖像顯示區域進行實時顯示,并在功能區顯示相應的信息。
基于EPOLL機制進行視頻監控系統的設計和實現,實驗采用2臺Intel-i5和2臺分別ARM9、ARM11架構的設備。首先分析阻塞I/O、SELECT、POLL、EPOLL等架構處理能力,其次分別在Intel、ARM平臺下實現視頻監控系統,最后對基于EPOLL機制視頻監控系統進行分析。
多線程、多進程雖然可以改進模型的處理效率,但是并沒有對網絡編程模型進行實質性改善。故服務端實驗環境采用單線程處理模式,分別在阻塞I/O、SELECT、POLL、EPOLL等架構下進行單Byte傳輸,客戶端成功完成讀寫操作的連接請求數如圖8所示。

圖8 網絡連接窗體
4種模型函數調用所占用時間見表2。

表2 I/O、SELECT、POLL、EPOLL函數占時比 %
由圖8可見,模型處理能力由高到低的排序是阻塞I/O、EPOLL、POLL、SELECT。由于實驗采用一次性交互的短連接,該場景是捕獲一個請求后即刻進行讀寫操作,傳統的阻塞I/O效率最高,EPOLL模型效率要優于POLL模型和SELECT模型。
主函數進行Socket網絡編程,結合表2數據,SELECT模型在主函數占用時間更多,是因為每次進行SELCET都需要對監聽池里的事件進行遍歷,這也導致相比其他模型,SELECT模型連接性能最差。
視頻監控系統基于高并發處理服務器,阻塞I/O模型、SELECT只能通過引入多線程提高傳輸效率,而不能達到高并發的狀態。故只考慮POLL和EPOLL模型面對長連接時的性能比較。對服務器連接數分別為3 000和20 000時,POLL和EPOLL模型性能見表3。

表3 POLL、EPOLL函數占時比 %
通過表3 POLL和EPOLL模型對比可看出,當最大連接數為3 000時,POLL模型的傳輸效率高于EPOLL模型。隨著連接數的增加,最大連接數達到20 000時,EPOLL模型主函數所耗時間低于POLL模型,說明傳輸效率高于POLL模型。EPOLL模型函數調用率基本保存不變,而POLL模型主函數調用率由12.11%上升至64.65%,讀寫操作分別由36.93%、48.15%降低至3.73%、4.87%,說明EPOLL傳輸穩定性更強。由于視頻監控系統的傳輸數據大,且面向多用戶連接的網絡通信,所以EPOLL架構來實現視頻監控系統是合理的,相對于其他模型,該模型傳輸效率更高,穩定性更好。
本文客戶端使用Intel-i5處理器,采用通信子系統和顯示子系統設計方法進行搭建。服務端分別使用Intel-i5、ARM9、ARM11設備,采用圖像采集子系統和傳輸子系統設計方法進行搭建。通信效果如圖9所示。

圖9 EPOLL架構視頻監控系統
本文針對大數據量的視頻采集傳輸研究高效的實時傳輸方案。通過對傳統EPOLL模型進行優化,實現在Intel、ARM架構下的攝像頭數據采集,并通過網絡進行圖像的顯示。
實驗表明,采用單線程網絡服務器進行單Byte數據交互時,阻塞I/O對單線程短連接傳輸效率高。采用大數據長連接交互時,EPOLL模型函數調用率基本保持不變,POLL模型主函數調用率上升52.54%,讀寫操作分別降低33.2%、43.28%。說明EPOLL模型架構傳輸效率優于POLL模型,該機制制作視頻監控系統的傳輸效率更高,穩定性更好,適用性強。
本文提出的基于EPOLL機制應用通過實驗數據得出,EPOLL模型傳輸效率相比POLL、SELECT和阻塞I/O傳輸效率都要好,傳輸質量高,可應用于實時視頻采集、視頻監控等場景。