mfplat: Implement MFAverageTimePerFrameToFrameRate().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
305a315a25
commit
381c2a9ae1
|
@ -3215,15 +3215,15 @@ HRESULT WINAPI MFConvertColorInfoToDXVA(DWORD *dxva_info, const MFVIDEOFORMAT *f
|
|||
|
||||
struct frame_rate
|
||||
{
|
||||
UINT64 rate;
|
||||
UINT64 frame_time;
|
||||
UINT64 key;
|
||||
UINT64 value;
|
||||
};
|
||||
|
||||
static int __cdecl frame_rate_compare(const void *a, const void *b)
|
||||
{
|
||||
const UINT64 *rate = a;
|
||||
const UINT64 *key = a;
|
||||
const struct frame_rate *known_rate = b;
|
||||
return *rate == known_rate->rate ? 0 : ( *rate < known_rate->rate ? 1 : -1 );
|
||||
return *key == known_rate->key ? 0 : ( *key < known_rate->key ? 1 : -1 );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -3252,7 +3252,7 @@ HRESULT WINAPI MFFrameRateToAverageTimePerFrame(UINT32 numerator, UINT32 denomin
|
|||
if ((entry = bsearch(&rate, known_rates, ARRAY_SIZE(known_rates), sizeof(*known_rates),
|
||||
frame_rate_compare)))
|
||||
{
|
||||
*avgframetime = entry->frame_time;
|
||||
*avgframetime = entry->value;
|
||||
}
|
||||
else
|
||||
*avgframetime = numerator ? denominator * (UINT64)10000000 / numerator : 0;
|
||||
|
@ -3260,6 +3260,64 @@ HRESULT WINAPI MFFrameRateToAverageTimePerFrame(UINT32 numerator, UINT32 denomin
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static unsigned int get_gcd(unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int m;
|
||||
|
||||
while (b)
|
||||
{
|
||||
m = a % b;
|
||||
a = b;
|
||||
b = m;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MFAverageTimePerFrameToFrameRate (mfplat.@)
|
||||
*/
|
||||
HRESULT WINAPI MFAverageTimePerFrameToFrameRate(UINT64 avgtime, UINT32 *numerator, UINT32 *denominator)
|
||||
{
|
||||
static const struct frame_rate known_rates[] =
|
||||
{
|
||||
#define KNOWN_RATE(ft,n,d) { ft, ((UINT64)n << 32) | d }
|
||||
KNOWN_RATE(417188, 24000, 1001),
|
||||
KNOWN_RATE(416667, 24, 1),
|
||||
KNOWN_RATE(400000, 25, 1),
|
||||
KNOWN_RATE(333667, 30000, 1001),
|
||||
KNOWN_RATE(333333, 30, 1),
|
||||
KNOWN_RATE(200000, 50, 1),
|
||||
KNOWN_RATE(166833, 60000, 1001),
|
||||
KNOWN_RATE(166667, 60, 1),
|
||||
#undef KNOWN_RATE
|
||||
};
|
||||
const struct frame_rate *entry;
|
||||
unsigned int gcd;
|
||||
|
||||
TRACE("%s, %p, %p.\n", wine_dbgstr_longlong(avgtime), numerator, denominator);
|
||||
|
||||
if ((entry = bsearch(&avgtime, known_rates, ARRAY_SIZE(known_rates), sizeof(*known_rates),
|
||||
frame_rate_compare)))
|
||||
{
|
||||
*numerator = entry->value >> 32;
|
||||
*denominator = entry->value;
|
||||
}
|
||||
else if (avgtime)
|
||||
{
|
||||
if (avgtime > 100000000) avgtime = 100000000;
|
||||
gcd = get_gcd(10000000, avgtime);
|
||||
*numerator = 10000000 / gcd;
|
||||
*denominator = avgtime / gcd;
|
||||
}
|
||||
else
|
||||
{
|
||||
*numerator = *denominator = 0;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MFMapDXGIFormatToDX9Format (mfplat.@)
|
||||
*/
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
@ stdcall MFAllocateWorkQueue(ptr)
|
||||
@ stdcall MFAllocateWorkQueueEx(long ptr) rtworkq.RtwqAllocateWorkQueue
|
||||
@ stub MFAppendCollection
|
||||
@ stub MFAverageTimePerFrameToFrameRate
|
||||
@ stdcall MFAverageTimePerFrameToFrameRate(int64 ptr ptr)
|
||||
@ stdcall MFBeginCreateFile(long long long wstr ptr ptr ptr)
|
||||
@ stub MFBeginGetHostByName
|
||||
@ stdcall MFBeginRegisterWorkQueueWithMMCSS(long wstr long ptr ptr)
|
||||
|
|
|
@ -6399,6 +6399,53 @@ static void test_MFFrameRateToAverageTimePerFrame(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_MFAverageTimePerFrameToFrameRate(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 },
|
||||
|
||||
{ 1000000, 25641, 256410 },
|
||||
{ 10000000, 83333, 83333 },
|
||||
{ 1, 10, 100000000 },
|
||||
{ 1, 10, 100000001 },
|
||||
{ 1, 10, 200000000 },
|
||||
{ 1, 1, 10000000 },
|
||||
{ 1, 2, 20000000 },
|
||||
{ 5, 1, 2000000 },
|
||||
{ 10, 1, 1000000 },
|
||||
};
|
||||
unsigned int i, numerator, denominator;
|
||||
HRESULT hr;
|
||||
|
||||
numerator = denominator = 1;
|
||||
hr = MFAverageTimePerFrameToFrameRate(0, &numerator, &denominator);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(!numerator && !denominator, "Unexpected output %u/%u.\n", numerator, denominator);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
|
||||
{
|
||||
numerator = denominator = 12345;
|
||||
hr = MFAverageTimePerFrameToFrameRate(frame_rate_tests[i].avgtime, &numerator, &denominator);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(numerator == frame_rate_tests[i].numerator && denominator == frame_rate_tests[i].denominator,
|
||||
"%u: unexpected %u/%u, expected %u/%u.\n", i, numerator, denominator, frame_rate_tests[i].numerator,
|
||||
frame_rate_tests[i].denominator);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_MFMapDXGIFormatToDX9Format(void)
|
||||
{
|
||||
static const struct format_pair
|
||||
|
@ -7874,6 +7921,7 @@ START_TEST(mfplat)
|
|||
test_MFCreateDXSurfaceBuffer();
|
||||
test_MFCreateTrackedSample();
|
||||
test_MFFrameRateToAverageTimePerFrame();
|
||||
test_MFAverageTimePerFrameToFrameRate();
|
||||
test_MFMapDXGIFormatToDX9Format();
|
||||
test_d3d11_surface_buffer();
|
||||
test_d3d12_surface_buffer();
|
||||
|
|
|
@ -500,6 +500,7 @@ HRESULT WINAPI MFAddPeriodicCallback(MFPERIODICCALLBACK callback, IUnknown *cont
|
|||
HRESULT WINAPI MFAllocateSerialWorkQueue(DWORD target_queue, DWORD *queue);
|
||||
HRESULT WINAPI MFAllocateWorkQueue(DWORD *queue);
|
||||
HRESULT WINAPI MFAllocateWorkQueueEx(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
|
||||
HRESULT WINAPI MFAverageTimePerFrameToFrameRate(UINT64 avgtime, UINT32 *numerator, UINT32 *denominator);
|
||||
HRESULT WINAPI MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode, MF_FILE_OPENMODE open_mode, MF_FILE_FLAGS flags,
|
||||
const WCHAR *path, IMFAsyncCallback *callback, IUnknown *state, IUnknown **cancel_cookie);
|
||||
HRESULT WINAPI MFBeginRegisterWorkQueueWithMMCSS(DWORD queue, const WCHAR *usage_class, DWORD taskid,
|
||||
|
|
Loading…
Reference in New Issue