步驟 4: 設定配置器屬性
[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]
這是 撰寫轉換篩選器教學課程的步驟 4。
注意
衍生自 CTransInPlaceFilter的篩選準則不需要此步驟。
在兩個針腳同意媒體類型之後,他們會選取連接的配置器,並交涉配置器屬性,例如緩衝區大小和緩衝區數目。
在 CTransformFilter 類別中,有兩個配置器,一個用於上游針腳連接,另一個用於下游針腳連接。 上游篩選會選取上游配置器,並選擇配置器屬性。 輸入針腳會接受上游篩選準則所決定的任何專案。 如果您需要修改此行為,請覆寫 CBaseInputPin::NotifyAllocator 方法。
轉換篩選的輸出針腳會選取下游配置器。 它會執行下列步驟:
- 如果下游篩選準則可以提供配置器,則輸出針腳會使用該配置器。 否則,輸出針腳會建立新的配置器。
- 如果有任何) 呼叫 IMemInputPin::GetAllocatorRequirements,輸出針腳會取得下游篩選準則的配置器需求 (。
- 輸出針腳會呼叫轉換篩選器的 CTransformFilter::D ecideBufferSize 方法,這是純虛擬的。 這個方法的參數是配置器的指標,以及具有下游篩選準則需求的 ALLOCATOR_PROPERTIES 結構。 如果下游篩選沒有配置器需求,結構就會零出。
- 在 DecideBufferSize 方法中,衍生類別會呼叫 IMemAllocator::SetProperties來設定配置器屬性。
一般而言,衍生類別會根據輸出格式、下游篩選的需求,以及篩選本身的需求來選取配置器屬性。 嘗試選取與下游篩選要求相容的屬性。 否則,下游篩選可能會拒絕連線。
在下列範例中,RLE 編碼器會設定緩衝區大小、緩衝區對齊和緩衝區計數的最小值。 針對前置詞,它會使用下游篩選所要求的任何值。 前置詞通常是零個位元組,但有些篩選準則需要它。 例如, AVI Mux 篩選器會使用前置詞來寫入 RIFF 標頭。
HRESULT CRleFilter::DecideBufferSize(
IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
{
AM_MEDIA_TYPE mt;
HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
if (FAILED(hr))
{
return hr;
}
ASSERT(mt.formattype == FORMAT_VideoInfo);
BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
pProp->cbBuffer = DIBSIZE(*pbmi) * 2;
if (pProp->cbAlign == 0)
{
pProp->cbAlign = 1;
}
if (pProp->cBuffers == 0)
{
pProp->cBuffers = 1;
}
// Release the format block.
FreeMediaType(mt);
// Set allocator properties.
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pProp, &Actual);
if (FAILED(hr))
{
return hr;
}
// Even when it succeeds, check the actual result.
if (pProp->cbBuffer > Actual.cbBuffer)
{
return E_FAIL;
}
return S_OK;
}
配置器可能無法完全符合您的要求。 因此,SetProperties方法會在上一個範例 (Actual參數的個別ALLOCATOR_PROPERTIES結構中傳回實際結果) 。 即使 SetProperties 成功,您也應該檢查結果,以確定它們符合您篩選的最低需求。
自訂配置器
根據預設,所有篩選類別都會針對其配置 器使用 CMemAllocator 類別。 這個類別會使用 VirtualAlloc) ,從用戶端進程 (的虛擬位址空間配置記憶體。 如果您的篩選需要使用某種其他類型的記憶體,例如 DirectDraw 表面,您可以實作自訂配置器。 您可以使用 CBaseAllocator 類別,或撰寫全新的配置器類別。 如果您的篩選有自訂配置器,請根據哪一個針腳使用配置器來覆寫下列方法:
- 輸入釘選: CBaseInputPin::GetAllocator 和 CBaseInputPin::NotifyAllocator。
- 輸出釘選: CBaseOutputPin::D ecideAllocator。
如果其他篩選拒絕使用自訂配置器進行連線,您的篩選準則可能會失敗連線,或與其他篩選的配置器連線。 在後者的情況下,您可能需要設定內部旗標,指出配置器的類型。 如需此方法的範例,請參閱 CDrawImage 類別。
下一 步:步驟 5。轉換影像。
相關主題