From: Derek Lesho Subject: [PATCH v2 12/18] winegstreamer: Implement IMFMediaSource::Start. Message-Id: <20200401220539.522012-12-dlesho@codeweavers.com> Date: Wed, 1 Apr 2020 17:05:33 -0500 In-Reply-To: <20200401220539.522012-1-dlesho@codeweavers.com> References: <20200401220539.522012-1-dlesho@codeweavers.com> Signed-off-by: Derek Lesho --- 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