Conversioni dei tipi di supporto

Occasionalmente è necessario convertire tra tipi di supporti di Media Foundation e le strutture del tipo di supporto meno recenti da DirectShow o Windows Media Format SDK.

Da una struttura di formato a un tipo di base multimediale

Le funzioni seguenti inizializzano un tipo di supporto di Media Foundation da una struttura di formato. Queste funzioni sono utili anche se un flusso di dati o un'intestazione di file contiene una struttura di formato. Ad esempio, l'intestazione di file per i file audio WAVE contiene una struttura WAVEFORMATEX .

Struttura da convertire Funzione
AM_MEDIA_TYPE (DirectShow)
DMO_MEDIA_TYPE (oggetti multimediali DirectX)
WM_MEDIA_TYPE (Windows Media Format SDK)
Nota: Queste strutture sono equivalenti.
MFInitMediaTypeFromAMMediaType
BITMAPINFOHEADER MFCreateVideoMediaTypeFromBitMapInfoHeaderEx
MFVIDEOFORMAT MFInitMediaTypeFromMFVideoFormat
MPEG1VIDEOINFO MFInitMediaTypeFromMPEG1VideoInfo
MPEG2VIDEOINFO MFInitMediaTypeFromMPEG2VideoInfo
VIDEOINFOHEADER2 MFInitMediaTypeFromVideoInfoHeader2
VIDEOINFOHEADER MFInitMediaTypeFromVideoInfoHeader
WAVEFORMATEX o WAVEFORMATEXTENSIBLE MFInitMediaTypeFromWaveFormatEx

 

Da un tipo di media foundation a una struttura di formato

Le funzioni seguenti creano o inizializzano una struttura di formato da un tipo di supporto di Media Foundation.

Funzione Struttura di destinazione
FMMediaType::GetRepresentation AM_MEDIA_TYPE, MFVIDEOFORMAT, VIDEOINFOHEADER o VIDEOINFOHEADER2
MFCreateAMMediaTypeFromMFMediaType AM_MEDIA_TYPE
MFCreateMFVideoFormatFromMFMediaType MFVIDEOFORMAT
MFCreateWaveFormatExFromMFMediaType WAVEFORMATEX o WAVEFORMATEXTENSIBLE
MFInitAMMediaTypeFromMFMediaType AM_MEDIA_TYPE

 

Mapping di formato

Le tabelle seguenti elencano gli attributi di Media Foundation corrispondenti a varie strutture di formato. Non tutti questi attributi possono essere convertiti direttamente. Per eseguire conversioni, è necessario usare le funzioni elencate nella sezione precedente; queste tabelle vengono fornite principalmente per riferimento.

AM_MEDIA_TYPE

Membro Attributo
bTemporalCompression MF_MT_ALL_SAMPLES_INDEPENDENT
bFixedSizeSamples MF_MT_FIXED_SIZE_SAMPLES
lSampleSize MF_MT_SAMPLE_SIZE

 

WAVEFORMATEX, WAVEFORMATEXEXTENSIBLE

Membro Attributo
wFormatTag MF_MT_SUBTYPE
Se wFormatTag è WAVE_FORMAT_EXTENSIBLE, il sottotipo viene trovato nel membro 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
SottoFormat MF_MT_SUBTYPE
Dati aggiuntivi MF_MT_USER_DATA

 

VIDEOINFOHEADER, VIDEOINFOHEADER2

Membro Attributo
dwBitRate MF_MT_AVG_BITRATE
dwBitErrorRate MF_MT_AVG_BIT_ERROR_RATE
AvgTimePerFrame MF_MT_FRAME_RATE; usare MFAverageTimePerFrameToFrameRate per calcolare questo valore.
dwInterlaceFlags MF_MT_INTERLACE_MODE
dwCopyProtectFlags Nessun equivalente definito
dwPictAspectRatioX, dwPictAspectRatioY MF_MT_PIXEL_ASPECT_RATIO; deve essere convertito da proporzioni immagine a proporzioni immagine.
dwControlFlags MF_MT_PAD_CONTROL_FLAGS. Se il flag AMCONTROL_COLORINFO_PRESENT è presente, impostare gli attributi di colore estesi descritti in Informazioni sul colore esteso.
bmiHeader.biWidth, bmiHeader.biHeight MF_MT_FRAME_SIZE
bmiHeader.biBitCount Implicito nel sottotipo (MF_MT_SUBTYPE).
bmiHeader.biCompression Implicito nel sottotipo.
bmiHeader.biSizeImage MF_MT_SAMPLE_SIZE
Informazioni sul riquadro MF_MT_PALETTE

 

Gli attributi seguenti possono essere dedotti dalla struttura VIDEOINFOHEADER o VIDEOINFOHEADER2 , ma richiedono anche alcune informazioni sui dettagli del formato. Ad esempio, diversi formati YUV hanno requisiti stride diversi.

MPEG1VIDEOINFO

Membro Attributo
dwStartTimeCode MF_MT_MPEG_START_TIME_CODE
bSequenceHeader MF_MT_MPEG_SEQUENCE_HEADER
biXPelsPerMeter, biYPelsPerMeter MF_MT_PIXEL_ASPECT_RATIO

 

MPEG2VIDEOINFO

Membro Attributo
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

 

Esempio

Il codice seguente compila una struttura BITMAPINFOHEADER da un tipo di supporto video. Si noti che queste conversioni perdono alcune delle informazioni sul formato (interlacciamento, frequenza dei fotogrammi, dati di colore estesi). Tuttavia, potrebbe essere utile quando si salva una bitmap da un fotogramma video, ad esempio.

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

Tipi di supporti