支援 AVStream 編解碼器中的動態格式變更
當動態格式變更發生在執行中的媒體資料流程時,系統提供的 Devproxy 模組會與擷取針腳交涉,以判斷是否可接受新的格式。
當動態格式變更源自媒體來源時,就會發生下列事件順序:
驅動程式會收到 KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT 要求,以判斷輸入 KS 針腳是否支援新的媒體類型。 驅動程式必須支援這個屬性。
如果輸入針腳支援新的媒體類型,KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT處理常式應該會傳回STATUS_SUCCESS。 然後,驅動程式會使用建議的輸入與目前選取的輸出媒體類型,判斷是否可以繼續資料流程。 如果是,資料流程會繼續。
如果輸入針腳不支援新建議的媒體類型,KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT處理常式應該會傳回錯誤。 然後,HW MFT 會與連接的元件重新分類媒體類型。
如果輸入針腳支援新的媒體輸入類型,但 KS 篩選器需要不同的輸出媒體類型,驅動程式應該會產生 KSEVENT_DYNAMIC_FORMAT_CHANGE 事件,如本主題稍後所述,通知 HW MFT 有關媒體類型變更。
當 HW MFT 收到 KSEVENT 通知時,它會將輸出針腳從 KSSTATE_RUN 轉換為KSSTATE_STOP。
HW MFT 接著會查詢驅動程式是否有可用的媒體類型,這會轉譯為驅動程式 的 AVStrMiniIntersectHandlerEx 交集處理常式的呼叫。 驅動程式應該會依喜好設定的順序報告慣用的輸出媒體類型。
使用者模式用戶端會選取媒體類型,並在 HW MFT 的輸出針腳上設定新的媒體類型。 這會導致呼叫驅動程式的 AVStrMiniPinSetDataFormat 分派常式。 如果驅動程式透過傳回STATUS_SUCCESS來接受格式,串流會以新的媒體類型繼續執行。 如果呼叫失敗,則格式變更所涉及的元件必須重新分類媒體類型。
HW MFT 會檢查連線媒體是否有任何變更。 如果沒有變更,它會在釘選上設定選取的媒體類型,並將它放入KSSTATE_RUN。 如果連線媒體有變更,HW MFT 會終結針腳,並使用新選取的媒體類型和媒體重新建立。 然後,MFT 會將針腳放入KSSTATE_RUN。
串流繼續。
在某些情況下,媒體來源可能不會偵測到格式變更。 例如,MPEG2 解碼器必須解碼每個封包,才能尋找任何格式變更。
在這種情況下,如果驅動程式偵測到格式變更,硬體驅動程式應該會產生動態格式變更 KSEVENT。 HW MFT 接著會查詢其支援的媒體類型針腳。 針腳應該會依喜好設定順序傳回慣用的媒體類型。 接著,HW MFT 會遵循上一節步驟 4 到 9 中所述的事件順序。
如果驅動程式無法處理這類格式變更,它應該會傳回串流錯誤,然後傳播至 MF。
下列程式碼範例示範如何使用 KSEVENT 來定義新的動態格式變更:
// {162AC456-83D7-4239-96DF-C75FFA138BC6}
#define STATIC_KSEVENTSETID_DynamicFormatChange\
0x162ac456, 0x83d7, 0x4239, 0x96, 0xdf, 0xc7, 0x5f, 0xfa, 0x13, 0x8b, 0xc6 DEFINE_GUIDSTRUCT("162AC456-83D7-4239-96DF-C75FFA138BC6", KSEVENTSETID_ DynamicFormatChange);
#define KSEVENTSETID_DynamicFormatChange DEFINE_GUIDNAMED(KSEVENTSETID_ DynamicFormatChange)
typedef enum {
KSEVENT_DYNAMIC_FORMAT_CHANGE = 0
};
DEFINE_KSEVENT_TABLE(DynamicFormatChangeEventTable) {
DEFINE_KSEVENT_ITEM
(
KSEVENT_DYNAMIC_FORMAT_CHANGE,
sizeof(KSEVENTDATA),
0,
NULL,
NULL,
NULL
)
};
KSEVENT_SET PinEventTable[] =
{
DEFINE_KSEVENT_SET
(
&KSEVENTSETID_DynamicFormatChange,
SIZEOF_ARRAY(DynamicFormatChangeEventTable),
DynamicFormatChangeEventTable
)
};
每個針腳都應該在其釘選描述元中公開此事件。 事件的類型為 KSEVENTF_EVENT_HANDLE。
在驅動程式產生此事件之前,它應該根據目前選取的輸入媒體類型,設定 KS 針腳的慣用媒體類型。 您可以在針腳的描述項上使用 _KsEdit 函式來執行此動作。
若要產生事件,驅動程式應該呼叫 KsGenerateEvents。