引言
1994年歐洲制定的數字視頻廣播(DVB)標準和1996年美國聯邦通信委員會(FCC)的先進電視制式委員會(ATSC)地面廣播電視標準,在視頻部分都采用了MPEG-2 標準。我國的CATV 數字網,也采用DVB 標準。MPEG-2 標準的出現,大大推動了數字視頻業務的發展。越來越多的節目交換是以MPEG-2壓縮方式進行的,使演播室制作涉及大量對MPEG編碼壓縮節目的處理,如非線性編輯涉及的不同節目間的切換、剪切和串編、在畫面上加字幕、臺標、實現淡入淡出等。其中節目剪切和串編是實現其他編輯功能的基礎,因此實現節目剪切和串編功能更加重要。
本文針對MPEG-2 音視頻,采用DirectShow(微軟公司提供的在Windows 平臺上進行流媒體處理的開發包)的DirectShow編輯業務(DES,DirectShow Editing Services)來實現MPEG-2音視頻節目的剪切和串編。DES作為DirectShow的增強應用,簡化了原本煩瑣的視頻編輯,彌補了非線性編輯應用軟件的空白,可方便地進行音視頻編輯,因此用它來編輯MPEG-2音視頻文件不失為一個行之有效的方法。
DES 簡介
時間線模型
DES的內部結構模型,是一個基于時間線(Timeline)的模型,它提出了一個時間線和軌道的概念,將所有的多媒體編輯組織到一個虛擬的時間線之上,實際上代表了最終的音視頻剪輯作品。而對于程序員來說,這些時間線和軌道同一般的通信(COM)接口一樣,都是一個個的純虛類,可以通過繼承、派生和添加必要的函數,來實現編輯操作。圖1給出了DES的時間線內部模型。
這是一個樹形結構,在這棵樹中,音視頻文件是葉結點,稱作為媒體源(Source);一個或多個Source組成一個軌道(Track),每個Track都有統一的媒體格式輸出;Track的集合Express總線回傳給CPU。CPU或者將數據通過PCI總線傳輸給I/O板卡轉換成基帶信號輸出,或者再回送到軟件編解碼器編碼成DV格式的數據并通過1394總線輸出。
相對于基于專門硬件的非編系統,基于CPU+GPU軟件架構的非編系統完全擺脫了對硬件板卡的依賴,突破了專用硬 件結構的局限,利用通用的硬件系統資源實現了高性能的視頻編輯和處理。
在性能方面,目前基于CPU+GPU的主流非編系統已經可以輕松實現4~6層三維特技的實時輸出,遠遠超越了目前基 于專用板卡的主流非編系統。
在可擴展性方面,由于系統完全采取軟件架構,一方面通過提高計算機平臺的配置來獲得更高的硬件性能,從而直接提高非編系統的性能;另一方面,通過軟件模塊的添加和升級,可以支持更多的編輯格式、獲得更多的特技效果。
在穩定性方面,由于拋棄了專用的硬件板卡,改用結構簡單的I/O板卡實現基帶信號輸出,系統故障率、功耗、發熱量等都大大下降,穩定性則大大提高。通過進一步優化系統硬件結構,選用設計更成熟和安全的品牌圖形工作站,同時將I/O板卡作進一步的模塊拆分,將模擬處理電路從板卡中拆分出來作為一個獨立供電、獨立散熱的接口盒,可使非編系統實現工作站和服務器級的安全性和穩定性,從而大大降低維護成本,提高設備利用率。
在成本方面,目前基于CPU+GPU的非編系統,其缺點主要是對計算機系統的配置要求高,計算機平臺上的成本投入高昂,但由于沒有專用板卡上的成本投入,總體成本并沒有增加。由于計算機技術快速發展和性價比不斷提高,基于CPU+GPU的非編系統在性能不斷提高的同時總體成本呈下降趨勢。
稱作為集合(Composition),每個Composition可以對其所有的Composition 或Track 進行各種復雜的編輯;頂級的Composition或Track就組成了組(Group);每個Group輸出單一格式的媒體流,所有的Group組成一個時間線(Timeline),Timeline表示一個視頻編輯的項目,它是這棵樹的根節點。一個Timeline項目必須至少包含一個Group,最典型的情況一般包含兩個Group: 音頻組(Audio Group)和視頻組(VideoGroup)。
圖2所示的是一個典型的基于時間線的媒體軌道圖,箭頭方向即是時間線的方向。這個時間線由兩個組組成,每個組中包含兩個媒體源軌道(SourceTrack)。在視頻組中,軌道是有優先級的(軌道0具有最低的優先級,依次類推)。運行時,總是輸出高優先級的軌道中的媒體源內容。如果此時高優先級的軌道中沒有媒體源輸出,則讓低優先級的軌道中的媒體源輸出。如圖1中視頻組的輸出順序為媒體源A→媒體源C→媒體源B。而對于音頻組,它的所有軌道的輸出只是簡單的合成。我們利用時間線的這一原理,將媒體素材挨個賦予到相應的媒體源上去,隨后將媒體源組織到不同優先級 別的軌道上,最終在時間線模型的組織下輸出我們所需要的合成節目。這也就是MPEG-2 音視頻編輯功能的核心模型。
時間概念
DES中大致有3種時間:
(1) 時間線時間(Timeline Time):相對于整個時間線項目的時間;
(2) 媒體時間(Media Time):相對于媒體源的時間,比如媒體源是一個文件,那么媒體時間實際上是指相對于文件開頭的位置時間;
(3) 父對象時間(Parent Time):相對于時間線中已編排的某個對象的時間。
設計方案
設計方案如下:首先要完成播放MPEG-2音視頻文件的功能,在瀏覽的過程中對需要的音視頻片斷的編入點和編出點作標記。其次要完成可對編輯好的音視頻預覽的功能,如果編輯結果比較滿意,要將其保存到文件中。剪切時,僅需對播放中的文件設置入出點,按保存按鈕即可邊預覽邊保存;串編時,依次打開要編輯的文件,設置入出點,然后再按預覽或保存按鈕即可。
實現過程
用DirectShow實現播放功能非常方便。該功能模塊主要是由GetCurrentPosition()函數得到編入點和編出點的時間,為后面的編輯提供媒體起始時間。下面主要介紹用DES進行預覽和保存的實現方法。
時間線的構建
用DES實現剪輯后的預覽或保存功能首先必須構建時間線模型。首先調用了系統提供的一個虛接口(虛接口的含義是:該接口包含許多未被定義的函數方法,它只提供了一個面向應用層的接口)。這個虛接口,稱為IAMTimeline。我們要做的事情就是,遵循圖1中時間線的結構定義自己所需要的屬性和函數,并且建立出我們的時間線對象。最基本的屬性包括有圖1中所提到的組(Group),集合(Composition),軌道(Track)和媒體源(Source)。
(1) 首先創建一個時間線對象
IAMTimeline*pTL=NULL;
hr=CoCreatelnstance(CLSID_IAMTimeline,NULL,CLSCTX_INPROC_SERVER,IID IAMTimeline,(void* *)&pTL);
這時,我們面對的是一個空的時間線框架,接下來所作的是根據自己的需要為我們的“樹形”時間線結構填上“枝 葉”。
(2) 接下來使用接口方法IAMTimeline::CreateEmptyNode創建各種DES 對象。包括:IAMTimelineGroup(視頻組pVideoGroup,音頻組pAudioGroup)、IAMTimelineComp(視頻pVideoComp,音頻pAuioComp)、IAMTimelineTrack(視頻pVideoTrack,音頻pAuioTrack)、IAMTimelineSrc(視頻pVideoSrc,音頻pAuioSrc)。
以下示例均為視頻組代碼,音頻組與視頻組類似。
IAMTimelineGroup *pVideoGroup=NULL;
IAMTimelineObj *pVideoGroupObj=NULL;
pTL → CreateEmptyNode(&pVideoGroupObj,TIMELINE_MAJOR_TYPE_GROUP);
pGroupObj→Querylnterface(IID_IAMTimelineGroup,(void **)&pVideoGroup);
調用IAMTimeline::CreateEmptyNode成功后,我們可以得到一個IAMTimelineObj接口指針。也就是說,每個我們創造的DES對象上都實現了IAMTimelineObj接口。
(3) 接著在組中加入軌道
pVideoComp→VTracklnsBefore(pVideoTrackObj, -1);
pVideoTrackObj→Querylnterface(IID_IAMTimelineTrack,(void **)&pVideoTrack)。
(4) 這是最關鍵的一步,設置媒體源的剪切時間和其在時間線上的時間,然后將其放到相應的軌道上。串編情況下,筆者設計了一個類記錄該媒體源的文件名、片斷長度、編入點和編出點,并用模版類CArray管理該類。
"class CFileInfo
" {
"public:
" CString filename;
" LONGLONG ClipLen;
" LONGLONG Outdot;
" LONGLONG Indot;
" CFileInfo();
" virtual ~CFileInfo();
" } ;
"CArrayFileArray
" for (i=1; i<=FileArray.GetSize();i++)
" {
"FileArray[0].ClipLen = 0;
hr=pVideoSrcObj→SetStartStop(FileArray[i-1].ClipLen,FileArray[i-1].ClipLen+FileArray[i].ClipLen);//設置時間線時間
hr=pVideoSrcObj→SetMediaTimes(FileArray[i].Indot,FileArray[i].Outdot );//設置媒體源時間
hr=pVideoSrcObj → SetMediaName(T2W(FileArray[i].filename));//設置媒體源文件名
hr=pVideoTrack→SrcAdd(pVideoSrcObj);//將媒體源添加到相應的軌道上
FileArray[i].ClipLen=FileArray[i-1].ClipLen+FileArray[i].ClipLen;//下一個媒體源的時間線起點時間是前一個媒體源時間線的終點時間。
" }
預覽功能的實現
創建好時間線后,創建基本渲染引擎IRenderEngine,它的作用是通過已經建立好的時間線構建濾波器圖(FilterGraph)供預覽或者輸出文件。所以,我們需把時間線的信息傳遞給它。接下來的過程很簡單了,調用ConnectFrontEnd連接時間線部分所建立的濾波器(F i l t e r ),調用RenderOutputPins。至此,濾波器圖已成功建立,只要調用IMediaControl接口的Run()函數即可進行預覽了。
IRenderEngine *pRenderEngine = NULL;
hr=CoCreatelnstance(CLSID_RenderEngine, NULL,CLSCTX_INPROC_SERVER,IID_IRenderEngine, (void**)&pRenderEngine); //創建基本渲染引擎
hr=pRender→SetTimelineObject(pTL); //確定要渲染的時間線
hr=pRenderEngine→ConnectFrontEnd( );//構建graph的前端
hr=pRenderEngine→RenderOutputPins( );//將前端出來的引腳根據媒體類型分別連接到音視頻渲染器,完成graph的構建
IGraphBuilder *pGraph=NULL;
IMediaControl *pControl=NULL;
hr=pRender→GetFilterGraph(&pGraph);
hr=pGraph→QueryInterface(IID_IMediaControl, (void **)&pControl);
hr=pControl→Run();//運行Filter Graph。
保存功能實現
創建好時間線和前端后,前端輸出的是非壓縮的音頻流和視頻流,而我們要保存的是壓縮數據,所以必須向濾波器圖中加入MPEG-2音頻編碼器和視頻編碼器以及復用器。
第一步,將視頻編碼器、音頻編碼器和復用器以及文件寫入程序濾波器加入到濾波器圖中
hr=AddFilterByCLSID(pGraph,LSID_VIDEO_ENCODER,L"mpeg video encoder",&pVideoEncoder);
第二步,得到組的個數及輸出引腳指針,根據引腳的媒體類型將其連接到相應的編碼器上。
long NumGroups;
pTL->GetGroupCount(&NumGroups);
IPin *pPin;
"for (i = 0; i < NumGroups; i++)
" {
" if (pRenderEngine->GetGroupOutputPin(i, &pPin)== S_OK)
" {
" hr=GetMediaType(pPin);
" if (hr==TRUE) // 返回值為TRUE,則引腳輸出的是視頻流
" ConnectFilters(pGraph,pPin,pVideoEncoder,TRUE);
" else
" ConnectFilters(pGraph,pPin,pAudioEncoder,TRUE);
" }
" }
第三步,將視頻編碼器和音頻編碼器濾波器連接到復用器濾波器上
hr=ConnectFilters(pGraph,pVideoEncoder,pMux,TRUE);
hr=ConnectFilters(pGraph,pAudioEncoder,pMux,TRUE);
第四步,連接復用器和文件寫入程序濾波器
hr=ConnectFilters(pGraph,pMux,pfilewriter,TRUE);
第五步,創建MPEG輸出文件IFileSinkFilter *pSin= 0;pfilewriter→QueryInterface(IID_IFileSinkFilter,(void**)&pSink);
pSink→SetFileName(T2W(strSaveFile), NULL);
最后調用IMediaControl接口的Run()函數即可進行保存了。
測試效果
實現MPEG-2 音視頻剪輯的界面如圖3 所示。列表框顯示了待編輯的文件列表,雙擊文件名即可顯示該文件的第一圖3 MPEG-2 音視頻剪輯界面幀,點擊播放按鈕可實現對本地文件的回放。點擊入點按鈕可設置要剪切文件的入點,點擊出點按鈕后,將先暫停播放并得到剪切終止點。依次對多個文件進行出入點設置后點擊預覽按鈕后,回放的畫面流暢,無馬賽克現象,無明顯延時。點擊保存按鈕可保存串編結果,保存后的MPEG-2音視頻流,用暴風影音等軟件對該文件進行回放,回放的畫面流暢,質量令人滿意。
結束語
音視頻剪輯,無論是對電視臺的節目編輯制作,還是對一般的家庭用戶,都具有很大的吸引力。因此,視頻剪輯功能的實用化、普及化具有很強的現實意義。采用DES可使時間線管理、特技合成更加方便可靠,同時DES采用插件方式,可以有很多支持微軟DirectX的第三方插件使用,使軟件更易于擴展,為用戶提供更多的選擇。DES使得程序的模塊化更強,有利于軟件的開發,同時在不斷升級過程中,更可以方便地集成新的功能。當然,這種視頻編輯的方法也存在著它的局限性,即編輯的精度較傳統的硬件實現方法低,不適合應用于精度要求很高的編輯,這也是該軟件實現視頻編輯的一個缺陷。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
