[PATCH v2 12/18] winegstreamer: Implement IMFMediaSource::Start.

Derek Lesho dlesho at codeweavers.com
Wed Apr 1 17:05:33 CDT 2020


Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
---
 dlls/mfplat/tests/mfplat.c        |  8 ++---
 dlls/winegstreamer/media_source.c | 59 +++++++++++++++++++++++++++++--
 2 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index bde6684515..b666b54cc0 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -519,10 +519,7 @@ static void test_source_resolver(void)
 
     var.vt = VT_EMPTY;
     hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
-todo_wine
     ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
-    if (FAILED(hr))
-        goto skip_source_tests;
 
     get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var);
     ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MENewStream event.\n", var.vt);
@@ -540,10 +537,13 @@ todo_wine
         hr = IMFMediaStream_RequestSample(video_stream, NULL);
         if (i == sample_count)
             break;
+todo_wine
         ok(hr == S_OK, "Failed to request sample %u, hr %#x.\n", i + 1, hr);
         if (hr != S_OK)
             break;
     }
+    if (FAILED(hr))
+        goto skip_source_tests;
 
     for (i = 0; i < sample_count; ++i)
     {
@@ -581,11 +581,11 @@ todo_wine
 
     hr = IMFMediaStream_RequestSample(video_stream, NULL);
     ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
-    IMFMediaStream_Release(video_stream);
 
     get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
 
 skip_source_tests:
+    IMFMediaStream_Release(video_stream);
     IMFMediaTypeHandler_Release(handler);
     IMFPresentationDescriptor_Release(descriptor);
 
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index fcaba45cd9..2b330a442e 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -513,13 +513,68 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD
                                      const GUID *time_format, const PROPVARIANT *start_position)
 {
     struct media_source *This = impl_from_IMFMediaSource(iface);
+    int ret;
+    PROPVARIANT empty_var;
+    empty_var.vt = VT_EMPTY;
 
-    FIXME("(%p)->(%p, %p, %p): stub\n", This, descriptor, time_format, start_position);
+    TRACE("(%p)->(%p, %p, %p)\n", This, descriptor, time_format, start_position);
 
     if (This->state == SOURCE_SHUTDOWN)
         return MF_E_SHUTDOWN;
 
-    return E_NOTIMPL;
+    /* Find out which streams are active */
+    for (unsigned int i = 0; i < This->stream_count; i++)
+    {
+        IMFStreamDescriptor *stream_desc;
+        DWORD in_stream_id;
+        BOOL selected;
+
+        IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, i, &selected, &stream_desc);
+        IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &in_stream_id);
+
+        for (unsigned int k = 0; k < This->stream_count; k++)
+        {
+            DWORD cur_stream_id;
+
+            IMFStreamDescriptor_GetStreamIdentifier(This->streams[k]->descriptor, &cur_stream_id);
+
+            if (in_stream_id == cur_stream_id)
+            {
+                BOOL was_active = This->streams[k]->state != STREAM_INACTIVE;
+                This->streams[k]->state = selected ? STREAM_RUNNING : STREAM_INACTIVE;
+                if (selected)
+                {
+                    IMFMediaEventQueue_QueueEventParamUnk(This->event_queue,
+                        was_active ? MEUpdatedStream : MENewStream, &GUID_NULL,
+                        S_OK, (IUnknown*) &This->streams[k]->IMFMediaStream_iface);
+                    IMFMediaEventQueue_QueueEventParamVar(This->streams[k]->event_queue,
+                        MEStreamStarted, &GUID_NULL, S_OK, &empty_var);
+                }
+            }
+        }
+
+        IMFStreamDescriptor_Release(stream_desc);
+    }
+
+    if (!(IsEqualIID(time_format, &GUID_NULL) &&
+          (start_position->vt == VT_EMPTY || (start_position->vt == VT_I8 && start_position->u.hVal.QuadPart == 0))))
+    {
+        ERR("unhandled start time\n");
+        return MF_E_UNSUPPORTED_TIME_FORMAT;
+    }
+
+    This->state = SOURCE_RUNNING;
+    gst_element_set_state(This->container, GST_STATE_PLAYING);
+    ret = gst_element_get_state(This->container, NULL, NULL, -1);
+    if (ret == GST_STATE_CHANGE_FAILURE)
+    {
+        ERR("Failed to play source.\n");
+        return E_FAIL;
+    }
+
+    IMFMediaEventQueue_QueueEventParamVar(This->event_queue, MESourceStarted, &GUID_NULL, S_OK, &empty_var);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI media_source_Stop(IMFMediaSource *iface)
-- 
2.26.0




More information about the wine-devel mailing list