DirectShow是微軟公司在ActiveMovie和Video for Windows的基礎上推出的新一代基於COM(Component Object Model)的流媒體處理的開發包,9.0之前與DirectX開發包一起發布,之后包含在windows SDK中。。DirectShow使用一種叫Filter Graph的模型來管理整個數據流的處理過程,運用DirectShow,我們可以很方便地從支持WDM驅動模型的采集卡上捕獲數據,並且進行相應的后期處理乃至存儲到文件中。這樣使在多媒體數據庫管理系統(MDBMS)中多媒體數據的存取變得更加方便。它廣泛地支持各種媒體格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等,為多媒體流的捕捉和回放提供了強有力的支持。另外,DirectShow還集成了DirectX其它部分(比如DirectDraw、DirectSound)的技術,直接支持DVD的播放,視頻的非線性編輯,以及與數字攝像機的數據交換。
ActiveMovie,開發代號 Quartz, 這個由 Geraint Davies 為微軟公司設計的 DirectShow 的前身,在 Windows 3.0 時代,是作為一種對當時最流行的媒體平台 QuickTime 的回應而開發的。ActiveMovie 最早的出現是被附加在 Windows 95 上面的並且需要系統安裝了 IE3.0 。它當時的使命是作為 IE 的附件播放在其窗口內的媒體文件,正如當時 QuickTime 為 Netscape 以及 IE 提供的服務那樣,它的另一個功能是作為 Windows 視頻技術(VFW,Video For Windows)的一個替換,特別地為在 VFW 架構中難於處理的 MPEG(移動圖象專家組格式文件)文件提供輔助處理。
在 1998 年,大致在 DirectX 5 年代的時候,ActiveMovie 被重命名為 DirectShow(反映了微軟公司在那時正在努力加強"直接地"在一個通常的取名系統之下與硬件合作的技術)並且被包含為 " DirectMedia SDK" 的一部份。在 DirectX 的 7 版中,DirectShow 變成了 DirectX SDK 主要組成部分而且如同 DirectInput 等其它 DirectX APIs 一樣被給予了它自己的位置。甚至之后, DirectShow 被主要用來接收來自像一個手提攝像機這樣的電視輸入裝置的數據,而且它從文件中顯示數據的能力被廣泛用在 Windows Media Player 上面。 從 2005 年四月起,DirectShow 被從 DirectX SDK 移除,必須單獨下載Extra包才能得以支持,之后DirectShow的文檔和示例被轉移到Windows SDK,DirectShow也正式成為Windows的一個組件。然而,在編譯某些 DirectShow 的示例時,DirectX SDK 仍然是必需的。
在網上找了一些資料,比較好資料的地址為 http://www.yesky.com/259/1854259.shtml ,大部分資料都來自於陸其明寫的《DirectShow開發指南》和《DirectShow實務精選》兩本書。總結如下:
1) DirectShow的系統結構
DirectShow的體系結構如圖1所示。
圖1 DirectShow系統 |
DirectShow位於應用層中。它使用一種叫Filter Graph的模型來管理整個數據流的處理過程;參與數據處理的各個功能模塊叫Filter;各個Filter 在Filter Graph中按一定的順序連接成一條"流水線"協同工作。
( 可以看出TFilterGraph是個Filter的容器 )
按照功能來分,Filter大致分為三類:Source Filters、Transform Filters和Rendering Filters。
Source Filters主要負責取得數據,數據源可以是文件、因特網、或者計算機里的采集卡、數字攝像機等,然后將數據往下傳輸;
Transform Fitlers主要負責數據的格式轉換、傳輸;
Rendering Filtes主要負責數據的最終去向,我們可以將數據送給聲卡、顯卡進行多媒體的演示,也可以輸出到文件進行存儲。
在DirectShow系統之上,我們看到的,即是我們的應用程序(Application)。應用程序要按照一定的意圖建立起相應的Filter Graph,然后通過Filter Graph Manager來控制整個的數據處理過程。DirectShow能在Filter Graph運行的時候接收到各種事件,並通過消息的方式發送到我們的應用程序。這樣,就實現了應用程序與DirectShow系統之間的交互。
2) Filter概述以及連接
過濾器(Filter)是DirectShow中最基本的概念。DirectShow是通過Filter Graph來管理Filter的。Filter Graph是Filter的"容器",而Filter是Filter Graph中的最小功能模塊。
Filter是一種COM組件,對於每個Filter,都有其自己的Pin,它是由Filter創建的COM對象。 Filter通過Pin來進行他們之間的連接。
Pin分為兩種:輸出Pin和輸入Pin。輸出的Pin把Filter處理后的數據傳送到Filter的外 部,而輸入Pin則是把Filter外部的數據接收到Filter中,以便Filter對這些數據進行處理。
對於三種類型的Filter(Source Filter,Transform Filter,Rendering Filter)的連接圖如下:
圖2 Filter的連接
可以根據Filter所包含的輸入Pin和輸出Pin的熟練來判斷Filter的類型:
只有輸出Pin,沒有輸入pin,為Source Filter
既有輸出Pin,又有輸入pin,為Transform Filter
沒有輸出Pin,只有輸入pin,為Rendering Filter
3)DirectShow 的重要接口
DirectShow采用了COM標准,所以很多重要的功能都是通過COM接口來完成。下面就列舉一些重要的DirectShow的接口。
(1) IGraphBuilder接口
用於構造Filter Graph的接口,建立和管理一系列的Filter,過濾和處理源媒體流。
(2) IMediaControl接口
用於控制多媒體流在Filter Graph中的流動,如流的啟動和停止。
(3) IMediaEvent接口
用於捕獲播放過程中發生的事件,並通知應用程序,如EC_COMPLETE等。
(4) IVideoWindow接口
用於控制視頻窗口的屬性。
(5) IMeadiaSeeking接口
用於查找媒體的接口,定位流媒體,控制多媒體數據播放提供精確控制。
(6) IBaseFilter接口
從ImediaFilter接口繼承,用來定義一個具體的過濾器指針,並對多媒體數據進行處理。
(7) IPin接口
用於管理兩個過濾器之間的Pin,從而連接過濾器。
(8) IsampleGrabberCB接口
是Sample Grabber過濾器的一個接口,用於當流媒體數據通過過濾器時進行采樣以獲得幀圖象。
還有一個可以參考的介紹,地址為:http://www.yesky.com/259/1854259.shtml
摘自:http://www.cnblogs.com/zhusd/archive/2010/06/18/1760139.html
1.DirectShow概述
DirectShow的主要功能是流媒體的采集與回放。
它集成了DirectDraw,DirectSound,Direct3D的一些技術。
它是一個開放的架構,你自己可以寫自己的Filter組件。
DirectShow的架構:
2.Filter
Filter其實就是一個COM組件,但它有自己的特性。它由輸入,處理,輸出三部分組成,
輸入,輸出是叫PIN,輸入的叫輸入pin,輸出的叫輸出PIN。PIN也是一.種COM組件,它實現了IPin接口。
在Filter的實現里,PIN其實是Filter的一個數據成員。(個人想法)
(1)Filter分為三類:Source Filter(源過濾器),Transform Filter(轉換過濾器) Render Filter(渲染過濾器)
(2)Source Filter 的主要互責音、視頻數據的采集,讀取。比如File Source Filter(文件源過濾器),它是從磁盤里的音視文件讀取數據的。
Transform Filter 互責音、視數據的壓縮,解壓,編碼、解碼、分析。
比如:Spliiter Filter(分離器),其功能是將音頻流和視頻流分離開來
Mux Filter(復合器),將音頻流和視頻流 全成單一數據流
還有一此Encoder,Decoder,Compressor等。
(3)Render Filter 互責音、視流的渲染,就是和輸出,它將數據流送到輸出設備,(顯示器、磁盤、聲卡)
Filter有三種狀態,運行,暫停,停止。
關於數據流:
3.Filter Graph(過濾器圖)
Filter Graph是DirectShow一個基本的概念。我們開發一個DirectShow應用,其中最重要的步驟就是構造一個Filter Graph。下圖就是一個
Filter Graph
這是一個實現本地文件(avi文件)回放的Filter Graph,File Source互責讀文件理的數據,之后將數據傳輸給AVI Splitter,AVI Spliiter 將接收的數據進行分析,分離成視頻流和音頻流。視頻流經過AVI Ddcompressor的解碼,送到Video Renderer輸出到顯示器。從AVI Spliter出來的音頻流則送到DirectSound Device,由DirectSound Device送到音頻輸出設備。
4.Filter Graph Manager
Filter Graph Manager也是一個COM組件,它是DirectShow的控制中心,它控制Filter的運行。它有以下幾個功能:
(1)協調各個Filter的狀態。Filter有運行,暫停,停止三種狀態,在Filter Graph中,各個Filter的狀態必須協調一到,否則會引起沖突。Filter Graph Manager互責協調各個Filter的狀態。
(2) 提供一個參考時間,用以同步音頻流和視頻流。
(3) 提供一套用於建立Filter Graph的方法
(4)與應用程序進行交互,它會將Filter Graph內部發生的事件,通過消息的方式通知應用程序。
5.Sample
Filter Graph運行的時候,數據從上游的Filter傳到下游的Filter,數據有一個單位,這個單位叫Sample,就是數據將分成一個一個的Sample進行傳輸。
6.Media Type
媒體類型是DirectShow的一個基本的概念,它描述了兩個過濾器之間傳輸數據(Sample)的格式。兩個過濾器在連接之前,必須就所采用的媒體類型進行協商。
媒體類型,用AM_MEDIA_TYPE結構體來表示,它的結構可以看MSDN文檔。其中有幾個域是比較重要的
typedef struct _MediaType{
GUID majortype //主類型
GUID subtype //輔助類型(進一步描述數據格式)
GUID formattype //更詳細描述數據格式
ULONG cbFormat //描述formatype數據塊的大小
BYTE* pbFormat //描述formattype數據塊的內存指針
//其它略
}
比較常用的描述媒體類型的GUID
majortype的有:
MEDIATYPE_Video(數字視頻)
MEDIATYPE_Audio(數字音頻)
MEDIATYPE_AnologVideo(模擬視頻) //似乎沒用過
MEDIATYPE_AnologAudio(模擬音頻) //同上
MEDIATYPE_Stream(字節流) //Filter Source Filter從文件里讀出來的數據
MEDIATYPE_Interleaved //DV的數據流(包括音視頻數據)
Subtype
//MEDIASUBTYPE_Y
Formattype
FORMAT_None
FORMAT_DvInfo (描述DV的數據類型格式)
FORMAT_VideoInfo (描述一般視頻數據格式)
FORMAT_WaveFormatE (描述一般音頻數據格式)
FORMAT_VideoInfo2 ////
媒體類型協商:兩個過濾器在傳輸數據之前,必須就所采用的媒體類型進行協商。
7.Filter的連接過程
DirectShow提供了多方法來連接Filter,如IFilterGraph::ConectDirect,IGraphBuilder::Connect
Filter的連接過程實際是兩個過濾器就媒體類型進行協商的過程。Filter連接的過程其實它們的PIN連接的過程,就是上游的輸出PIN與上游的輸入PIN連接。我們知道,每一個PIN都有它自己支持的媒體類型,而當兩個PIN沒有共同支持的媒體類型的時候,它們是不能連接的,所以連接之前要進行協商。
在Conect函數的實現里,可以看到大致過程是這樣的:
連接是由輸出PIN發出的
Connect Start
IF PIN已連接 THEN EXIT
IF Filter不是停止狀態 THEN EXIT
//開始協商過程
CALL AgreeMediaType
Connect End
AgreeMediaType Start
在輸出PIN或輸入PIN媒體類型枚舉器mediatypeEnums
調用函數TryMediaTypes,並把枚舉器的指針傳給它
AgreeMediaType End
TryMediaTypes Start
FOR EACH mediatype IN mediatypEnums
AttempConnection(media)
NEXT
TryMediaTypes End
AttemptConnection Start
CheckMediaType //檢查媒體類型是否被支持(輸出PIN自己)
IF 支持 THEN
在PIN上保存媒體類型
ELSE
FAILED
END IF
CALL ReceiveConnect // 詢問輸入PIN是否接受當前的媒體類型。
IF SUCCEED THEN
CALL CompleteConnect
ELSE
FAIL
END IF
AttemptConnect End
CompleteConnect的作用是完成連接后的一些后續工作,主要是決定數據傳輸的時候使用哪一個內存分配器,由誰來創建內存分配器(IMemAllocator)。
注:Filter傳輸的數據單元叫Sample,它是一個COM組件,封裝了一個緩沖區。Sample由內存分配器來管理。內存分配器是實現了IMenAllocator接口的COM組件,互責管理Sample。
智能連接:構造Filter Graph的時候通過一些方法的調用,DirectShow會幫我們構造整個Filter Graph。用到的方法有IGraphBuilder::RenderFile, IGraphBuilder:Render
ICaptureGraphBuilder2::RenderStream
8.Filter 的數據傳送
(1)數據傳送有兩種模式:拉模式,推模式。
推模式:上游Filter調用下游輸入PIN上的IMemInputPin::Receive,使用這種模式的話,輸入PIN 必須實現IMemInputPin接口。比較典型的使用推模式的Filter是Capture Source Filter。
拉模式:下游的Filter調用 上游輸出PIN的IAsycnRender接口的方法,這是,輸出PIN必須實現IAsyncReader接口。比較典型的使用拉模式的是Fillter Source.
(2)傳送過程中的內存管理:在傳送的過程中,必須分配一定的緩沖。這個過程是通過內存分配器(IMemAllocator)來實現,它管理一系列的Sample。Sample是一個COM對象(實現IMediaSample接口),它封裝並管理一個緩沖區。
在連接的過程中,Filter協商雙方共同使用的內存管理器,並知道了內存管理器的位置。
這樣,當上游的Filter要傳輸數據的時候,它將調用IMemAllocator::GetBuffer來得到一個閑的Sample然后將數據進去,傳輸給下游。
9.關於Filter Graph的狀態轉換:
10.質量控制:好像沒什么用,沒用到過
11.音、視同步:
(1) 參考時鍾:
主要就是為Filter Graph設置一個參考時鍾,凡實現了IReferenceClock接口的都可以作為參考時鍾,FGM(Filter Graph Manager)有一套選定參考時鍾的策略:一般有Live Source(Capture Source Filter)就選它作時鍾,因為,這種Filter 包裝的硬件上一般都有一個定時器。如果沒有Live Source,那就選Audio Renderer,因為聲卡上一般也有定時器。如果還沒有的話,那就看其它Filter有沒有實現IReferenceClock。確實沒有的話,就選系統時鍾。
(2) 時間戳(Time Stample)
送到Renderer渲染的Sample必須打上時間戳,就是一個渲染的Start Time 和End Time
好讓Renderer 為它選擇渲染時間。IMediaSample::SetTime
12.DirectShow對硬件的支持
DirectShow中Filter是工作在用戶模式(user mode),而硬件設備,比如:視頻采集卡,是工作是內核模式(kernel mode),那么,它們是怎樣進行交互的呢?DirectShow為我們提供了包裝Filter,包裝Filter也是工作用戶模式,不過它可以跟硬件驅動程序進行交互,再通過硬件驅動去控制硬件設備。
DirectShow里面有一個叫ksProxy的包裝Filter,它是支持所有WDM設備,它提供了一個框架,然后由硬件廠商進行實現。
二.常用的接口
比較有用的接口和方法
IBaseFilter 這是所有Filter至少要實現的接口
IPin PIN至少要實現的接口
IFilterGraph 提供了一些建立Filter Graph的方法
IGraphBuilder (這個接口是由IFilterGraph繼承來的,它提供了一些更方便的方法來建立Filter Graph,比如:RenderFile,Render,AddSourceFilter)
IMediaControl(控制Filter Graph的狀態)
IVideoWindow(控制視頻窗口)
//接口方法:put_MessageDrain
IMediaEventEx(事件處理有關的)
IMediaSeeking(用於媒體播放定位的)
上面這些接口,都是通過Filter Graph Manager暴露出來的,我們只創建一個Filter Graph Manaer 組件,就可以它們
ICaptureGraphBuilder2(用來建立Capture Filter Graph,這是一個非常有用的接口)
方法:
(1)SetFiltergraph //設置對應的IGraphBuilder*,也就是FilterGraph
(2)RenderStream //用得最多的方法,對Capture Source Filter指定的輸出PIN(Capture ,Preview,CC,VBI,)完成Filter Graph下游其它部分的構造。
它的原型如下:HRESULT RenderStream( const GUID *pCategory, const GUID *pType, IUnknown *pSource, IBaseFilter *pIntermediate, IBaseFilter *pSink);它比較常見的用法如下:
為了對視頻進行預覽,我們只要如下調用:
RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,pCap,NULL,NULL);
為了對視頻進行保存的:
RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pCap,NULL,pMux);
pMux是一個Mux Splitter對輸入的音、視頻數據合並並進行編碼,
(3) SetOutputFileName 這個方法是在對視頻進行保存時調用的,可以設置保存文件路徑,保存類型(如avi,asf),並會返回一個Mux Filter指針。
它的原型是:
HRESULT SetOutputFileName( const GUID *pType, LPCOLESTR lpwstrFile, //文件保存位置 IBaseFilter **ppf, //返回一個Mux Filter指針 IFileSinkFilter **pSink //這個指針用來更改文件保存路徑,如果不需要可以置為NULL);pType 可能是一個subtype,當它是subtype時,只能下面兩種取值:
MEDIASUBTYPE_Avi(保存為Avi格式),
MEDIASUBTYPE_Asf(保存為Asf),
因為這兩種格式是windows可以識別的,所以它自動返回一個Mux Filter指針
如果要保存為其它格式,那么要將pType這個參數指定為一個Mux Filter或一個File Writer的GUID。
模擬電視卡可能用到的接口:
ICrossbar //輸入端子選擇
IAMTuner
IAMTVTuner //電視卡上TV Tuner的包裝類,控制電視頻道的接收與選擇
常用方法:put_Channel //設置接收頻道
三、DirectShow應用開發一般步驟
1. DirectShow開發環境的配置(VC 6.0)
一般包含的頭文件是 dshow.h 或streams.h 有時還會用到其它頭文件,比如:qedit.h
用到的靜態連接庫文件:strmiids.lib strmbasd.lib(strmbase.lib Release版本) quartz.lib
winmm.lib uuid.lib
路徑配置:VC tools\option\
有配置的時候,最后把所有的庫文件都包含上去,這樣連接的時候就不會出現莫名其妙的錯誤了。
2. DirectShow應用開發的一般步驟
(1) 創建一個Filter Graph Manager組件
(2) 構造一個完整的Filter Graph
(3) 從 Filter Graph Manager組件得到各種接口,比如:IMediaControl,對程序進行控制
具體如下:
(1) 創建Filter Graph Manager組件的代碼如下:
hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_FilterGraph, (void**)&pGraph)
相關接口的查詢:
IMediaControl *pControl=NULL;
Hr=pGraph->QueryInterface(IID_IMediaControl,(void**)&pControl):
IVideoWindow* pVW=NULL;
Hr=pGraph->QueryInterface(IID_IVideoWindow,(void**)&pVW);
(2) 之后,創建Filter Graph
這是整個程序最關鍵的部分
創建Filter Graph 有下面一些方法
IFilterGraph::AddFilter IFilterGraph::ConnectDirect
IGraphBuilder::AddSourceFilter IGraphBuilder::Connect IGraphBuilder::RenderFile
IGraphBuilder::Render
ICaptureGraphBuilder2::RenderStream
一般采用智能連接比較方便,當智能連接不行的時候再自己手動連接
(3) 視頻窗口的設置:如果要對視頻進行預覽的話,那就要設置視頻窗口。視頻窗口是由Renderer Filter 自動創建出來,我們編程的時候,只需要對它時進行設置就行了
IVideoWindow接口用來專門控制視頻窗口,用以下常見的方法:
//put_Owner 為視頻窗口指定父窗口,通過這個方法,我們可以將視頻窗口嵌到我們自己的窗口,比如一個靜態文本控件,
SetWindowPosition 設置視頻窗口的位置,
//put_MessageDrain 這個是比較有用的。對視頻窗口而言,我們是不能改寫它的窗口處理過程,因為它是由DirectShow自動創建的。我們可以通過這個方法將視頻窗口收到的消息掛接到一個我們自己的窗口,這樣就實現了對視頻窗口的消息處理了。
//put_Visible 將視頻窗口顯示出來
//SetNotifyWindow 當Filter Graph中發生一些事件時,會向應用程序發送一些消息,這個方法是指定處理這此消息的的窗口
//put_WindowStyle 設置Video Window的樣式,比如:
long style=0;
get_WindowStyle(&style);
style&=~WS_CAPTION;
put_WindowStyle(style)
這樣就可以去掉Video Window的標題欄了
///put_FullScreenMode 設置全屏模式
(4)啟動Filter Graph
pGraph->Run();
3. 常用的Filter Graph 的構造
構造Filter Graph,可以GraphEdit這個工具來測試
(1) 本地文件播放
最方便的方法:IGraphBuilder::RenderFile(filename);
只要選擇播放的文件,IGraphBuilder就智能地幫你構造出整個Filter Graph
(2) 視頻輸入設備采集視頻的預覽
ICaptureGraphBuilder2 * pGB=NULL;
Hr=CoCreateInstance (CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC,IID_ICaptureGraphBuilder2,(void**)&pGB);
//對於DV面言,它可能有兩種視頻輸出PIN,一種是Interleaved Pin, 一種是Video Pin
//前面一種包含音視頻流,后面一種只有視頻流,所以我們預覽的時候,可以先試一下
Interleaved Pin,如果失敗的話,再試一下Video Pin
Hr=pGB->RenderStream(PIN_CATEGORY_PREVIEW,MEDIATYPE_Interleaved,
//pCap,NULL,NULL);
if(FAILED(hr))
{
hr=pGB->RenderStream(PIN_GATEGORY_PREVIEW,MEDIATYPE_Video,pCap,NULL,NULL);
}
if(FAILED(hr))
{
return hr;
}
(3) 采集視頻的錄制(輸出為本地文件)
pGB->SetOutputFileName(&MEDIASUBTYPE_Asf, filename, &pMux,&pSink);
MEDIASUBTYPE_Asf 指定為保存為Asf格式,
MEDIASUBTYPE_Avi 保存為AVI格式
如是要保存為其它格式,要有相應格式的Mux Spliiter 或 Filter Writer,然后傳入它的GUID
filename 是保存路徑
hr=pGB->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,pCap,NULL,pMux);
if(FAILED(hr))
{
hr=pGB->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pCap,NULL,pMux);
}
(4) 模擬電視卡VBI信息的渲染
電視卡的VBI信息,用以下三種:CC(Closed Caption),WST(World Standard Teletext), 忘記了
CC( Closed Caption)
電視卡的VBI信號可能是從VBI PIN輸出的,也可能是從CC PIN輸出的,所以我們要進行判斷。
Hr=pGB->RenderStream(&PIN_CATEGORY_VBI,&MEDIATYPE_Video,pCap,NULL,NULL);
If(FAILED(hr))
{
pGB->RenderStream(&PIN_CATEGORY_CC,&MEDIATYPE_Video,pCap,NULL,NULL);
}
if(FAILED(hr))
{
return hr;
}
RenderStream會幫我們創建整個Filter Graph
RenderStream不支持WST信號的渲染,我們必須手動創建Filter Graph
四.雜記
(1)電視卡Crossbar, TV Tuner
Crossbar是用於輸入端子的選擇。使用的時候,我們只要用ICrossbar::Route 導通相應的端子就可以了。有的電視卡有兩個Crossbar。
TV Tuner控制電視卡接收與頻道選擇,可以通過接口IAMTVTuner進行操作
(2)Stream Buffer Engine
這個可以實現實時流媒體的緩沖。它有兩個Filters,Stream Buffer Source,Stream Buffer Sink
Stream Buffer Source 互責流媒體的采集,並寫入磁盤,以供給 Stream Buffer Sink讀取。
對於流媒體,Stream Buffer Source只支持DV和MPEG-2兩種格式,所以,在輸入Source時,有時候要進行格式轉換。Stream Buffer Source 優先采用的格式是MPEG-2。
Stream Buffer Sink 互責讀取Source 寫入的數據,然后進行回放。
讀取的時候,它會先找到Stream Buffer Source寫入的一個 Stub文件,里面包含了指向其它文件的指針。
使用Stream Buffer Engine時,我們要構造兩個Filter Graph。
(3) WM Asf Writer
將視頻保存為Asf文件的時候,要用到WM Asf Writer,它有一個音頻輸入端,一個視頻輸入端,它要求只兩個端都要接上,否則構造出來的Filter Graph無法啟動。這個要求感覺有點勉強,不知有沒有解決方法。
(4) ISampleGrabber
在創建CLSID_SampleGrabber組件的時候,我們不能直接就得到里面的ISampleGrabber
,而是要先得到IBaseFilter接口,然后再用QueryInterface得到ISampleGrabber.感覺很奇怪。
根據IUnknown原則,無論我們先得到那個接口都是可以的啊。
摘自:http://hi.baidu.com/584433640/blog/item/7e682befa89ef927b90e2d53.html