媒體類型轉換
有時候,必須從 DirectShow 或 Windows Media Format SDK 在 Media Foundation 媒體類型與較舊的媒體類型結構之間進行轉換。
從格式結構到媒體基礎類型
下列函式會從格式結構初始化 Media Foundation 媒體類型。 如果資料流程或檔案標頭包含格式結構,這些函式也很有用。 例如,WAVE 音訊檔案的檔案標頭包含 WAVEATEX 結構。
從媒體基礎類型到格式結構
下列函式會從 Media Foundation 媒體類型建立或初始化格式結構。
格式對應
下表列出對應至各種格式結構的 Media Foundation 屬性。 並非所有屬性都可以直接翻譯。 若要執行轉換,您應該使用上一節所列的函式;這些資料表主要提供供參考。
AM_MEDIA_TYPE
成員 | 屬性 |
---|---|
bTemporalCompression | MF_MT_ALL_SAMPLES_INDEPENDENT |
bFixedSizeSamples | MF_MT_FIXED_SIZE_SAMPLES |
lSampleSize | MF_MT_SAMPLE_SIZE |
電壓X、波狀XTENSIBLE
成員 | 屬性 |
---|---|
wFormatTag |
MF_MT_SUBTYPE 如果 wFormatTag 是WAVE_FORMAT_EXTENSIBLE, 則會在 SubFormat 成員中找到子類型。 |
nChannels | MF_MT_AUDIO_NUM_CHANNELS |
nSamplesPerSec | MF_MT_AUDIO_SAMPLES_PER_SECOND |
nAvgBytesPerSec | MF_MT_AUDIO_AVG_BYTES_PER_SECOND |
nBlockAlign | MF_MT_AUDIO_BLOCK_ALIGNMENT |
wBitsPerSample | MF_MT_AUDIO_BITS_PER_SAMPLE |
wValidBitsPerSample | MF_MT_AUDIO_VALID_BITS_PER_SAMPLE |
wSamplesPerBlock | MF_MT_AUDIO_SAMPLES_PER_BLOCK |
dwChannelMask | MF_MT_AUDIO_CHANNEL_MASK |
SubFormat | MF_MT_SUBTYPE |
額外的資料 | MF_MT_USER_DATA |
VIDEOINFOHEADER、VIDEOINFOHEADER2
成員 | 屬性 |
---|---|
dwBitRate | MF_MT_AVG_BITRATE |
dwBitErrorRate | MF_MT_AVG_BIT_ERROR_RATE |
AvgTimePerFrame | MF_MT_FRAME_RATE;使用 MFAverageTimePerFrameToFrameRate 計算此值。 |
dwInterlaceFlags | MF_MT_INTERLACE_MODE |
dwCopyProtectFlags | 未定義對等專案 |
dwPictAspectRatioX, dwPictAspectRatioY | MF_MT_PIXEL_ASPECT_RATIO;必須從圖片外觀比例轉換為圖片外觀比例。 |
dwControlFlags | MF_MT_PAD_CONTROL_FLAGS。 如果 AMCONTROL_COLORINFO_PRESENT旗標 存在,請設定擴充色彩資訊中所述的 擴充色彩屬性。 |
bmiHeader.biWidth、 bmiHeader.biHeight | MF_MT_FRAME_SIZE |
bmiHeader.biBitCount | 在子類型中隱含 (MF_MT_SUBTYPE) 。 |
bmiHeader.biCompression | 在子類型中隱含。 |
bmiHeader.biSizeImage | MF_MT_SAMPLE_SIZE |
調色盤資訊 | MF_MT_PALETTE |
您可以從VIDEOINFOHEADER 或 VIDEOINFOHEADER2結構推斷下列屬性,但也需要一些格式詳細資料的知識。 例如,不同的 YUV 格式有不同的步進需求。
MPEG1VIDEOINFO
成員 | 屬性 |
---|---|
dwStartTimeCode | MF_MT_MPEG_START_TIME_CODE |
bSequenceHeader | MF_MT_MPEG_SEQUENCE_HEADER |
biXPelsPerMeter、 biYPelsPerMeter | MF_MT_PIXEL_ASPECT_RATIO |
MPEG2VIDEOINFO
成員 | 屬性 |
---|---|
dwStartTimeCode | MF_MT_MPEG_START_TIME_CODE |
dwSequenceHeader | MF_MT_MPEG_SEQUENCE_HEADER |
dwProfile | MF_MT_MPEG2_PROFILE |
dwLevel | MF_MT_MPEG2_LEVEL |
dwFlags | MF_MT_MPEG2_FLAGS |
範例
下列程式碼會從視訊媒體類型填入 BITMAPINFOHEADER 結構。 請注意,此轉換會遺失部分格式資訊, (交錯、畫面播放速率、擴充色彩資料) 。 不過,從視訊畫面儲存點陣圖時可能很有用,例如。
#include <dshow.h>
#include <dvdmedia.h>
// Converts a video type to a BITMAPINFO structure.
// The caller must free the structure by calling CoTaskMemFree.
// Note that this conversion loses some format information, including
// interlacing, and frame rate.
HRESULT GetBitmapInfoHeaderFromMFMediaType(
IMFMediaType *pType, // Pointer to the media type.
BITMAPINFOHEADER **ppBmih, // Receives a pointer to the structure.
DWORD *pcbSize) // Receives the size of the structure.
{
*ppBmih = NULL;
*pcbSize = 0;
GUID majorType = GUID_NULL;
AM_MEDIA_TYPE *pmt = NULL;
DWORD cbSize = 0;
DWORD cbOffset = 0;
BITMAPINFOHEADER *pBMIH = NULL;
// Verify that this is a video type.
HRESULT hr = pType->GetMajorType(&majorType);
if (FAILED(hr))
{
goto done;
}
if (majorType != MFMediaType_Video)
{
hr = MF_E_INVALIDMEDIATYPE;
goto done;
}
hr = pType->GetRepresentation(AM_MEDIA_TYPE_REPRESENTATION, (void**)&pmt);
if (FAILED(hr))
{
goto done;
}
if (pmt->formattype == FORMAT_VideoInfo)
{
cbOffset = (FIELD_OFFSET(VIDEOINFOHEADER,bmiHeader));
}
else if (pmt->formattype == FORMAT_VideoInfo2)
{
cbOffset = (FIELD_OFFSET(VIDEOINFOHEADER2,bmiHeader));
}
else
{
hr = MF_E_INVALIDMEDIATYPE; // Unsupported format type.
goto done;
}
if (pmt->cbFormat - cbOffset < sizeof(BITMAPINFOHEADER))
{
hr = E_UNEXPECTED; // Bad format size.
goto done;
}
cbSize = pmt->cbFormat - cbOffset;
pBMIH = (BITMAPINFOHEADER*)CoTaskMemAlloc(cbSize);
if (pBMIH == NULL)
{
hr = E_OUTOFMEMORY;
goto done;
}
CopyMemory(pBMIH, pmt->pbFormat + cbOffset, cbSize);
*ppBmih = pBMIH;
*pcbSize = cbSize;
done:
if (pmt)
{
pType->FreeRepresentation(AM_MEDIA_TYPE_REPRESENTATION, pmt);
}
return hr;
}
相關主題