常數比特率編碼
在常數位速率 (CBR) 編碼中,編碼器會在編碼會話開始之前知道輸出媒體樣本的比特率和緩衝區視窗(流失值區參數)。 編碼器會使用相同數位來編碼整個檔案持續時間內的每秒樣本,以達到數據流的目標比特率。 這會限制數據流樣本大小的變化。 此外,在編碼會話期間,位速率不完全位於指定的值,但仍接近目標比特率。
當您想要知道檔案的比特率或大約持續時間,而不剖析整個檔案時,CBR 編碼很有用。 在即時串流案例中,需要以可預測的比特率和一致的頻寬使用量串流媒體內容。
CBR 編碼的缺點是編碼內容的品質不會是常數。 由於某些內容較難以壓縮,因此 CBR 數據流的部分品質會比其他內容低。 例如,典型的電影有一些場景相當靜態,有些場景充滿了動作。 如果您使用 CBR 來編碼電影,則靜態場景因此容易有效率地編碼,其質量會高於動作場景,因此需要較高的樣本大小,才能維持相同的品質。
一般而言,CBR 檔案質量的變化會以較低的比特率更明顯。 以較高的比特率,CBR 編碼檔案的品質仍會有所不同,但質量問題對使用者較不明顯。 使用 CBR 編碼時,您應該將頻寬設定為傳遞案例允許的頻寬。
CBR 組態設定
您必須在編碼會話之前指定編碼類型和各種數據流特定設定,以設定編碼器。
若要設定 CBR 編碼的編碼器
指定 CBR 編碼模式。
根據預設,編碼器會設定為使用 CBR 編碼。 編碼器組態是透過屬性值來設定。 這些屬性定義於 wmcodecdsp.h 中。 您可以將 MFPKEY_VBRENABLED 屬性設定為 VARIANT_FALSE,以明確指定此模式。 如需如何在編碼器上設定屬性的詳細資訊,請參閱 設定編碼器。
選擇編碼比特率。
針對 CBR 編碼,您必須知道編碼會話開始之前要編碼數據流的比特率。 您必須在設定編碼器期間設定比特率。 若要這樣做,當您執行媒體類型交涉時,請檢查可用輸出媒體類型的 MF_MT_AUDIO_AVG_BYTES_PER_SECOND 屬性(適用於音訊串流)或 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;
}
流失貯體設定
針對 CBR 編碼,數據流的平均和最大流失值區值都相同。 如需這些參數的詳細資訊,請參閱 流失貯體緩衝區模型。
若要使用 CBR 編碼的音訊串流,您必須在編碼器上交涉輸出媒體類型之後設定流失值區值。 編碼器會根據輸出媒體類型上設定的平均比特率,在內部計算緩衝區視窗。
若要設定流失值區值,請建立 DWORD 陣列,可以在媒體接收屬性存放區中的 MFPKEY_ASFSTREAMSINK_CORRECTED_LEAKYBUCKET 屬性中設定下列值。 如需詳細資訊,請參閱在檔案接收 中設定屬性。
- 平均比特率:從媒體類型交涉期間選取的輸出媒體類型取得平均比特率。 使用 MF_MT_AUDIO_AVG_BYTES_PER_SECOND 屬性。
- 緩衝區視窗:查詢 IWMCodecLeakyBucket 介面的編碼器,然後呼叫 IWMCodecLeakyBucket::GetBufferSizeBits (wmcodecifaces.h, wmcodecdspuuid.lib)。
- 初始緩衝區大小:設定為 0。
相關主題