Quality-Based 變數比特率編碼
與 常數比特率編碼(CBR)不同,編碼器會努力維持編碼媒體的特定比特率,在可變比特率 (VBR) 模式中,編碼器會努力達到編碼媒體的最佳品質。 CBR 和 VBR 之間的主要差異是所使用的緩衝區視窗大小。 相較於 CBR 編碼數據流,VBR 編碼數據流通常會有大型緩衝區視窗。
編碼內容的品質取決於壓縮內容時遺失的數據量。 許多因素會影響壓縮過程中的數據遺失;但一般而言,原始數據越複雜,壓縮比例越高,壓縮過程中會遺失越多細節。
在以質量為基礎的 VBR 模式中,您不會定義編碼器必須遵循的比特率或緩衝區視窗。 相反地,您可以指定數位媒體串流的品質層級,而不是比特率。 編碼器會壓縮內容,讓所有樣本都具有可比較的品質;這可確保不論產生的數據流的緩衝區需求為何,在播放期間內的品質都一致。
以質量為基礎的 VBR 編碼通常會建立大型壓縮數據流。 一般而言,這種類型的編碼非常適合本機播放或高頻寬網路連線(或下載和播放)。 例如,您可以撰寫應用程式,將歌曲從 CD 複製到電腦上的 ASF 檔案。 使用以質量為基礎的 VBR 編碼可確保複製的所有歌曲品質都相同。 在這些情況下,一致的品質將提供更好的用戶體驗。
以質量為基礎的 VBR 編碼的缺點是,在編碼會話之前,確實沒有辦法知道編碼媒體的大小或頻寬需求,因為編碼器會使用單一編碼傳遞。 這可能會使以品質為基礎的 VBR 編碼檔案不適合記憶體或頻寬受限的情況,例如在可攜式媒體播放機上播放內容,或透過低頻寬網路串流。
編碼器的 Quality-Based VBR 編碼設定
編碼器組態是透過屬性值來設定。 這些屬性定義於 wmcodecdsp.h 中。 在交涉輸出媒體類型之前,必須在編碼器上設定組態屬性。 如需如何在編碼器上設定屬性的詳細資訊,請參閱 設定編碼器。
下列清單顯示您必須針對這種類型的編碼設定的屬性:
- 將 MFPKEY_VBRENABLED 屬性設定為 VARIANT_TRUE,以指定 VBR 編碼模式。
- 將 MFPKEY_PASSESUSED 設定為 1,因為此 VBR 模式會使用一個編碼階段。
- 藉由設定 MFPKEY_DESIRED_VBRQUALITY 屬性,設定所需的品質等級(從 0 到 100)。 以質量為基礎的 VBR 不會將內容編碼為任何預先定義的緩衝區參數。 不論產生的比特率需求為何,都會針對整個數據流維護此品質等級。
- 針對視訊串流,請將編碼器輸出媒體類型的 MF_MT_AVG_BITRATE 屬性中的平均比特率設定為非零值。 編碼會話完成之後,就會更新精確的比特率。
下列程式代碼範例顯示 SetEncodingProperties 的實作。 此函式會設定 CBR 和 VBR 的數據流層級編碼屬性。
//-------------------------------------------------------------------
// SetEncodingProperties
// Create a media source from a URL.
//
// guidMT: Major type of the stream, audio or video
// pProps: A pointer to the property store in which
// to set the required encoding properties.
//-------------------------------------------------------------------
HRESULT SetEncodingProperties (const GUID guidMT, IPropertyStore* pProps)
{
if (!pProps)
{
return E_INVALIDARG;
}
if (EncodingMode == NONE)
{
return MF_E_NOT_INITIALIZED;
}
HRESULT hr = S_OK;
PROPVARIANT var;
switch (EncodingMode)
{
case CBR:
// Set VBR to false.
hr = InitPropVariantFromBoolean(FALSE, &var);
if (FAILED(hr))
{
goto done;
}
hr = pProps->SetValue(MFPKEY_VBRENABLED, var);
if (FAILED(hr))
{
goto done;
}
// Set the video buffer window.
if (guidMT == MFMediaType_Video)
{
hr = InitPropVariantFromInt32(VIDEO_WINDOW_MSEC, &var);
if (FAILED(hr))
{
goto done;
}
hr = pProps->SetValue(MFPKEY_VIDEOWINDOW, var);
if (FAILED(hr))
{
goto done;
}
}
break;
case VBR:
//Set VBR to true.
hr = InitPropVariantFromBoolean(TRUE, &var);
if (FAILED(hr))
{
goto done;
}
hr = pProps->SetValue(MFPKEY_VBRENABLED, var);
if (FAILED(hr))
{
goto done;
}
// Number of encoding passes is 1.
hr = InitPropVariantFromInt32(1, &var);
if (FAILED(hr))
{
goto done;
}
hr = pProps->SetValue(MFPKEY_PASSESUSED, var);
if (FAILED(hr))
{
goto done;
}
// Set the quality level.
if (guidMT == MFMediaType_Audio)
{
hr = InitPropVariantFromUInt32(98, &var);
if (FAILED(hr))
{
goto done;
}
hr = pProps->SetValue(MFPKEY_DESIRED_VBRQUALITY, var);
if (FAILED(hr))
{
goto done;
}
}
else if (guidMT == MFMediaType_Video)
{
hr = InitPropVariantFromUInt32(95, &var);
if (FAILED(hr))
{
goto done;
}
hr = pProps->SetValue(MFPKEY_VBRQUALITY, var);
if (FAILED(hr))
{
goto done;
}
}
break;
default:
hr = E_UNEXPECTED;
break;
}
done:
PropVariantClear(&var);
return hr;
}
相關主題