1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

mfplat: Support flexible frame time in MFAverageTimePerFrameToFrameRate.

This commit is contained in:
Rémi Bernon 2024-03-18 13:41:28 +01:00 committed by Alexandre Julliard
parent 578d104cf6
commit aa385765a1
2 changed files with 57 additions and 59 deletions

View file

@ -3353,15 +3353,45 @@ HRESULT WINAPI MFConvertColorInfoToDXVA(DWORD *dxva_info, const MFVIDEOFORMAT *f
struct frame_rate
{
UINT64 key;
UINT64 value;
UINT64 time;
UINT64 rate;
};
static int __cdecl frame_rate_compare(const void *a, const void *b)
static const struct frame_rate known_rates[] =
{
const UINT64 *key = a;
const struct frame_rate *known_rate = b;
return *key == known_rate->key ? 0 : ( *key < known_rate->key ? 1 : -1 );
#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
};
static const struct frame_rate *known_rate_from_rate(UINT64 rate)
{
UINT i;
for (i = 0; i < ARRAY_SIZE(known_rates); i++)
{
if (rate == known_rates[i].rate)
return known_rates + i;
}
return NULL;
}
static const struct frame_rate *known_rate_from_time(UINT64 time)
{
UINT i;
for (i = 0; i < ARRAY_SIZE(known_rates); i++)
{
if (time >= known_rates[i].time - 30
&& time <= known_rates[i].time + 30)
return known_rates + i;
}
return NULL;
}
/***********************************************************************
@ -3369,29 +3399,13 @@ static int __cdecl frame_rate_compare(const void *a, const void *b)
*/
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->value;
}
if ((entry = known_rate_from_rate(rate)))
*avgframetime = entry->time;
else
*avgframetime = numerator ? denominator * (UINT64)10000000 / numerator : 0;
@ -3417,29 +3431,15 @@ static unsigned int get_gcd(unsigned int a, unsigned int b)
*/
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)))
if ((entry = known_rate_from_time(avgtime)))
{
*numerator = entry->value >> 32;
*denominator = entry->value;
*numerator = entry->rate >> 32;
*denominator = entry->rate;
}
else if (avgtime)
{

View file

@ -8206,40 +8206,39 @@ static void test_MFAverageTimePerFrameToFrameRate(void)
unsigned int numerator;
unsigned int denominator;
UINT64 avgtime;
BOOL todo;
} frame_rate_tests[] =
{
{ 60000, 1001, 166863, TRUE },
{ 60000, 1001, 166863 },
{ 60000, 1001, 166833 },
{ 60000, 1001, 166803, TRUE },
{ 60000, 1001, 166803 },
{ 30000, 1001, 333697, TRUE },
{ 30000, 1001, 333697 },
{ 30000, 1001, 333667 },
{ 30000, 1001, 333637, TRUE },
{ 30000, 1001, 333637 },
{ 24000, 1001, 417218, TRUE },
{ 24000, 1001, 417218 },
{ 24000, 1001, 417188 },
{ 24000, 1001, 417158, TRUE },
{ 24000, 1001, 417158 },
{ 60, 1, 166697, TRUE },
{ 60, 1, 166697 },
{ 60, 1, 166667 },
{ 60, 1, 166637, TRUE },
{ 60, 1, 166637 },
{ 30, 1, 333363, TRUE },
{ 30, 1, 333363 },
{ 30, 1, 333333 },
{ 30, 1, 333303, TRUE },
{ 30, 1, 333303 },
{ 50, 1, 200030, TRUE },
{ 50, 1, 200030 },
{ 50, 1, 200000 },
{ 50, 1, 199970, TRUE },
{ 50, 1, 199970 },
{ 25, 1, 400030, TRUE },
{ 25, 1, 400030 },
{ 25, 1, 400000 },
{ 25, 1, 399970, TRUE },
{ 25, 1, 399970 },
{ 24, 1, 416697, TRUE },
{ 24, 1, 416697 },
{ 24, 1, 416667 },
{ 24, 1, 416637, TRUE },
{ 24, 1, 416637 },
{ 1000000, 25641, 256410 },
{ 10000000, 83333, 83333 },
@ -8264,7 +8263,6 @@ static void test_MFAverageTimePerFrameToFrameRate(void)
numerator = denominator = 12345;
hr = MFAverageTimePerFrameToFrameRate(frame_rate_tests[i].avgtime, &numerator, &denominator);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
todo_wine_if(frame_rate_tests[i].todo)
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);