Module: wine Branch: master Commit: ec0455b97a0faf9ca1dc0f08afd8aab75881f811 URL: https://gitlab.winehq.org/wine/wine/-/commit/ec0455b97a0faf9ca1dc0f08afd8aab...
Author: Rémi Bernon rbernon@codeweavers.com Date: Thu May 9 10:57:54 2024 +0200
mfplat: Implement FORMAT_MPEG2Video for MFInitAMMediaTypeFromMFMediaType.
---
dlls/mfplat/mediatype.c | 30 +++++++++++++++++ dlls/mfplat/tests/mfplat.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 3ff42769349..7e2e5d45c1c 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -4136,6 +4136,14 @@ static UINT32 get_am_media_type_video_format_size(const GUID *format_type, IMFMe return size; }
+ if (IsEqualGUID(format_type, &FORMAT_MPEG2Video)) + { + UINT32 size = sizeof(MPEG2VIDEOINFO), sequence_size; + if (SUCCEEDED(IMFMediaType_GetBlobSize(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, &sequence_size))) + size += sequence_size; + return size; + } + return 0; }
@@ -4156,6 +4164,8 @@ static HRESULT init_am_media_type_video_format(AM_MEDIA_TYPE *am_type, IMFMediaT if (IsEqualGUID(&am_type->subtype, &MEDIASUBTYPE_MPEG1Payload) || IsEqualGUID(&am_type->subtype, &MEDIASUBTYPE_MPEG1Packet)) am_type->formattype = FORMAT_MPEGVideo; + else if (IsEqualGUID(&am_type->subtype, &MEDIASUBTYPE_MPEG2_VIDEO)) + am_type->formattype = FORMAT_MPEG2Video; else am_type->formattype = FORMAT_VideoInfo; } @@ -4211,6 +4221,26 @@ static HRESULT init_am_media_type_video_format(AM_MEDIA_TYPE *am_type, IMFMediaT am_type->bFixedSizeSamples = !!video_format; am_type->bTemporalCompression = !video_format; } + else if (IsEqualGUID(&am_type->formattype, &FORMAT_MPEG2Video)) + { + MPEG2VIDEOINFO *format = (MPEG2VIDEOINFO *)am_type->pbFormat; + + init_video_info_header2(&format->hdr, &am_type->subtype, media_type); + + format->dwStartTimeCode = media_type_get_uint32(media_type, &MF_MT_MPEG_START_TIME_CODE); + format->dwProfile = media_type_get_uint32(media_type, &MF_MT_MPEG2_PROFILE); + format->dwLevel = media_type_get_uint32(media_type, &MF_MT_MPEG2_LEVEL); + format->dwFlags = media_type_get_uint32(media_type, &MF_MT_MPEG2_FLAGS); + + if (am_type->cbFormat > sizeof(*format) && FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, + (BYTE *)format->dwSequenceHeader, am_type->cbFormat - sizeof(*format), NULL))) + return hr; + format->cbSequenceHeader = am_type->cbFormat - sizeof(*format); + + am_type->subtype = get_am_subtype_for_mf_subtype(am_type->subtype); + am_type->bFixedSizeSamples = !!video_format; + am_type->bTemporalCompression = !video_format; + } else { WARN("Unknown format %s\n", debugstr_mf_guid(&am_type->formattype)); diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 78c4ce9d583..98f88c0c73e 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7352,6 +7352,7 @@ static void test_MFInitAMMediaTypeFromMFMediaType(void) VIDEOINFOHEADER *video_info; WAVEFORMATEX *wave_format; MPEG1VIDEOINFO *mpeg1_info; + MPEG2VIDEOINFO *mpeg2_info; IMFMediaType *media_type, *other_type; AM_MEDIA_TYPE am_type; MFVideoArea *area; @@ -7459,6 +7460,13 @@ static void test_MFInitAMMediaTypeFromMFMediaType(void) ok(IsEqualGUID(&am_type.formattype, &FORMAT_MPEGVideo), "got %s.\n", debugstr_guid(&am_type.formattype)); ok(am_type.cbFormat == sizeof(MPEG1VIDEOINFO), "got %lu\n", am_type.cbFormat); CoTaskMemFree(am_type.pbFormat); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_MPEG2Video, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MEDIASUBTYPE_RGB32), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &FORMAT_MPEG2Video), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == sizeof(MPEG2VIDEOINFO), "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat);
/* test WAVEFORMATEX mapping */ @@ -8099,6 +8107,81 @@ static void test_MFInitAMMediaTypeFromMFMediaType(void) IMFMediaType_DeleteAllItems(media_type);
+ /* MEDIASUBTYPE_MPEG2_VIDEO uses FORMAT_MPEG2Video by default */ + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MEDIASUBTYPE_MPEG2_VIDEO); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MEDIASUBTYPE_MPEG2_VIDEO), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &FORMAT_MPEG2Video), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == sizeof(MPEG2VIDEOINFO), "got %lu\n", am_type.cbFormat); + mpeg2_info = (MPEG2VIDEOINFO *)am_type.pbFormat; + ok(mpeg2_info->dwStartTimeCode == 0, "got %lu\n", mpeg2_info->dwStartTimeCode); + ok(mpeg2_info->dwProfile == 0, "got %lu\n", mpeg2_info->dwProfile); + ok(mpeg2_info->dwLevel == 0, "got %lu\n", mpeg2_info->dwLevel); + ok(mpeg2_info->dwFlags == 0, "got %lu\n", mpeg2_info->dwFlags); + ok(mpeg2_info->cbSequenceHeader == 0, "got %lu\n", mpeg2_info->cbSequenceHeader); + CoTaskMemFree(am_type.pbFormat); + + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_MPEG_START_TIME_CODE, 1234); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_MPEG2_PROFILE, 6); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_MPEG2_LEVEL, 7); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_MPEG2_FLAGS, 8910); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(MPEG2VIDEOINFO), "got %lu\n", am_type.cbFormat); + mpeg2_info = (MPEG2VIDEOINFO *)am_type.pbFormat; + ok(mpeg2_info->dwStartTimeCode == 1234, "got %lu\n", mpeg2_info->dwStartTimeCode); + ok(mpeg2_info->dwProfile == 6, "got %lu\n", mpeg2_info->dwProfile); + ok(mpeg2_info->dwLevel == 7, "got %lu\n", mpeg2_info->dwLevel); + ok(mpeg2_info->dwFlags == 8910, "got %lu\n", mpeg2_info->dwFlags); + CoTaskMemFree(am_type.pbFormat); + + /* MF_MT_USER_DATA is ignored */ + + hr = IMFMediaType_SetBlob(media_type, &MF_MT_USER_DATA, (BYTE *)dummy_user_data, sizeof(dummy_user_data)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(MPEG2VIDEOINFO), "got %lu\n", am_type.cbFormat); + mpeg2_info = (MPEG2VIDEOINFO *)am_type.pbFormat; + ok(mpeg2_info->hdr.bmiHeader.biSize == sizeof(mpeg2_info->hdr.bmiHeader), "got %lu\n", mpeg2_info->hdr.bmiHeader.biSize); + ok(mpeg2_info->cbSequenceHeader == 0, "got %lu\n", mpeg2_info->cbSequenceHeader); + CoTaskMemFree(am_type.pbFormat); + + /* MF_MT_MPEG_SEQUENCE_HEADER is used instead in MPEG2VIDEOINFO */ + + hr = IMFMediaType_SetBlob(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, (BYTE *)dummy_mpeg_sequence, sizeof(dummy_mpeg_sequence)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(MPEG2VIDEOINFO) + sizeof(dummy_mpeg_sequence), "got %lu\n", am_type.cbFormat); + mpeg2_info = (MPEG2VIDEOINFO *)am_type.pbFormat; + ok(mpeg2_info->hdr.bmiHeader.biSize == sizeof(mpeg2_info->hdr.bmiHeader), "got %lu\n", mpeg2_info->hdr.bmiHeader.biSize); + ok(mpeg2_info->cbSequenceHeader == sizeof(dummy_mpeg_sequence), "got %lu\n", mpeg2_info->cbSequenceHeader); + ok(!memcmp(mpeg2_info->dwSequenceHeader, dummy_mpeg_sequence, mpeg2_info->cbSequenceHeader), "got wrong data\n"); + CoTaskMemFree(am_type.pbFormat); + + /* MFVIDEOFORMAT loses MF_MT_MPEG_SEQUENCE_HEADER */ + + hr = IMFMediaType_DeleteItem(media_type, &MF_MT_USER_DATA); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_MFVideoFormat, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(MFVIDEOFORMAT), "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat); + + IMFMediaType_DeleteAllItems(media_type); + + IMFMediaType_Release(media_type); }