媒體類型轉換
有時候,必須從 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 |
工作訊號、超聲波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.biWidthbmiHeader.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 |
biXPelsPerMeterbiYPelsPerMeter | 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;
}
相關主題