Conversiones de tipos multimedia

En ocasiones, es necesario convertir entre tipos de medios de Media Foundation y las estructuras de tipos de medios anteriores de DirectShow o windows Media Format SDK.

De una estructura de formato a un tipo de Media Foundation

Las siguientes funciones inicializan un tipo de medio de Media Foundation a partir de una estructura de formato. Estas funciones también son útiles si un flujo de datos o un encabezado de archivo contiene una estructura de formato. Por ejemplo, el encabezado de archivo para los archivos de audio WAVE contiene una estructura WAVEFORMATEX .

Estructura que se va a convertir Función
AM_MEDIA_TYPE (DirectShow)
DMO_MEDIA_TYPE (objetos multimedia de DirectX)
WM_MEDIA_TYPE (SDK de Windows Media Format)
Nota: Estas estructuras son equivalentes.
MFInitMediaTypeFromAMMediaType
BITMAPINFOHEADER MFCreateVideoMediaTypeFromBitMapInfoHeaderEx
MFVIDEOFORMAT MFInitMediaTypeFromMFVideoFormat
MPEG1VIDEOINFO MFInitMediaTypeFromMPEG1VideoInfo
MPEG2VIDEOINFO MFInitMediaTypeFromMPEG2VideoInfo
VIDEOINFOHEADER2 MFInitMediaTypeFromVideoInfoHeader2
VIDEOINFOHEADER MFInitMediaTypeFromVideoInfoHeader
WAVEFORMATEX o WAVEFORMATEXTENSIBLE MFInitMediaTypeFromWaveFormatEx

 

De un tipo de Media Foundation a una estructura de formato

Las siguientes funciones crean o inicializan una estructura de formato a partir de un tipo de medio de Media Foundation.

Función Estructura de destino
IMFMediaType::GetRepresentation AM_MEDIA_TYPE, MFVIDEOFORMAT, VIDEOINFOHEADER o VIDEOINFOHEADER2
MFCreateAMMediaTypeFromMFMediaType AM_MEDIA_TYPE
MFCreateMFVideoFormatFromMFMediaType MFVIDEOFORMAT
MFCreateWaveFormatExFromMFMediaType WAVEFORMATEX o WAVEFORMATEXTENSIBLE
MFInitAMMediaTypeFromMFMediaType AM_MEDIA_TYPE

 

Asignaciones de formato

En las tablas siguientes se enumeran los atributos de Media Foundation que corresponden a varias estructuras de formato. No todos estos atributos se pueden traducir directamente. Para realizar conversiones, debe usar las funciones enumeradas en la sección anterior; estas tablas se proporcionan principalmente como referencia.

AM_MEDIA_TYPE

Member Atributo
bTemporalesCompression MF_MT_ALL_SAMPLES_INDEPENDENT
bFixedSizeSamples MF_MT_FIXED_SIZE_SAMPLES
lSampleSize MF_MT_SAMPLE_SIZE

 

WAVEFORMATEX, WAVEFORMATEXTENSIBLE

Member Atributo
wFormatTag MF_MT_SUBTYPE
Si wFormatTag es WAVE_FORMAT_EXTENSIBLE, el subtipo se encuentra en el miembro 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
SubFormato MF_MT_SUBTYPE
Datos adicionales MF_MT_USER_DATA

 

VIDEOINFOHEADER, VIDEOINFOHEADER2

Member Atributo
dwBitRate MF_MT_AVG_BITRATE
dwBitErrorRate MF_MT_AVG_BIT_ERROR_RATE
AvgTimePerFrame MF_MT_FRAME_RATE; use MFAverageTimePerFrameToFrameRate para calcular este valor.
dwInterlaceFlags MF_MT_INTERLACE_MODE
dwCopyProtectFlags No hay equivalente definido
dwPictAspectRatioX, dwPictAspectRatioY MF_MT_PIXEL_ASPECT_RATIO; debe convertir de la relación de aspecto de la imagen a la relación de aspecto de la imagen.
dwControlFlags MF_MT_PAD_CONTROL_FLAGS. Si la marca AMCONTROL_COLORINFO_PRESENT está presente, establezca los atributos de color extendidos descritos en Información de color extendida.
imcHeader.biWidth, imcHeader.biHeight MF_MT_FRAME_SIZE
indexHeader.biBitCount Implícito en el subtipo (MF_MT_SUBTYPE).
indexHeader.biCompression Implícito en el subtipo.
imcHeader.biSizeImage MF_MT_SAMPLE_SIZE
Información de la paleta MF_MT_PALETTE

 

Los siguientes atributos se pueden deducir de la estructura VIDEOINFOHEADER o VIDEOINFOHEADER2 , pero también requieren cierto conocimiento de los detalles del formato. Por ejemplo, los diferentes formatos YUV tienen requisitos de intervalo diferentes.

MPEG1VIDEOINFO

Member Atributo
dwStartTimeCode MF_MT_MPEG_START_TIME_CODE
bSequenceHeader MF_MT_MPEG_SEQUENCE_HEADER
biXPelsPerMeter, biYPelsPerMeter MF_MT_PIXEL_ASPECT_RATIO

 

MPEG2VIDEOINFO

Member 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

 

Ejemplos

El código siguiente rellena una estructura BITMAPINFOHEADER de un tipo de medio de vídeo. Tenga en cuenta que esta conversión pierde parte de la información de formato (entrelazado, velocidad de fotogramas, datos de color extendidos). Sin embargo, puede resultar útil al guardar un mapa de bits de un fotograma de vídeo, por ejemplo.

#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 medios