常數位元速率編碼

在常數位速率 (CBR) 編碼中,編碼器知道輸出媒體樣本的位元速率,以及緩衝區視窗 (在編碼會話開始之前) 流失貯體參數。 編碼器會使用相同數目的位,在檔案的持續時間內編碼每秒鐘的樣本,以達到資料流程的目標位元速率。 這會限制資料流程樣本的大小變化。 此外,在編碼會話期間,位速率不完全位於指定的值,但會維持接近目標位元速率。

CBR 編碼在您想要在不剖析完整檔案的情況下,想知道位元速率或檔案的約略長度時十分好用。 這在即時資料流中是必要的,因為媒體內容需要以可預測的位元速率以及固定的頻寬用量來進行串流。

CBR 編碼的缺點是編碼內容的品質不會是常數。 由於某些內容較難以壓縮,所以 CBR 資料流程的元件品質會比其他內容低。 例如,典型的電影有一些場景相當靜態,有些場景則完全是動作。 如果您使用 CBR 編碼電影,靜態場景因此容易有效率地編碼,其品質會高於動作場景,其樣本大小需要較高的樣本大小,才能維持相同的品質。

一般而言,CBR 檔案品質的變化會以較低的位元速率更明顯。 以較高的位元速率,CBR 編碼檔案的品質仍會有所不同,但品質問題對使用者較不明顯。 使用 CBR 編碼時,您應該將頻寬設定為高,因為您的傳遞案例允許。

CBR 組態設定

您必須在編碼會話之前指定編碼類型和各種資料流程特定設定,以設定編碼器。

設定 CBR 編碼的編碼器

  1. 指定 CBR 編碼模式。

    根據預設,編碼器會設定為使用 CBR 編碼。 編碼器組態是透過屬性值來設定。 這些屬性定義于 wmcodecdsp.h 中。 您可以將 MFPKEY_VBRENABLED 屬性設定為 VARIANT_FALSE ,以明確指定此模式。 如需如何在編碼器上設定屬性的詳細資訊,請參閱 設定編碼器

  2. 選擇編碼位元速率。

    針對 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 屬性中設定下列值。 如需詳細資訊,請參閱 在檔案接收中設定屬性

ASF 編碼類型

教學課程:1-Pass Windows 媒體編碼

教學課程:使用 CBR 編碼撰寫 WMA 檔案