共用方式為


設定視訊輸出格式

[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]

注意

本主題所述的功能已被取代。 若要設定擷取裝置的輸出格式,應用程式應該在pmt參數中使用IAMStreamConfig::GetFormat所傳回的AM_MEDIA_TYPE結構。

 

擷取裝置可以支援各種輸出格式。 例如,裝置可能支援 16 位 RGB、32 位 RGB 和 YUYV。 在這些格式中,裝置可以支援各種畫面大小。

在 WDM 裝置中, IAMStreamConfig 介面用來報告裝置支援的格式,以及設定格式。 (針對舊版 VFW 裝置,請使用 [視訊格式 VFW] 對話方塊,如 顯示 VFW擷取對話方塊中所述。) IAMStreamConfig 介面會在擷取篩選器的擷取釘選、預覽釘選或兩者上公開。 使用 ICaptureGraphBuilder2::FindInterface 方法來取得介面指標:

IAMStreamConfig *pConfig = NULL;
hr = pBuild->FindInterface(
    &PIN_CATEGORY_PREVIEW, // Preview pin.
    0,    // Any media type.
    pCap, // Pointer to the capture filter.
    IID_IAMStreamConfig, (void**)&pConfig);

裝置有其支援的媒體類型清單。 針對每個媒體類型,裝置也會提供一組功能。 這些包括適用于該格式的框架大小範圍、裝置可以縮放或縮小影像的方式,以及畫面播放速率的範圍。

若要取得媒體類型的數目,請呼叫 IAMStreamConfig::GetNumberOfCapabilities 方法。 方法會傳回兩個值:

  • 媒體類型的數目。
  • 保存功能資訊的結構大小。

大小值是必要的,因為 IAMStreamConfig 介面同時用於音訊和視訊 (,而且可以擴充至其他媒體類型) 。 針對影片,這些功能會使用 VIDEO_STREAM_CONFIG_CAPS 結構來描述,而音訊則會使用 AUDIO_STREAM_CONFIG_CAPS 結構。

若要列舉媒體類型,請使用以零起始的索引呼叫 IAMStreamConfig::GetStreamCaps 方法。 GetStreamCaps方法會傳回媒體類型和對應的功能結構:

int iCount = 0, iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);

// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
{
    // Use the video capabilities structure.

    for (int iFormat = 0; iFormat < iCount; iFormat++)
    {
        VIDEO_STREAM_CONFIG_CAPS scc;
        AM_MEDIA_TYPE *pmtConfig;
        hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
        if (SUCCEEDED(hr))
        {
            /* Examine the format, and possibly use it. */

            // Delete the media type when you are done.
            DeleteMediaType(pmtConfig);
        }
}

請注意結構如何配置給 GetStreamCaps 方法。 方法會配置媒體類型結構,而呼叫端則會配置功能結構。 將功能結構強制轉型為位元組陣列指標。 完成媒體類型之後,請刪除 AM_MEDIA_TYPE 結構,以及媒體類型的格式區塊。

您可以將裝置設定為使用 GetStreamCaps 方法中傳回的格式。 只要使用媒體類型呼叫 IAMStreamConfig::SetFormat

hr = pConfig->SetFormat(pmtConfig);

如果未連接針腳,它會嘗試在連線時使用此格式。 如果針腳已經連線,它會嘗試使用新的格式重新連線。 不論是哪一種情況,下游篩選準則都可能會拒絕格式。

您也可以先修改媒體類型,再將它傳遞至 SetFormat 方法。 這是 VIDEO_STREAM_CONFIG_CAPS 結構所在的位置。 它會描述變更媒體類型的所有有效方式。 若要使用這項資訊,您必須瞭解該特定媒體類型的詳細資料。

例如,假設 GetStreamCaps 會傳回 24 位 RGB 格式,其畫面大小為 320 x 240 圖元。 您可以檢查媒體類型的主要類型、子類型和格式區塊,以取得這項資訊:

if ((pmtConfig.majortype == MEDIATYPE_Video) &&
    (pmtConfig.subtype == MEDIASUBTYPE_RGB24) &&
    (pmtConfig.formattype == FORMAT_VideoInfo) &&
    (pmtConfig.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
    (pmtConfig.pbFormat != NULL))
{
    VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig.pbFormat;
    // pVih contains the detailed format information.
    LONG lWidth = pVih->bmiHeader.biWidth;
    LONG lHeight = pVih->bmiHeader.biHeight;
}

VIDEO_STREAM_CONFIG_CAPS結構提供可用於此媒體類型的最小和最大寬度和高度。 它也提供「步驟」大小,其定義您可以調整寬度或高度的遞增。 例如,裝置可能會傳回下列專案:

  • MinOutputSize:160 x 120
  • MaxOutputSize:320 x 240
  • OutputGranularityX:8 圖元 (水準步驟大小)
  • OutputGranularityY:8 圖元 (垂直步驟大小)

根據這些數位,您可以將寬度設定為範圍中的任何專案, (160、168、176、 ...304、312、320) ,以及範圍中任何高度 (120、128、136...104、112、120) 。 下圖說明此程序。

視訊格式大小

若要設定新的框架大小,請直接修改GetStreamCaps中傳回的AM_MEDIA_TYPE結構:

pVih->bmiHeader.biWidth = 160;
pVih->bmiHeader.biHeight = 120;
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);

然後,將媒體類型傳遞至 SetFormat 方法,如先前所述。

VIDEO_STREAM_CONFIG_CAPSMinFrameInterval 和 MaxFrameInterval成員是每個視訊畫面的最小和最大長度,您可以轉譯成畫面播放速率,如下所示:

frames per second = 10,000,000 / frame duration

若要要求特定畫面播放速率,請修改媒體類型中VIDEOINFOHEADER 或 VIDEOINFOHEADER2結構中的AvgTimePerFrame值。 裝置可能不支援最小值和最大值之間的每個可能值,因此驅動程式會使用最接近的值。 若要查看驅動程式實際使用的值,請在呼叫SetFormat之後呼叫IAMStreamConfig::GetFormat

有些驅動程式可能會針對MaxFrameInterval的值回報MAXLONGLONG (0x7FFFFFFFFFFFFFFF) ,這表示沒有最大持續時間。 不過,您可能想要在應用程式中強制執行最小畫面播放速率,例如 1 fps。

關於媒體類型

設定視訊擷取裝置