田六方 徐州電視臺
在LED大屏播放零散節(jié)目的過程中,常常會在節(jié)目與節(jié)目切換時出現(xiàn)短暫的黑屏,這是由于解碼器解碼不連續(xù)引起的[1]。特別是在進行廣告插播時,節(jié)目的不斷切換,產(chǎn)生不斷的黑屏和閃爍,將嚴(yán)重影響LED大屏的視覺效果?;谶@種情況,就要對零散的節(jié)目流進行無縫拼接,其順序應(yīng)滿足當(dāng)天播放序列的要求。電視節(jié)目的拼接[2]技術(shù)是指從某一路電視信號源瞬間切換到另一路電視信號源,在電視屏幕上表現(xiàn)為一個畫面迅速轉(zhuǎn)換到另一個畫面,無黑場、無抖動、無停頓的連續(xù)過程。
自從多媒體問世以來,多媒體的開發(fā)工具也應(yīng)運而生。DirectShow 技術(shù)是微軟公司開發(fā)的一套編程接口,架構(gòu)在DirectX 等其他的一些多媒體服務(wù)的基礎(chǔ)上[3]。DirectShow作為高效的多媒體開發(fā)系統(tǒng),其底層的硬件設(shè)備與高層的應(yīng)用程序互相影響、作用,圖1是DirectShow系統(tǒng)的框圖[4]。
圖1 Direct Show系統(tǒng)框圖
Direct Show使用Filter Graph模型來管理整個數(shù)據(jù)流的處理過程。Filter Graph中包含了各種Filter,各個Filter在Filter Graph Manager的統(tǒng)一控制下,按一定順序連接在一起,從而使數(shù)據(jù)在由Filter組成的鏈表中流動[5],圖1中的箭頭表示Filter鏈表中的數(shù)據(jù)流的方向。在Direct Show系統(tǒng)框架外,是與用戶直接交互的應(yīng)用程序。應(yīng)用程序要按照一定的功能建立起相應(yīng)的Filter Graph,然后通過Filter Graph Manager來控制系統(tǒng)的數(shù)據(jù)處理過程。DirectShow能在Filter Graph運行時接收到各種事件,并通過消息的方式發(fā)送給應(yīng)用程序。這樣,就實現(xiàn)了應(yīng)用程序與DirectShow系統(tǒng)之間的交互[6]。
為了統(tǒng)一對靜態(tài)圖片和視頻圖片進行相同的處理,針對播放的FilterGraph進行了統(tǒng)一封裝,為此定義了如圖2的類繼承關(guān)系。
CPlayItem類為系統(tǒng)中播放單元的基礎(chǔ)類,主要內(nèi)容包括構(gòu)建FilterGraph的虛函數(shù)InitGraph()和播放虛函數(shù)PlayIt();這些虛函數(shù)必須在繼承類中進行實現(xiàn)。其主要結(jié)構(gòu)如表1所示:
圖2 播放對象各類之間的繼承關(guān)系
表 1 CPlayItem 成員
其中InitGraph()函數(shù)在程序加載播放序列時根據(jù)播放文件類型構(gòu)建相應(yīng)的FilterGraph;PlayIt()在合適的適合播放本對象,并根據(jù)字幕信息和播放時間控制來確定文件的起播點和播放長度。SetPositions()函數(shù)設(shè)置該FilterGraph的播放控制。
CPlayPic實現(xiàn)播放靜態(tài)圖片時的行為,包括渲染字幕和時長控制等。由于播放靜態(tài)圖片不需要創(chuàng)建Filter Graph,所以其初始化函數(shù)僅僅只需直接返回即可,CPlayPic:InitGraph() 實現(xiàn)見表 2。
表 2 CPlayPic:InitGraph() 實現(xiàn)
在播放靜態(tài)圖片時,由于需要動態(tài)顯示字幕和時鐘等隨時間改變的圖像元素,所以其播放過程被實現(xiàn)為一個線程,CPlayPic:PlayIt()實現(xiàn)見表 3。
表 3 CPlayPic:PlayIt()實現(xiàn)
在線程InitialThreadProc_Play中的每一個循環(huán)均按順序做如下過程,播放靜態(tài)圖片的一個循環(huán)動作見表4。
表4 播放靜態(tài)圖片的一個循環(huán)動作
CPlayAVI實現(xiàn)對視頻片段的FilterGraph的構(gòu)建和播放過程的控制。為此,該類中添加了一系列處理FilterGraph的類成員,如表5所示。
表5 CPlayAVI中與視頻播放相關(guān)的類成員
其中初始化FilterGraph的過程中加入攔截解碼后圖片數(shù)據(jù)流的Filter,目的是對視頻中的每一幀圖片進行處理,包括添加字幕和時鐘等。其中CPlayAVI:InitGraph()的實現(xiàn)基本如表 6 所示。
表 6 CPlayAVI:InitGraph()的創(chuàng)建 FilterGraph 主要流程
Graph在播放的過程中,每幀圖像在解碼完畢后,都會調(diào)用CSampleGrabberCB_TXT類的BufferCB(double SampleTime, BYTE ? pBuffer, long BufferSize )函數(shù),在此函數(shù)內(nèi),進行類似表4的相同過程。
為了實現(xiàn)各節(jié)目片段之間的無縫連接,程序在初始化節(jié)目單時,將節(jié)目單中的所有播放文件按照播放順序創(chuàng)建播放列表,表7是加載節(jié)目單時創(chuàng)建播放列表代碼片段。
表7 加載節(jié)目單時創(chuàng)建播放列表
當(dāng)一個節(jié)目對象播放完畢時,主線程會收到一個事件,此時立刻進行下一個播放對象的播放。由于此對象的Graph已經(jīng)在初始化時渲染就位,所以播放圖像立刻出現(xiàn)在屏幕上,不會出現(xiàn)黑屏的現(xiàn)象。播放下一個對象的事件相應(yīng)如表8所示。
LRESULT CPlayVedioDlg:OnGNotify(WPARAM w,LPARAM iScreenID){int ino =GetNextMedia(iScreenID); //下一個要播放
的播放對象序號saPalylist[ino]->PlayIt(); //播放下一個對象}
本系統(tǒng)采用VC++語言,在DirectShow框架基礎(chǔ)上進行開發(fā)。使用多線程進行各個節(jié)目片段的緩沖播放,實現(xiàn)了各相鄰節(jié)目片段之間的無縫播放。本系統(tǒng)的主要目的是為了方便多個LED大屏的節(jié)目在組織管理時的靈活性。目前該系統(tǒng)已在鎮(zhèn)江廣電的多個大屏上使用,效果良好,播放順暢。能夠?qū)崿F(xiàn)每個節(jié)目、臺標(biāo)、時鐘和字母的自由組合,如圖3所示,基本達到了設(shè)計目標(biāo)。
圖3 本系統(tǒng)實現(xiàn)了臺標(biāo)(左上)、字幕和時鐘(右上)的自由組合
1.譚建國, 張文軍. 數(shù)字HDTVTS流無縫拼接技術(shù)研究 [J]. 通信學(xué)報 ,2004,25(5):119-124.
2. 郭淑艷. 數(shù)字電視TS流實時低延遲無縫拼接技術(shù)的研究與實現(xiàn)[D]. 廣東: 華南師范大學(xué). 2007.
3. 趙炯, 陳力. 利用VC++實現(xiàn)基于DirectShow的視頻播放器開發(fā)[J]. 成都大學(xué)學(xué)報(自然科學(xué)版 ),2011,30(4):349-352.
4. 孟月華, 鄧基. Direct Show技術(shù)的應(yīng)用研究與開發(fā)[J]. 計算機系統(tǒng)應(yīng)用 , 2013,22(6):196-199.
5.謝屈波,王六森,夏定純. 基于Direct Show的圖像采集的實現(xiàn)[J].軟件導(dǎo)刊,2010,9(6):183-184.
6. 郭昊. 基于DirectShow技術(shù)實現(xiàn)視頻采集[J]. 火控雷達技術(shù) , 2008, 37(2):97-100.