From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 25 ++++++++ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 113 +++++++++++++++++++++++++++++++++++++ include/mfapi.h | 3 + 4 files changed, 142 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 7e2e5d45c1c..dfd695ecfb3 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -31,6 +31,7 @@ #include "ksmedia.h" #include "amvideo.h" #include "wmcodecdsp.h" +#include "wmsdkidl.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
@@ -3987,6 +3988,27 @@ HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader(IMFMediaType *media_type, cons return MFInitMediaTypeFromVideoInfoHeader2(media_type, &vih2, sizeof(vih2), subtype); }
+/*********************************************************************** + * MFInitMediaTypeFromMPEG1VideoInfo (mfplat.@) + */ +HRESULT WINAPI MFInitMediaTypeFromMPEG1VideoInfo(IMFMediaType *media_type, const MPEG1VIDEOINFO *vih, UINT32 size, + const GUID *subtype) +{ + HRESULT hr; + + TRACE("%p, %p, %u, %s.\n", media_type, vih, size, debugstr_guid(subtype)); + + if (FAILED(hr = MFInitMediaTypeFromVideoInfoHeader(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, vih->bSequenceHeader, vih->cbSequenceHeader, &hr); + + return hr; +} + static HRESULT init_am_media_type_audio_format(AM_MEDIA_TYPE *am_type, IMFMediaType *media_type) { HRESULT hr; @@ -4314,6 +4336,9 @@ HRESULT WINAPI MFInitMediaTypeFromAMMediaType(IMFMediaType *media_type, const AM else if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo2) && am_type->cbFormat >= sizeof(VIDEOINFOHEADER2)) hr = MFInitMediaTypeFromVideoInfoHeader2(media_type, (VIDEOINFOHEADER2 *)am_type->pbFormat, am_type->cbFormat, subtype); + 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 { 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 57db3cdf9f6..6babe6c6498 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -121,7 +121,7 @@ @ stdcall MFInitAttributesFromBlob(ptr ptr long) @ stdcall MFInitMediaTypeFromAMMediaType(ptr ptr) @ stdcall MFInitMediaTypeFromMFVideoFormat(ptr ptr long) -@ stub MFInitMediaTypeFromMPEG1VideoInfo +@ stdcall MFInitMediaTypeFromMPEG1VideoInfo(ptr ptr long ptr) @ stub MFInitMediaTypeFromMPEG2VideoInfo @ stdcall MFInitMediaTypeFromVideoInfoHeader2(ptr ptr long ptr) @ stdcall MFInitMediaTypeFromVideoInfoHeader(ptr ptr long ptr) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 98f88c0c73e..29ab0adeea4 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -11478,6 +11478,118 @@ static void test_MFInitMediaTypeFromVideoInfoHeader2(void) IMFMediaType_Release(media_type); }
+static void test_MFInitMediaTypeFromMPEG1VideoInfo(void) +{ + IMFMediaType *media_type; + MPEG1VIDEOINFO vih; + BYTE 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 = MFInitMediaTypeFromMPEG1VideoInfo(media_type, &vih, 0, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = MFInitMediaTypeFromMPEG1VideoInfo(media_type, &vih, sizeof(vih), NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = MFInitMediaTypeFromMPEG1VideoInfo(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 = MFInitMediaTypeFromMPEG1VideoInfo(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 = MFInitMediaTypeFromMPEG1VideoInfo(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 = MFInitMediaTypeFromMPEG1VideoInfo(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); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value64 == ((UINT64)1 << 32 | 1), "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); + 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 = MFInitMediaTypeFromMPEG1VideoInfo(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); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value64 == ((UINT64)1 << 32 | 1), "Unexpected value %#I64x.\n", value64); + + value32 = 0xdeadbeef; + vih.hdr.bmiHeader.biSizeImage = 12345; + hr = MFInitMediaTypeFromMPEG1VideoInfo(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 = MFInitMediaTypeFromMPEG1VideoInfo(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_MPEG_SEQUENCE_HEADER, NULL); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + value32 = 0xdeadbeef; + memset(buffer, 0xcd, sizeof(buffer)); + vih.cbSequenceHeader = 1; + vih.bSequenceHeader[0] = 0xad; + hr = MFInitMediaTypeFromMPEG1VideoInfo(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, buffer, sizeof(buffer), &value32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value32 == 1, "Unexpected value %#x.\n", value32); + ok(buffer[0] == 0xad, "Unexpected value %#x.\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}}; @@ -12098,6 +12210,7 @@ START_TEST(mfplat) test_MFCreateVideoMediaTypeFromVideoInfoHeader(); test_MFInitMediaTypeFromVideoInfoHeader(); test_MFInitMediaTypeFromVideoInfoHeader2(); + test_MFInitMediaTypeFromMPEG1VideoInfo(); test_MFInitMediaTypeFromAMMediaType(); test_MFCreatePathFromURL(); test_2dbuffer_copy(); diff --git a/include/mfapi.h b/include/mfapi.h index 0a9f7c6f415..8bd3fd6e4f9 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -510,6 +510,7 @@ typedef struct tagVIDEOINFOHEADER VIDEOINFOHEADER; struct tagVIDEOINFOHEADER2; typedef struct tagVIDEOINFOHEADER2 VIDEOINFOHEADER2; typedef struct _AMMediaType AM_MEDIA_TYPE; +typedef struct tagMPEG1VIDEOINFO MPEG1VIDEOINFO;
HRESULT WINAPI MFAddPeriodicCallback(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key); HRESULT WINAPI MFAllocateSerialWorkQueue(DWORD target_queue, DWORD *queue); @@ -600,6 +601,8 @@ HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader(IMFMediaType *media_type, cons UINT32 size, const GUID *subtype); HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader2(IMFMediaType *media_type, const VIDEOINFOHEADER2 *vih, UINT32 size, const GUID *subtype); +HRESULT WINAPI MFInitMediaTypeFromMPEG1VideoInfo(IMFMediaType *media_type, const MPEG1VIDEOINFO *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);