mfplat: Implement FORMAT_MPEG2Video for MFInitAMMediaTypeFromMFMediaType.

This commit is contained in:
Rémi Bernon 2024-05-09 10:57:54 +02:00 committed by Alexandre Julliard
parent dce8d8b552
commit ec0455b97a
2 changed files with 113 additions and 0 deletions

View file

@ -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));

View file

@ -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);
}