劉立才,康維新,王海生,繆 晶,張 強(qiáng),李 鵬,吳學(xué)文
(1.哈爾濱工程大學(xué)信息與通信工程學(xué)院,黑龍江 哈爾濱 150001;2.華北電力大學(xué)控制與計(jì)算機(jī)工程學(xué)院,北京 102206;3.黑龍江省哈雙高速公路管理處,黑龍江 哈爾濱 150090)
責(zé)任編輯:任健男
隨著Linux在中國(guó)的普及,必須保證能夠用Linux實(shí)現(xiàn)其他操作系統(tǒng)(如Windows系列操作系統(tǒng))下的功能,如文字處理、電子表格、上網(wǎng)等,也就是說,必須有大量圖形用戶接口(GUI)應(yīng)用程序滿足用戶各方面的需求[1]。而基于Linux下的C/C++語言的GUI編程有多種方案,較為流行的有基于QT庫和基于GTK+/GNOME兩種。KDE(K Desktop Environment)曾經(jīng)是Linux下最流行的用QT庫開發(fā)的桌面環(huán)境,但是,KDE依賴于Troll Technologles公司所開發(fā)的QT庫[2],該庫許可證的獲得非常困難。所以,應(yīng)該避免使用 QT 庫及 KDE[3-5]。
基于上述原因,本項(xiàng)目采用GTK+/GNOME函數(shù)庫研究客戶端用戶界面設(shè)計(jì)。該庫僅需XLIB、GLIB(圖形底層函數(shù)庫)和GDK庫的支持,且這些庫操作簡(jiǎn)便,同時(shí)GTK具有移植性好、可定制、占用空間小、運(yùn)行穩(wěn)定等優(yōu)點(diǎn),加之它模塊化設(shè)計(jì)和全C編寫的特性,使得GTK不但應(yīng)用在專用嵌入式系統(tǒng)上,也可以在通用PC機(jī)上使用,出于這種考慮,采用GTK開發(fā)GUI應(yīng)用程序比較合適[6]。
由客戶端軟件構(gòu)成的系統(tǒng)整體架構(gòu)如圖1所示。該系統(tǒng)大致由通信協(xié)議端程序、服務(wù)器端程序和客戶端程序三部分組成。由于篇幅所限,這里重點(diǎn)研究客戶端程序的設(shè)計(jì),具體包括基于GNOME桌面環(huán)境下GTK圖形用戶界面的設(shè)計(jì)以及視頻采集客戶端程序的設(shè)計(jì)過程。而對(duì)于通信協(xié)議端程序和服務(wù)器端程序的設(shè)計(jì),這里只簡(jiǎn)單介紹它們?cè)谡麄€(gè)系統(tǒng)中所實(shí)現(xiàn)的功能。其中通信協(xié)議端程序所實(shí)現(xiàn)的功能有:通過該協(xié)議能夠?qū)⒎?wù)器采集的視頻數(shù)據(jù)傳輸?shù)娇蛻舳?能夠?qū)z像頭圖像屬性,如對(duì)比度、分辨力等信息傳遞給客戶端;通過該協(xié)議客戶端能夠控制服務(wù)器端攝像頭改變采集的圖像屬性;在客戶端程序退出時(shí)能夠通知服務(wù)器一般進(jìn)行后續(xù)處理。
圖1 系統(tǒng)總體架構(gòu)
服務(wù)器端程序?qū)崿F(xiàn)的功能有:實(shí)現(xiàn)基于多線程的循環(huán)服務(wù)器;傳輸層基于TCP/IP協(xié)議進(jìn)行通信;通過V4L2接口獲取攝像頭采集數(shù)據(jù);通過V4L2接口設(shè)置攝像頭圖像屬性,如對(duì)比度、分辨力等;應(yīng)用層通過自定義通信協(xié)議與客戶端進(jìn)行通信;根據(jù)命令行參數(shù)初始化攝像頭。
客戶端程序?qū)崿F(xiàn)的功能有:傳輸層基于TCP/IP協(xié)議進(jìn)行通信;應(yīng)用層通過自定義通信協(xié)議與服務(wù)器進(jìn)行通信;用戶界面基于GNOME桌面環(huán)境,并利用GTK進(jìn)行開發(fā)。
主函數(shù)程序設(shè)計(jì)流程如圖2所示,程序開始運(yùn)行時(shí)先進(jìn)行必要的初始化操作,先通過判斷函數(shù)g_thread_supported()的值,如果該函數(shù)的返回值為true,則說明線程已經(jīng)初始化,否則要調(diào)用g_thread_init()函數(shù)進(jìn)行線程初始化,接著要依次對(duì)GDK庫和GTK庫進(jìn)行初始化操作。然后創(chuàng)建并啟動(dòng)攝像頭運(yùn)行線程來完成客戶端視頻采集的功能。如果這時(shí)在連接界面中能夠通過Connect按鈕成功連接至服務(wù)器端,則立即通過調(diào)用函數(shù)create_main_app()進(jìn)入視頻監(jiān)控界面并進(jìn)行實(shí)時(shí)視頻圖像的顯示。在視頻監(jiān)控界面下,程序會(huì)停留在gtk_main()處,直到用戶驅(qū)動(dòng)某事件后被主循環(huán)捕獲到,要根據(jù)事件攜帶的窗口ID信息決定接收的構(gòu)件,然后將信息格式化后以信號(hào)的形式傳給構(gòu)件,最后構(gòu)件調(diào)用關(guān)聯(lián)的回調(diào)函數(shù)進(jìn)行處理操作。有關(guān)連接界面和視頻監(jiān)控界面的軟件設(shè)計(jì)將在下面詳細(xì)研究。
圖2 主程序的軟件流程
根據(jù)功能需求,客戶端所設(shè)計(jì)的連接界面在頂層窗口下建立的構(gòu)件區(qū)主要由圖片區(qū)、輸入?yún)^(qū)、按鈕區(qū)和狀態(tài)區(qū)構(gòu)成。圖片區(qū)插入圖片構(gòu)件的目的是使整個(gè)界面更加美觀、更具個(gè)性化,這里采用哈爾濱工程大學(xué)標(biāo)志性建筑作為應(yīng)用圖片。對(duì)于界面輸入?yún)^(qū)主要由標(biāo)簽和輸入條構(gòu)成,它主要完成人機(jī)交互的功能。即用戶可以在輸入條中輸入要連接服務(wù)器端的IP地址和端口號(hào)。按鈕區(qū)由Connect和Quit兩個(gè)按鈕構(gòu)成,主要負(fù)責(zé)建立C/S之間的連接以及退出連接界面的操作。而當(dāng)鼠標(biāo)在上述三個(gè)區(qū)域動(dòng)作時(shí),就會(huì)在狀態(tài)區(qū)顯示相應(yīng)操作的狀態(tài)信息。客戶端連接界面的軟件設(shè)計(jì)是在主程序中通過調(diào)用connect_app()函數(shù)來實(shí)現(xiàn),此函數(shù)具體的軟件實(shí)現(xiàn)如圖3所示。可見,函數(shù)init_conn_if()的調(diào)用是用來完成圖片區(qū)、輸入?yún)^(qū)、按鈕區(qū)和狀態(tài)區(qū)的創(chuàng)建過程,具體軟件流程如圖4所示。界面軟件設(shè)計(jì)中各個(gè)區(qū)域的界線由新建的分割線構(gòu)件構(gòu)成,且在圖4中每個(gè)調(diào)用函數(shù)中都要完成相應(yīng)區(qū)域中各個(gè)構(gòu)件的生成、構(gòu)件屬性的設(shè)置、構(gòu)件擺放位置的設(shè)定以及當(dāng)用戶驅(qū)動(dòng)某事件產(chǎn)生相應(yīng)信號(hào)傳遞給某構(gòu)件后,構(gòu)件處理事件所需關(guān)聯(lián)回調(diào)函數(shù)的編寫等任務(wù)。圖5為運(yùn)行客戶端軟件時(shí)所生成的連接界面,可見,達(dá)到了所要設(shè)計(jì)的預(yù)期。
由于用戶實(shí)際應(yīng)用的需求,客戶端所要設(shè)計(jì)的視頻監(jiān)控界面大致分為視頻區(qū)、狀態(tài)區(qū)、設(shè)置區(qū)和按鈕區(qū)四部分。視頻區(qū)主要負(fù)責(zé)實(shí)時(shí)視頻的監(jiān)控,同時(shí)還可以根據(jù)監(jiān)控圖像的畫質(zhì)情況,在設(shè)置區(qū)設(shè)置服務(wù)端攝像頭的圖像屬性,如圖像的亮度、對(duì)比度、分辨力、銳利度、灰度系數(shù)等參數(shù)。設(shè)置后可通過點(diǎn)擊按鈕區(qū)中的設(shè)置按鈕實(shí)時(shí)對(duì)服務(wù)端攝像頭采集的視頻幀進(jìn)行設(shè)置與控制,同時(shí)服務(wù)端又會(huì)將設(shè)置攝像頭后的圖像屬性通過自定義通信協(xié)議實(shí)時(shí)返回給客戶端,所以在客戶端監(jiān)控界面上這些信息將在狀態(tài)區(qū)中得到實(shí)時(shí)顯示。這些功能的軟件實(shí)現(xiàn)主要通過自定義函數(shù)create_main_app()來完成。在主程序運(yùn)行過程中,當(dāng)客戶端成功與服務(wù)端建立連接后,也就是connect_app()函數(shù)被成功調(diào)用后,程序會(huì)立即執(zhí)行自定義函數(shù)create_main_app()來生成視頻監(jiān)控界面,該函數(shù)的具體軟件實(shí)現(xiàn)如圖6所示。圖中函數(shù)video_status_setup()的作用是初始化采集的同時(shí)也完成填充全局狀態(tài)結(jié)構(gòu)的工作,使界面顯示后體現(xiàn)出如設(shè)備名稱、服務(wù)器、端口號(hào)、捕獲幀大小、分辨力以及用戶控制和設(shè)置等項(xiàng)的狀態(tài)信息。自定義函數(shù)init_main_if()調(diào)用主要完成視頻監(jiān)控界面的整體布局和層次分配,它的軟件實(shí)現(xiàn)如圖7所示,每個(gè)區(qū)的建立通過調(diào)用相應(yīng)的實(shí)現(xiàn)函數(shù)來完成,而相應(yīng)實(shí)現(xiàn)函數(shù)所要實(shí)現(xiàn)功能具體包括各個(gè)構(gòu)件的生成、構(gòu)件屬性的設(shè)置、構(gòu)件擺放位置的設(shè)定以及當(dāng)用戶驅(qū)動(dòng)某事件產(chǎn)生相應(yīng)信號(hào)傳遞給某構(gòu)件后,構(gòu)件處理事件所需關(guān)聯(lián)回調(diào)函數(shù)的編寫等??蛻舳塑浖\(yùn)行時(shí)所生成的視頻監(jiān)控界面如圖8所示,該界面的監(jiān)控區(qū)域畫面圖像清晰、流暢,且整個(gè)界面工作穩(wěn)定。
圖8 客戶端監(jiān)控界面的設(shè)計(jì)(截圖)
為了克服多進(jìn)程在軟件設(shè)計(jì)上占用系統(tǒng)資源多、運(yùn)行效率低和響應(yīng)速度慢等缺點(diǎn),更好地保證視頻數(shù)據(jù)及時(shí)處理,滿足視頻圖像實(shí)時(shí)性的要求,本項(xiàng)目采用Linux環(huán)境下具有并發(fā)性更高的多線程處理技術(shù)。通過調(diào)用線程執(zhí)行函數(shù)cam_thread()對(duì)視頻數(shù)據(jù)進(jìn)行各種處理操作。在主程序開始運(yùn)行并初始化后,通過調(diào)用攝像頭運(yùn)行線程來完成客戶端視頻采集的功能。該函數(shù)的具體軟件實(shí)現(xiàn)過程如圖9所示。圖中g(shù)_bcamoff為關(guān)閉設(shè)備標(biāo)識(shí)符,g_bcamrun為正在視頻采集標(biāo)識(shí)符。程序運(yùn)行過程中根據(jù)查詢到不同階段這兩個(gè)標(biāo)識(shí)符的狀態(tài),來完成相應(yīng)的處理操作。函數(shù)cam_get_img()的調(diào)用主要完成的工作是客戶端向服務(wù)端發(fā)出獲取攝像頭采集數(shù)據(jù)的命令,服務(wù)器正常響應(yīng)后,通過自定義通信協(xié)議,把相應(yīng)采集到的一幀數(shù)據(jù)發(fā)送給客戶端,客戶端根據(jù)與之對(duì)應(yīng)的自定義通信協(xié)議,從套接字中得到該幀并把它讀取到相應(yīng)的視頻緩沖區(qū)。隨后調(diào)用gwin_draw_area()函數(shù)將緩沖區(qū)中的該幀視頻數(shù)據(jù)實(shí)時(shí)地更新到用戶監(jiān)控界面中去??梢姶司€程的重要性,它成功創(chuàng)建與否直接決定整個(gè)軟件運(yùn)行狀況。
在客戶端軟件運(yùn)行過程中,主函數(shù)通過調(diào)用工作線程來完成視頻幀數(shù)據(jù)的獲取及處理操作。如果在工作線程運(yùn)行過程中,客戶端從服務(wù)端得到的一幀新視頻數(shù)據(jù)不經(jīng)任何處理直接更新到視頻監(jiān)控界面中,將會(huì)出現(xiàn)與工作線程沖突的情況發(fā)生,導(dǎo)致視頻監(jiān)控界面出現(xiàn)假死的狀況,造成整個(gè)軟件不能正常工作。為了防止視頻監(jiān)控界面在進(jìn)行界面更新時(shí)出現(xiàn)界面假死的情況。這里在工作線程中采取創(chuàng)建子界面線程的編程方法來加以克服,它是通過調(diào)用自定義gwin_draw_area()函數(shù)來實(shí)現(xiàn)。此函數(shù)定義如下:
圖9 攝像頭運(yùn)行線程
此線程執(zhí)行函數(shù)的功能就是在修改界面語句前加gdk_threads_enter()進(jìn)入修改界面的線程鎖定,修改完界面后再使用gdk_threads_leave()解除鎖定。這樣就可以避免界面線程與工作線程沖突所導(dǎo)致的監(jiān)控界面假死情況的發(fā)生,使得界面得到及時(shí)的更新,這也是保證視頻監(jiān)控界面實(shí)時(shí)性好的關(guān)鍵所在。所以,該處理技術(shù)在本軟件設(shè)計(jì)中最為重要。
本文在Linux環(huán)境下充分利用多線程編程方法和GTK+/GNOME技術(shù)的優(yōu)點(diǎn),結(jié)合現(xiàn)代通信傳輸技術(shù),對(duì)能夠處理實(shí)時(shí)視頻數(shù)據(jù)的客戶端軟件進(jìn)行了詳細(xì)設(shè)計(jì)分析。經(jīng)過測(cè)試該客戶端軟件性能可靠穩(wěn)定,所設(shè)計(jì)的視頻監(jiān)控界面不但協(xié)調(diào)、美觀,而且由該軟件構(gòu)成的監(jiān)控系統(tǒng)的監(jiān)控畫面清晰、流暢、實(shí)時(shí)性好,克服了界面在工作過程中遇到的界面假死等現(xiàn)象。此外,如果將無線監(jiān)控系統(tǒng)客戶端和服務(wù)端的功能繼續(xù)加以完善,可以根據(jù)不同終端的IP及端口號(hào)進(jìn)行音視頻雙向通信,就能從根本上解決在嵌入式移動(dòng)終端上依據(jù)IP技術(shù)實(shí)現(xiàn)網(wǎng)絡(luò)任意節(jié)點(diǎn)間點(diǎn)對(duì)點(diǎn)通信的難題,這也是后續(xù)研究的重點(diǎn)課題。
[1]許宏松,吳明行.Linux應(yīng)用程序開發(fā)指南使用Gtk+/Gnome庫[M].北京:機(jī)械工業(yè)出版社,2000.
[2]HARLOW.實(shí)用技術(shù):Linux中Gtk+和GDK開發(fā)Linux圖形界面應(yīng)用[M].北京:電子工業(yè)出版社,2000.
[3]陳健.Linux高級(jí)程序設(shè)計(jì)[M].北京:人民郵電出版社,2008.
[4]閆娟,程武山,孫鑫.基于嵌入式Linux的實(shí)時(shí)網(wǎng)絡(luò)視頻監(jiān)控系統(tǒng)[J].電視技術(shù),2006,30(12):81-84.
[5]宋國(guó)偉.GTK+2.0編程范例[M].北京:清華大學(xué)出版社,2002.
[6]戰(zhàn)曉蘇.GTK+程序設(shè)計(jì)C語言版[M].北京:清華大學(xué)出版社,2002.