利用VC++實(shí)現(xiàn)局域網(wǎng)實(shí)時(shí)視頻傳輸

字號(hào):

摘要 本文針對(duì)不同的局域網(wǎng),提出一種通用的實(shí)時(shí)視頻傳輸?shù)慕鉀Q方案。在使用Divx編解碼的基礎(chǔ)上,提出了從壓縮、組幀、發(fā)送到接收、解壓整個(gè)流程的思想,具體實(shí)施方案和VC++實(shí)現(xiàn)核心源代碼以及傳輸控制策略,有效地保證了高質(zhì)量的實(shí)時(shí)視頻傳輸。
    關(guān)鍵詞 客戶/服務(wù)器;實(shí)時(shí)視頻傳輸;Divx
    引言
    在局域網(wǎng)內(nèi)部實(shí)時(shí)傳輸視頻已經(jīng)得到廣泛應(yīng)用?,F(xiàn)在用以傳輸視頻的局域網(wǎng)大多數(shù)是有線局域網(wǎng),因?yàn)橛芯€局域網(wǎng)技術(shù)成熟,傳輸速度快,穩(wěn)定性好。但是視頻數(shù)據(jù)量大,有線網(wǎng)絡(luò)也會(huì)出現(xiàn)工作不穩(wěn)定,引起數(shù)據(jù)堵塞,時(shí)間久了會(huì)導(dǎo)致嚴(yán)重的延遲現(xiàn)象;如果工作的環(huán)境不固定,要求移動(dòng)性,那么就要采用無線網(wǎng)絡(luò),如今無線網(wǎng)卡的工作隨環(huán)境的變化而變得不穩(wěn)定,這樣會(huì)導(dǎo)致視頻傳輸?shù)馁|(zhì)量大幅度下降,容易引起畫面的重影、抖動(dòng)、花屏等現(xiàn)象。本文針對(duì)不同的局域網(wǎng),提出一種通用的實(shí)時(shí)視頻傳輸?shù)慕鉀Q方案,使用VC++自封裝的Windows VFW SDK軟件開發(fā)包進(jìn)行二次開發(fā),通過Divx編解碼,按照制定的傳輸策略,能夠有效地解決由于網(wǎng)絡(luò)的局部不穩(wěn)定導(dǎo)致的視頻圖像重影、抖動(dòng)、花屏等的問題。
    局域網(wǎng)中實(shí)時(shí)視頻傳輸存在的問題
    為了在局域網(wǎng)上有效的、高質(zhì)量的傳輸視頻流,需要多種技術(shù)的支持,包括視頻的壓縮、編碼技術(shù),應(yīng)用層質(zhì)量控制技術(shù)等等。
    網(wǎng)絡(luò)的帶寬是有限的,所以需要壓縮傳輸視頻圖像,MPEG-4被廣泛的應(yīng)用于網(wǎng)絡(luò)環(huán)境下的實(shí)時(shí)視頻傳輸,因?yàn)镸PEG-4具有:可以達(dá)到很高的壓縮比;具有靈活的編碼和解碼復(fù)雜性;基于對(duì)象的編碼方式,允許視頻、音頻對(duì)象的交互;具有很強(qiáng)的容錯(cuò)能力等優(yōu)點(diǎn)。本文采用Divx編解碼器對(duì)視頻進(jìn)行編碼、壓縮,實(shí)際上Divx=(視頻)MPEG-4+(音頻)MP3。
    應(yīng)用層質(zhì)量控制技術(shù)現(xiàn)在采用的是RTP/RTCP協(xié)議,以確保視頻流在網(wǎng)絡(luò)中低時(shí)延、高質(zhì)量地傳輸。RTP數(shù)據(jù)傳輸協(xié)議負(fù)責(zé)音視頻數(shù)據(jù)的流化和負(fù)載,RTCP負(fù)責(zé)RTP數(shù)據(jù)報(bào)文的傳輸控制。此協(xié)議是通過客戶端(接收方)反饋網(wǎng)絡(luò)的狀況,服務(wù)器端(發(fā)送方)來調(diào)整信息采集、發(fā)送的速度和壓縮率。但是,對(duì)于圖像采集速度固定,需要軟件進(jìn)行壓縮、解壓,調(diào)整采集的速度會(huì)引起采集的數(shù)據(jù)來不及壓縮而直接丟棄,調(diào)整編碼器的壓縮率需要重新設(shè)置編碼器的參數(shù),重啟編碼器,相應(yīng)的解碼器也要調(diào)整,這個(gè)過程中需要很長(zhǎng)的時(shí)間,達(dá)不到實(shí)時(shí)的要求。所以本文沒有采用RTP/RTCP協(xié)議,而是從發(fā)送端出發(fā),實(shí)時(shí)判斷網(wǎng)絡(luò)狀況,采用“停等”策略進(jìn)行實(shí)時(shí)傳輸。
    網(wǎng)絡(luò)通信有兩種協(xié)議TCP和UDP,UDP更適合于網(wǎng)絡(luò)環(huán)境下的視頻傳輸,但是它不提供檢錯(cuò)和糾錯(cuò)功能,一旦網(wǎng)絡(luò)出現(xiàn)堵塞時(shí),大量的數(shù)據(jù)報(bào)文會(huì)丟失。對(duì)于Divx編解碼技術(shù),是以幀為單位進(jìn)行編解碼的,分為關(guān)鍵幀和非關(guān)鍵幀。在傳輸過程中,由于壓縮率比較高,只要一幀中錯(cuò)一比特位,將影響其它幾百甚至幾千的比特位,直接造成圖像的模糊、花屏等現(xiàn)象。只有等到下一次關(guān)鍵幀的到來才有可能恢復(fù)圖像的清晰。為了保證傳輸?shù)恼_性,自己需要在應(yīng)用層制定協(xié)議。如此一來,UDP的優(yōu)勢(shì)蕩然無存。所以本文選擇使用TCP來進(jìn)行網(wǎng)絡(luò)通信。綜合使用VFW技術(shù)、流媒體技術(shù),輔助以“停等”控制策略,較好的解決局域網(wǎng)中實(shí)時(shí)視頻傳輸容易引起的重影、抖動(dòng)、花屏的問題。
    實(shí)時(shí)視頻傳輸實(shí)現(xiàn)
    為了達(dá)到視頻傳輸?shù)膶?shí)時(shí)性,總的思想是最少的發(fā)送冗余信息,程度上發(fā)送最新的視頻。
    局域網(wǎng)實(shí)時(shí)視頻傳輸采用服務(wù)器/客戶機(jī)模式,利用VC++實(shí)現(xiàn)。其工作流程如圖1所示。
    圖1 實(shí)時(shí)視頻傳輸工作流程
    視頻采集采用AVICap從視頻采集卡捕獲視頻圖像,得到的是位圖型式的視頻幀,然后用Divx編碼器進(jìn)行壓縮,通過Winsock實(shí)現(xiàn)壓縮后的視頻數(shù)據(jù)在局域網(wǎng)中的實(shí)時(shí)傳輸,接收完的數(shù)據(jù)交給Divx解碼器解壓,最后實(shí)現(xiàn)視頻顯示。
    在VC++中,采用VFW技術(shù),客戶端通過capSetCallbackOnFrame()注冊(cè)回調(diào)函數(shù),當(dāng)采集卡采集到一幅圖像后,系統(tǒng)就會(huì)自動(dòng)調(diào)用回調(diào)函數(shù),然后再回調(diào)函數(shù)中使用ICSeqCompressFrame()函數(shù)進(jìn)行壓縮。然后再通過Winsock將壓縮后的數(shù)據(jù)發(fā)送到服務(wù)器端。服務(wù)器端接收完一幀以后,交給ICDecompress()解壓,最后用SetDIBitsToDevice()將圖像顯示出來。
    1、視頻幀的組建
    視頻采集的數(shù)據(jù)是位圖型式的視頻幀,Divx編碼器壓縮以后形成以幀為格式的Mpeg4流。Divx解碼器也是以幀的格式解壓。所以提出以幀為單位發(fā)送視頻數(shù)據(jù)流。為了在接收端能夠方便地提取出一幀,提出如圖2所示的格式組建幀。
    幀開始標(biāo)志
    幀大小
    幀編號(hào)
    幀類型
    幀數(shù)據(jù)
    圖2 視頻幀格式
    完整的一幀由5個(gè)字段組成,各個(gè)字段的意義如下:幀開始標(biāo)志,標(biāo)志著一幀地開始,占用4個(gè)字節(jié)的空間。不妨設(shè)為0xffffffff。幀大小,表示整個(gè)幀的大小,包括5個(gè)字段的大小,占用4個(gè)字節(jié)的空間。幀編號(hào),表示幀的順序編號(hào),占用4個(gè)字節(jié)的空間。幀類型,標(biāo)志此幀是否是關(guān)鍵幀,占用1個(gè)字節(jié)的空間。幀數(shù)據(jù),存放壓縮后一幀的完整數(shù)據(jù)