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