1. DSPack 2.3.4 安裝
一. 下載
由於sourceforge最近不能訪問,所以可以去 http://www.progdigy.com/ 下載。
下載 http://www.progdigy.com/files/DSPACK234.zip 后,解壓縮到一個目錄(我用的是C:\Borland\VCL\DSPACK234)。
二. 安裝
1 增加搜索路徑 (DSPackDir)\src\DirectX9 和 (DSPackDir)\src\DSPack
在delphi7中選擇菜單【Tools】-【Enviroment Options】,在打開的窗口中選擇Library頁簽,在Library Path一項中添加這兩個目錄C:\Borland\VCL\DSPACK234\src\Directx9 ;C:\Borland\VCL\DSPACK234\src\DSPack
(將其直接粘貼在原有內容的后面,或者點擊Library Path后面的...按鈕添加)
2 編譯 (DSPackDir)\packages\DirectX9_D7.dpk
雙擊(DSPackDir)\packages\DirectX9_D7.dpk,在delphi7中會顯示一個關於重新創建資源文件的對話框,點擊OK就可以了。
在delphi7中的打開窗口中點擊compile按鈕,完成編譯。
在delphi7中選擇菜單【File】-【Close All】,在提問是否保存時,選擇保存。
3 編譯 (DSPackDir)\packages\DSPack_D7.dpk
雙擊(DSPackDir)\packages\DSPack_D7.dpk,在delphi7中會顯示一個關於重新創建資源文件的對話框,點擊OK就可以了。
在delphi7中的打開窗口中,點擊compile按鈕,完成編譯。
在delphi7中選擇菜單【File】-【Close All】,在提問是否保存時,選擇保存。
4 編譯並安裝 (DSPackDir)\packages\DSPackDesign_D7.dpk
雙擊(DSPackDir)\packages\DSPackDesign_D7.dpk,在delphi7中會顯示一個關於重新創建資源文件的對話框,點擊OK就可以了。
在delphi7中的打開窗口中,點擊compile按鈕,完成編譯。 點擊Install按鈕,完成安裝。
在delphi7中選擇菜單【File】-【Close All】,在提問是否保存時,選擇保存。
至此,安裝已完成,在delphi的控件面板上可以找到DSPack的頁簽了。
如果在Delphi5或6中安裝,則選擇對應的D5或D6的文件。
(安裝過程中遇到了一個編譯錯誤,說找不到Jedi.inc。這個文件在src\Directx9目錄下,為什么不能搜索。原來文檔里寫的路徑是 (DSPackDir)\src\Directx9,而實際解壓縮出來的目錄名是DirectX9,所以添加搜索路徑的時候一定要注意這個問題。把x改成X后,編譯就通過了)
2. 用DSPack播放視頻
安裝完后,開始學習DSPack。
首先,要閱讀一下(DSPackDir)\help目錄下的help.chm文件,粗略地看了一下,內容太多看不出頭緒。
還是先學習一下(DSPackDir)\Demos\D6-D7目錄下的那些例子,邊動手做邊學習吧。
研究的第一個例子是PlayWin。研究了一下,主要使用TFilterGraph和TVideoWindow來完成。
TFilterGraph是DSPack中的核心類,其他類都要圍繞着它,但是怎么理解它還不清楚。TVideoWindow是個顯示播放視頻的控件。這兩個類的關系好像是數據庫控件中Dataset控件和DBGrid控件的關系一樣。
看得差不多后,自己照葫蘆畫瓢仿制一個。
1. 新建一個應用,在界面上先放4、5個按鈕。
2. 在控件面板上選擇DSPack那頁,把前兩個控件(TFilterGraph和TVideoWindow)在窗口上各放一個。
3. 關聯
選中VideoWindow1控件,在屬性窗口中將FilterGraph屬性設置為FilterGraph1。
選中FilterGraph1控件,確認屬性窗口中的Mode屬性為gmNormal。
4.為Form1增加一個onCreate事件處理程序。
內容為:
if not FilterGraph1.Active then FilterGraph1.Active := true;
FilterGraph1.ClearGraph;
FilterGraph1.RenderFile('E:\v\951.wmv'); // 簡化一點,這里用你本地硬盤上的一個視頻文件
5. 為Form1增加一個onCloseQuery事件處理程序。
內容為:
FilterGraph1.Active := false ;
6.把button1的Caption改為Start,並增加一個OnClick事件
內容為:
FilterGraph1.Play;
運行一下,就可以播放了。下面再增加幾個功能按鈕,如pause、stop。
7. 把button2的Caption改為Pause,並增加一個OnClick事件
內容為:
FilterGraph1.Pause;
8. 把button3的Caption改為Stop,並增加一個OnClick事件
內容為:
FilterGraph1.stop;
可以看出4-8步都是調用了TFilterGraph類的方法。
下面,再增加個全屏功能吧。
9. 把button4的Caption改為FullScreen,並增加一個OnClick事件
內容為:
VideoWindow1.FullScreen :=true ;
10. 為VideoWindow1增加一個OnClick事件
內容為:
if videowindow1.FullScreen then
videowindow1.FullScreen := false ; //退出全屏方式
一般的視頻播放創窗口都有一個進度條,現在我們也來加一個。
A.1. 在DSPack控件面板上選擇倒數第2個控件(TDSTrackBar),放到在窗口上。
A.2. 關聯
選中DSTrackBar1控件,在屬性窗口中將FilterGraph屬性設置為FilterGraph1。(這一步好像很熟悉哦)
重新運行程序,你就會看到一個進度條,並且能夠使用這一進度條來調整播放的進度。
3. 使用DSPack打開攝像頭
現在我們來看看(DSPackDir)\Demos\D6-D7目錄下的PlayVideoCap,這是一個打開本機的視頻輸入設備的例子。
在這個例子中,又用到了一個新類:TFilter。
在我們依葫蘆畫瓢之前,你要裝個攝像頭或虛擬攝像頭。虛擬攝像頭可以用VCDCut、Softcam或Vcam等軟件,也可以使用9158(http://www.9158.com/)或MVBox(http://www.mvbox.cn/)的虛擬視頻。
先跟上次一樣:
1. 新建一個應用,在界面上先放4、5個按鈕,這次多放一個Listbox,這個列表框中將列出系統中安裝的視頻輸入設備。
2. 在控件面板上選擇DSPack那頁,把前兩個控件(TFilterGraph和TVideoWindow)在窗口上各放一個。
下面該有所不同了
3.在DSPack中選擇TFilter控件,放到窗口上。
4.選中FilterGraph1控件,在屬性窗口中將Mode屬性設為gmCapture。
5. 關聯
選中VideoWindow1控件,將FilterGraph屬性設置為FilterGraph1。
選中Filter1控件,將FilterGraph屬性設置為FilterGraph1。
6. 在代碼模式中,在Interface后的Uses中增加
DSUtil, DirectShow9,
在implementation前面的Var中增加
SysDev: TSysDevEnum;
7. 為Form1增加一個onCreate事件處理程序,讀取系統中的視頻輸入設備。
內容為:
var
i: integer;
begin
// 讀取系統中的視頻輸入設備
SysDev:= TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
if SysDev.CountFilters > 0 then
for i := 0 to SysDev.CountFilters - 1 do
begin
Listbox1.Items.Add(SysDev.Filters[i].FriendlyName)
end;
end;
7. 同前。為Form1增加一個onCloseQuery事件處理程序。
內容為:
SysDev.Free;
FilterGraph1.ClearGraph;
FilterGraph1.Active := false ;
8. 為Listbox1增加一個onClick事件處理程序
內容為:
FilterGraph1.ClearGraph;
FilterGraph1.Active := false;
//設filter為所選視頻輸入設備
Filter1.BaseFilter.Moniker := SysDev.GetMoniker(Listbox1.ItemIndex);
FilterGraph1.Active := true;
// 打開所選的視頻輸入設備
with FilterGraph1 as ICaptureGraphBuilder2 do
RenderStream(@PIN_CATEGORY_PREVIEW, nil, Filter1 as IBaseFilter, nil, VideoWindow1 as IbaseFilter);
// 顯示出來
FilterGraph1.Play;
運行一下試試,看是否能看到自己的攝像頭的內容。
幾個按鈕沒用,等到下一個例子用吧。
4. DSPack抓幀
我們以前兩個例子為基礎,增加抓幀的功能。
打開前面的例子,然后:
1. 在DSPack中選擇TSampleGrabber控件,放到窗口上。然后將其FilterGraph屬性設置為FilterGraph1。
2. 在選擇一個標准控件TImage(在Additional頁簽中),放在窗口上。
3.講一個沒用的按鈕的Caption改為“Snapshot”,在它的OnClick事件中寫:
SampleGrabber1.GetBitmap(Image1.Picture.Bitmap);
前面兩個例子都可以這樣增加抓幀功能。不過,對於第二個例子(即操作攝像頭的例子),需要做額外的修改,就是:
將
RenderStream(@PIN_CATEGORY_PREVIEW, nil, Filter as IBaseFilter, nil, VideoWindow as IbaseFilter);
改為
RenderStream(@PIN_CATEGORY_PREVIEW, nil, Filter as IBaseFilter, SampleGrabber as IBaseFilter, VideoWindow as IbaseFilter);
這樣就可以了
5. DirectShow基本概念
到這里,我基本用DSPack做了一點東西,了解了DSPack中的3個基本類及其一些方法。但要理解它們,還要了解一下DirectShow中Filter Graph、Filter、Pin的基本概念。
在網上找了一些資料,比較好資料的地址為 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)的連接圖如下:
可以根據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
Filter是一種COM組件。為了實現在Filter Graph中的統一操作,每個Filter上都至少實現了一個IBaseFilter接口。實現Filter的文件一般是一個DLL,擴展名可以是.dll,但更多的時候是.ax。
Filter必須加入到Filter Graph並接入到工作鏈路中才能發揮作用。如果想繞過Filter Graph而直接使用Filter實現的功能模塊,那就要將Filter功能移植成DirectX媒體對象(DMO)。
在使用Filter之前,必須注冊。 命令格式為
regsvr32 c:\yourdirectory\yourfilter.ax
Filter Chain是相互連接着的一條Filter鏈路,並且鏈路中的每個Filter全都有一個處於“已連接”狀態的輸入Pin,至多有一個處於“已連接”狀態的輸出Pin,這條Filter鏈路中的數據流不依賴鏈路外的其他Filter。Filter Chain通過IFilterChain接口來進行相關操作。
當Filter Graph處於運行狀態下,Filter Chain可以在運行和停止狀態之間切換;
當Filter Graph處於暫停狀態下,Filter Chain可以在暫停和停止狀態之間切換。這是Filter Chain僅有的兩種狀態轉換。
Filter的數據傳送
Filter之間以Sample的形式傳送數據。Sample是一個封裝了一定大小數據內存的COM組件。用於數據傳輸的一般是輸入pin上實現的IMemInputPin接口。
Filter有3種狀態:停止、暫停和運行。