Conversões de tipo de mídia

Ocasionalmente, é necessário converter entre os tipos de mídia do Media Foundation e as estruturas de tipo de mídia mais antigas do DirectShow ou do SDK de Formato de Mídia do Windows.

De uma estrutura de formato para um tipo de base de mídia

As funções a seguir inicializam um tipo de mídia do Media Foundation de uma estrutura de formato. Essas funções também serão úteis se um fluxo de dados ou um cabeçalho de arquivo contiver uma estrutura de formato. Por exemplo, o cabeçalho do arquivo para arquivos de áudio WAVE contém uma estrutura WAVEFORMATEX .

Estrutura a ser convertida Função
AM_MEDIA_TYPE (DirectShow)
DMO_MEDIA_TYPE (Objetos de Mídia DirectX)
WM_MEDIA_TYPE (SDK de Formato de Mídia do Windows)
Nota: Essas estruturas são equivalentes.
MFInitMediaTypeFromAMMediaType
BITMAPINFOHEADER MFCreateVideoMediaTypeFromBitMapInfoHeaderEx
MFVIDEOFORMAT MFInitMediaTypeFromMFVideoFormat
MPEG1VIDEOINFO MFInitMediaTypeFromMPEG1VideoInfo
MPEG2VIDEOINFO MFInitMediaTypeFromMPEG2VideoInfo
VIDEOINFOHEADER2 MFInitMediaTypeFromVideoInfoHeader2
VIDEOINFOHEADER MFInitMediaTypeFromVideoInfoHeader
WAVEFORMATEX ou WAVEFORMATEXTENSIBLE MFInitMediaTypeFromWaveFormatEx

 

De um tipo de base de mídia para uma estrutura de formato

As funções a seguir criam ou inicializam uma estrutura de formato de um tipo de mídia do Media Foundation.

Função Estrutura de Destino
IMFMediaType::GetRepresentation AM_MEDIA_TYPE, MFVIDEOFORMAT, VIDEOINFOHEADER ou VIDEOINFOHEADER2
MFCreateAMMediaTypeFromMFMediaType AM_MEDIA_TYPE
MFCreateMFVideoFormatFromMFMediaType MFVIDEOFORMAT
MFCreateWaveFormatExFromMFMediaType WAVEFORMATEX ou WAVEFORMATEXTENSIBLE
MFInitAMMediaTypeFromMFMediaType AM_MEDIA_TYPE

 

Mapeamentos de formato

As tabelas a seguir listam os atributos do Media Foundation que correspondem a várias estruturas de formato. Nem todos esses atributos podem ser traduzidos diretamente. Para executar conversões, você deve usar as funções listadas na seção anterior; essas tabelas são fornecidas principalmente para referência.

AM_MEDIA_TYPE

Membro Atributo
bTemporalCompression MF_MT_ALL_SAMPLES_INDEPENDENT
bFixedSizeSamples MF_MT_FIXED_SIZE_SAMPLES
lSampleSize MF_MT_SAMPLE_SIZE

 

WAVEFORMATEX, WAVEFORMATEXTENSIBLE

Membro Atributo
Wformattag MF_MT_SUBTYPE
Se wFormatTag for WAVE_FORMAT_EXTENSIBLE, o subtipo será encontrado no 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
SubFormatação MF_MT_SUBTYPE
Dados extras MF_MT_USER_DATA

 

VIDEOINFOHEADER, VIDEOINFOHEADER2

Membro Atributo
dwBitRate MF_MT_AVG_BITRATE
dwBitErrorRate MF_MT_AVG_BIT_ERROR_RATE
AvgTimePerFrame MF_MT_FRAME_RATE; use MFAverageTimePerFrameToFrameRate para calcular esse valor.
dwInterlaceFlags MF_MT_INTERLACE_MODE
dwCopyProtectFlags Nenhum equivalente definido
dwPictAspectRatioX, dwPictAspectRatioY MF_MT_PIXEL_ASPECT_RATIO; deve converter de taxa de proporção de imagem para taxa de proporção de imagem.
Dwcontrolflags MF_MT_PAD_CONTROL_FLAGS. Se o sinalizador AMCONTROL_COLORINFO_PRESENT estiver presente, defina os atributos de cor estendidos descritos em Informações de Cor Estendidas.
bmiHeader.biWidth, bmiHeader.biHeight MF_MT_FRAME_SIZE
bmiHeader.biBitCount Implícito no subtipo (MF_MT_SUBTYPE).
bmiHeader.biCompression Implícito no subtipo.
bmiHeader.biSizeImage MF_MT_SAMPLE_SIZE
Informações da paleta MF_MT_PALETTE

 

Os atributos a seguir podem ser inferidos da estrutura VIDEOINFOHEADER ou VIDEOINFOHEADER2 , mas também exigem algum conhecimento dos detalhes do formato. Por exemplo, diferentes formatos YUV têm requisitos de passo diferentes.

MPEG1VIDEOINFO

Membro Atributo
dwStartTimeCode MF_MT_MPEG_START_TIME_CODE
bSequenceHeader MF_MT_MPEG_SEQUENCE_HEADER
biXPelsPerMeter, biYPelsPerMeter MF_MT_PIXEL_ASPECT_RATIO

 

MPEG2VIDEOINFO

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

 

Exemplos

O código a seguir preenche uma estrutura BITMAPINFOHEADER de um tipo de mídia de vídeo. Observe que essas conversões perdem algumas das informações de formato (interlacing, taxa de quadros, dados de cor estendida). No entanto, pode ser útil ao salvar um bitmap de um quadro de vídeo, por exemplo.

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

Tipos de mídia