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;
}

ASF 編碼類型