DirectShow技術是建立在DirectDraw和DirectSound組件基礎之上的,
它通過DirectDraw對顯卡進行控制以顯示視頻,
通過DirectSound對聲卡進行控制以播放聲音。
DirectShow功能實現:
1.可提供高質量的多媒體流的捕獲和回放功能;
2.支持多種媒體格式,包括ASF(Advanced Systems Format),MPEG(Motion Picture Experts Group),AVI(Audio-Video Interleaved),MP3(MPEG Audio Layer-3)和WAV聲音文件;
3.可從硬件上捕獲媒體數據流;
4.可自動檢測并使用視頻和音頻加速硬件。
故,DirectShow是用于多媒體應用開發。(其實就是一個軟編碼(or解碼))
它充分發揮媒體的性能,提高運行速度,可以簡化媒體播放、媒體間的格式轉換
和媒體捕獲等工作。同時,它還具有極大的可擴展性和靈活性,可以由用戶自己
創建組件,并將這個組件加入DirectShow結構中以支持新的格式或特殊的效果。
應用程序與DirectShow組件以及DirectShow所支持的軟硬件之間的關系
如圖1

二。概念
1.過濾器
過濾器分為以下幾種類型:
a 源過濾器(source filter):
源過濾器引入數據到過濾器圖表中,數據來源可以是文件、網絡、照相機等。
不同的源過濾器處理不同類型的數據源。
b 變換過濾器(transform filter):
變換過濾器的工作是獲取輸入流,處理數據,并生成輸出流。
變換過濾器對數據的處理包括編解碼、格式轉換、壓縮解壓縮等。
c 提交過濾器(renderer filter):
接收數據并把數據提交給外設。
d 分割過濾器(splitter filter):
把輸入流分割成多個輸出。
如,AVI分割過濾器把一個AVI格式的字節流分割成視頻流和音頻流。
e 混合過濾器(mux filter):
把多個輸入組合成一個單獨的數據流。
如,AVI混合過濾器把視頻流和音頻流合成一個AVI格式的字節流。
過濾器的這些分類并不是絕對的,如一個ASF讀過濾器(ASF Reader filter)
既是一個源過濾器又是一個分割過濾器。
2 filter graph
過濾器圖表用來連接過濾器以控制媒體流,它也可以將數據返回給應用程序,
并搜索所支持的過濾器。
過濾器有三種可能的狀態:運行、停止和暫停。
暫停是一種中間狀態,停止狀態到運行狀態必定經過暫停狀態。
暫停可以理解為數據就緒狀態,是為了快速切換到運行狀態而設計的。
在暫停狀態下,數據線程是啟動的,但被提交過濾器阻塞了。
通常情況下,過濾器圖表中所有過濾器的狀態是一致的。
3. 引腳(pin)
過濾器可以和一個或多個過濾器相連,
連接的接口也是COM形式的,稱為引腳。
過濾器利用引腳在各個過濾器間傳輸數據。
每個引腳都從Ipin這個COM對象派生出來的。
每個引腳都是過濾器的私有對象,過濾器可以動態的創建引腳,銷毀引腳,自由控制引腳的生存時間。
引腳分輸入引腳(Input pin)和輸出引腳(Output pin)兩種類型,
兩個相連的引腳必須是不同種類的,即輸入引腳只能和輸出引腳相連
過濾器之間的連接(也就是引腳之間的連接),實際上是連接雙方媒體類型(Media Type)協商的過程。(媒體類型,不完全媒體類型 再下一節有講解)
連接的大致過程為:
如果調用連接函數時已經指定了完整的媒體類型,則用這個媒體類型進行連接,
成功與否都結束連接過程;
如果沒有指定或不完全指定了媒體類型,
則枚舉過程見后面.其兩個filter的連接設定如下.
Filter A ------------------> Filter B
------------------------------------------------------------- ------------------
說明:
媒體類型(Media Type)
兩個過濾器相連時,必須使用一致的媒體類型,否則這兩個過濾器就不能相連。
媒體類型能識別上一級過濾器傳送給下一級過濾器的數據類型,并對數據進行分類。
媒體類型的結構 AM_MEDIA_TYPE
AM_MEDIA_TYPE由三部分組成:
Major type
Subtype
Format type
都使用GUID 來唯一標示
Major type主要定性描述一種媒體類型,這種媒體類型可以是視頻、音頻、比特數據流或MIDI數據等;
Subtype 進一步細化媒體類型,
拿視頻的說就是進一步指定是RGB-24,還是RGB-32,或是UYVY等;
Format type則用一個結構更進一步細化媒體類型。
媒體類型的三個部分都指定了某個具體的GUID值,則稱這個媒體類型是完全指定的;
媒體類型的三個部分中有任何一個值是GUID_NULL,則稱這個媒體類型是不完全指定的。
GUID_NULL起通配符作用
pinout和pinin的連接過程可以用下面邏輯語言表達.
1.如調用連接函數時已經指定了完整的Media type,則用這個Media type進行連接,
成功與否都結束連接過程;
2.如沒有指定或不完全指定了Media type,
則如下:
BOOL CheckFilterB_PinIn()
{
for(i = 0 ; i < FilterB.FPinIn.MediaTypeCount ; i++)
{
if (IsSameMediaType(FilterA.FPinOut,FilterB.FPinIn.MediaType[i]) = True)
{
return TRUE; //Pin之間的連接成功;
}
}
return FALSE; //在Input pin不支持該媒體類型,失敗.
}
返回FALSE再枚舉Output pin上的所有Media type,并逐一用這些Media type與Input pin進行連接。
for(i = 0 ; i < FilterA.FPinOut.MediaTypeCount; i++)
{
if (CheckFilteB_PinIn(FilterA.FPinOut.MediaType[i]) = True )
{
return TRUE;
}
}
return FALSE; //filterA和filterB的連接失敗.