DirectShow開發快速入門之事件通知機制

2021-06-15 22:42:43 字數 2289 閱讀 1975

摘要:這篇文件描述directshow中事件產生的機制,以及應用程式是如何處理事件的。

概述

事件是graph圖和應用程式之間互相通訊的機制,類似於訊息機制。當某個事件發生時,比如資料流結束,產生乙個錯誤等,filter就要給filter圖表管理器(graph manager)傳送乙個事件通知。filter圖表管理器處理其中的一部分事件,將其他事件要交給應用程式處理。如果圖表管理器沒有處理乙個filter事件,它就把事件通知放入到乙個佇列中,圖表管理器也可以將自己的事件通知放進佇列中。然後應用程式可以自己處理佇列中的事件。directshow中的事件通知就和windows的訊息機制差不多。filter,圖表管理器和應用程式通過這種機制就可以互相通訊。

如何處理事件

filter圖表管理器暴露了三個介面用來處理事件通知

imediaeventsink filter用這個介面來post事件。

imediaevent 應用程式利用這個介面來從佇列中查詢訊息

imediaeventex 是imediaevent的擴充套件。

filter都是通過呼叫圖表管理器的 imediaeventsink::notify方法來通知圖表管理器某種事件發生。事件通知包括乙個事件code,這個code不僅僅代表了事件的型別,還包含兩個dword型別的引數用來傳遞一些其他的資訊。

關於事件code的內容,在下面的乙個專題中列出,這裡暫略,使用時可以參考幫助。

應用程式通過呼叫圖表管理器的imediaevent::getevent方法來從事件佇列中獲取事件。如果有事件發生,該函式就返回乙個事件碼和兩個引數,如果沒有事件,則一直阻塞直到有事件發生和超過某個時間。呼叫getevent函式後,應用程式必須呼叫imediaevent::freeeventparams來釋放事件碼所帶引數的資源。例如,某個引數可能是由filter graph分配的記憶體。

下面的**演示了如何從事件佇列中提取事件

為了過載filter圖表管理器對事件的預設處理,你可以使用某個事件碼做引數呼叫imediaevent::canceldefaulthandling ,這樣就可以遮蔽圖表管理器對某個事件碼的處理了。如果要恢復圖表管理器對該事件碼的預設處理,可以呼叫 imediaevent::restoredefaulthandling。如果圖表管理器對某個事件碼沒有預設的處理,呼叫這兩個函式是不起作用的。

事件是如何發生的

為了處理事件,應用程式需要一種機制來獲取正在佇列中等待的事件。filter圖表管理器提供了兩種方法。

1、視窗通知,圖表管理器傳送開發者自己定義的視窗訊息

2、事件訊號 如果佇列中有dshow事件,就用事件訊號通知應用程式,如果隊列為空就重新設定事件訊號。

下面的**演示了如何利用訊息通知

然後在視窗訊息處理過程中處理該訊息如下:

由於事件通知和視窗的訊息迴圈都是非同步的,因此,當你的應用程式處理訊息的時候,佇列中或許有n個事件等待處理。因此,在你呼叫getevent的時候,一定要迴圈呼叫,直到返回乙個錯誤碼,這表明佇列是空的。

當你釋放imediaeventex 指標時,你可以呼叫setnotifywindow來取消事件通知,記住此時要給這個函式傳遞乙個null指標。在你的事件處理程式中,在呼叫getevent之前一定要檢查imediaeventex指標是否為空,這樣就可以避免錯誤。

下面看看採取事件訊號的通知方式。

在filter圖表管理器裡有乙個手動設定的event核心物件,用來反映事件佇列的狀態。如果佇列中有等待處理的事件,event就處於通知狀態,如果佇列是空的,imediaevent::getevent函式呼叫就會重置該event物件。

應用程式可以呼叫imediaevent::geteventhandle獲得event核心物件的控制代碼,然後就可以呼叫waitformultipleobjects來等待事件的發生,如果event被通知了,就可以呼叫imediaevent::getevent來獲得dshow的事件。

下面的**演示了如何利用event核心物件來獲取ec_complete事件:

handle hevent;

long evcode, param1, param2;

boolean bdone = false;

hresult hr = s_ok;

hr = pevent->geteventhandle((oaevent*)&hevent);

if (failed(hr)

while(!bdone) }}

事件通知碼(event notification codes)

常用的事件通知碼如下:

DirectShow開發快速入門之二資料流的流動

directshow資料流動概述 filter之間的資料是通過sample來傳送的。sample是乙個com元件,擁有自己的一段資料緩衝buffer,這個com元件暴露了imediasample介面。這個sample一般都有乙個叫做記憶體分配器 alloctor 的com物件來建立管理,這個物件具有...

DirectShow開發快速入門之慨述(三)

4 samples和allocators filters通過pin的連線來傳遞資料,資料流是從乙個filter的輸出pin流向相連的filter的輸入pin。輸出pin常用的傳遞資料的方式是呼叫輸入pin上的imeminputpin receive方法。對於filter來說,可以有好幾種方式來分配 ...

DirectShow開發快速入門之資料流的流動

摘要 本篇文件中主要講述了graph圖表中資料流是如何傳遞的,如果你是做directshow的應用開發也許對於這些細節並不需要了解,如果你要開發自己的filter,就很有必要了解這些細節。directshow資料流動概述 filter之間的資料是通過sample來傳送的。sample是乙個com元件...