MPEG 解碼器前置處理轉換
[與此頁面相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議使用舊版 API 的現有程式碼盡可能重寫為使用新的 API。
Letterbox 和 PanScan
4x3 影像可以藉由填補影像的頂端和底部, (稱為 Letterbox 影像) ,或擷取 4x3 部分的影像, (稱為 PanScan 影像) 來形成。 功能表和子圖形串流會覆寫在最終影片影像之上。 16x9 比例影像會以 4x3 同型格式儲存。 將多型 4x3 外觀比例 720x480 來源視訊延展為 16x9 外觀比例,形成原始的 16x9 外觀影像。
以下是如何正確顯示每個模式及其醒目提示的描述:
- 寬屏: 來源視訊會延展至輸出視窗的最大 16x9 區域。 醒目提示相對於 16x9 區域內的 。 黑色橫條應該新增至頂端和底部或側邊,以維持 16x9 區域。
- 移動流覽掃描: 從 16x9 視訊中,使用 MPEG2 資料流程中提供的水準位移來擷取 4x3 子視窗。 將 4x3 子視窗放在輸出用戶端視窗的最大 4x3 區域。 醒目提示的座標相對於 4x3 輸出視窗,且與來源 16x9 視訊沒有關聯性。 黑色橫條應該新增至頂端和底部或側邊,以維護 4x3 區域。
- 信箱: 計算輸出視窗的最大 4x3 區域。 黑色橫條應該新增至頂端和底部或側邊,以維護 4x3 區域。 代表 16x9 影像) 的來源多型 4x3 視訊 (放在 4x3 區域內的最大 16x9 子視窗。 黑色橫條應該新增至子視窗的頂端和底部,以維持 16x9 區域。 醒目提示的座標相對於 4x3 區域,且與來源 16x9 視訊沒有關聯性。 磁片可以指定位於 16x9 區域的醒目提示 (,但仍位於 4x3 視窗) 。 針對 4x3 視訊,視訊會放在輸出用戶端視窗的最大 4x3 輸出區域。 黑色橫條應該新增至頂端和底部或側邊,以維護 4x3 區域。
MPEG 前置處理與 DVD 導覽器和 VMR
目前,解碼器會傳遞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 範例。 簡單的實作可能會改變來源矩形,以指出左邊緣等於picture_display_extension中顯示位移的 540 寬來源區域。AMMPEG2_LetterboxAnalogOut (0x00000020)
:當硬體解碼器將此串流顯示至視訊輸出 (卡片上的 SVIDEO 連接器) 時,它應該套用規則,以在 4x3 顯示器上顯示 16x9 範例。軟體解碼器 (或硬體解碼器,在處理映射時會產生傳送至 VMR) 的輸出有兩個選項:
- 忽略此旗標,並將 VideoInfoHeader2 內容傳遞至 VMR (範例) 上的 DVD 導覽器 已設定AMCONTROL_PAD_TO_4x3旗標。 VMR 將遇到 16x9 影片範例,其中包含AMCONTROL_PAD_TO_4x3旗標集和 4x3 子圖片資料流程。 應用程式必須將兩個數據流的輸出標準化目的地矩形設定為相同的寬度。
- 藉由填補影像的頂端和底部,並將影像外觀比例設定為 4x3 (請參閱) 上方的 Letterbox,並從 VIDEOINFOHEADER2 移除AMCONTROL_PAD_TO_4x3位,以將反轉資料流程轉換成 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來偵測輸入針腳上的媒體變更,並將MPEG2INFOHEADER) 中包含的VIDEOINFOHEADER2 (內容複寫到輸出針腳。 它們可能只會處理 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;
}