雖然網上已有很多關於directshow寫source filter的資料,不過很多剛開始學的朋友總說講的不是很清楚(可能其中作者省略了許多他認為簡單的過程),讀者總希望看到象第一步怎麼做,第二步怎麼做....這樣的demo。其實寫你的第乙個filter是有一定難度的,只要過了這關以後就容易多了。
由於最近需要自己寫乙個push推模式的source filter,加上剛啟用了blog,不好意思blog上沒有一篇文章,所以將寫這個filter的過程寫下來,為了照顧剛開始學的朋友,我採用第一步第二步....這樣的方式盡可能的講解詳細,相信你按照這個步驟一定沒問題的,對於vc中directshow開發環境的配置,這裡不做講解。下面開始:
(vc 6.0 + directshow 9.0)
我也記得剛學時候的迷茫,所以會盡量詳細每個過程,所以很多是sdk的例子我沒改動它,沒講的是我提供的源**裡面我加有比較詳細的注釋,可以配合我提供的源**一起看。
第一步:建立工程
file->new->project選擇win32 dynamic-link library,(由於是個demo,名字我用的push_test_01)->next後選擇a ****** dll project(這裡為了避免自己寫dllmain的麻煩,所以沒選an empty dll project)->可以finish了到這裡工程建立結束。
第二步:相關設定和需要加入的檔案等操作
首先將debug方式改為release。接著project->seetings->link裡的output file name從release/push_test_01.dll改為release/push_test_01.ax。
在工程目錄下建立乙個文字檔案,修改名字為push_test_01.def。將其加入工程:project->add to project->files 選擇push_test_01.def後加入。
對push_test_01.def進行修改,fileview->source files 雙擊push_test_01.def後輸入:
library push_test_01.ax
exports
dllmain private
dllgetclassobject private
dllcanunloadnow private
dllregisterserver private
dllunregisterserver private
,確定project->seetings->link下object/library modules裡面為:
strmbase.lib msvcrt.lib quartz.lib vfw32.lib winmm.lib kernel32.lib advapi32.lib version.lib largeint.lib user32.lib
gdi32.lib comctl32.lib ole32.lib olepro32.lib oleaut32.lib uuid.lib
新增標頭檔案:
#include
#include
#include
生成全球唯一標識,這裡這樣
define_guid(clsid_pushtest,
0xfd501041, 0x8ebe, 0x11ce, 0x81, 0x83, 0x00, 0xaa, 0x00, 0x57, 0x7d, 0xa1);
第三步:註冊等函式的新增
首先修改入口函式,並新增註冊和反註冊函式,操作後的內容如下:
//註冊
stdapi dllregisterserver()
//反註冊
stdapi dllunregisterserver()
//filter的入口函式
extern "c" bool winapi dllentrypoint(hinstance, ulong, lpvoid);
bool apientry dllmain(handle hmodule,
dword dwreason,
lpvoid lpreserved)
此時編譯會有class cfactorytemplate沒實現等錯誤,下面我們來實現它。
新增下面的**,每個地方我基本都加了大體意思的注釋:
/**************開始填寫註冊資訊***************/
//**型別
const amoviesetup_mediatype sudoppintypes =
; //pin的資訊
const amoviesetup_pin sudoppin =
; const amoviesetup_filter sudballax =
; //建立例項時用,有類,名字等需要的資訊
cfactorytemplate g_templates =
}; int g_ctemplates = sizeof(g_templates) / sizeof(g_templates[0]);
通過上面的注釋,我們看到該filter有乙個輸出pin,支援video型別等等資訊,不多說了。
這裡主要對pushtestfilter::createinstance //建立乙個例項用的函式
說明一下!!pushtestfilter就是我們的filter類!!在下面實現它。
第四步:filter類的實現
新增新類pushtestfilter,使其繼承自csource。這就是我們的filter類,在這個類裡面沒有過多的操作,就只有2個函式而已:
//filter的主類,繼承自csource
class pushtestfilter : public csource
; 這裡有2點需要注意:
建構函式pushtestfilter()是private的,不是一般的public!!!!!!!!!!!
createinstance()函式是static的,因為它不能通過物件來呼叫!!!!
2個函式的具體實現如下:
//建構函式,注意這裡是private屬性的,不是public,
//所以要建立它的例項,只能是通過createinstance()函式的方式
pushtestfilter::pushtestfilter(lpunknown lpunk, hresult *phr):
csource(name("pushtest"), lpunk, clsid_pushtest)
//為剛分配的那個空間付值,這就自動給filter加入了乙個pin,析構的
//時候會自動釋放
m_pastreams[0] = new pushtesipin(phr,this,l"push_test");
if(m_pastreams[0] == null) }
//createinstance()該函式是static屬性的,因為不能通過物件來呼叫
cunknown * winapi pushtestfilter::createinstance(lpunknown lpunk, hresult *phr)
return punk;
} 這裡的類pushtesipin就是我們的pin類,在後面要實現!!其實主要的操作是在pin類pushtesipin裡面的。
第五步:pin類的實現
新增類pushtesipin,使其繼承自csourcestream。這裡需要過載的函式會多一點!不過沒關係!我會乙個乙個的進行說明。
主要是這3個:
//由於我們的filter就一種**型別,所以過載了getmediatype(cmediatype *pmediatype)
//如果有多種型別,就應該過載另外2個函式了,具體參考基類csourcestream
hresult getmediatype(cmediatype *pmediatype);
//這個函式是用來設定sample大小的,在pin連線成功後會被呼叫
hresult decidebuffersize(imemallocator *pimemalloc,allocator_properties *pproperties);
//對sample資料的填充
hresult fillbuffer(imediasample *pms);
其實這個filter沒做別的,就相當與將sdk下的pushsource例子自己再寫了一遍,主要是為了說明這個過程,
確定project->seetings->link下object/library modules裡面加上:
strmbasd.lib winmm.lib msvcrtd.lib quartz.lib
ODATA入門 filter實現
在odata中,我們可以指定某些字段值的篩選。如 sap opu odata sap zdemo po srv zpoheaderset?filter ebeln eq 4500000002 語法 filter 其中操作符支援 eq ne,le,lt ge,gt。現在來實現zpoheaderset ...
Filter與Listener入門學習
1 概念 2 快速入門 webfilter 訪問所有資源之前都會執行該過濾器 public class filterdemo implements filter override public void dofilter servletrequest servletrequest,servletre...
DirectShow程式設計之Filter原理
在directshow系統概述中介紹了directshow的總體系統框架。本文我們從程式設計師的角度,進一步深入 一下directshow的應用以及filter的開發。學習directshow filter的開發,不外乎以下幾種方法 看幫助文件 看示例 和看sdk基類源 看幫助文件,應著重於總體概念...