Media Type Conversions

Occasionally it is necessary to convert between Media Foundation media types and the older media type structures from DirectShow or the Windows Media Format SDK.

From a Format Structure to a Media Foundation Type

The following functions initialize a Media Foundation media type from a format structure. These functions are also useful if a data stream or a file header contains a format structure. For example, the file header for WAVE audio files contains a WAVEFORMATEX structure.

Structure to Convert Function
AM_MEDIA_TYPE (DirectShow)
DMO_MEDIA_TYPE (DirectX Media Objects)
WM_MEDIA_TYPE (Windows Media Format SDK)
Note: These structures are equivalent.
MFInitMediaTypeFromAMMediaType
BITMAPINFOHEADER MFCreateVideoMediaTypeFromBitMapInfoHeaderEx
MFVIDEOFORMAT MFInitMediaTypeFromMFVideoFormat
MPEG1VIDEOINFO MFInitMediaTypeFromMPEG1VideoInfo
MPEG2VIDEOINFO MFInitMediaTypeFromMPEG2VideoInfo
VIDEOINFOHEADER2 MFInitMediaTypeFromVideoInfoHeader2
VIDEOINFOHEADER MFInitMediaTypeFromVideoInfoHeader
WAVEFORMATEX or WAVEFORMATEXTENSIBLE MFInitMediaTypeFromWaveFormatEx

 

From a Media Foundation Type to a Format Structure

The following functions create or initialize a format structure from a Media Foundation media type.

Function Target Structure
IMFMediaType::GetRepresentation AM_MEDIA_TYPE, MFVIDEOFORMAT, VIDEOINFOHEADER, or VIDEOINFOHEADER2
MFCreateAMMediaTypeFromMFMediaType AM_MEDIA_TYPE
MFCreateMFVideoFormatFromMFMediaType MFVIDEOFORMAT
MFCreateWaveFormatExFromMFMediaType WAVEFORMATEX or WAVEFORMATEXTENSIBLE
MFInitAMMediaTypeFromMFMediaType AM_MEDIA_TYPE

 

Format Mappings

The following tables list the Media Foundation attributes that correspond to various format structures. Not all of these attributes can be translated directly. To perform conversions, you should use the functions listed in the previous section; these tables are provided mainly for reference.

AM_MEDIA_TYPE

Member Attribute
bTemporalCompression MF_MT_ALL_SAMPLES_INDEPENDENT
bFixedSizeSamples MF_MT_FIXED_SIZE_SAMPLES
lSampleSize MF_MT_SAMPLE_SIZE

 

WAVEFORMATEX, WAVEFORMATEXTENSIBLE

Member Attribute
wFormatTag MF_MT_SUBTYPE
If wFormatTag is WAVE_FORMAT_EXTENSIBLE, the subtype is found in the SubFormat member.
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
Extra data MF_MT_USER_DATA

 

VIDEOINFOHEADER, VIDEOINFOHEADER2

Member Attribute
dwBitRate MF_MT_AVG_BITRATE
dwBitErrorRate MF_MT_AVG_BIT_ERROR_RATE
AvgTimePerFrame MF_MT_FRAME_RATE; use MFAverageTimePerFrameToFrameRate to calculate this value.
dwInterlaceFlags MF_MT_INTERLACE_MODE
dwCopyProtectFlags No defined equivalent
dwPictAspectRatioX, dwPictAspectRatioY MF_MT_PIXEL_ASPECT_RATIO; must convert from picture aspect ratio to picture aspect ratio.
dwControlFlags MF_MT_PAD_CONTROL_FLAGS. If the AMCONTROL_COLORINFO_PRESENT flag is present, set the extended color attributes described in Extended Color Information.
bmiHeader.biWidth, bmiHeader.biHeight MF_MT_FRAME_SIZE
bmiHeader.biBitCount Implicit in the subtype (MF_MT_SUBTYPE).
bmiHeader.biCompression Implicit in the subtype.
bmiHeader.biSizeImage MF_MT_SAMPLE_SIZE
Palette information MF_MT_PALETTE

 

The following attributes can be inferred from the VIDEOINFOHEADER or VIDEOINFOHEADER2 structure but also require some knowledge of the format details. For example, different YUV formats have different stride requirements.

MPEG1VIDEOINFO

Member Attribute
dwStartTimeCode MF_MT_MPEG_START_TIME_CODE
bSequenceHeader MF_MT_MPEG_SEQUENCE_HEADER
biXPelsPerMeter, biYPelsPerMeter MF_MT_PIXEL_ASPECT_RATIO

 

MPEG2VIDEOINFO

Member Attribute
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

 

Examples

The following code fills in a BITMAPINFOHEADER structure from a video media type. Note that this conversions loses some of the format information (interlacing, frame rate, extended color data). However, it might be useful when saving a bitmap from a video frame, for example.

#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;
}

Media Types