設定視訊壓縮屬性
[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]
視訊壓縮篩選器可以支援其輸出針腳上的 IAMVideoCompression 介面。 使用此介面可設定壓縮屬性,例如主要畫面格速率、每個主要畫面格的預測 (P) 畫面數,以及相對壓縮品質。
首先,呼叫 IBaseFilter::EnumPins 方法來尋找篩選的輸出釘選,並查詢介面的針腳。 某些篩選完全不支援 介面。 其他人可能會公開 介面,但不支援每個壓縮屬性。 若要判斷支援哪些屬性,請呼叫 IAMVideoCompression::GetInfo。 此方法會傳回數項資訊:
- 一組功能旗標
- 描述性字串和版本號碼字串
- 支援) 時,主要畫面播放速率、P 畫面播放速率和品質 (的預設值
方法具有下列語法:
hr = pCompress->GetInfo(pszVersion, &cbVersion, pszDesc, &cbDesc,
&lKeyFrame, &lPFrame, &dblQuality, &lCap);
pszVersion和pszDesc參數是接收版本字串和描述字串的寬字元緩衝區。 cbVersion和cbDesc參數會接收所需的緩衝區大小,以位元組為單位, (不是字元) 。 lKeyFrame、lPFrame和dblQuality參數會接收主要畫面播放速率、P 畫面播放速率和品質的預設值。 品質會以從 0.0 到 1.0 的浮點數表示。 lCap參數會接收由CompressionCaps列舉類型所定義的功能旗標位OR。
任何這些參數可以是 Null,在此情況下,方法會忽略該參數。 例如,若要配置版本和描述字串的緩衝區,請先在第一個和第三個參數中使用 Null 呼叫 方法。 使用 cbVersion 和 cbDesc 的傳回值來配置緩衝區,然後再次呼叫 方法:
int cbVersion, cbDesc; // Size in bytes, not characters!
hr = pCompress->GetInfo(0, &cbVersion, 0, &cbDesc, 0, 0, 0, 0);
if (SUCCEEDED(hr))
{
WCHAR *pszVersion = new WCHAR[cbVersion/2]; // Wide character = 2 bytes
WCHAR *pszDesc = new WCHAR[cbDesc/2];
hr = pCompress->GetInfo(pszVersion, 0, pszDesc, 0, 0, 0, 0, 0);
}
lCap的值表示篩選支援的其他IAMVideoCompression方法之哪一種。 例如,如果 lCap 包含CompressionCaps_CanKeyFrame旗標,您可以呼叫 IAMVideoCompression::get_KeyFrameRate 以取得主要畫面播放速率和 IAMVideoCompression::p ut_KeyFrameRate 來設定主要畫面播放速率。 負值表示篩選會使用預設值,如從 IAMVideoCompression::GetInfo取得。 例如:
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
{
lKeyFrame = lDefaultKeyFrame; // From GetInfo.
}
}
下列程式碼範例會嘗試在輸出釘選上尋找 IAMVideoCompression 介面。 如果成功,它會擷取壓縮屬性的預設值和實際值:
HRESULT hr = E_FAIL;
IEnumPins *pEnum = NULL;
IPin *pPin = NULL;
IAMVideoCompression *pCompress = NULL;
// Find the pin that supports IAMVideoCompression (if any).
pFilter->EnumPins(&pEnum);
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
hr = pPin->QueryInterface(IID_IAMVideoCompression, (void**)&pCompress);
pPin->Release();
if (SUCCEEDED(hr)) // Found the interface.
{
break;
}
}
if (SUCCEEDED(hr))
{
long lCap; // Capability flags
long lKeyFrame, lPFrame; // Real values
double m_Quality;
long lKeyFrameDef, lPFrameDef; // Default values
double QualityDef;
// Get default values and capabilities.
hr = pCompress->GetInfo(0, 0, 0, 0, &KeyFrameDef, &lPFrameDef,
&QualityDef, &lCap);
if (SUCCEEDED(hr))
{
// Get actual values where possible.
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
lKeyFrame = lKeyFrameDef;
}
if (lCap & CompressionCaps_CanBFrame)
{
hr = pCompress->get_PFramesPerKeyFrame(&lPFrame);
if (FAILED(hr) || lPFrame < 0)
lPFrame = lPFrameDef;
}
if (lCap & CompressionCaps_CanQuality)
{
hr = pCompress->get_Quality(&Quality);
if (FAILED(hr) || Quality < 0)
Quality = QualityDef;
}
}
}
注意
如果您使用ICaptureGraphBuilder2介面來建置圖形,您可以呼叫ICaptureGraphBuilder2::FindInterface來取得IAMVideoCompression介面,而不是使用IBaseFilter::EnumPins。 FindInterface方法是協助程式方法,可搜尋圖形中指定介面的篩選和釘選。