Nikolay Sivov : mfplat: Implement MFFrameRateToAverageTimePerFrame().
Alexandre Julliard
julliard at winehq.org
Mon Nov 2 16:21:19 CST 2020
Module: wine
Branch: master
Commit: abb8852077c6f74ae73ab430f3b2b5e7f42ef0df
URL: https://source.winehq.org/git/wine.git/?a=commit;h=abb8852077c6f74ae73ab430f3b2b5e7f42ef0df
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Nov 2 15:27:50 2020 +0300
mfplat: Implement MFFrameRateToAverageTimePerFrame().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mfplat/mediatype.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/mfplat/mfplat.spec | 2 +-
dlls/mfplat/tests/mfplat.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
include/mfapi.h | 1 +
4 files changed, 96 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c
index 0217237d85a..fcaef110038 100644
--- a/dlls/mfplat/mediatype.c
+++ b/dlls/mfplat/mediatype.c
@@ -3164,3 +3164,50 @@ HRESULT WINAPI MFConvertColorInfoToDXVA(DWORD *dxva_info, const MFVIDEOFORMAT *f
return S_OK;
}
+
+struct frame_rate
+{
+ UINT64 rate;
+ UINT64 frame_time;
+};
+
+static int __cdecl frame_rate_compare(const void *a, const void *b)
+{
+ const UINT64 *rate = a;
+ const struct frame_rate *known_rate = b;
+ return *rate == known_rate->rate ? 0 : ( *rate < known_rate->rate ? 1 : -1 );
+}
+
+/***********************************************************************
+ * MFFrameRateToAverageTimePerFrame (mfplat.@)
+ */
+HRESULT WINAPI MFFrameRateToAverageTimePerFrame(UINT32 numerator, UINT32 denominator, UINT64 *avgframetime)
+{
+ static const struct frame_rate known_rates[] =
+ {
+#define KNOWN_RATE(n,d,ft) { ((UINT64)n << 32) | d, ft }
+ KNOWN_RATE(60000, 1001, 166833),
+ KNOWN_RATE(30000, 1001, 333667),
+ KNOWN_RATE(24000, 1001, 417188),
+ KNOWN_RATE(60, 1, 166667),
+ KNOWN_RATE(50, 1, 200000),
+ KNOWN_RATE(30, 1, 333333),
+ KNOWN_RATE(25, 1, 400000),
+ KNOWN_RATE(24, 1, 416667),
+#undef KNOWN_RATE
+ };
+ UINT64 rate = ((UINT64)numerator << 32) | denominator;
+ const struct frame_rate *entry;
+
+ TRACE("%u, %u, %p.\n", numerator, denominator, avgframetime);
+
+ if ((entry = bsearch(&rate, known_rates, ARRAY_SIZE(known_rates), sizeof(*known_rates),
+ frame_rate_compare)))
+ {
+ *avgframetime = entry->frame_time;
+ }
+ else
+ *avgframetime = numerator ? denominator * (UINT64)10000000 / numerator : 0;
+
+ return S_OK;
+}
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index 80064e1980e..36e009c2db9 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -90,7 +90,7 @@
@ stub MFEndGetHostByName
@ stdcall MFEndRegisterWorkQueueWithMMCSS(ptr ptr) rtworkq.RtwqEndRegisterWorkQueueWithMMCSS
@ stdcall MFEndUnregisterWorkQueueWithMMCSS(ptr) rtworkq.RtwqEndUnregisterWorkQueueWithMMCSS
-@ stub MFFrameRateToAverageTimePerFrame
+@ stdcall MFFrameRateToAverageTimePerFrame(long long ptr)
@ stub MFFreeAdaptersAddresses
@ stub MFGetAdaptersAddresses
@ stdcall MFGetAttributesAsBlob(ptr ptr long)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index a0789ee6b2c..a6c8a10f777 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -5865,6 +5865,52 @@ static void test_MFCreateTrackedSample(void)
IMFTrackedSample_Release(tracked_sample);
}
+static void test_MFFrameRateToAverageTimePerFrame(void)
+{
+ static const struct frame_rate_test
+ {
+ unsigned int numerator;
+ unsigned int denominator;
+ UINT64 avgtime;
+ } frame_rate_tests[] =
+ {
+ { 60000, 1001, 166833 },
+ { 30000, 1001, 333667 },
+ { 24000, 1001, 417188 },
+ { 60, 1, 166667 },
+ { 30, 1, 333333 },
+ { 50, 1, 200000 },
+ { 25, 1, 400000 },
+ { 24, 1, 416667 },
+
+ { 39, 1, 256410 },
+ { 120, 1, 83333 },
+ };
+ unsigned int i;
+ UINT64 avgtime;
+ HRESULT hr;
+
+ avgtime = 1;
+ hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(!avgtime, "Unexpected frame time.\n");
+
+ avgtime = 1;
+ hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(!avgtime, "Unexpected frame time.\n");
+
+ for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
+ {
+ avgtime = 0;
+ hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
+ frame_rate_tests[i].denominator, &avgtime);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
+ i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
+ }
+}
+
START_TEST(mfplat)
{
char **argv;
@@ -5923,6 +5969,7 @@ START_TEST(mfplat)
test_MFCreateMFVideoFormatFromMFMediaType();
test_MFCreateDXSurfaceBuffer();
test_MFCreateTrackedSample();
+ test_MFFrameRateToAverageTimePerFrame();
CoUninitialize();
}
diff --git a/include/mfapi.h b/include/mfapi.h
index 25fced1c7d6..8661b41fc4e 100644
--- a/include/mfapi.h
+++ b/include/mfapi.h
@@ -526,6 +526,7 @@ HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *type, WAVEFORMA
HRESULT WINAPI MFEndCreateFile(IMFAsyncResult *result, IMFByteStream **stream);
HRESULT WINAPI MFEndRegisterWorkQueueWithMMCSS(IMFAsyncResult *result, DWORD *taskid);
HRESULT WINAPI MFEndUnregisterWorkQueueWithMMCSS(IMFAsyncResult *result);
+HRESULT WINAPI MFFrameRateToAverageTimePerFrame(UINT32 numerator, UINT32 denominator, UINT64 *avgtime);
void * WINAPI MFHeapAlloc(SIZE_T size, ULONG flags, char *file, int line, EAllocationType type);
void WINAPI MFHeapFree(void *ptr);
HRESULT WINAPI MFGetAttributesAsBlob(IMFAttributes *attributes, UINT8 *buffer, UINT size);
More information about the wine-cvs
mailing list