碩士論文-實時視頻系統(tǒng)的設(shè)計與實現(xiàn)_第1頁
碩士論文-實時視頻系統(tǒng)的設(shè)計與實現(xiàn)_第2頁
碩士論文-實時視頻系統(tǒng)的設(shè)計與實現(xiàn)_第3頁
碩士論文-實時視頻系統(tǒng)的設(shè)計與實現(xiàn)_第4頁
碩士論文-實時視頻系統(tǒng)的設(shè)計與實現(xiàn)_第5頁
已閱讀5頁,還剩35頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

PAGE第1頁共39頁分類號:TP31UDC:D10621-408-(2016)1411-0密級:公開編號:2012051171學位論文實時視頻系統(tǒng)的設(shè)計與實現(xiàn)論文作者姓名:申請學位專業(yè):申請學位類別:論文提交日期:實時視頻系統(tǒng)的設(shè)計與實現(xiàn)摘要隨著互聯(lián)網(wǎng)時代的不斷發(fā)展,移動終端在社會的應(yīng)用不斷擴大,傳統(tǒng)的PC端實時視頻通訊變得笨重而不方便,極大的降低了人們的工作效率。為了緩解這一情況,本文采用基于軟件工程的設(shè)計、分析方法,將傳統(tǒng)的PC端實時視頻通訊移植到Android端。由于條件限制,此系統(tǒng)的視頻是通過PC端的視頻攝像頭進行采集,通過本地服務(wù)器的數(shù)據(jù)傳送,到達Android手機端進行實時的視頻播放。在軟件平臺方面,是基于visualstudio2013進行Win7上C++的開發(fā),基于eclipse和AndroidSDK進行Java服務(wù)器開發(fā)和Android端的開發(fā)。在技術(shù)層面,本系統(tǒng)在PC端使用了FFmpeg這種穩(wěn)定性較強、運用范圍比較廣的開源三方庫進行PC端的視頻采集和視頻轉(zhuǎn)碼。在服務(wù)器端,運用socket套接字和固定端口監(jiān)聽實現(xiàn)客戶端的數(shù)據(jù)監(jiān)聽和數(shù)據(jù)傳輸。在Android端將FFmpeg開源庫進行編譯,封裝成動態(tài)庫,使用Jni實現(xiàn)C和Java端的數(shù)據(jù)通信和接口調(diào)用。本系統(tǒng)將運算量較大的視頻采集和視頻編解碼用C語言來進行處理,提高了效率。將服務(wù)器搭建、數(shù)據(jù)傳輸、數(shù)據(jù)同步以及界面交互這種較為繁瑣的工作用Java來進行處理。很好的利用了C語言面向過程的高效性和Java面向?qū)ο笥押玫慕换バ?。使得系統(tǒng)即擁有較好的視頻處理性能,又具有友好的人機交互。本系統(tǒng)實現(xiàn)了對視頻的實時處理和傳輸,使人們脫離了傳統(tǒng)實時視頻通訊的地理位置現(xiàn)在,可以更加靈活的進行視頻接收、查看,使人們的生活變得更加便捷,極大的提高了人們的工作效率。關(guān)鍵詞:實時視頻;視頻編解碼;FFmpeg;Jni;Android;socketDesignandImplementationofReal-timevideosystemAbstractWiththecontinuousdevelopmentoftheInternetage,expandingtheapplicationofmobileterminalsinsociety,thetraditionalPCreal-timevideocommunicationbecomesheavyandinconvenient,greatlyreducestheproductivity.Inordertoalleviatethesituation,inthispaper,basedonthedesignofsoftwareengineering,analysismethods,thetraditionalPCreal-timevideocommunicationtransplantationtoAndroid.Becauseoftheconstraints,thevideoofthissystemisthroughtheacquisitionofthevideocameraonthePCthroughthelocalserverdatatransfer,reachtheAndroidmobileterminalreal-timevideoplayback.Intheaspectofsoftwareplatform,whichisbasedonvisualstudio2013c++developmentonWindows7,basedoneclipseandtheAndroidSDKforJavaserverdevelopmentandthedevelopmentonAndroid.Atthetechnicallevel,thesystemstabilityinPCusingFFmpegthisstrong,usingrangeiswideopensourcelibraryforthePCvideocaptureandvideotranscoding.Ontheserverside,usesocketsocketandfixedportsfortheclient'sdatatomonitoranddatatransmission.OnAndroidwillFFmpegopensourcelibrariestocompile,encapsulatedintoadynamiclibrary,usingJnitorealizethedatacommunicationandinterfacecallonCandJava.ThissystemwillbethecomputationofthelargervideocaptureandvideocodectouseClanguagetoundertakeprocessing,improvetheefficiency.Theserverbuildinterfaceinteraction,datatransmission,datasynchronization,andthemoretediousworktouseJavaforprocessing.GooduseoftheClanguagetoprocessefficiencyandJavaobject-orientedfriendlyinteractive.Ismakesthesystempossessbetterperformanceofvideoprocessing,butalsohasafriendlyhuman-computerinteraction.Thissystemhasrealizedthereal-timeprocessingandtransmissionofvideo,makespeopleawayfromthetraditionalreal-timevideocommunicationlocationnow,canbevideoreceiving,amoreflexibleview,makepeople'slifebecomemoreconvenient,greatlyimprovedtheworkefficiencyofpeople.Keywords:Real-timevideo;videoencodeanddecode;FFmpeg;Jni;Android;socket目錄論文總頁數(shù):34頁1 引言 11.1 課題背景 11.2 國內(nèi)外研究現(xiàn)狀 11.2.1 視頻技術(shù)發(fā)展現(xiàn)狀 21.2.2 視頻技術(shù)應(yīng)用現(xiàn)狀 21.2.3 本系統(tǒng)的相關(guān)技術(shù)現(xiàn)狀 31.2.4 本系統(tǒng)的應(yīng)用現(xiàn)狀 31.3 本課題研究的意義 41.4 本課題的研究方案 41.4.1 前人已實現(xiàn)方案 41.4.2 本系統(tǒng)使用方案 51.4.3 方案的確定及其優(yōu)缺點 61.5 全文結(jié)構(gòu) 62 系統(tǒng)概要設(shè)計 72.1 系統(tǒng)框架結(jié)構(gòu) 72.2 系統(tǒng)需求分析 82.2.1 系統(tǒng)功能模塊 82.2.2 系統(tǒng)數(shù)據(jù)傳輸 102.2.3 系統(tǒng)性能需求 102.3 系統(tǒng)重點技術(shù)簡介 112.4 本章小結(jié) 133 系統(tǒng)詳細設(shè)計 133.1 視頻采集技術(shù)實現(xiàn)方法 133.1.1 攝像頭驅(qū)動及FFmpeg平臺搭建 133.1.2 PC端獲取視頻解碼顯示 143.1.3 視頻編碼存儲 173.1.4 視頻緩存?zhèn)鬏?203.2 服務(wù)器傳輸技術(shù)實現(xiàn)方法 223.2.1 客戶端數(shù)據(jù)監(jiān)聽 223.2.2 數(shù)據(jù)傳輸和緩存處理 233.3 移動終端視頻處理技術(shù)實現(xiàn)方法 233.3.1 數(shù)據(jù)接收和存儲 233.3.2 視頻數(shù)據(jù)解碼 243.3.3 界面設(shè)計及視頻播放 243.4 本章小結(jié) 254 特殊問題及解決方法 254.1 動態(tài)庫運用問題 254.2 C與Java數(shù)據(jù)通信問題 264.3 數(shù)據(jù)傳輸同步問題 264.4 編碼幀頻和參數(shù)設(shè)置問題 274.5 本章小結(jié) 285 系統(tǒng)測試分析 285.1 功能模塊測試概述 285.2 系統(tǒng)PC端測試 285.3 系統(tǒng)服務(wù)器測試 295.4 系統(tǒng)移動終端測試 295.5 性能測試分析 295.6 本章小結(jié) 30結(jié)束語 31參考文獻 32致謝 33聲明 34第35頁共40頁引言課題背景即時通訊(Instant

Messaging)是目前Internet上最為流行的通訊方式。而視頻信息又是人們最直觀的理解的信息。而隨著移動終端的不斷發(fā)展,移動應(yīng)用在人們生活中的普及,使得實時視頻通訊有了發(fā)展到移動終端設(shè)備上的必要性。而比較傳統(tǒng)的視頻實時通訊基本上都是建立在攝像頭和PC電腦之間,這極大的約束了人們的活動范圍。而且占用一臺電腦資源,不能做其他事物,使得資源極其浪費。而且這種視頻的通行方式僅僅限于短距離之間,不能做到遠距離監(jiān)控。使得視頻傳輸?shù)牡赜蚴盏搅藰O大的限制。這就可能直接導(dǎo)致人們對于所關(guān)心的事物由于各種原因而不能達到實時關(guān)注的情況。而本系統(tǒng)的設(shè)計極大的彌補這一方面的不足,既能實時的通過視頻查看所關(guān)心的重要事物,又不用局限于地域和設(shè)備限制,極大提高了人們工作效率。國內(nèi)外研究現(xiàn)狀視頻技術(shù)在九十年代就已經(jīng)有了初步的發(fā)展,對視頻和音頻進行編解碼。從最開始ITU-T頒布的H.261到現(xiàn)在的H.264以及MPEG系列,都有了較為成熟的發(fā)展。隨著近幾年來的網(wǎng)絡(luò)通訊越發(fā)發(fā)達,IP化成為了網(wǎng)絡(luò)發(fā)展的主流,也使得視頻音頻的編解碼協(xié)議發(fā)展變得更為重要,一些對視頻音頻進行處理的軟件和開源項目的需求也變得急迫。而現(xiàn)在應(yīng)用比較廣泛和較為成熟的開源視頻編解碼的三方庫就是FFmpeg,它提供了錄制、轉(zhuǎn)換及流化音視頻的完整解決方案。而且支持多種編碼解碼方案。在這套三方庫推出以來,已經(jīng)有多個版本,使用的人也非常多,其對于音視頻處理的技術(shù)也是相當成熟。而且有許多的播放器都是采用了基于FFmpeg的庫進行開發(fā)的,比如VLC,Mplayer,HandBrake,GoogleChrome,DirectShow和ffdshow等等。由于FFmpeg是完全開源的項目,而且是在遵守LGPL/GPL的協(xié)議下發(fā)布的,因此也就因為某些軟件使用或者包含了FFmpeg對應(yīng)的源碼,但是并沒有遵守LGPL/GPL協(xié)議對其軟件進行開源化,而產(chǎn)生了FFmpeg恥辱柱(Hallofshame)。其中包括韓國名軟KMPlayer,以及國內(nèi)的暴風影音、QQ影音等軟件,也由此引發(fā)了許多學者對于開源的基本規(guī)則和開發(fā)者如何尊重開源作者的一些思考。從這些方面,也可以看出FFmpeg在音視頻軟件行業(yè)以及計算機行業(yè)的一定影響力。其中VLC是基于它而制作出來的一款比較成功的開源軟件,和FFmpeg一樣,VLC也支持眾多音視頻解碼器及檔案格式,并支持DVD、VCD及各類串流協(xié)定。而且VLC也在此基礎(chǔ)上進行了開發(fā),能夠作為unicast或multicast的串流服務(wù)器在IP4或IP6高速網(wǎng)絡(luò)下的連接和使用。后續(xù)版本還提供了基于Mozilla和ActiveX的插件,使其在Mozilla和IE瀏覽器中也能夠正常的顯示。而且VLC還能夠播放那些并沒有下載完整的視頻文件,這也是它的一個非常好而強大的功能。而進年來的移動終端的流行,也推出了FFmpeg對應(yīng)的移植方法,應(yīng)用技術(shù)也相對成熟。下面就是對視頻技術(shù)相應(yīng)的模塊進行細節(jié)的講解。視頻技術(shù)發(fā)展現(xiàn)狀網(wǎng)絡(luò)時代的不斷發(fā)展,網(wǎng)速的不斷提升,使得視頻技術(shù)也得到了不斷的提升和加強。從最起初的H.261的頒布到現(xiàn)在的MPEG-2,視頻通訊技術(shù)在不斷的完善。視頻通訊的相關(guān)協(xié)議的不斷成熟,以及編碼、信息壓縮技術(shù)和寬帶技術(shù)的不斷普及深化發(fā)展,使得現(xiàn)在的視頻通訊技術(shù)已經(jīng)達到了一個較為成熟的階段。不管是在視頻采集壓縮處理,視頻監(jiān)控,視頻電話,以及視頻會議,都能達到穩(wěn)定的通訊性能。目前的視頻技術(shù)發(fā)展方向是更加高清,更加現(xiàn)實以及數(shù)字轉(zhuǎn)換。也就是高清視頻的處理、虛擬現(xiàn)實的技術(shù)發(fā)展以及視頻數(shù)字化處理和信息提取這一方面的技術(shù)發(fā)展。高清視頻技術(shù)的發(fā)展多為高清720p(HD)和全高清1080P(Full-HD)類型的攝像頭獲取的視頻數(shù)據(jù),傳輸?shù)膸l為25幀/秒,通常在經(jīng)過H.264或者MPEG4等不同編碼格式的壓縮處理下進行傳輸,碼率一般是在4-20MB/S。一般高清視頻的視頻數(shù)據(jù)量在每小時2-10G之間。當然將這些數(shù)據(jù)進行下載存儲播放,并不是什么太大的難題。但是如果要將這是數(shù)據(jù)進行實時傳輸?shù)脑挘绱舜罅康臄?shù)據(jù),在存儲、網(wǎng)絡(luò)環(huán)境、系統(tǒng)穩(wěn)定性等各個方面都會受到巨大的挑戰(zhàn)。這也算是現(xiàn)在高清視頻通話,高清視頻會議,以及其他高清視頻實時通訊的一個重難點所在。視頻數(shù)字化和信息提起主要是將視屏中的數(shù)據(jù),或者是某個關(guān)鍵性的點進行信息的提起,轉(zhuǎn)化成可以處理的數(shù)字信息。這也就是現(xiàn)在發(fā)展比較火熱的智能視頻分析技術(shù)。其中主要發(fā)展的形成的應(yīng)用有:目標移動軌跡跟蹤、目標移動范圍監(jiān)測、目標移動方向監(jiān)測、靜態(tài)物體監(jiān)測、特殊人體行為監(jiān)測、人臉識別、數(shù)量統(tǒng)計以及視頻圖像質(zhì)量診斷等等。這些更多的是應(yīng)用于嵌入式視頻處理的產(chǎn)品,以算法、結(jié)構(gòu)、硬件的優(yōu)化來提高視頻信息的處理,盡量使其更加自動化、智能化,能更加快捷準確的獲取某些有效信息。但是這些技術(shù)的發(fā)展還不夠成熟和穩(wěn)定,都有一定條件的限制。對于算法,前端設(shè)備的依賴性比較大,目前也是處于研發(fā)優(yōu)化狀態(tài)。視頻技術(shù)應(yīng)用現(xiàn)狀視頻技術(shù)的應(yīng)用在我們生活中可謂無處不見,小到平常的電影電視以及身邊的攝像監(jiān)控,大到天氣預(yù)報衛(wèi)星云圖。可以說視頻技術(shù)的應(yīng)用幾乎涉及各個領(lǐng)域。下面就列舉幾個常見的領(lǐng)域。日常生活中的視頻應(yīng)用,莫過于在手機上、電視上或者電腦上觀看電視或者電影?;蛘哒f通過這些設(shè)備來進行視頻通話,網(wǎng)絡(luò)直播這類實時視頻通訊的應(yīng)用。這類只是處理好視頻清晰度和網(wǎng)絡(luò)帶寬的問題,能夠清晰流暢的觀看視頻或者進行視頻通話即可。隨著帶寬的發(fā)展,網(wǎng)絡(luò)技術(shù)的不斷提升,這一技術(shù)也已經(jīng)發(fā)展成熟。其次常見的就是醫(yī)療設(shè)備的視頻圖像處理,這類主要還是針對核磁共振,超聲波圖像這一類的醫(yī)學圖像處理。當然這種技術(shù)也發(fā)展的較為成熟,已經(jīng)應(yīng)用到大多數(shù)的醫(yī)院。但醫(yī)學類的視頻圖像處理依舊還在發(fā)展中,使其能夠更加準清晰的判斷病情。還有一類是在軍事國防方面的應(yīng)用,當然這些應(yīng)用就對視頻信息的處理要求更加準確,更加智能化,速度更快,安全性更強。軍事領(lǐng)域的應(yīng)用就跟加的復(fù)雜,技術(shù)難度也就越大。本系統(tǒng)的相關(guān)技術(shù)現(xiàn)狀本系統(tǒng)的技術(shù)主要是用到視頻的編碼與解碼,視頻數(shù)據(jù)的傳輸,視頻數(shù)據(jù)在移動終端的編解碼以及播放。本系統(tǒng)視頻編解碼是基于FFmpeg的三方庫,進行編解碼的?,F(xiàn)在使用的FFmpeg已經(jīng)到達了3.0的版本,而且有基于win平臺和基于Linux平臺兩個版本。官方還有對于的動態(tài)庫,開發(fā)包以及源碼下載,幾乎都能夠滿足開發(fā)者的基本需求。對于FFmpeg的平臺移植,也有相應(yīng)的簡介和平臺搭建方法,而且也有許多人在此基礎(chǔ)上進行過開發(fā),有相對成熟的經(jīng)驗。不足的是,網(wǎng)上可利用的資源不多,許多問題的研究并不見得深入。對于PC端的視頻數(shù)據(jù)獲取和播放,使用的是SDL的三方庫。現(xiàn)在官方也發(fā)布2.0版本,對于老式的vfw攝像頭驅(qū)動和現(xiàn)在較多的directshow都有較好的支持,網(wǎng)絡(luò)上也有相應(yīng)的基礎(chǔ)應(yīng)用的示例,包含對應(yīng)的事件機制和緩沖刷新機制,能夠基本滿足攝像頭視頻獲取相應(yīng)的功能。視頻數(shù)據(jù)的傳輸是基于TCP協(xié)議的socket套接字的一個傳輸方式,這種方式適用于建立長時間的連接,而且數(shù)據(jù)傳輸相對有保證,通常是應(yīng)用于即時傳輸。這類數(shù)據(jù)傳輸協(xié)議和傳輸方法,已經(jīng)有了較成熟的示例,但是要根據(jù)不同的應(yīng)用來加以更改,理解對于流數(shù)據(jù)的處理機制,才能更好的應(yīng)用。手機終端視頻解碼的處理和播放,是基于FFmpeg的方式進行,由于Android平臺近年來才興起,對于FFmpeg的移植有先例,但是并不是完全的成熟,有許多的問題有待解決。作為開發(fā)者,這一方面網(wǎng)上的資源可謂也少了許多。至于Android前端界面的編寫,現(xiàn)在已經(jīng)是發(fā)展到了相當成熟的階段,幾乎能夠滿足所有應(yīng)用的一種移植所需的前端設(shè)計。本系統(tǒng)的應(yīng)用現(xiàn)狀本系統(tǒng)的主要應(yīng)用更加趨向于視頻監(jiān)控方向,由于采集端是基于PC的攝像頭,可能要真正進行應(yīng)用的話,還需要一定的改進。目前基于Android移動終端的視頻監(jiān)控還不常見,大多數(shù)都是基于PC的一個視頻監(jiān)控,并沒有將視屏傳輸?shù)椒?wù)器,與移動終端進行一定的交互,將視屏實時傳輸?shù)揭苿咏K端。而大多數(shù)的攝像頭的開發(fā)精力主要是集中在智能視頻監(jiān)控方面,以及高清視頻監(jiān)控方面。少有對移動終端方面的視頻監(jiān)控進行研發(fā)。本系統(tǒng)研發(fā)成功后,在以后的智能家居這方面,對于私人的視頻監(jiān)控的應(yīng)用有著廣闊的空間。特別是在人們外出時,依舊可以在有網(wǎng)絡(luò)的情況下,對家中的一些情況進行監(jiān)視和查看。例如:防止有陌生人物侵入自己的房間。家中小孩遇到的突發(fā)情況。配合紅外感應(yīng)及時查看和預(yù)防家中可能出現(xiàn)的火災(zāi)。若攝像頭的安裝方便,還可以根據(jù)自己的需求對于一些需要觀察監(jiān)視的物品進行實時查看。本課題研究的意義本系統(tǒng)的研究,致力于將視頻監(jiān)控變得跟加方便化,人性化。在于傳統(tǒng)意義上的PC視頻監(jiān)控上,增加了服務(wù)器存儲,以免重要的視頻信息遺漏、丟失。而且可以同步實時傳輸?shù)綄?yīng)的移動終端。夠跟加方便人們出行時對于房屋、車庫或者自己所重視的東西進行一個實時視頻查看的效果。能夠使人們更加快捷的對危險情況進行反應(yīng)和處理,保障人們財產(chǎn)和生命安全。與此同時,又不會極大的約束人們的生活節(jié)奏和工作活動,與智能家居進行配合合作,在智能家居進行一些數(shù)字化的檢測過后,由視頻數(shù)據(jù)來進行更加準確的判定。例如在有人進入你家中的時候,在智能家居感應(yīng)到時,你可以通過視頻數(shù)據(jù)來判定是否是你的家人,還是外來入侵者。這些與此相近的一系列的應(yīng)用能更加方便人們的生活,保障人們的財產(chǎn)。本課題的研究方案本系統(tǒng)在設(shè)計之前,對設(shè)計方案有過初始簡單的了解和建立,F(xiàn)Fmpeg是個成熟穩(wěn)定的三方開源庫,而且支持攝像頭視頻提取功能。并且可以通過Jni與Java通訊,能很好的移植到Android上??傮w來說,這個方案的可行性更加高,而且和實際的需求有很高程度上的契合度,也依舊有一些缺陷和不足有待改進和優(yōu)化。前人已實現(xiàn)方案Anychat即時通訊平臺,是一套基于相對成熟的即時通訊視頻解決方案,而且可以更好的融合不同平臺之間的通訊。針對的主要是視頻網(wǎng)絡(luò)視頻聊天和視頻游戲一類的需求開發(fā)的一套實現(xiàn)方案。其中也是基于第三方的開源技術(shù)進行開發(fā)的。其中包含了FFmpeg、libvpx、libspeex、webrtc。在視頻壓縮編解碼方面是基于H.264的視頻編碼標準、AAC音頻編碼標準和P2P技術(shù)。其中包含了音視頻處理模塊、流媒體管理模塊、流媒體播放模塊以及P2P網(wǎng)絡(luò)模塊。對于底層的硬件操作比如音視頻采集、播放和流媒體處理比如音視頻的編碼解碼等非常專業(yè)的技術(shù)都進行了封裝。只為上層提供了對應(yīng)的API接口,方便開發(fā)者進行調(diào)用。但是由于此系統(tǒng)主要是針對上層進行開發(fā),重點突出的是跨平臺。更多用于大型的視頻實時通訊的一種解決方案,并且它對于底層的操作都進行了封裝,在本系統(tǒng)的開發(fā)中自由度受到了限制。另一種實現(xiàn)方案相對與anychat來說,沒有那么多現(xiàn)成的功能較為豐富的API接口,但是提供了更多在基本音視頻處理方面的API接口。比如圖像縮放具體實現(xiàn),每一幀視頻數(shù)據(jù)的提取處理一類的。具體是用FFmpeg獲取視頻并進行壓縮轉(zhuǎn)碼,自行編碼服務(wù)器,進行數(shù)據(jù)實時傳輸,移動終端基于Android或者iOS對Ffmpeg又進行平臺移植,自己編碼實現(xiàn)視頻數(shù)據(jù)的解碼,并用自帶的視頻顯示控件進行播放。這一種實現(xiàn)方式是在網(wǎng)上看到的一些分塊的設(shè)計自行組合而成的,這個方案只是有人提出可以實現(xiàn),但是并沒有相關(guān)的源碼。但是FFmpeg對視頻數(shù)據(jù)的獲取,編碼壓縮技術(shù)基本已經(jīng)成熟,而且也有相對應(yīng)參考文獻。關(guān)于FFmpeg在移動平臺的移植技術(shù)也有先例,但是技術(shù)還并不成熟。這里面也有關(guān)于C和Java之間的數(shù)據(jù)傳輸問題,大多使用的都是Jni進行接口調(diào)用,也有許多的參考資源。兩種方案比較,anychat開發(fā)更為簡單快捷。比如使用anychat進行視頻攝像頭調(diào)用,僅僅需要一個函數(shù)BRAC_SetVideoPos就可以啟用攝像頭,里面已近具體實現(xiàn)了攝像頭類型檢測,驅(qū)動監(jiān)測和攝像頭開啟等工作。其他的功能也相對于FFmpeg來說,又進行了豐富和集成。而且anychat還擁有一套的sdk可供不同平臺開發(fā),免去了跨平臺的移植麻煩,也提供了對應(yīng)的服務(wù)器開發(fā)方案,用此來搭建服務(wù)器。但是,anychat比較FFmpeg封裝的較多,遇到問題不能直接看源碼實現(xiàn),而且它支持的音視頻解碼器比FFmpeg少了許多。這就使得使用anychat的自由度少了許多。其實anychat也就是基于FFmpeg進行開發(fā)的,并且相比FFmpeg,開發(fā)文檔和相關(guān)開發(fā)資料也少了許多?;谧杂啥取⒋a開放度、開發(fā)資料的豐富程度選擇使用FFmpeg對應(yīng)的方案。本系統(tǒng)使用方案本系統(tǒng)由于相對接近底層,也就并沒有采用第一種Anychat的方案,Anychat是一種已經(jīng)實現(xiàn)和封裝好的即時通訊平臺,更加針對的是上層開發(fā)。也就采用了第二種實現(xiàn)方案,本系統(tǒng)也在此基礎(chǔ)上進行細節(jié)性的更改,使其更加適合本項目的開發(fā)。本系統(tǒng)的方案具體為使用FFmpeg來對視頻數(shù)據(jù)進行獲取、編碼、壓縮。由于此三方庫相對比較成熟,而且功能強大,網(wǎng)上資源較為豐富。但是想要靈活運用比較困難。使用SDL三方庫來對視頻攝像頭的硬件驅(qū)動進行檢測,能夠有效的運行對應(yīng)的驅(qū)動來進行視頻數(shù)據(jù)的獲取,并且對已經(jīng)解碼好的視頻數(shù)據(jù)進行播放。由于SDL有消息機制以及緩存刷新機制,對于視頻的播放相對也比較流暢,對于基本的攝像頭驅(qū)動也能很好的支持,是相對理想的選擇。在數(shù)據(jù)傳輸方面,使用的是基于TCP協(xié)議的Socket套接字來進行數(shù)據(jù)是實時傳輸,這種方式適用于建立長時間的連接,而且數(shù)據(jù)傳輸相對有保證,通常是應(yīng)用于即時傳輸。由于C和Java之間要建立通訊連接,故采用Jni技術(shù)來進行接口的調(diào)用,這種調(diào)用方式能夠很好的支持字節(jié)、數(shù)組、對象等基本數(shù)據(jù)的參數(shù)傳遞和返回,也能實現(xiàn)C對Java函數(shù)的調(diào)用,以及回調(diào)。由于是基于FFmpeg的視頻壓縮處理,在Android移動終端使用的也是基于FFmpeg的三方庫視頻解碼,和Android自帶的視頻播放控件。方案的確定及其優(yōu)缺點優(yōu)點:本系統(tǒng)的這套方案,每一個部分清晰明了,恰到好處的實現(xiàn)了對應(yīng)的功能。FFmpeg是專門針對視頻數(shù)據(jù)進行處理的,支持許多的編解碼方案,性能穩(wěn)定,而且基于C有更高的效率。SDL(SimpleDirectMediaLayer)也是個簡單的三方庫,專門針對視頻圖像和音頻圖像的輸出,而且能夠?qū)z像頭驅(qū)動進行有效的檢測和調(diào)用。對應(yīng)的服務(wù)器使用的是Socket套接字,相對于URL和webserver這類的通訊方式,這種方式更加適合于長連接和即時通訊,而且數(shù)據(jù)也有所保障?;贏ndroid的移動終端,現(xiàn)在Android手機的使用也很廣泛,開發(fā)技術(shù)也相對成熟,支持很多功能的實現(xiàn),是個較為方便和成熟的平臺。缺點:由于運用了Jni對Native進行了調(diào)用,在系統(tǒng)的穩(wěn)定性和安全性上并沒有那么可靠。全文結(jié)構(gòu)第一章,引言部分,大致介紹了本系統(tǒng)的課題背景,現(xiàn)階段國內(nèi)外的研究現(xiàn)狀,本系統(tǒng)實現(xiàn)的方案選擇以及其優(yōu)缺點。第二章,系統(tǒng)概要設(shè)計,簡單介紹了本系統(tǒng)的結(jié)構(gòu)框架,展示系統(tǒng)結(jié)構(gòu)框架圖,以及系統(tǒng)所需求的結(jié)構(gòu)、功能、性能等各方面的設(shè)計簡潔。第三章,系統(tǒng)詳細設(shè)計,是本論文的重點部分。詳細的介紹了本系統(tǒng)的每個部分的詳細設(shè)計,設(shè)計框架結(jié)構(gòu),數(shù)據(jù)詳細設(shè)計說明等。其中附有詳細的結(jié)構(gòu)圖和對應(yīng)的關(guān)鍵源程序代碼。第四章,是在本系統(tǒng)的開發(fā)過程中所遇到的一些比較有代表性的問題以及其解決方案,當然也有尚未解決的問題。第五章,是對本系統(tǒng)的測試分析,主要是在本系統(tǒng)開發(fā)中的一些測試,及開發(fā)完成后完善的一些測試。本章小結(jié),此章的重點就是在系統(tǒng)的總體簡介之前對其課題背景的一個描述,和對當前相關(guān)技術(shù)的一個大致了解。這其中大多數(shù)是從書籍、網(wǎng)絡(luò)上了解的知識,對于本系統(tǒng)的大體設(shè)計有著很大的幫助。除此之外,還學習了其他與視頻通訊相關(guān)的知識,有助于其他開發(fā)者的參考,也幫助我更加完善和改進自己的設(shè)計。系統(tǒng)概要設(shè)計系統(tǒng)框架結(jié)構(gòu)系統(tǒng)框架結(jié)構(gòu)主要是通過PC采集視頻,由服務(wù)器進行同步傳輸,再通過Android手機端進行播放。其結(jié)構(gòu)框圖如下圖2-1:圖SEQ圖\*ARABIC1系統(tǒng)框架結(jié)構(gòu)圖下面是與之對應(yīng)的功能結(jié)構(gòu)框架圖:SEQ圖\*ARABIC2系統(tǒng)功能機構(gòu)圖系統(tǒng)需求分析本小結(jié)主要是針對系統(tǒng)的各個方面的性能進行一個相關(guān)的闡述,對于各個模塊功能的大致需求。本系統(tǒng)的運行環(huán)境硬件需求,win7的PC電腦一臺,支持directShow的視頻攝像頭,并且能夠正常的工作。PC端有對應(yīng)的無線網(wǎng)卡,能夠產(chǎn)生一個良好的局域網(wǎng)。本系統(tǒng)所需的軟件和其他條件,使用本軟件的人能夠熟練的運用PC電腦和Android手機,對于網(wǎng)絡(luò)也要有一方面的了解。在本系統(tǒng)運行之前,要對系統(tǒng)的局域網(wǎng)IP進行查看,能夠獲取到對應(yīng)客戶端的局域網(wǎng)IP地址。而且本系統(tǒng)運行時,確認系統(tǒng)沒有其他軟件對9876(自定義端口,可更改)端口進行占用,如果有占用,要先解除占用,本系統(tǒng)才能夠正常運行。移動終端的Android手機要基于4.0平臺以上,能夠正常工作的手機。并且要先安裝本系統(tǒng)對應(yīng)的Android客戶端軟件。系統(tǒng)功能模塊本系統(tǒng)的功能需求,是實現(xiàn)在PC端的數(shù)據(jù)采集和數(shù)據(jù)編解碼,并且在客戶端進行顯示。獲取到數(shù)據(jù)編碼壓縮完畢后連接到服務(wù)器,進行數(shù)據(jù)的同步傳輸。在移動終端接收到數(shù)據(jù)過后進行解碼,而后由手機端進行同步播放。在此分別給出三個大模塊對應(yīng)的結(jié)構(gòu)框架圖:圖SEQ圖\*ARABIC4PC端結(jié)構(gòu)框架圖圖SEQ圖\*ARABIC5服務(wù)器結(jié)構(gòu)圖圖SEQ圖\*ARABIC6移動終端結(jié)構(gòu)框架圖系統(tǒng)數(shù)據(jù)傳輸有關(guān)數(shù)據(jù)傳輸?shù)男枨?,主要是針對?shù)據(jù)傳輸?shù)耐叫院蛿?shù)據(jù)傳輸?shù)恼_性。從數(shù)據(jù)的獲取到數(shù)據(jù)最終的播放,都盡量做到數(shù)據(jù)的正確和同步。數(shù)據(jù)獲取階段,Buffer的創(chuàng)建是在Java代碼里面完成的,通過Jni的調(diào)用,將其對象的引用傳輸?shù)紺代碼里,用于存儲從攝像頭你獲取的視頻數(shù)據(jù)。如果存儲完成,則對標志位置位。以此來通知Java代碼里的數(shù)據(jù)傳輸線程,可以讀取數(shù)據(jù)Buffer里的數(shù)據(jù)來進行傳輸。在數(shù)據(jù)傳輸階段,在服務(wù)器與PC客戶端以及移動終端的客戶端建立連接完成以后,服務(wù)器讀線程監(jiān)聽PC端傳輸過來的數(shù)據(jù),并且讓寫進程等待。當PC端數(shù)據(jù)傳輸?shù)椒?wù)器后,存儲到建立的數(shù)據(jù)Buffer中,解除寫進程等待,讓讀進程進行等待。此時寫進程開始講數(shù)據(jù)Buffer中的數(shù)據(jù)寫入到移動終端,完成后解除讀進程等待。在移動終端數(shù)據(jù)接收時,新建一個線程進行服務(wù)器連接,獲取視頻數(shù)據(jù)Buffer,當數(shù)據(jù)緩沖完成過后,傳輸?shù)紽Fmpeg對應(yīng)的動態(tài)庫中進行解碼,由相應(yīng)的視頻控件來進行播放。同樣,在數(shù)據(jù)Buffer不同的讀寫操作時,要保證進程間的互斥。系統(tǒng)性能需求系統(tǒng)性能需求主要集中的方面是數(shù)據(jù)傳輸?shù)乃俣?,和視頻播放的效果。在數(shù)據(jù)傳輸方面,由于在采集的時候采用的是延遲40毫秒采集一次視頻數(shù)據(jù),也就是得到的視頻數(shù)據(jù)為25幀頻。每幀的數(shù)據(jù)在沒有壓縮的時候是460800個字節(jié),也就是450kb。若不進行壓縮就傳輸數(shù)據(jù),那么一秒鐘傳輸?shù)臄?shù)據(jù)在10M左右,一般的帶寬都無法承受這樣的數(shù)據(jù)量。因此只能采用H264的壓縮方式來進行壓縮,一般的H264的壓縮比在100:1左右,折算下來每秒鐘傳輸?shù)臄?shù)據(jù)為100kb左右,這樣的數(shù)據(jù)量在一般的網(wǎng)絡(luò)寬帶都能夠有效的支持。而在這40秒獲取到數(shù)據(jù)時,要同步傳輸?shù)綄?yīng)的手機端并且能夠播放出來,其中包括視頻數(shù)據(jù)解碼,傳輸,在服務(wù)器中進行讀取各個方面的操作。由于從視頻獲取、解碼、編碼、傳輸、數(shù)據(jù)獲取、解碼播放都是一個線性操作,加上網(wǎng)絡(luò)的傳輸不穩(wěn)定因素。因此要保證在通訊連接建立過后不掉幀的難度很大,但是在范圍程度內(nèi)的掉幀不影響播放效果是可以接受的。在第三章中會對H264的編碼結(jié)構(gòu)和其中的I,P幀進行詳解。視頻播放效果質(zhì)量主要是在數(shù)據(jù)編碼和數(shù)據(jù)傳輸?shù)恼_性方面。由于視頻采集的時候,得到的是YUV數(shù)據(jù),要轉(zhuǎn)碼成為H264編碼的格式,進行壓縮方便傳輸和播放。但是在編碼時,要注意時間的控制,以及編碼方式的控制。要不就會出現(xiàn)編碼過后與原來的幀頻不能有效的對應(yīng),使得播放過快或者過慢。同樣,視頻播放的速度也取決于數(shù)據(jù)傳輸?shù)乃俣?,?shù)據(jù)傳輸?shù)乃俣炔荒苡行M足,實時播放的效果也就不能實現(xiàn)。其中在傳輸?shù)臅r候,Java函數(shù)的選擇也是很重要的,本系統(tǒng)采用的是inputoustream和outputstream對應(yīng)的字節(jié)流輸入輸出函數(shù)來保證數(shù)據(jù)傳輸?shù)恼_性。傳輸?shù)耐娇刂坪侠硪彩潜WC數(shù)據(jù)傳輸正確性的一個重要方面。系統(tǒng)重點技術(shù)簡介本節(jié)主要是針對本系統(tǒng)的重點一些技術(shù)進行簡介。其中主要涉及的重點技術(shù)有FFmpeg編解碼,Jni運用,SDL視頻播放,socket套接字使用。FFmpeg編解碼,這個三方庫是本系統(tǒng)的核心。使用它來完成了數(shù)據(jù)的獲取,視頻數(shù)據(jù)的編碼壓縮這些核心功能。下面是大致的一個編解碼步驟:其中數(shù)據(jù)獲取是先使用av_register_all()進行初始化(這個函數(shù)是所有模塊初始化,也可以用對應(yīng)模塊的函數(shù)進行初始化)。使用avformat_find_stream_info函數(shù)獲取對應(yīng)流媒體的各個方面的信息(具體會在下面詳解)。avcodec_open2初始化音視頻編解碼器,再使用av_read_frame讀取幀頻數(shù)據(jù)。并用avcodec_decode_video2()解碼一幀視頻數(shù)據(jù)。輸入一個壓縮編碼的結(jié)構(gòu)體AVPacket。avcodec_decode_video2函數(shù)返回成功后,我們就可以通過這個AVPacket結(jié)構(gòu)體獲取對應(yīng)的視頻數(shù)據(jù)了。FFmpeg的視頻編解碼的庫都主要集中于libavcodec對應(yīng)的文件夾下,其中包含了大部分對于音視頻的編解碼函數(shù)。下面是就基本的FFmpeg編解碼的流程圖:圖SEQ圖\*ARABIC7音視頻編解碼流程圖Jni其實就是一個橋梁,連接Java和C其中主要的就是一個動態(tài)庫的生成,對應(yīng)函數(shù)的編寫格式,和傳參方式。其中大致實現(xiàn)步驟如下:編寫Java類,帶有native的聲明方法。使用Javah命令生成對應(yīng)的類的頭文件。使用C/C++實現(xiàn)與之對應(yīng)的本地方法。使用vs2013將你的C/C++文件編譯生成對應(yīng)的動態(tài)鏈接庫。配置對應(yīng)的環(huán)境變量,使Java能夠?qū)雽?yīng)的動態(tài)鏈接庫。在這些方法實現(xiàn)的過程中,要使用到對應(yīng)的參數(shù)調(diào)用,和函數(shù)回調(diào)。在后面的詳解中會詳細說明。SDL在本系統(tǒng)的主要作用是對系統(tǒng)攝像頭的驅(qū)動監(jiān)測,和攝像頭啟動。主要包括以下幾步:監(jiān)測攝像頭驅(qū)動信息。使用對應(yīng)的攝像頭驅(qū)動啟動攝像頭。SDL_CreateWindow函數(shù)創(chuàng)建對應(yīng)的視頻播放窗口。使用SDL_Texture函數(shù)存儲一幀的像素數(shù)據(jù)。使用SDL_UpdateYUVTexture更新紋理,顯示一幀的視頻數(shù)據(jù)。這里介紹的也是SDL使用的大致的幾個常用和關(guān)鍵的幾個函數(shù)和步驟,后面還會對其進行詳細的介紹。Socket套接字使用相對比較簡單,要很好的控制和利用也要好好學習。本系統(tǒng)中的服務(wù)器中的主要步驟如下:服務(wù)器申請端口,創(chuàng)建serversocket對象。使用accept函數(shù)進行客戶端的監(jiān)聽。客戶端使用socket套接字進行連接。建立連接過后,建立一個實例化的socket套接字。使用socket類中的inputstream和outputstream進行字節(jié)流的傳輸。Socket套接字是基于TCP的通訊協(xié)議,在Java中寫的,對于底層的具體通訊方式?jīng)]有進行詳細的了解,后面會對其具體詳情進行介紹。本章小結(jié)本章對于本系統(tǒng)的大致框架結(jié)構(gòu),每一部分的框架結(jié)構(gòu)有了一個大致的了解,對應(yīng)其相關(guān)的技術(shù)以及其中重點或者關(guān)鍵的部分也有相關(guān)的提及。對于本系統(tǒng)的數(shù)據(jù)傳輸質(zhì)量、速度方面進行了簡單的介紹,也分析了本系統(tǒng)影響視頻播放的各個方面做了一些簡介。本章的目的只是讓讀者了解本系統(tǒng)的大致結(jié)構(gòu),其中具體的實現(xiàn)方法以及細節(jié),會在下一章節(jié)進行說明。系統(tǒng)詳細設(shè)計視頻采集技術(shù)實現(xiàn)方法這里介紹的是PC端視頻采集技術(shù)的具體實現(xiàn)方法,以及對應(yīng)的FFmpeg進行編解碼的具體實現(xiàn)方式。這也是本系統(tǒng)的核心重點所在。攝像頭驅(qū)動及FFmpeg平臺搭建視頻攝像頭視頻獲取,主要是針對攝像頭的啟動,和運行進行說明。由于視頻獲取和后面的視頻顯示是在一起的,就放在下面講解。本系統(tǒng)基于的PC平臺是win7的平臺,win平臺使用的攝像頭驅(qū)動有老版本的vfw(videoforWindows)對應(yīng)的封裝庫(這個基本已經(jīng)不用了)。也有現(xiàn)在使用較為廣泛的是基于DirectShow來驅(qū)動攝像頭的。而本系統(tǒng)進行檢測是基于DirectShow的攝像頭,因此采用了FFmpeg自帶的攝像頭驅(qū)動方式來對攝像頭進行驅(qū)動。主要的函數(shù)是av_find_input_format獲取系統(tǒng)攝像頭設(shè)備,其中參數(shù)是對應(yīng)你攝像頭的驅(qū)動類型。而后使用avformat_open_input函數(shù)就能打開對應(yīng)攝像頭,獲取到里面對應(yīng)的視頻流數(shù)據(jù)。但是此函數(shù)里的參數(shù)需要你事先獲得你攝像頭使用的設(shè)備驅(qū)動名稱,這里獲取攝像頭驅(qū)動信息的方式有一下幾種:使用FFmpeg自帶的命令進行查看,查看攝像頭設(shè)備信息的命令為:ffmpeg-list_devicestrue-fdshow-idummy使用代碼在控制臺打印出對應(yīng)的設(shè)備信息主要使用函數(shù)av_dict_set。使用一些軟件來實現(xiàn)這個功能,比如DirectShow的調(diào)試工具GraphEdit。這里使用到的FFmpeg函數(shù)并不多,但是需要事先在win7平臺下基于vs2013進行FFmpeg的平臺搭建,就在此進行介紹。下面只搭建平臺的步驟:官網(wǎng)上下載對應(yīng)FFmpeg在win平臺下編譯的包,根據(jù)你系統(tǒng)的平臺來選擇。在vs中新建控制臺工程,并設(shè)置動態(tài)鏈接庫路徑(也可以使用代碼來實現(xiàn)動態(tài)庫的連接)。將所需要的dll文件拷貝到你所見工程當中。編寫一個測試代碼進行測試,成功就完成了。由于后面Android也需要FFmpeg移植,搭建基于Android的FFmpeg平臺,下面就根據(jù)Android平臺說明一下搭建步驟:下載對應(yīng)的FFmpeg源代碼。建立編譯平臺,一般在Linux下編譯,如果你用的是win平臺,可以使用模擬Linux平臺的軟件,如Cygwin。編寫和修改configure文件,和編寫build_Android.sh腳本文件,準備進行編譯(如果平臺是win平臺,還要進行其他文件的修改)。創(chuàng)建普通的Android工程,將編譯出來的so動態(tài)庫加入對應(yīng)的Jni文件夾創(chuàng)建對應(yīng)的含有native本地調(diào)用程序的類。創(chuàng)建對應(yīng)的頭文件,編寫對應(yīng)的Android.mk文件。運行Android.mk文件,編譯生成對應(yīng)的so文件。加載對應(yīng)的so動態(tài)庫。進行基本測試,成功完成。以上就是針對攝像頭監(jiān)測和啟動以及FFmpeg的一些平臺搭建的類容,都是只寫出了核心的內(nèi)容,若要實踐還需要多多參考其他資源。PC端獲取視頻解碼顯示視頻的獲取工作,主要是由FFmpeg完成,而PC端的視頻數(shù)據(jù)顯示基本由SDL完成。這里就分別進行視頻數(shù)據(jù)獲取和視頻數(shù)據(jù)顯示的詳細介紹。下面是對應(yīng)的視頻獲取解碼的路程圖:圖SEQ圖\*ARABIC8視頻解碼這里需要說明的是,視頻的獲取中也包含了視頻解碼的過程,從攝像頭中獲取的視頻數(shù)據(jù)通過解碼成一幀幀的YUV數(shù)據(jù),傳遞給SDL來進行播放。這里對部分函數(shù)進行說明:Av_register_all():對所有的FFmpeg編解碼器進行注冊。Av_find_stream_info():新建AVStream的輸入碼流,這里是對應(yīng)的攝像頭輸入碼流。avcodec_find_encoder():查找對應(yīng)的編碼器。avcodec_open2():打開對應(yīng)的編碼器。av_read_frame():讀取一幀的數(shù)據(jù)到對應(yīng)的packet。avcodec_dencode_video2():真正解碼碼一幀視頻,將對應(yīng)的packet里的數(shù)據(jù)解碼到AVFrame里。sws_scale():對AVFrame里的一幀圖片進行縮放處理。這里最耗時的兩個函數(shù)是avcodec_dencode_video2()和sws_scale(),由于獲取的視頻數(shù)據(jù)格式是rawdata數(shù)據(jù),在進行解碼和圖像縮放的時候,在PC端的耗時并不長,兩個函數(shù)加起來在3ms左右,對于這里采集視頻使用的是25幀,即40ms采集一幀,在此的影響不大。圖像的縮放函數(shù)并沒有改變原函數(shù)的長寬,僅僅是改變了數(shù)據(jù)格式,從rawdata變?yōu)榱薡UV。其中黃色的內(nèi)容是SDL2.0新增加的內(nèi)容。下面就是針對這一幀幀的數(shù)據(jù)SDL進行播放的流程圖:圖SEQ圖\*ARABIC9SDL視頻播放流程圖關(guān)于SDL播放問題,這里主要關(guān)注的是兩個點:第一,在播放是窗口是否可拖動,或者其他操作。第二,視頻播放的流暢度,如果不流暢如何處理。關(guān)于第一點,本系統(tǒng)使用的是消息緩存機制。即新建一個線程,對窗口的操作進行消息緩存,并且進行40ms的延時來控制視頻幀數(shù)。而主線程進行消息緩存的等待,獲取到對應(yīng)的緩存消息,介紹等待。這樣處理就能夠有一個線程處理窗口操作消息,不會使窗口一直處于忙碌狀態(tài),而且還能夠更加準確的控制幀數(shù)。關(guān)于第二點,在視頻播放不流暢的時候,會彈出bufferfull的提示,并且將當時的幀進行舍棄。以保證視頻能夠正常播放。這種情況在進行窗口移動的過程中,視頻會暫停,就會出現(xiàn)這種情況,但當移動結(jié)束后又能正常播放。下面是PC端視頻獲取顯示的運行截圖:圖SEQ圖\*ARABIC10PC端運行截圖視頻編碼存儲視頻編碼的主要目的是對占用空間很大的視頻數(shù)據(jù)進行壓縮,使其方便傳輸。不同的編碼格式有不同的優(yōu)缺點,也有不同的應(yīng)用場景和范圍。下面就是視頻編碼中主要的編碼方案:表格SEQ表格\*ARABIC1主要視頻編碼方案名稱推出機構(gòu)推出時間目前使用領(lǐng)域HEVC(H.265)MPEG/IUT-T2013推廣中H.264MPEG/IUT-T2003各個領(lǐng)域MPEG4MPEG2001不溫不火MPEG2MPEG1994數(shù)字電視VP9Google2013研發(fā)中VP8Google2008不普及CV-1MicrosoftInc.2006微軟平臺由于本系統(tǒng)并不需要進行音頻壓縮處理,所有在進行編碼的時候,僅僅做了視頻編碼處理。如果要加入音頻壓縮處理時,往往還需要進行封裝,進行音視頻同步方面的問題。在本系統(tǒng)中并沒有必要加入這些。因此,本系統(tǒng)采用的是使用范圍較為廣泛的H.264的壓縮編碼方案,將得到的YUV數(shù)據(jù)轉(zhuǎn)換成對應(yīng)的H.264格式,現(xiàn)在就YUV數(shù)據(jù)流和H.264的碼流進行一個簡單的介紹。YUV數(shù)據(jù)是指視頻像素數(shù)據(jù),是最為基本的視頻數(shù)據(jù)。其中包括YUV420P、YUV422P和YUV444P。當然基本的非壓縮像素數(shù)據(jù)也有RGB格式類型,在本系統(tǒng)中使用的是YUV420P的格式。其中YUV表示的是三個分量,Y表示的是亮度,也就是灰度值;而U和V表示的是色度,主要功能是描述影像的色彩和飽和度,用來指定像素的顏色。YUV的存儲格式和采樣方式密切相關(guān),其中后面的420P、422P和444P代表的就是三種不同的采樣方式。具體情況在此就不詳述了。我想重點強調(diào)的就是通過不同的采樣方式,會有不同的格式,只有通過對應(yīng)的采樣格式從數(shù)據(jù)碼流中提取像素點的YUV值,才能夠正確的轉(zhuǎn)換成RGB像素點的值,然后顯示出來。H.264碼流,是將對應(yīng)的YUV像素數(shù)據(jù)格式進行壓縮過后得到的數(shù)據(jù)。H.264原始碼流,又稱為“裸流”,是由一個一個的NALU組成的。其中每個NALU之間通過startcode(起始碼)進行分割。其中起始碼的類型必須是“0X00000001”或者“0X000001”這兩種類型其中的一種。而如果要進行H.264碼流的解析,就要首先從碼流中找到這些起始碼,分離出單個的NALU,然后再對單個的NALU單元進行分析。當然我們在進行編碼的時候,并不需要對其了解太多,因為FFmpeg已經(jīng)有對應(yīng)的函數(shù)可以實現(xiàn)這些壓縮解壓的過程了。這是對一個H264碼流的結(jié)構(gòu)進行的分析,下面就是對其編碼方式進行分析。H264是以高質(zhì)量高壓縮和支持多種網(wǎng)絡(luò)流媒體協(xié)議而聞名的。其主要是實現(xiàn)方式就是通過參考,在有一個完整幀的情況下,后面的相鄰幀圖像差距一般只有不到10%的差距,而H264的編碼就是依靠一個完整的幀,后面相鄰的幀對前面完整的幀進行參考,如果差距不大,就只需要進行變化部分的參考即可,要是變化較大,那么久從新生成一個新的參考幀。從而大大降低了數(shù)據(jù)量。在H264中定義的三種幀,分別是I幀、P幀、B幀。其中I幀是完整的編碼幀,P幀是參考之前的I幀生成的差異幀,B幀是參考前后編碼的幀。I幀包含完整的圖像數(shù)據(jù),直接解碼I幀就可以有完整的圖像數(shù)據(jù),而P幀是表示的這一幀和之前的I幀或者是P幀之間的差別,解碼時就要實現(xiàn)緩存之前的幀,再加上本幀定義的差別,才能夠生成最后的畫面。而B幀對應(yīng)的是前后幀與本幀之間的差別,在進行B幀解碼時,不僅先要取得前面一幀的緩存畫面,而且還要取得后面一幀的緩存畫面,通過前后兩幀和本幀的差別疊加過后取得最終的畫面,由于B幀需求的條件和比較多,而且壓縮率高,在解碼的時候CPU的耗時會很多,這也是B幀和H264編解碼速度之間的關(guān)系。下面就是對YUV數(shù)據(jù)轉(zhuǎn)化成H.264格式數(shù)據(jù)的一個流程圖:圖SEQ圖\*ARABIC11視頻編碼路程圖其中綠色的部分是實際上輸出數(shù)據(jù)的函數(shù),藍色部分才是真正意義上的視頻編碼函數(shù)。下面就將上面所有的函數(shù)進行相應(yīng)的解釋說明:Av_register_all():對所有的FFmpeg編解碼器進行注冊。avformat_alloc_output_context2():初始化輸出流碼的AVFormatContext,這個函數(shù)也就可以更加自動的選擇編碼方式,可以根據(jù)你的輸出文件后綴名進行判斷編碼方式。avio_open():打開對應(yīng)輸出文件,雖然本系統(tǒng)緩存在Buffer中,不過也向文件中進行本地存儲寫入。av_new_stream():新建AVStream的輸出碼流。avcodec_find_encoder():查找對應(yīng)的編碼器。avcodec_open2():打開對應(yīng)的編碼器。avformat_write_header():寫文件頭,但對于一些沒有頭文件封裝格式的編碼方式來說,并不需要這個函數(shù)。avcodec_encode_video2():真正編碼一幀視頻,將存儲的YUV數(shù)據(jù)編碼為對應(yīng)的H.264的AVPacket。av_write_frame():將編碼好的流視頻寫入對應(yīng)的文件,而本系統(tǒng)還需要把對應(yīng)的H.264的數(shù)據(jù)同時緩存到數(shù)據(jù)Buffer中。flush_encoder():要在YUV像素數(shù)據(jù)讀取完畢過后調(diào)用此函數(shù),用于輸出編碼器中剩余的AVPacket。這個函數(shù)是自己編寫的,具體看源碼。av_write_trailer():寫文件尾,同樣,有些封裝格式不需要寫文件尾,根據(jù)不同的編碼方式來定。視頻緩存?zhèn)鬏敂?shù)據(jù)緩存?zhèn)鬏數(shù)姆椒ǎ臼腔贘ni的一個傳參和調(diào)用方法。本系統(tǒng)由于服務(wù)器選用的是Java,加上客戶端也是基于Java的Android平臺,因此選用的方式就是在Java層進行Buffer緩存的實例化,將其引用傳入C語言層,再將其填充,填充完成過后,再由另外一個線程將其傳輸?shù)椒?wù)器。這里對Jni的機制進行簡單講解,Jni(JavaNativeInterface)其主要功能是進行Java和C/C++進行通訊。實際上,Jni是JVM中實現(xiàn)的一個部分,由此native語言(C/C++)都對應(yīng)的運行在JVM宿主環(huán)境中(HostEnvironment)。也是這種方式加上Jni是一個雙向接口,使得開發(fā)者不僅可以在Java中通過Jni訪問Native代碼,也可以在Native中嵌入一個對應(yīng)的JVM實現(xiàn)在Native代碼中對Java代碼的訪問。也正是通過這種方式,彌補了一些時候Java開發(fā)中一些缺陷。例如你希望你提高默寫關(guān)鍵的模塊代碼的效率的時候,你就可以通過C/C++等Native語言來進行相關(guān)程序庫的開發(fā)。當然是用Jni的時候,也有其相應(yīng)的缺點:因為要使用Native模塊的代碼,因此Java會失去原來的跨平臺性和其安全性等等的特性。除此之外,Jni的應(yīng)用中,Native代碼和Java代碼都是運行在同一宿主的進程空間內(nèi),如果是跨進程或者是宿主機之間的通訊,就只能考慮采用socket、IPC或者是WebService等通訊機制來進行實現(xiàn)。其具體的數(shù)據(jù)傳輸方式如下結(jié)構(gòu)圖所示:圖SEQ圖\*ARABIC12視頻數(shù)據(jù)傳輸結(jié)構(gòu)圖在數(shù)據(jù)從C語言層里面獲取的時候,傳輸?shù)絁ava層,這里也有相應(yīng)的數(shù)據(jù)對應(yīng)關(guān)系,畢竟這兩個語言所用的基本數(shù)據(jù)單位還是有一定的差別。下面就對C和Java的基本數(shù)據(jù)對應(yīng)列出了大致的表格:表格SEQ表格\*ARABIC2Java和C的數(shù)據(jù)對應(yīng)表Java類型本地類型(JNI)本地類型(C)描述BooleanJbooleanUnsignedchar無符號8個字節(jié)ByteJbyteSignedchar有符號8個字節(jié)CharJcharUnsignedshort無符號16個字節(jié)ShortJshortShort有符號16個字節(jié)IntJintLong有符號32個字節(jié)LongJlong_int64有符號64個字節(jié)FloatJfloatFloat32個字節(jié)DoubleJdoubleDouble64個字節(jié)ObjectJobject_jobject自定義結(jié)構(gòu)VoidVoidVoidN/A在JNI的調(diào)用時,往往還會使用到Jni的簽名,其實就是對應(yīng)的數(shù)據(jù)類型,通常在函數(shù)調(diào)用的時候會用到。下面是所有Jni中的變量標簽:表格SEQ表格\*ARABIC3Jni變量標簽類型相應(yīng)的簽名BooleanZByteBCharCShortSIntILongLFloatFDoubleDVoidVObjectL用/分割包的完整類型名;Ljava/lang/stringArray[簽名[I[Ljava/lang/object;Method(參數(shù)1類型簽名參數(shù)2類型簽名…)返回值類型簽名服務(wù)器傳輸技術(shù)實現(xiàn)方法本系統(tǒng)的服務(wù)器部分并沒有多么大量的代碼,也只是簡單的對socket套接字進行運用,對客戶端進行監(jiān)聽,以及對數(shù)據(jù)進行同步傳輸。在上一章已經(jīng)對此模塊的大體框架進行了一個大致的描述。其中有幾個較為重要的實現(xiàn)方法,下面就對其進行詳細的介紹??蛻舳藬?shù)據(jù)監(jiān)聽使用Java進行服務(wù)器編程,稍微要容易一些,畢竟很多東西都進行了封裝。Java進行客戶端的數(shù)據(jù)監(jiān)聽,主要是在服務(wù)器端新建一個serversocket套接字。進行阻塞監(jiān)聽。Socket和serversocket類都是位于J包中,serversocket位于服務(wù)器端,socket是在客戶端和服務(wù)器端進行連接時兩邊都會產(chǎn)生的一個實例。服務(wù)器或者客戶端都可以通過對這個socke實例進行對這個網(wǎng)絡(luò)連接進行操作。對于這個套接字而言,客戶端和服務(wù)器端都是平等的,沒有什么差別。不管是Socket或者ServerSocket它們的實現(xiàn)方式都是通過SocketImpl類及其子類完成的。服務(wù)器要實現(xiàn)監(jiān)聽,在新建serversocket套接字以后,要給它進行實例化,其中要分配一個固定端口進行監(jiān)聽。這里要注意不要使用一些常用的接口,這些接口很容易被占用,導(dǎo)致程序無法運行。監(jiān)聽方法主要的是accept方法,當調(diào)用此方法是,就會在這里產(chǎn)生阻塞,直到有一個客戶端進行連接,返回一個實例化的socket套接字。因此在服務(wù)器進行編程的時候,在產(chǎn)生一個實例化的socket套接字過后,應(yīng)新建一個進程對這個套接字進行處理,而主程序繼續(xù)監(jiān)聽后面即將到來的客戶端連接。由于大多數(shù)的服務(wù)器基本上都是不斷地監(jiān)聽或者處理數(shù)據(jù),因此多線程的處理也顯得較為重要。數(shù)據(jù)傳輸和緩存處理這里的實現(xiàn)方法,就是.socket繼承與java.lang.object的幾個使用最頻繁的兩個函數(shù),以及基本的多線程之間同步的實現(xiàn)方法。數(shù)據(jù)的獲取和傳輸使用的是getinputstream和getoutputstream方法,使用這兩個方法都會得到一個對應(yīng)的inputstream對象實例或者outputstream對象實例。這里使用的是getinputstream獲得PC端傳輸過來的視頻數(shù)據(jù),這里需要強調(diào)的是,getinputstream函數(shù)是一個阻塞函數(shù),當沒有數(shù)據(jù)來臨時,它就會產(chǎn)生阻塞,一直等待數(shù)據(jù)來臨。這也是socket實現(xiàn)長連接的一個重要特性。而getoutputstream并不是一個阻塞函數(shù),當輸出客戶端連接時,數(shù)據(jù)存在它就會將數(shù)據(jù)發(fā)送到客戶端。同樣這兩個函數(shù)也會產(chǎn)生一個ioexception,要必須對其進行捕捉。兩個客戶端連接過后,都會新建兩個線程分別對其進行控制,而這兩個線程都是要對同一個數(shù)據(jù)Buffer進行操作,這就涉及到多線程對于同一資源的互斥訪問。本系統(tǒng)使用的是同步鎖synchronized。在使用同步鎖時,要加上對應(yīng)的訪問控制對象,否則不能實現(xiàn)你想要的同步控制方法。本系統(tǒng)在讀線程中由于getinputstream是阻塞函數(shù),在這個函數(shù)后面進行寫完成的等待,以防寫進程還沒有完成,又進行下一幀的讀取。當然這樣也有可能造成掉幀的情況,不過在獲取數(shù)據(jù)的時候有40毫秒的延遲,一般還是足夠。在寫進程的開始進行等待,當讀進程讀取數(shù)據(jù)完成后,釋放寫進程的等待。寫進程開始工作,完成過后釋放度進程的等待。這也是較為基本的同步實現(xiàn)方法,在此就不給流程圖了。移動終端視頻處理技術(shù)實現(xiàn)方法數(shù)據(jù)接收和存儲數(shù)據(jù)的接受也相對比較簡單,由于前面對socket套接字進行過介紹,這里就描述一些客戶端的socket應(yīng)用??蛻舳艘惨陆ㄒ粋€socket套接字,并對其進行實例化,在實例化的時候,要和你對應(yīng)的服務(wù)器本地的IP地址和服務(wù)器監(jiān)聽的接口進行對應(yīng),否則會產(chǎn)生runtimeException的異常。在移動終端客戶端也進行了數(shù)據(jù)的本地存儲,在接受到服務(wù)器傳輸?shù)臄?shù)據(jù)后,傳輸?shù)綌?shù)據(jù)Buffer中,同時也輸出到本地文件夾中。但由于每次啟動都會對新建一個文件夾,因此只能保持一次的視頻通訊數(shù)據(jù)。視頻數(shù)據(jù)傳輸?shù)絁ava層,再通過本地動態(tài)庫的調(diào)用,在對應(yīng)的FFmpeg里面進行解碼。其運用的方式和上面的一致,也是通過Jni,在此不再贅述。視頻數(shù)據(jù)解碼這一模塊和上述PC端的視頻數(shù)據(jù)解碼的方式差距不大,也是使用的FFmpeg進行的解碼,僅僅是運行的平臺不一樣,但實現(xiàn)的方式幾乎一致。這里是通過接收到的buffer數(shù)據(jù)里的H264數(shù)據(jù)包使用avcodec_dencode_video2()函數(shù)進行解碼,解碼后的數(shù)據(jù)傳送給顯示控件進行顯示。這里需要說明一點,PC端的視頻顯示是基于SDL,而Android移動終端上的視頻顯示是在Android對應(yīng)的surfaceView的控件上進行顯示的。界面設(shè)計及視頻播放移動終端的界面設(shè)計在此進行了簡化,處理一個連接使用的端口地址輸入框,就是一個視屏顯示窗口,以及對應(yīng)的信息顯示窗口。這里使用的不是傳統(tǒng)的mediaplayer,而是surfaceView,這個控件相對于前一個來說有更大的自主性。Mediaplayer控件的使用基本上都是前篇一律,沒有什么可以自己操控的空間,限制比較大。而surfaceView不同,surfaceView空間的使用是和SurfaceHolder配合進行操作,可以實現(xiàn)自己想要的一些特殊的效果。Surfaceview意思就我們可以自己繪制的一塊view,當然這只是我自己的一個見解,當然就是們想要的什么畫面,通過內(nèi)存或者硬件將這塊圖形數(shù)據(jù)繪制到屏幕上,而這個surfaceview正好就是這個畫布。Surfaceview是對應(yīng)有內(nèi)存區(qū)域的,有內(nèi)存區(qū)域就自然有生命周期,可以動態(tài)的申請和銷毀,也就有了我們對于surfaceview的一個基本操作:surfaceCreated/Changed/Destroyed,這三個操作加在一起就是callback函數(shù),也就是回調(diào)函數(shù)。而每當我們創(chuàng)建一個surfaceview的時候,都需要一個SurfaceHolder來進行控制,可以調(diào)用getholder來得到這個holder。大多數(shù)使用surfaceview時都會創(chuàng)建兩個線程,一個是UI線程,一個是負責繪圖的線程。這個模型的好處就是畫圖線程不會依賴于UI線程,不會對UI線程進行阻塞,而是單純的依賴UI繪圖線程,對于本系統(tǒng)這種實時更新數(shù)據(jù)來顯示的情況來說,這種方式更為合理,當然由于本系統(tǒng)的UI界面本來就不復(fù)雜,也不太考慮阻塞的問題。下面是surfaceView實現(xiàn)視頻播放的一個結(jié)構(gòu)框架圖:圖SEQ圖\*ARABIC13surfaceview結(jié)構(gòu)框圖本章小結(jié)本章是全文的重點,對所有核心的技術(shù)進行了一個較為全面的講解和說明。其中對SDL顯示進行了大致的講解,對服務(wù)器的搭建和數(shù)據(jù)同步傳輸進行簡單的介紹,其重點還是對FFmpeg編解碼一塊進行了深入的講解和解析。相對而言,在移動終端的介紹上就沒有那么詳細,移動終端的實現(xiàn)方式基本和PC端差距不大,存在的區(qū)別就是顯示方式,和FFmpeg的環(huán)境平臺搭建而已。特殊問題及解決方法這一章介紹了一些本系統(tǒng)在編寫中遇見的一些較為關(guān)鍵性的問題,解決的方法有些或許就是一些小小的設(shè)置問題,當然還有些未完全解決的問題,在此列出,方便讀者遇到后好對應(yīng)嘗試、解決。動態(tài)庫運用問題動態(tài)庫運行問題,其一,當你寫好程序,生成動態(tài)庫后,Java程序無法調(diào)用,找不到對應(yīng)的動態(tài)庫。解決方案:更改系統(tǒng)環(huán)境變量,將動態(tài)庫的路徑添加到系統(tǒng)環(huán)境變量中,再重啟eclipse。其中注意,在你的Java程序在使用動態(tài)庫的時候,其他的程序不能占用此動態(tài)庫。問題二,你生成的不是有效的win32程序。 解決方案:一看這個問題你貌似就知道了是環(huán)境位數(shù)問題,但是這里的位數(shù)全部都要調(diào)成統(tǒng)一的,很有可能你就遺漏了一個小點。需要統(tǒng)一的環(huán)境有,系統(tǒng)環(huán)境,vs環(huán)境(即使是64位的電腦上,默認的也是win32平臺),jdk環(huán)境,你引用的三方庫環(huán)境,eclipse環(huán)境。C與Java數(shù)據(jù)通信問題C與Java的通訊問題,主要是對Java和C的基本數(shù)據(jù)的理解,要正確理解對應(yīng)的數(shù)據(jù),才能夠通過Jni正確的傳送參數(shù)。這里常常遇到的問題就是數(shù)據(jù)傳輸不正確。解決方法:更具上面給的數(shù)據(jù)對應(yīng)圖,以及Jni對應(yīng)的變量標簽列表進行函數(shù)調(diào)用和數(shù)據(jù)傳參,根據(jù)里面的數(shù)據(jù)對應(yīng)進行相應(yīng)的數(shù)據(jù)傳輸。其次就是理解Java里面的類和對象關(guān)系,引用和域的意義。由于Java里面沒有指針,而C里面有,所以在使用時一定要弄清楚這些基本概念。數(shù)據(jù)傳輸同步問題這里主要對Java的幾種流式傳輸方式進行一個簡介,因為在系統(tǒng)編寫過程中遇到的很多數(shù)據(jù)傳輸正確性的問題,和同步處理不當?shù)膯栴}都與這有關(guān)。下面就對Java中主要的流式操作和相關(guān)的IO操作類進行簡介:File(文件特征和管理):用于文件或目錄的描述信息??梢赃M行修改文件,增刪文件,判斷路徑等等操作。Inputstream(二進制格式操作):基于字節(jié)流的輸入操作,幾乎其他的輸入字節(jié)流操作都是繼承這個類,此抽象類定義了所有的輸入流具有的共同特征。Outputstream(二進制格式操作):基于字節(jié)流的輸出操作,幾乎其他的輸出字節(jié)流操作都是繼承這個類,此抽象類定義了所有的輸出流具有的共同特征。Reader(文件格式操作):基于字符的輸入操作,是個抽象類。Writer(文件格式操作):基于字符的輸出操作,是個抽象類。RandomAccessFile(隨機文件操作):可以對文件進行任意位置的隨機存儲操作,功能豐富。以下就關(guān)于這幾個主要IO操作的一個關(guān)系圖:圖SEQ圖\*ARABIC14IO操作類關(guān)系圖編碼幀頻和參數(shù)設(shè)置問題編碼幀頻問題是一個很復(fù)雜的問題,雖然說使用采集的定時延遲可以大致控制視頻幀頻數(shù),在進行轉(zhuǎn)碼的時候,根據(jù)你采集時的延遲給定固定幀頻。不僅如此,在進行編碼的時候還許多參數(shù)進行設(shè)置這里包含了幾乎你編碼想要使用的所有參數(shù)方式。下圖就是一些有關(guān)編解碼時AVCodecContext結(jié)構(gòu)體中一些常見參數(shù)的含義:表格SEQ表格\*ARABIC4編解碼AVCodecContext參數(shù)變量含義enumAVMediaTypecodec_type編解碼器的類型structAVCodec*codec采用的解碼器AVCodecintbit_rate平均比特率,就是碼率uint8_t*extradata針對特定編碼器包含的附加信息intextradata_size針對特定編碼器包含的附加信息AVRationaltime_base可以把PTS轉(zhuǎn)化成實際的時間(秒)intwidth,height視頻數(shù)據(jù),代表寬高Intrefs運動估計參考幀的個數(shù)intsample_rate采樣率(針對音頻)intchannels聲道數(shù)(針對音頻)enumAVSampleFormatsample_fmt采樣格式intprofile型intlevel級(和profile有些相似)本章小結(jié)本章主要是針對一些較為常見的問題,或者說筆者認為有必要提出的較為重要的一些問題進行了一些講解,當然沒有說出具體的方法,只是給了一些解決的參考資

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論