Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mediatype.c | 6 ++---- dlls/mfplat/tests/mfplat.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index ccae999b7d7..0217237d85a 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2003,10 +2003,8 @@ static HRESULT WINAPI mediatype_handler_GetMajorType(IMFMediaTypeHandler *iface, TRACE("%p, %p.\n", iface, type);
EnterCriticalSection(&stream_desc->attributes.cs); - if (stream_desc->current_type) - hr = IMFMediaType_GetGUID(stream_desc->current_type, &MF_MT_MAJOR_TYPE, type); - else - hr = MF_E_ATTRIBUTENOTFOUND; + hr = IMFMediaType_GetGUID(stream_desc->current_type ? stream_desc->current_type : + stream_desc->media_types[0], &MF_MT_MAJOR_TYPE, type); LeaveCriticalSection(&stream_desc->attributes.cs);
return hr; diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index fed6b392b21..a0789ee6b2c 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -3679,6 +3679,42 @@ static void test_stream_descriptor(void) IMFMediaTypeHandler_Release(type_handler);
IMFStreamDescriptor_Release(stream_desc); + + /* Major type is returned for first entry. */ + hr = MFCreateMediaType(&media_types[0]); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = MFCreateMediaType(&media_types[1]); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler); + ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr); + + hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type)); + + hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type)); + + IMFMediaType_Release(media_types[0]); + IMFMediaType_Release(media_types[1]); + + IMFMediaTypeHandler_Release(type_handler); + IMFStreamDescriptor_Release(stream_desc); }
static void test_MFCalculateImageSize(void)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/tests/mfplat.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index ef25bbcb3eb..2a6e3a1cc36 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1013,6 +1013,29 @@ static void test_source_reader_from_media_source(void) hr = IMFSourceReader_ReadSample(reader, 0, 0, &actual_index, &stream_flags, ×tamp, &sample); ok(hr == E_NOTIMPL, "Unexpected ReadSample result, hr %#x.\n", hr);
+ actual_index = ~0u; + stream_flags = 0; + hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &actual_index, &stream_flags, + ×tamp, &sample); + ok(hr == E_NOTIMPL, "Unexpected ReadSample result, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected index %u.\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ERROR, "Unexpected flags %#x.\n", stream_flags); + + actual_index = ~0u; + stream_flags = 0; + hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &actual_index, &stream_flags, + ×tamp, &sample); + ok(hr == E_NOTIMPL, "Unexpected ReadSample result, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected index %u.\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ERROR, "Unexpected flags %#x.\n", stream_flags); + + actual_index = ~0u; + stream_flags = 0; + hr = IMFSourceReader_ReadSample(reader, 0, 0, &actual_index, &stream_flags, ×tamp, &sample); + ok(hr == E_NOTIMPL, "Unexpected ReadSample result, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected index %u.\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ERROR, "Unexpected flags %#x.\n", stream_flags); + IMFSourceReader_Release(reader); IMFMediaSource_Release(source);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- 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);