Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfmediaengine/main.c | 33 +++++++++++++++++++++--- dlls/mfmediaengine/tests/mfmediaengine.c | 15 +++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index 9da802f0df6..e126a925b67 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -71,6 +71,11 @@ enum media_engine_flags FLAGS_ENGINE_FIRST_FRAME = 0x2000, };
+struct video_frame +{ + LONGLONG pts; +}; + struct media_engine { IMFMediaEngine IMFMediaEngine_iface; @@ -93,6 +98,7 @@ struct media_engine IMFMediaSession *session; IMFSourceResolver *resolver; BSTR current_source; + struct video_frame video_frame; CRITICAL_SECTION cs; };
@@ -319,6 +325,7 @@ static HRESULT WINAPI media_engine_session_events_Invoke(IMFAsyncCallback *iface
EnterCriticalSection(&engine->cs); media_engine_set_flag(engine, FLAGS_ENGINE_FIRST_FRAME, FALSE); + engine->video_frame.pts = MINLONGLONG; LeaveCriticalSection(&engine->cs);
IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_ENDED, 0, 0); @@ -1264,11 +1271,28 @@ static HRESULT WINAPI media_engine_TransferVideoFrame(IMFMediaEngine *iface, IUn return E_NOTIMPL; }
-static HRESULT WINAPI media_engine_OnVideoStreamTick(IMFMediaEngine *iface, LONGLONG *time) +static HRESULT WINAPI media_engine_OnVideoStreamTick(IMFMediaEngine *iface, LONGLONG *pts) { - FIXME("(%p, %p): stub.\n", iface, time); + struct media_engine *engine = impl_from_IMFMediaEngine(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, pts); + + EnterCriticalSection(&engine->cs); + + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else if (!pts) + hr = E_POINTER; + else + { + *pts = engine->video_frame.pts; + hr = *pts == MINLONGLONG ? S_FALSE : S_OK; + } + + LeaveCriticalSection(&engine->cs); + + return hr; }
static const IMFMediaEngineVtbl media_engine_vtbl = @@ -1360,6 +1384,7 @@ static HRESULT WINAPI media_engine_grabber_callback_OnClockStop(IMFSampleGrabber
EnterCriticalSection(&engine->cs); media_engine_set_flag(engine, FLAGS_ENGINE_FIRST_FRAME, FALSE); + engine->video_frame.pts = MINLONGLONG; LeaveCriticalSection(&engine->cs);
return S_OK; @@ -1402,6 +1427,7 @@ static HRESULT WINAPI media_engine_grabber_callback_OnProcessSample(IMFSampleGra IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_FIRSTFRAMEREADY, 0, 0); engine->flags |= FLAGS_ENGINE_FIRST_FRAME; } + engine->video_frame.pts = sample_time;
LeaveCriticalSection(&engine->cs);
@@ -1469,6 +1495,7 @@ static HRESULT init_media_engine(DWORD flags, IMFAttributes *attributes, struct engine->playback_rate = 1.0; engine->volume = 1.0; engine->duration = NAN; + engine->video_frame.pts = MINLONGLONG; InitializeCriticalSection(&engine->cs);
hr = IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, &IID_IMFMediaEngineNotify, diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 0394bcf6a0e..21ead1b0afa 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -394,6 +394,7 @@ static void test_Play(void) struct media_engine_notify notify_impl = {{&media_engine_notify_vtbl}, 1}; IMFMediaEngineNotify *callback = ¬ify_impl.IMFMediaEngineNotify_iface; IMFMediaEngine *media_engine; + LONGLONG pts; HRESULT hr; BOOL ret;
@@ -402,6 +403,14 @@ static void test_Play(void) ret = IMFMediaEngine_IsPaused(media_engine); ok(ret, "Unexpected state %d.\n", ret);
+ hr = IMFMediaEngine_OnVideoStreamTick(media_engine, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + pts = 0; + hr = IMFMediaEngine_OnVideoStreamTick(media_engine, &pts); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + ok(pts == MINLONGLONG, "Unexpected timestamp.\n"); + hr = IMFMediaEngine_Play(media_engine); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
@@ -414,6 +423,12 @@ static void test_Play(void) hr = IMFMediaEngine_Shutdown(media_engine); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMFMediaEngine_OnVideoStreamTick(media_engine, NULL); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEngine_OnVideoStreamTick(media_engine, &pts); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + ret = IMFMediaEngine_IsPaused(media_engine); ok(!ret, "Unexpected state %d.\n", ret);