미디어 형식 변환

경우에 따라 DirectShow 또는 Windows Media Format SDK에서 Media Foundation 미디어 형식과 이전 미디어 형식 구조 간에 변환해야 합니다.

형식 구조에서 Media Foundation 형식으로

다음 함수는 형식 구조에서 Media Foundation 미디어 형식을 초기화합니다. 이러한 함수는 데이터 스트림 또는 파일 헤더에 형식 구조가 포함된 경우에도 유용합니다. 예를 들어 WAVE 오디오 파일의 파일 헤더에는 WAVEFORMATEX 구조가 포함됩니다.

 

Media Foundation 형식에서 형식 구조로

다음 함수는 Media Foundation 미디어 형식에서 형식 구조를 만들거나 초기화합니다.

 

서식 매핑

다음 표에는 다양한 형식 구조에 해당하는 Media Foundation 특성이 나열되어 있습니다. 이러한 특성을 모두 직접 변환할 수 있는 것은 아닙니다. 변환을 수행하려면 이전 섹션에 나열된 함수를 사용해야 합니다. 이러한 테이블은 주로 참조용으로 제공됩니다.

AM_MEDIA_TYPE

멤버 attribute
bTemporalCompression MF_MT_ALL_SAMPLES_INDEPENDENT
bFixedSizeSamples MF_MT_FIXED_SIZE_SAMPLES
lSampleSize MF_MT_SAMPLE_SIZE

 

WAVEFORMATEX, WAVEFORMATEXTENSIBLE

멤버 attribute
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

멤버 attribute
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

멤버 attribute
dwStartTimeCode MF_MT_MPEG_START_TIME_CODE
bSequenceHeader MF_MT_MPEG_SEQUENCE_HEADER
biXPelsPerMeter, biYPelsPerMeter MF_MT_PIXEL_ASPECT_RATIO

 

MPEG2VIDEOINFO

멤버 attribute
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;
}

미디어 형식