共用方式為


如何設定視訊擷取格式

視訊擷取裝置可能支援數種擷取格式。 格式通常會因壓縮類型、色彩空間 (YUV 或 RGB) 、畫面大小或畫面播放速率而有所不同。

支援的格式清單包含在 簡報描述元中。 如需詳細資訊,請參閱 簡報描述元

若要列舉支援的格式:

  1. 建立擷取裝置的媒體來源。 請參閱 列舉視訊擷取裝置
  2. 在媒體來源上呼叫 IMFMediaSource::CreatePresentationDescriptor 以取得簡報描述元。
  3. 呼叫 IMFPresentationDescriptor::GetStreamDescriptorByIndex 以取得視訊串流的資料流程描述元。
  4. 在資料流程描述元上呼叫 IMFStreamDescriptor::GetMediaTypeHandler
  5. 呼叫 IMFMediaTypeHandler::GetMediaTypeCount 以取得支援的格式數目。
  6. 在迴圈中,呼叫 IMFMediaTypeHandler::GetMediaTypeByIndex 以取得每個格式。 格式是以 媒體類型表示。 如需詳細資訊,請參閱 視訊媒體類型

下列範例會列舉裝置的擷取格式:

HRESULT EnumerateCaptureFormats(IMFMediaSource *pSource)
{
    IMFPresentationDescriptor *pPD = NULL;
    IMFStreamDescriptor *pSD = NULL;
    IMFMediaTypeHandler *pHandler = NULL;
    IMFMediaType *pType = NULL;

    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    BOOL fSelected;
    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSD->GetMediaTypeHandler(&pHandler);
    if (FAILED(hr))
    {
        goto done;
    }

    DWORD cTypes = 0;
    hr = pHandler->GetMediaTypeCount(&cTypes);
    if (FAILED(hr))
    {
        goto done;
    }

    for (DWORD i = 0; i < cTypes; i++)
    {
        hr = pHandler->GetMediaTypeByIndex(i, &pType);
        if (FAILED(hr))
        {
            goto done;
        }

        LogMediaType(pType);
        OutputDebugString(L"\n");

        SafeRelease(&pType);
    }

done:
    SafeRelease(&pPD);
    SafeRelease(&pSD);
    SafeRelease(&pHandler);
    SafeRelease(&pType);
    return hr;
}

LogMediaType此範例中使用的函式列于媒體類型偵錯程式碼主題中。

若要設定擷取格式:

  1. 取得 IMFMediaTypeHandler 介面的指標,如上一個範例所示。
  2. 呼叫 IMFMediaTypeHandler::GetMediaTypeByIndex 以取得索引所指定的所需格式。
  3. 呼叫 IMFMediaTypeHandler::SetCurrentMediaType 來設定格式。

如果您未設定擷取格式,裝置會使用其預設格式。

下列範例會設定擷取格式:

HRESULT SetDeviceFormat(IMFMediaSource *pSource, DWORD dwFormatIndex)
{
    IMFPresentationDescriptor *pPD = NULL;
    IMFStreamDescriptor *pSD = NULL;
    IMFMediaTypeHandler *pHandler = NULL;
    IMFMediaType *pType = NULL;

    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    BOOL fSelected;
    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSD->GetMediaTypeHandler(&pHandler);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->GetMediaTypeByIndex(dwFormatIndex, &pType);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->SetCurrentMediaType(pType);

done:
    SafeRelease(&pPD);
    SafeRelease(&pSD);
    SafeRelease(&pHandler);
    SafeRelease(&pType);
    return hr;
}

傳回格式的順序取決於裝置。 一般而言,它們會先依壓縮類型或色彩空間分組;然後,從最小畫面大小到每個群組內的最大畫面大小。

畫面播放速率的處理方式與其他格式屬性稍有不同。 如需詳細資訊,請參閱 如何設定視訊擷取畫面播放速率

注意

在某些裝置中,格式清單會包含每個格式的重複專案。 例如,如果裝置支援 15 個不同的擷取格式,清單將包含 30 個專案。 在每個配對內,其中一個媒體類型的屬性 MF_MT_AM_FORMAT_TYPE 等於 FORMAT_VideoInfo,而另一個類型則 MF_MT_AM_FORMAT_TYPE 等於 FORMAT_VideoInfo2。 (這兩個值定義在標頭檔 uuids.h.) 第二個類型也可能包含其他色彩資訊 (擴充色彩資訊) ,或顯示不同的交錯 (MF_MT_INTERLACE_MODE) 值。 這些重複的類型存在,可支援較舊的 DirectShow 應用程式。 在 Media Foundation 應用程式中,每當列出重複的FORMAT_VideoInfo2類型時,您應該忽略FORMAT_VideoInfo類型。

 

影片擷