[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、IMFMediaEngine,以及媒體基礎結構中的音訊/視訊擷取 取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayer、IMFMediaEngine 和 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]
Letterbox 和 PanScan
4x3 影像可以藉由填補影像的頂端和底部(稱為 Letterbox 影像)或擷取影像的 4x3 部分來形成(稱為 PanScan 影像)。 功能表和子圖片串流會覆迭在最終影片影像之上。 16x9 比例影像會以 4x3 橢圓格式儲存。 將變形寬銀幕的 4x3 長寬比 720x480 源視頻伸展到 16x9 長寬比,即可形成原始的 16x9 長寬比影像。
以下說明如何正確顯示每個模式及其醒目提示:
- Widescreen: 來源視訊延展至輸出視窗的最大 16x9 區域。 亮點是相對於 16x9 區域內的。 黑條應新增至頂端和底部或側邊,以維持 16x9 區域。
- 平移掃描: 從 16x9 視訊中,使用 MPEG2 數據流中提供的水準位移來擷取 4x3 子視窗。 將 4x3 子視窗放入輸出客戶端視窗的最大 4x3 區域。 醒目提示的座標相對於 4x3 輸出視窗,且與來源 16x9 視訊沒有關聯性。 黑條應新增至頂端與底部或側邊,以維持 4x3 區域。
- Letterbox: 計算輸出視窗的最大 4x3 區域。 可以在頂部和底部或者側邊加上黑條,以維持 4x3 的區域。 來源4x3 視訊 (代表 16x9 影像) 放置在 4x3 區域內最大的 16x9 子視窗中。 黑條應該新增至子視窗的頂端和底部,以維持 16x9 區域。 亮點的座標是相對於 4x3 區域的,與 16x9 原始影片無關。 磁碟可以指定位於 16x9 區域外的醒目提示(但仍在 4x3 視窗中)。 針對 4x3 視訊,影片會放在輸出客戶端視窗的最大 4x3 輸出區域中。 黑條應新增至頂端和底部或側邊,以維持 4x3 區域。
DVD 導覽器和 VMR 的 MPEG 前置處理
目前,譯碼器會傳遞FORMAT_MPEG2_VIDEO媒體類型(其格式區塊指向 MPEG2VIDEOINFO 結構)。 在輸出引腳上,解碼器會產生 FORMAT_VideoInfo2 媒體類型,其格式區塊指向 VIDEOINFOHEADER2 結構。 結構的 dwReserved 欄位已重新命名為 dwControls 旗標。
dwControlFlags 成員現在將包含新的位元。
| 標籤 | 價值 |
|---|---|
| AMCONTROL_USED | 0x00000001 |
| AMCONTROL_PAD_TO_4x3 | 0x00000002 |
| AMCONTROL_PAD_TO_16x9 | 0x00000004 |
AMCONTROL_USED用來測試是否支持這些新旗標。 來源過濾器應設定 AMCONTROL_USED 標記,並確認 QueryAccept(MediaType) 是否在下游端子上成功。 如果遭到拒絕,就無法使用AMCONTROL旗標,而且 dwReserved1 必須設定為 0。
AMCONTROL_PAD_TO_4x3 表示影像應填充並顯示於 4x3 區域內。
AMCONTROL_PAD_TO_16x9表示影像應填補並顯示在16x9區域中。
譯碼器應該直接複製或處理位元。 如果解碼器本身執行信箱格式,則必須改變像素外形比例,填充影像並移除相應的AMCONTROL_*位。
MPEG2VIDEOINFO.dwFlags 現在包含三個旗標,可用來控制內容的顯示方式:
AMMPEG2_DoPanScan (0x00000001):如果設定此旗標,MPEG-2 視訊譯碼器應該根據picture_display_extension中的平移掃描向量裁剪輸出影像,並將圖片外觀比例變更為 4x3。 VMR 不應該收到具有此旗標的 16x9 範例。 簡單的實作可能會改變來源矩形,以指出一個寬度為540的來源區域,而該區域的左邊緣等於picture_display_extension中的顯示位移。AMMPEG2_LetterboxAnalogOut (0x00000020):當硬體譯碼器將此數據流顯示到視訊輸出時(通常是卡片上的 SVIDEO 連接器),它應該套用規則,以在 4x3 顯示器上顯示 16x9 範例。處理映射時,軟體譯碼器(或產生傳送至 VMR 輸出的硬體譯碼器)有兩個選項:
- 忽略此旗標,並將 VideoInfoHeader2 內容傳遞至 VMR(範例上的 DVD 導覽器 已經設定AMCONTROL_PAD_TO_4x3旗標)。 VMR 會遇到 16x9 視訊範例,並設有 AMCONTROL_PAD_TO_4x3 旗標和 4x3 子畫面流。 應用程式必須將兩個數據流的輸出標準化目的地矩形設定為相同的寬度。
- 將變形數據流轉換為 4x3 影像,方法是填補影像的頂端和底部,並將影像長寬比設定為 4x3(參閱上文之加黑邊處理),並從 VIDEOINFOHEADER2 移除 AMCONTROL_PAD_TO_4x3 位元。
混合視訊和子圖片數據流的 DirectXVA 譯碼器必須處理此旗標。 如果硬體無法調整混合的子圖形,譯碼器應該會產生個別的子圖片串流,讓 VMR 與影片混合。
AMMPEG2_WidescreenAnalogOut (0x00000200):當硬體譯碼器將此數據流顯示到視訊輸出時(通常是卡片上的 SVIDEO 連接器),它應該假設 16x9 (變形) 顯示器。軟體譯碼器(或產生傳送至 VMR 輸出的硬體譯碼器)在處理變形映射時有兩個選項:
- 忽略此旗標,並將 VideoInfoHeader2 內容複製到 VMR。 如果 VMR 已設定 AMCONTROL_PAD_TO_16x9,VMR 會將 4x3 圖片填補到 16x9。
- 將輸出的影像填充至16x9比例,並移除AMCONTROL_PAD_TO_16x9位。
大部分譯碼器應該使用 GetMediaType 來偵測輸入釘選上的媒體變更,並將 VIDEOINFOHEADER2 內容(包含在 MPEG2INFOHEADER中)複製到輸出釘選。 他們可能只會處理 PanScan 位元。
下列範例程式代碼示範如何將 VIDEOINFOHEADER2 內容從輸入釘選複製到輸出釘選。
#include <dvdmedia.h>
HRESULT CopyMPeg2ToVideoInfoHeader2(CMediaSample* pInSample, CMediaSample* pOutSample)
{
HRESULT hr = S_OK;
// Check for a media type on the input sample.
AM_MEDIA_TYPE* pInType;
if (pInSample->GetMediaType(&pInType) == S_OK)
{
// Make sure it's an MPEG2 Video format.
if ((pInType->formattype == FORMAT_MPEG2_VIDEO) &&
(pInType->cbFormat >= sizeof(MPEG2VIDEOINFO)))
{
hr = S_OK; // Initialize hr for the CMediaType constructor.
CMediaType outType(*pInType, &hr);
if (FAILED(hr))
{
DeleteMediaType( pInType );
return hr;
}
// Set the format type GUID.
outType.SetFormatType(&FORMAT_VideoInfo2);
// Truncate the format block to include just the VIDEOINFOHEADER part.
MPEG2VIDEOINFO *pMPeg2Header = (MPEG2VIDEOINFO*)pInType->pbFormat;
BYTE *pVIH = (BYTE*)&pMPeg2Header->hdr;
hr = (outType.SetFormat(pVIH, sizeof(VIDEOINFOHEADER2)) ? S_OK : E_OUTOFMEMORY);
if (SUCCEEDED(hr))
{
hr = pOutSample->SetMediaType(&outType);
}
}
else
{
ASSERT(FALSE); // Not a MPEG2 header.
hr = VFW_E_INVALIDMEDIATYPE;
}
DeleteMediaType( pInType );
}
return hr;
}