Konversi Tipe Media

Terkadang perlu untuk mengonversi antara jenis media Media Foundation dan struktur jenis media yang lebih lama dari DirectShow atau Windows Media Format SDK.

Dari Struktur Format ke Jenis Media Foundation

Fungsi berikut menginisialisasi jenis media Media Foundation dari struktur format. Fungsi-fungsi ini juga berguna jika aliran data atau header file berisi struktur format. Misalnya, header file untuk file audio WAVE berisi struktur WAVEFORMATEX .

Struktur untuk Dikonversi Fungsi
AM_MEDIA_TYPE (DirectShow)
DMO_MEDIA_TYPE (Objek Media DirectX)
WM_MEDIA_TYPE (Windows Media Format SDK)
Catatan: Struktur ini setara.
MFInitMediaTypeFromAMMediaType
BITMAPINFOHEADER MFCreateVideoMediaTypeFromBitMapInfoHeaderEx
MFVIDEOFORMAT MFInitMediaTypeFromMFVideoFormat
MPEG1VIDEOINFO MFInitMediaTypeFromMPEG1VideoInfo
MPEG2VIDEOINFO MFInitMediaTypeFromMPEG2VideoInfo
VIDEOINFOHEADER2 MFInitMediaTypeFromVideoInfoHeader2
VIDEOINFOHEADER MFInitMediaTypeFromVideoInfoHeader
WAVEFORMATEX atau WAVEFORMATEXTENSIBLE MFInitMediaTypeFromWaveFormatEx

 

Dari Jenis Media Foundation ke Struktur Format

Fungsi berikut membuat atau menginisialisasi struktur format dari jenis media Media Foundation.

Fungsi Struktur Target
IMFMediaType::GetRepresentation AM_MEDIA_TYPE, MFVIDEOFORMAT, VIDEOINFOHEADER, atau VIDEOINFOHEADER2
MFCreateAMMediaTypeFromMFMediaType AM_MEDIA_TYPE
MFCreateMFVideoFormatFromMFMediaType MFVIDEOFORMAT
MFCreateWaveFormatExFromMFMediaType WAVEFORMATEX atau WAVEFORMATEXTENSIBLE
MFInitAMMediaTypeFromMFMediaType AM_MEDIA_TYPE

 

Pemetaan Format

Tabel berikut mencantumkan atribut Media Foundation yang sesuai dengan berbagai struktur format. Tidak semua atribut ini dapat diterjemahkan secara langsung. Untuk melakukan konversi, Anda harus menggunakan fungsi yang tercantum di bagian sebelumnya; tabel ini disediakan terutama untuk referensi.

AM_MEDIA_TYPE

Anggota Atribut
bTemporalCompression MF_MT_ALL_SAMPLES_INDEPENDENT
bFixedSizeSamples MF_MT_FIXED_SIZE_SAMPLES
lSampleSize MF_MT_SAMPLE_SIZE

 

WAVEFORMATEX, WAVEFORMATEXTENSIBLE

Anggota Atribut
wFormatTag MF_MT_SUBTYPE
Jika wFormatTag WAVE_FORMAT_EXTENSIBLE, subjenis ditemukan di anggota 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
Data tambahan MF_MT_USER_DATA

 

VIDEOINFOHEADER, VIDEOINFOHEADER2

Anggota Atribut
dwBitRate MF_MT_AVG_BITRATE
dwBitErrorRate MF_MT_AVG_BIT_ERROR_RATE
AvgTimePerFrame MF_MT_FRAME_RATE; gunakan MFAverageTimePerFrameToFrameRate untuk menghitung nilai ini.
dwInterlaceFlags MF_MT_INTERLACE_MODE
dwCopyProtectFlags Tidak ada yang didefinisikan setara
dwPictAspectRatioX, dwPictAspectRatioY MF_MT_PIXEL_ASPECT_RATIO; harus mengonversi dari rasio aspek gambar ke rasio aspek gambar.
dwControlFlags MF_MT_PAD_CONTROL_FLAGS. Jika bendera AMCONTROL_COLORINFO_PRESENT ada, atur atribut warna yang diperluas yang dijelaskan dalam Informasi Warna yang Diperluas.
bmiHeader.biWidth, bmiHeader.biHeight MF_MT_FRAME_SIZE
bmiHeader.biBitCount Implisit dalam subjenis (MF_MT_SUBTYPE).
bmiHeader.biCompression Implisit dalam subjenis.
bmiHeader.biSizeImage MF_MT_SAMPLE_SIZE
Informasi palet MF_MT_PALETTE

 

Atribut berikut dapat disimpulkan dari struktur VIDEOINFOHEADER atau VIDEOINFOHEADER2 tetapi juga memerlukan beberapa pengetahuan tentang detail format. Misalnya, format YUV yang berbeda memiliki persyaratan langkah yang berbeda.

MPEG1VIDEOINFO

Anggota Atribut
dwStartTimeCode MF_MT_MPEG_START_TIME_CODE
bSequenceHeader MF_MT_MPEG_SEQUENCE_HEADER
biXPelsPerMeter, biYPelsPerMeter MF_MT_PIXEL_ASPECT_RATIO

 

MPEG2VIDEOINFO

Anggota Atribut
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

 

Contoh

Kode berikut mengisi struktur BITMAPINFOHEADER dari jenis media video. Perhatikan bahwa konversi ini kehilangan beberapa informasi format (interlacing, frame rate, extended color data). Namun, mungkin berguna saat menyimpan bitmap dari bingkai video, misalnya.

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

Jenis Media