학습
미디어 형식 변환
경우에 따라 DirectShow 또는 Windows Media Format SDK에서 Media Foundation 미디어 형식과 이전 미디어 형식 구조 간에 변환해야 합니다.
다음 함수는 형식 구조에서 Media Foundation 미디어 형식을 초기화합니다. 이러한 함수는 데이터 스트림 또는 파일 헤더에 형식 구조가 포함된 경우에도 유용합니다. 예를 들어 WAVE 오디오 파일의 파일 헤더에는 WAVEFORMATEX 구조가 포함됩니다.
변환할 구조체 | 기능 |
---|---|
AM_MEDIA_TYPE (DirectShow) DMO_MEDIA_TYPE (DirectX 미디어 개체) WM_MEDIA_TYPE (Windows Media Format SDK) 참고: 이러한 구조체는 동일합니다. |
MFInitMediaTypeFromAMMediaType |
BITMAPINFOHEADER | MFCreateVideoMediaTypeFromBitMapInfoHeaderEx |
MFVIDEOFORMAT | MFInitMediaTypeFromMFVideoFormat |
MPEG1VIDEOINFO | MFInitMediaTypeFromMPEG1VideoInfo |
MPEG2VIDEOINFO | MFInitMediaTypeFromMPEG2VideoInfo |
VIDEOINFOHEADER2 | MFInitMediaTypeFromVideoInfoHeader2 |
VIDEOINFOHEADER | MFInitMediaTypeFromVideoInfoHeader |
WAVEFORMATEX 또는 WAVEFORMATEXTENSIBLE | MFInitMediaTypeFromWaveFormatEx |
다음 함수는 Media Foundation 미디어 형식에서 형식 구조를 만들거나 초기화합니다.
다음 표에는 다양한 형식 구조에 해당하는 Media Foundation 특성이 나열되어 있습니다. 이러한 특성을 모두 직접 변환할 수 있는 것은 아닙니다. 변환을 수행하려면 이전 섹션에 나열된 함수를 사용해야 합니다. 이러한 테이블은 주로 참조용으로 제공됩니다.
멤버 | attribute |
---|---|
bTemporalCompression | MF_MT_ALL_SAMPLES_INDEPENDENT |
bFixedSizeSamples | MF_MT_FIXED_SIZE_SAMPLES |
lSampleSize | MF_MT_SAMPLE_SIZE |
멤버 | 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 |
멤버 | 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 형식에 따라 보폭 요구 사항이 다릅니다.
멤버 | attribute |
---|---|
dwStartTimeCode | MF_MT_MPEG_START_TIME_CODE |
bSequenceHeader | MF_MT_MPEG_SEQUENCE_HEADER |
biXPelsPerMeter, biYPelsPerMeter | MF_MT_PIXEL_ASPECT_RATIO |
멤버 | 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;
}