From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 31 ++++++++ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 143 +++++++++++++++++++++++++++++++++++++ include/mfapi.h | 3 + 4 files changed, 178 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index dfd695ecfb3..cebc458a1e3 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -4009,6 +4009,34 @@ HRESULT WINAPI MFInitMediaTypeFromMPEG1VideoInfo(IMFMediaType *media_type, const return hr; }
+/*********************************************************************** + * MFInitMediaTypeFromMPEG2VideoInfo (mfplat.@) + */ +HRESULT WINAPI MFInitMediaTypeFromMPEG2VideoInfo(IMFMediaType *media_type, const MPEG2VIDEOINFO *vih, UINT32 size, + const GUID *subtype) +{ + HRESULT hr; + + TRACE("%p, %p, %u, %s.\n", media_type, vih, size, debugstr_guid(subtype)); + + if (FAILED(hr = MFInitMediaTypeFromVideoInfoHeader2(media_type, &vih->hdr, sizeof(vih->hdr), subtype))) + return hr; + + if (vih->dwStartTimeCode) + mediatype_set_uint32(media_type, &MF_MT_MPEG_START_TIME_CODE, vih->dwStartTimeCode, &hr); + if (vih->cbSequenceHeader) + mediatype_set_blob(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, (BYTE *)vih->dwSequenceHeader, vih->cbSequenceHeader, &hr); + + if (vih->dwProfile) + mediatype_set_uint32(media_type, &MF_MT_MPEG2_PROFILE, vih->dwProfile, &hr); + if (vih->dwLevel) + mediatype_set_uint32(media_type, &MF_MT_MPEG2_LEVEL, vih->dwLevel, &hr); + if (vih->dwFlags) + mediatype_set_uint32(media_type, &MF_MT_MPEG2_FLAGS, vih->dwFlags, &hr); + + return hr; +} + static HRESULT init_am_media_type_audio_format(AM_MEDIA_TYPE *am_type, IMFMediaType *media_type) { HRESULT hr; @@ -4339,6 +4367,9 @@ HRESULT WINAPI MFInitMediaTypeFromAMMediaType(IMFMediaType *media_type, const AM else if (IsEqualGUID(&am_type->formattype, &FORMAT_MPEGVideo) && am_type->cbFormat >= sizeof(MPEG1VIDEOINFO)) hr = MFInitMediaTypeFromMPEG1VideoInfo(media_type, (MPEG1VIDEOINFO *)am_type->pbFormat, am_type->cbFormat, subtype); + else if (IsEqualGUID(&am_type->formattype, &FORMAT_MPEG2Video) + && am_type->cbFormat >= sizeof(MPEG2VIDEOINFO)) + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, (MPEG2VIDEOINFO *)am_type->pbFormat, am_type->cbFormat, subtype); else { FIXME("Unsupported format type %s / size %ld.\n", debugstr_guid(&am_type->formattype), am_type->cbFormat); diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 6babe6c6498..e311b3cf493 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -122,7 +122,7 @@ @ stdcall MFInitMediaTypeFromAMMediaType(ptr ptr) @ stdcall MFInitMediaTypeFromMFVideoFormat(ptr ptr long) @ stdcall MFInitMediaTypeFromMPEG1VideoInfo(ptr ptr long ptr) -@ stub MFInitMediaTypeFromMPEG2VideoInfo +@ stdcall MFInitMediaTypeFromMPEG2VideoInfo(ptr ptr long ptr) @ stdcall MFInitMediaTypeFromVideoInfoHeader2(ptr ptr long ptr) @ stdcall MFInitMediaTypeFromVideoInfoHeader(ptr ptr long ptr) @ stdcall MFInitMediaTypeFromWaveFormatEx(ptr ptr long) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 29ab0adeea4..72f9526c079 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -11590,6 +11590,148 @@ static void test_MFInitMediaTypeFromMPEG1VideoInfo(void) IMFMediaType_Release(media_type); }
+static void test_MFInitMediaTypeFromMPEG2VideoInfo(void) +{ + IMFMediaType *media_type; + MPEG2VIDEOINFO vih; + DWORD buffer[64]; + UINT32 value32; + UINT64 value64; + HRESULT hr; + GUID guid; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + memset(&vih, 0, sizeof(vih)); + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, 0, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected guid %s.\n", debugstr_guid(&guid)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&guid, &GUID_NULL), "Unexpected guid %s.\n", debugstr_guid(&guid)); + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + vih.hdr.bmiHeader.biWidth = 16; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + vih.hdr.bmiHeader.biHeight = -32; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + vih.hdr.bmiHeader.biHeight = 32; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value64 == ((UINT64)16 << 32 | 32), "Unexpected value %#I64x.\n", value64); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value32 == MFVideoInterlace_Progressive, "Unexpected value %#x.\n", value32); + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &value32); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + vih.hdr.bmiHeader.biXPelsPerMeter = 2; + vih.hdr.bmiHeader.biYPelsPerMeter = 3; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + value32 = 0xdeadbeef; + vih.hdr.bmiHeader.biSizeImage = 12345; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value32 == 12345, "Unexpected value %#x.\n", value32); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG_START_TIME_CODE, &value32); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + value32 = 0xdeadbeef; + vih.dwStartTimeCode = 1234; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG_START_TIME_CODE, &value32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value32 == 1234, "Unexpected value %#x.\n", value32); + hr = IMFMediaType_GetItem(media_type, &MF_MT_MPEG2_PROFILE, NULL); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + value32 = 0xdeadbeef; + vih.dwProfile = 1234; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_PROFILE, &value32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value32 == 1234, "Unexpected value %#x.\n", value32); + hr = IMFMediaType_GetItem(media_type, &MF_MT_MPEG2_LEVEL, NULL); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + value32 = 0xdeadbeef; + vih.dwLevel = 1234; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_LEVEL, &value32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value32 == 1234, "Unexpected value %#x.\n", value32); + hr = IMFMediaType_GetItem(media_type, &MF_MT_MPEG2_FLAGS, NULL); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + value32 = 0xdeadbeef; + vih.dwFlags = 1234; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_FLAGS, &value32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value32 == 1234, "Unexpected value %#x.\n", value32); + hr = IMFMediaType_GetItem(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, NULL); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + value32 = 0xdeadbeef; + memset(buffer, 0xcd, sizeof(buffer)); + vih.cbSequenceHeader = 3; + vih.dwSequenceHeader[0] = 0xabcdef; + hr = MFInitMediaTypeFromMPEG2VideoInfo(media_type, &vih, sizeof(vih), &GUID_NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, (BYTE *)buffer, sizeof(buffer), &value32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value32 == 3, "Unexpected value %#x.\n", value32); + ok(buffer[0] == 0xcdabcdef, "Unexpected value %#lx.\n", buffer[0]); + + IMFMediaType_Release(media_type); +} + static void test_MFInitMediaTypeFromAMMediaType(void) { static const MFVideoArea expect_aperture = {.OffsetX = {.value = 13}, .OffsetY = {.value = 46}, .Area = {.cx = 110, .cy = 410}}; @@ -12211,6 +12353,7 @@ START_TEST(mfplat) test_MFInitMediaTypeFromVideoInfoHeader(); test_MFInitMediaTypeFromVideoInfoHeader2(); test_MFInitMediaTypeFromMPEG1VideoInfo(); + test_MFInitMediaTypeFromMPEG2VideoInfo(); test_MFInitMediaTypeFromAMMediaType(); test_MFCreatePathFromURL(); test_2dbuffer_copy(); diff --git a/include/mfapi.h b/include/mfapi.h index 8bd3fd6e4f9..2e1c2345418 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -511,6 +511,7 @@ struct tagVIDEOINFOHEADER2; typedef struct tagVIDEOINFOHEADER2 VIDEOINFOHEADER2; typedef struct _AMMediaType AM_MEDIA_TYPE; typedef struct tagMPEG1VIDEOINFO MPEG1VIDEOINFO; +typedef struct tagMPEG2VIDEOINFO MPEG2VIDEOINFO;
HRESULT WINAPI MFAddPeriodicCallback(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key); HRESULT WINAPI MFAllocateSerialWorkQueue(DWORD target_queue, DWORD *queue); @@ -603,6 +604,8 @@ HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader2(IMFMediaType *media_type, con UINT32 size, const GUID *subtype); HRESULT WINAPI MFInitMediaTypeFromMPEG1VideoInfo(IMFMediaType *media_type, const MPEG1VIDEOINFO *vih, UINT32 size, const GUID *subtype); +HRESULT WINAPI MFInitMediaTypeFromMPEG2VideoInfo(IMFMediaType *media_type, const MPEG2VIDEOINFO *vih, + UINT32 size, const GUID *subtype); HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size); HRESULT WINAPI MFInitVideoFormat_RGB(MFVIDEOFORMAT *format, DWORD width, DWORD height, DWORD d3dformat); HRESULT WINAPI MFInvokeCallback(IMFAsyncResult *result);