Medientypkonvertierungen

Gelegentlich ist es erforderlich, zwischen Media Foundation-Medientypen und den älteren Medientypstrukturen aus DirectShow oder dem Windows Media Format SDK zu konvertieren.

Von einer Formatstruktur zu einem Media Foundation-Typ

Die folgenden Funktionen initialisieren einen Media Foundation-Medientyp aus einer Formatstruktur. Diese Funktionen sind auch nützlich, wenn ein Datenstrom oder ein Dateiheader eine Formatstruktur enthält. Beispielsweise enthält der Dateiheader für WAVE-Audiodateien eine WAVEFORMATEX-Struktur .

Zu konvertierende Struktur Funktion
AM_MEDIA_TYPE (DirectShow)
DMO_MEDIA_TYPE (DirectX-Medienobjekte)
WM_MEDIA_TYPE (Windows Media Format SDK)
Hinweis: Diese Strukturen sind gleichwertig.
MFInitMediaTypeFromAMMediaType
BITMAPINFOHEADER MFCreateVideoMediaTypeFromBitMapInfoHeaderEx
MFVIDEOFORMAT MFInitMediaTypeFromMFVideoFormat
MPEG1VIDEOINFO MFInitMediaTypeFromMPEG1VideoInfo
MPEG2VIDEOINFO MFInitMediaTypeFromMPEG2VideoInfo
VIDEOINFOHEADER2 MFInitMediaTypeFromVideoInfoHeader2
VIDEOINFOHEADER MFInitMediaTypeFromVideoInfoHeader
WAVEFORMATEX oder WAVEFORMATEXTENSIBLE MFInitMediaTypeFromWaveFormatEx

 

Von einem Media Foundation-Typ zu einer Formatstruktur

Die folgenden Funktionen erstellen oder initialisieren eine Formatstruktur aus einem Media Foundation-Medientyp.

Funktion Zielstruktur
IMFMediaType::GetRepresentation AM_MEDIA_TYPE, MFVIDEOFORMAT, VIDEOINFOHEADER oder VIDEOINFOHEADER2
MFCreateAMMediaTypeFromMFMediaType AM_MEDIA_TYPE
MFCreateMFVideoFormatFromMFMediaType MFVIDEOFORMAT
MFCreateWaveFormatExFromMFMediaType WAVEFORMATEX oder WAVEFORMATEXTENSIBLE
MFInitAMMediaTypeFromMFMediaType AM_MEDIA_TYPE

 

Formatzuordnungen

In den folgenden Tabellen sind die Media Foundation-Attribute aufgeführt, die verschiedenen Formatstrukturen entsprechen. Nicht alle dieser Attribute können direkt übersetzt werden. Zum Ausführen von Konvertierungen sollten Sie die im vorherigen Abschnitt aufgeführten Funktionen verwenden. diese Tabellen werden hauptsächlich als Referenz bereitgestellt.

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
Wenn wFormatTag WAVE_FORMAT_EXTENSIBLE ist, wird der Untertyp im SubFormat-Element gefunden.
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
Zusätzliche Daten 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; Verwenden Sie MFAverageTimePerFrameToFrameRate , um diesen Wert zu berechnen.
dwInterlaceFlags MF_MT_INTERLACE_MODE
dwCopyProtectFlags Kein definiertes Äquivalent
dwPictAspectRatioX, dwPictAspectRatioY MF_MT_PIXEL_ASPECT_RATIO; muss vom Bildseitenverhältnis in das Bildseitenverhältnis konvertiert werden.
dwControlFlags MF_MT_PAD_CONTROL_FLAGS. Wenn das flag AMCONTROL_COLORINFO_PRESENT vorhanden ist, legen Sie die erweiterten Farbattribute fest, die unter Erweiterte Farbinformationen beschrieben werden.
bmiHeader.biWidth, bmiHeader.biHeight MF_MT_FRAME_SIZE
bmiHeader.biBitCount Implizit im Untertyp (MF_MT_SUBTYPE).
bmiHeader.biCompression Implizit im Untertyp.
bmiHeader.biSizeImage MF_MT_SAMPLE_SIZE
Paletteninformationen MF_MT_PALETTE

 

Die folgenden Attribute können aus der VIDEOINFOHEADER - oder VIDEOINFOHEADER2-Struktur abgeleitet werden, erfordern aber auch einige Kenntnisse der Formatdetails. Beispielsweise gelten für verschiedene YUV-Formate unterschiedliche Stride-Anforderungen.

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

 

Beispiele

Der folgende Code füllt eine BITMAPINFOHEADER-Struktur aus einem Videomedientyp aus. Beachten Sie, dass durch diese Konvertierungen einige der Formatinformationen (Interlacing, Framerate, erweiterte Farbdaten) verloren gehen. Es kann jedoch nützlich sein, wenn sie z. B. eine Bitmap aus einem Videoframe speichern.

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

Medientypen