From 8140604763f679d8ea223c71ace077b9152d7d30 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 22 Jun 2020 17:20:36 +0300 Subject: [PATCH] mfplat: Implement MFCreateMFVideoFormatFromMFMediaType(). Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mfplat/mediatype.c | 98 ++++++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 20 ++++++++ include/mfapi.h | 1 + 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index ca806a899f5..66722a84b6f 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2640,3 +2640,101 @@ HRESULT WINAPI MFCreateVideoMediaTypeFromSubtype(const GUID *subtype, IMFVideoMe return S_OK; } + +static void media_type_get_ratio(UINT64 value, UINT32 *numerator, UINT32 *denominator) +{ + *numerator = value >> 32; + *denominator = value; +} + +/*********************************************************************** + * MFCreateMFVideoFormatFromMFMediaType (mfplat.@) + */ +HRESULT WINAPI MFCreateMFVideoFormatFromMFMediaType(IMFMediaType *media_type, MFVIDEOFORMAT **video_format, UINT32 *size) +{ + UINT32 flags, palette_size = 0, avgrate; + MFVIDEOFORMAT *format; + UINT64 value; + INT32 stride; + GUID guid; + + TRACE("%p, %p, %p.\n", media_type, video_format, size); + + *size = sizeof(*format); + + if (SUCCEEDED(IMFMediaType_GetBlobSize(media_type, &MF_MT_PALETTE, &palette_size))) + *size += palette_size; + + if (!(format = CoTaskMemAlloc(*size))) + return E_OUTOFMEMORY; + + *video_format = format; + + memset(format, 0, sizeof(*format)); + format->dwSize = *size; + + if (SUCCEEDED(IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid))) + { + memcpy(&format->guidFormat, &guid, sizeof(guid)); + format->surfaceInfo.Format = guid.Data1; + } + + if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value))) + media_type_get_ratio(value, &format->videoInfo.dwWidth, &format->videoInfo.dwHeight); + + if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &value))) + { + media_type_get_ratio(value, &format->videoInfo.PixelAspectRatio.Numerator, + &format->videoInfo.PixelAspectRatio.Denominator); + } + + IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_CHROMA_SITING, &format->videoInfo.SourceChromaSubsampling); + IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &format->videoInfo.InterlaceMode); + IMFMediaType_GetUINT32(media_type, &MF_MT_TRANSFER_FUNCTION, &format->videoInfo.TransferFunction); + IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_PRIMARIES, &format->videoInfo.ColorPrimaries); + IMFMediaType_GetUINT32(media_type, &MF_MT_YUV_MATRIX, &format->videoInfo.TransferMatrix); + IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_LIGHTING, &format->videoInfo.SourceLighting); + + if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_RATE, &value))) + { + media_type_get_ratio(value, &format->videoInfo.FramesPerSecond.Numerator, + &format->videoInfo.FramesPerSecond.Denominator); + } + + IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_NOMINAL_RANGE, &format->videoInfo.NominalRange); + IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&format->videoInfo.GeometricAperture, + sizeof(format->videoInfo.GeometricAperture), NULL); + IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8 *)&format->videoInfo.MinimumDisplayAperture, + sizeof(format->videoInfo.MinimumDisplayAperture), NULL); + + /* Video flags. */ + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_PAD_CONTROL_FLAGS, &flags))) + format->videoInfo.VideoFlags |= flags; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_SOURCE_CONTENT_HINT, &flags))) + format->videoInfo.VideoFlags |= flags; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_DRM_FLAGS, &flags))) + format->videoInfo.VideoFlags |= flags; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_PAN_SCAN_ENABLED, &flags)) && !!flags) + { + format->videoInfo.VideoFlags |= MFVideoFlag_PanScanEnabled; + IMFMediaType_GetBlob(media_type, &MF_MT_PAN_SCAN_APERTURE, (UINT8 *)&format->videoInfo.PanScanAperture, + sizeof(format->videoInfo.PanScanAperture), NULL); + } + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, (UINT32 *)&stride)) && stride < 0) + format->videoInfo.VideoFlags |= MFVideoFlag_BottomUpLinearRep; + + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BITRATE, &avgrate))) + format->compressedInfo.AvgBitrate = avgrate; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BIT_ERROR_RATE, &avgrate))) + format->compressedInfo.AvgBitErrorRate = avgrate; + IMFMediaType_GetUINT32(media_type, &MF_MT_MAX_KEYFRAME_SPACING, &format->compressedInfo.MaxKeyFrameSpacing); + + /* Palette. */ + if (palette_size) + { + format->surfaceInfo.PaletteEntries = palette_size / sizeof(*format->surfaceInfo.Palette); + IMFMediaType_GetBlob(media_type, &MF_MT_PALETTE, (UINT8 *)format->surfaceInfo.Palette, palette_size, NULL); + } + + return S_OK; +} diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 01f9efaecaa..e6069424fc9 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -52,7 +52,7 @@ @ stdcall MFCreateMFByteStreamOnStream(ptr ptr) @ stdcall MFCreateMFByteStreamOnStreamEx(ptr ptr) @ stdcall MFCreateMFByteStreamWrapper(ptr ptr) -@ stub MFCreateMFVideoFormatFromMFMediaType +@ stdcall MFCreateMFVideoFormatFromMFMediaType(ptr ptr ptr) @ stdcall MFCreateMediaBufferFromMediaType(ptr int64 long long ptr) @ stub MFCreateMediaBufferWrapper @ stdcall MFCreateMediaEvent(long ptr long ptr ptr) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 8a52279a081..aac6f734583 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -5262,6 +5262,25 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) IMFMediaType_Release(mediatype); } +static void test_MFCreateMFVideoFormatFromMFMediaType(void) +{ + MFVIDEOFORMAT *video_format; + IMFMediaType *media_type; + UINT32 size; + HRESULT hr; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); + + hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!!video_format, "Unexpected format.\n"); + ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size); + CoTaskMemFree(video_format); + + IMFMediaType_Release(media_type); +} + START_TEST(mfplat) { char **argv; @@ -5317,6 +5336,7 @@ START_TEST(mfplat) test_MFCreate2DMediaBuffer(); test_MFCreateMediaBufferFromMediaType(); test_MFInitMediaTypeFromWaveFormatEx(); + test_MFCreateMFVideoFormatFromMFMediaType(); CoUninitialize(); } diff --git a/include/mfapi.h b/include/mfapi.h index 4da25341c68..e86fb526f13 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -509,6 +509,7 @@ HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLO HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HRESULT status, const PROPVARIANT *value, IMFMediaEvent **event); HRESULT WINAPI MFCreateMediaType(IMFMediaType **type); +HRESULT WINAPI MFCreateMFVideoFormatFromMFMediaType(IMFMediaType *media_type, MFVIDEOFORMAT **video_format, UINT32 *size); HRESULT WINAPI MFCreateSample(IMFSample **sample); HRESULT WINAPI MFCreateVideoMediaTypeFromSubtype(const GUID *subtype, IMFVideoMediaType **media_type); HRESULT WINAPI MFCreateMemoryBuffer(DWORD max_length, IMFMediaBuffer **buffer);