媒体类型转换
有时需要在媒体基础媒体类型和 DirectShow 或 Windows 媒体格式 SDK 中的旧媒体类型结构之间进行转换。
从格式结构到媒体基础类型
以下函数从格式结构初始化 Media Foundation 媒体类型。 如果数据流或文件头包含格式结构,这些函数也很有用。 例如,WAVE 音频文件的文件头包含 WAVEFORMATEX 结构。
从媒体基础类型到格式结构
以下函数从媒体基础媒体类型创建或初始化格式结构。
格式映射
下表列出了对应于各种格式结构的媒体基础属性。 并非所有这些属性都可以直接转换。 若要执行转换,应使用上一部分中列出的函数;这些表主要供参考。
AM_MEDIA_TYPE
成员 | 属性 |
---|---|
bTemporalCompression | MF_MT_ALL_SAMPLES_INDEPENDENT |
bFixedSizeSamples | MF_MT_FIXED_SIZE_SAMPLES |
lSampleSize | MF_MT_SAMPLE_SIZE |
WAVEFORMATEX、WAVEFORMATEXTENSIBLE
成员 | 属性 |
---|---|
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;
}
相关主题