[PATCH 0/3] MR10754: mf/session: Initialise the stored presentation rate.
The latest argument passed to SetRate() is stored in presentation.rate, but if the client never called SetRate(), the stored rate remains zero, which results in preroll not being enabled. That could be fixed by instead calling GetRate() before enabling preroll, but always setting the stored rate reduces the risk of regression. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10754
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/mf/tests/mf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 122e56bb073..115d62ce591 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4550,6 +4550,7 @@ static void test_sample_grabber(void) hr = IMFMediaSink_GetCharacteristics(sink, &flags); ok(hr == S_OK, "Failed to get sink flags, hr %#lx.\n", hr); ok(flags & MEDIASINK_FIXED_STREAMS, "Unexpected flags %#lx.\n", flags); + ok(!(flags & MEDIASINK_CAN_PREROLL), "Unexpected flags %#lx.\n", flags); hr = IMFMediaSink_GetStreamSinkCount(sink, &count); ok(hr == S_OK, "Failed to get stream count, hr %#lx.\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10754
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/mf/tests/mf.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 115d62ce591..c4ca2b8b49c 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -10963,6 +10963,50 @@ static void test_media_session_scrubbing(void) PropVariantClear(&propvar); CHECK_CALLED(test_transform_ProcessMessage_BEGIN_STREAMING); + /* Test that during a default start (i.e. rate == 1.0), preroll is called on the sink */ + SET_EXPECT(test_media_sink_GetPresentationClock); + SET_EXPECT(test_media_sink_SetPresentationClock); + SET_EXPECT(test_transform_ProcessMessage_START_OF_STREAM); + SET_EXPECT(test_media_sink_preroll_NotifyPreroll); + + propvar.vt = VT_I8; /* hVal will be zero */ + hr = IMFMediaSession_Start(session, NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + SET_EXPECT(test_media_sink_GetStreamSinkCount); + hr = WaitForSingleObject(media_sink->preroll_event, 100); + todo_wine + ok(hr == WAIT_OBJECT_0, "Unexpected hr %#lx.\n", hr); + + todo_wine + CHECK_CALLED(test_media_sink_GetPresentationClock); + todo_wine + CHECK_CALLED(test_transform_ProcessMessage_START_OF_STREAM); + todo_wine + CHECK_CALLED(test_media_sink_preroll_NotifyPreroll); + + hr = wait_media_event_until_blocking(session, callback, MESessionStarted, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&propvar); + todo_wine + CHECK_CALLED(test_media_sink_GetStreamSinkCount); + + SET_EXPECT(test_transform_ProcessMessage_FLUSH); + SET_EXPECT(test_stream_sink_Flush); + hr = IMFMediaSession_Stop(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = wait_media_event_until_blocking(session, callback, MESessionStopped, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&propvar); + + /* The transform flush call can happen after receiving the MESessionStopped event */ + hr = WaitForSingleObject(transform->flush_event, 1000); + ok(hr == WAIT_OBJECT_0, "Unexpected hr %#lx.\n", hr); + CHECK_CALLED(test_transform_ProcessMessage_FLUSH); + CHECK_CALLED(test_stream_sink_Flush); + CLEAR_CALLED(test_transform_ProcessMessage_FLUSH); + /* Test that when rate is zero (i.e. we're scrubbing), no preroll occurs */ SET_EXPECT(test_media_sink_clock_sink_OnClockSetRate); SET_EXPECT(test_media_sink_GetPresentationClock); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10754
From: Conor McCarthy <cmccarthy@codeweavers.com> The latest argument passed to SetRate() is stored in presentation.rate, but if the client never called SetRate(), the stored rate remains zero, which results in preroll not being enabled. That could be fixed by instead calling GetRate() before enabling preroll, but always setting the stored rate reduces the risk of regression. --- dlls/mf/session.c | 3 +++ dlls/mf/tests/mf.c | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 095dfad3107..e0d94c8327f 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -5018,6 +5018,9 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses goto failed; } + if (FAILED(hr = IMFRateControl_GetRate(object->clock_rate_control, NULL, &object->presentation.rate))) + goto failed; + if (config) { GUID clsid; diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index c4ca2b8b49c..6fe6a81e6f0 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -10975,14 +10975,12 @@ static void test_media_session_scrubbing(void) SET_EXPECT(test_media_sink_GetStreamSinkCount); hr = WaitForSingleObject(media_sink->preroll_event, 100); - todo_wine ok(hr == WAIT_OBJECT_0, "Unexpected hr %#lx.\n", hr); todo_wine CHECK_CALLED(test_media_sink_GetPresentationClock); todo_wine CHECK_CALLED(test_transform_ProcessMessage_START_OF_STREAM); - todo_wine CHECK_CALLED(test_media_sink_preroll_NotifyPreroll); hr = wait_media_event_until_blocking(session, callback, MESessionStarted, 1000, &propvar); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10754
Nikolay Sivov (@nsivov) commented about dlls/mf/session.c:
goto failed; }
+ if (FAILED(hr = IMFRateControl_GetRate(object->clock_rate_control, NULL, &object->presentation.rate))) + goto failed; + if (config)
Could we assign it to 1.0f instead? Why do we need to call through the clock, for just created object. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10754#note_137750
Nikolay Sivov (@nsivov) commented about dlls/mf/tests/mf.c:
PropVariantClear(&propvar); CHECK_CALLED(test_transform_ProcessMessage_BEGIN_STREAMING);
+ /* Test that during a default start (i.e. rate == 1.0), preroll is called on the sink */ + SET_EXPECT(test_media_sink_GetPresentationClock); + SET_EXPECT(test_media_sink_SetPresentationClock); + SET_EXPECT(test_transform_ProcessMessage_START_OF_STREAM); + SET_EXPECT(test_media_sink_preroll_NotifyPreroll); + + propvar.vt = VT_I8; /* hVal will be zero */ + hr = IMFMediaSession_Start(session, NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + SET_EXPECT(test_media_sink_GetStreamSinkCount); + hr = WaitForSingleObject(media_sink->preroll_event, 100); + ok(hr == WAIT_OBJECT_0, "Unexpected hr %#lx.\n", hr);
Do we have to check the whole bunch of expected method calls? I think we are only interested in receiving prerolled event. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10754#note_137751
participants (3)
-
Conor McCarthy -
Conor McCarthy (@cmccarthy) -
Nikolay Sivov (@nsivov)