Udostępnij przez


Konwersje typów multimediów

Czasami konieczne jest przekonwertowanie między typami multimediów programu Media Foundation a starszymi strukturami typów multimediów z zestawu DirectShow lub zestawu SDK formatu Windows Media Format.

Z struktury formatu do typu media foundation

Następujące funkcje inicjują typ nośnika programu Media Foundation na podstawie struktury formatu. Te funkcje są również przydatne, jeśli strumień danych lub nagłówek pliku zawiera strukturę formatu. Na przykład nagłówek pliku dla plików audio WAVE zawiera strukturę WAVEFORMATEX.

Struktura do konwersji Funkcja
AM_MEDIA_TYPE (DirectShow)
DMO_MEDIA_TYPE (obiekty multimediów DirectX)
WM_MEDIA_TYPE (Zestaw SDK formatu Windows Media)
Uwaga: Te struktury są równoważne.
MFInitMediaTypeFromAMMediaType
BITMAPINFOHEADER MFCreateVideoMediaTypeFromBitMapInfoHeaderEx
MFVIDEOFORMAT MFInitMediaTypeFromMFVideoFormat
MPEG1VIDEOINFO MFInitMediaTypeFromMPEG1VideoInfo
MPEG2VIDEOINFO MFInitMediaTypeFromMPEG2VideoInfo
VIDEOINFOHEADER2 MFInitMediaTypeFromVideoInfoHeader2
VIDEOINFOHEADER MFInitMediaTypeFromVideoInfoHeader
WAVEFORMATEX lub WAVEFORMATEXTENSIBLE MFInitMediaTypeFromWaveFormatEx

 

Z typu programu Media Foundation do struktury formatu

Poniższe funkcje tworzą lub inicjują strukturę formatu na podstawie typu nośnika Programu Media Foundation.

Funkcja Struktura docelowa
IMFMediaType::GetRepresentation AM_MEDIA_TYPE, MFVIDEOFORMAT, VIDEOINFOHEADERlub VIDEOINFOHEADER2
MFCreateAMMediaTypeFromMFMediaType AM_MEDIA_TYPE
MFCreateMFVideoFormatFromMFMediaType MFVIDEOFORMAT
MFCreateWaveFormatExFromMFMediaType WAVEFORMATEX lub WAVEFORMATEXTENSIBLE
MFInitAMMediaTypeFromMFMediaType AM_MEDIA_TYPE

 

Formatowanie mapowań

W poniższych tabelach wymieniono atrybuty programu Media Foundation, które odpowiadają różnym strukturom formatu. Nie wszystkie te atrybuty można przetłumaczyć bezpośrednio. Aby wykonać konwersje, należy użyć funkcji wymienionych w poprzedniej sekcji; te tabele są udostępniane głównie do celów referencyjnych.

AM_MEDIA_TYPE

Członek Atrybut
bTemporalCompression MF_MT_ALL_SAMPLES_INDEPENDENT
bFixedSizeSamples MF_MT_FIXED_SIZE_SAMPLES
lSampleSize MF_MT_SAMPLE_SIZE

 

WAVEFORMATEX, WAVEFORMATEXTENSIBLE

Członek Atrybut
wFormatTag MF_MT_SUBTYPE
Jeśli wFormatTag jest WAVE_FORMAT_EXTENSIBLE, podtyp zostanie znaleziony w elemencie 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
podformatowanie MF_MT_SUBTYPE
Dodatkowe dane MF_MT_USER_DATA

 

VIDEOINFOHEADER, VIDEOINFOHEADER2

Członek Atrybut
dwBitRate MF_MT_AVG_BITRATE
dwBitErrorRate MF_MT_AVG_BIT_ERROR_RATE
AvgTimePerFrame MF_MT_FRAME_RATE; użyj MFAverageTimePerFrameToFrameToFrameRate, aby obliczyć tę wartość.
dwInterlaceFlags MF_MT_INTERLACE_MODE
dwCopyProtectFlags Brak zdefiniowanych odpowiedników
dwPictAspectRatioX, dwPictAspectRatioY MF_MT_PIXEL_ASPECT_RATIO; musi konwertować współczynnik proporcji obrazu na współczynnik proporcji obrazu.
dwControlFlags MF_MT_PAD_CONTROL_FLAGS. Jeśli flaga AMCONTROL_COLORINFO_PRESENT jest obecna, ustaw atrybuty koloru rozszerzonego opisane w rozszerzone informacje o kolorze.
bmiHeader.biWidth, bmiHeader.biHeight MF_MT_FRAME_SIZE
bmiHeader.biBitCount Niejawne w podtypie (MF_MT_SUBTYPE).
bmiHeader.biCompression Niejawne w podtypie.
bmiHeader.biSizeImage MF_MT_SAMPLE_SIZE
Informacje o palecie MF_MT_PALETTE

 

Następujące atrybuty można wywnioskować z VIDEOINFOHEADER lub VIDEOINFOHEADER2 struktury, ale także wymagać znajomości szczegółów formatu. Na przykład różne formaty YUV mają różne wymagania dotyczące kroku.

MPEG1VIDEOINFO

Członek Atrybut
dwStartTimeCode MF_MT_MPEG_START_TIME_CODE
bSequenceHeader MF_MT_MPEG_SEQUENCE_HEADER
biXPelsPerMeter, biYPelsPerMeter MF_MT_PIXEL_ASPECT_RATIO

 

MPEG2VIDEOINFO

Członek Atrybut
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

 

Przykłady

Poniższy kod wypełnia BITMAPINFOHEADER strukturę z typu nośnika wideo. Należy pamiętać, że te konwersje tracą niektóre informacje o formacie (przeploty, szybkość klatek, rozszerzone dane kolorów). Jednak może to być przydatne podczas zapisywania mapy bitowej z ramki wideo, na przykład.

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

typy multimediów