Поделиться через


Преобразования типов мультимедиа

Иногда необходимо преобразовать между типами мультимедиа Media Foundation и старыми структурами типов мультимедиа из DirectShow или пакета SDK для формата Windows Media.

От структуры форматирования до типа Media Foundation

Следующие функции инициализируют тип мультимедиа Media Foundation из структуры формата. Эти функции также полезны, если поток данных или заголовок файла содержит структуру формата. Например, заголовок файла для звуковых файлов WAVE содержит структуру WAVEFORMATEX.

Структура для преобразования Функция
AM_MEDIA_TYPE (DirectShow)
DMO_MEDIA_TYPE (объекты мультимедиа DirectX)
WM_MEDIA_TYPE (пакет SDK для формата Windows Media)
Примечание. эти структуры эквивалентны.
MFInitMediaTypeFromAMMediaType
BITMAPINFOHEADER MFCreateVideoMediaTypeFromBitMapInfoHeaderEx
MFVIDEOFORMAT MFInitMediaTypeFromMFVideoFormat
MPEG1VIDEOINFO MFInitMediaTypeFromMPEG1VideoInfo
MPEG2VIDEOINFO MFInitMediaTypeFromMPEG2VideoInfo
VIDEOINFOHEADER2 MFInitMediaTypeFromVideoInfoHeader2
VIDEOINFOHEADER MFInitMediaTypeFromVideoInfoHeader
WAVEFORMATEX или WAVEFORMATEXTENSIBLE MFInitMediaTypeFromWaveFormatEx

 

Из типа Media Foundation в структуру форматирования

Следующие функции создают или инициализируют структуру формата из типа носителя Media Foundation.

Функция Целевая структура
МВФMediaType::GetRepresentation AM_MEDIA_TYPE, MFVIDEOFORMAT, VIDEOINFOHEADERили VIDEOINFOHEADER2
MFCreateAMMediaTypeFromMFMediaType AM_MEDIA_TYPE
MFCreateMFVideoFormatFromMFMediaType MFVIDEOFORMAT
MFCreateWaveFormatExFromMFMediaType WAVEFORMATEX или WAVEFORMATEXTENSIBLE
MFInitAMMediaTypeFromMFMediaType AM_MEDIA_TYPE

 

Сопоставления форматов

В следующих таблицах перечислены атрибуты Media Foundation, соответствующие различным структурам формата. Не все эти атрибуты можно преобразовать напрямую. Для выполнения преобразований следует использовать функции, перечисленные в предыдущем разделе; Эти таблицы предоставляются главным образом для справки.

AM_MEDIA_TYPE

Член Атрибут
bTemporalCompression MF_MT_ALL_SAMPLES_INDEPENDENT
bFixedSizeSamples MF_MT_FIXED_SIZE_SAMPLES
lSampleSize MF_MT_SAMPLE_SIZE

 

WAVEFORMATEX, WAVEFORMATEXTENSIBLE

Член Атрибут
wFormatTag MF_MT_SUBTYPE
Если wFormatTag WAVE_FORMAT_EXTENSIBLE, подтип найден в элементе 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
SubFormat MF_MT_SUBTYPE
Дополнительные данные MF_MT_USER_DATA

 

VIDEOINFOHEADER, VIDEOINFOHEADER2

Член Атрибут
dwBitRate MF_MT_AVG_BITRATE
dwBitErrorRate MF_MT_AVG_BIT_ERROR_RATE
AvgTimePerFrame MF_MT_FRAME_RATE; Используйте MFAverageTimePerFrameToFrameRate для вычисления этого значения.
dwInterlaceFlags MF_MT_INTERLACE_MODE
dwCopyProtectFlags Нет определенного эквивалента
dwPictAspectRatioX, dwPictAspectRatioY MF_MT_PIXEL_ASPECT_RATIO; должен преобразовывать пропорции изображения в пропорции изображения.
dwControlFlags MF_MT_PAD_CONTROL_FLAGS. Если флаг AMCONTROL_COLORINFO_PRESENT присутствует, задайте расширенные атрибуты цвета, описанные в расширенных сведений о цвете.
bmiHeader.biWidth, bmiHeader.biHeight MF_MT_FRAME_SIZE
bmiHeader.biBitCount Неявно в подтипе (MF_MT_SUBTYPE).
bmiHeader.biCompression Неявное в подтипе.
bmiHeader.biSizeImage MF_MT_SAMPLE_SIZE
Сведения о палитре MF_MT_PALETTE

 

Следующие атрибуты можно вывести из структуры VIDEOINFOHEADER или VIDEOINFOHEADER2, но также требуют некоторых знаний о формате. Например, разные форматы YUV имеют разные требования к шагу.

MPEG1VIDEOINFO

Член Атрибут
dwStartTimeCode MF_MT_MPEG_START_TIME_CODE
bSequenceHeader MF_MT_MPEG_SEQUENCE_HEADER
biXPelsPerMeter, biYPelsPerMeter MF_MT_PIXEL_ASPECT_RATIO

 

MPEG2VIDEOINFO

Член Атрибут
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

 

Примеры

Следующий код заполняет структуру BITMAPINFOHEADER из типа видеомедийного носителя. Обратите внимание, что это преобразование теряет некоторые сведения о формате (перемешивание, частота кадров, расширенные цветовые данные). Однако это может быть полезно при сохранении растрового изображения из видеокадров, например.

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

Типы носителей