Commit eea53b3c authored by Anton Baskanov's avatar Anton Baskanov Committed by Alexandre Julliard

amstream: Implement MediaStreamFilter::EndOfStream.

parent b1e2780e
...@@ -178,6 +178,7 @@ struct filter ...@@ -178,6 +178,7 @@ struct filter
REFERENCE_TIME start_time; REFERENCE_TIME start_time;
struct list free_events; struct list free_events;
struct list used_events; struct list used_events;
LONG eos_count;
}; };
struct event struct event
...@@ -266,6 +267,22 @@ static HRESULT WINAPI filter_GetClassID(IMediaStreamFilter *iface, CLSID *clsid) ...@@ -266,6 +267,22 @@ static HRESULT WINAPI filter_GetClassID(IMediaStreamFilter *iface, CLSID *clsid)
return S_OK; return S_OK;
} }
static void send_ec_complete(struct filter *filter)
{
IMediaEventSink *event_sink;
if (!filter->graph)
return;
if (FAILED(IFilterGraph_QueryInterface(filter->graph, &IID_IMediaEventSink, (void **)&event_sink)))
return;
IMediaEventSink_Notify(event_sink, EC_COMPLETE, S_OK,
(LONG_PTR)&filter->IMediaStreamFilter_iface);
IMediaEventSink_Release(event_sink);
}
static void set_state(struct filter *filter, FILTER_STATE state) static void set_state(struct filter *filter, FILTER_STATE state)
{ {
if (filter->state != state) if (filter->state != state)
...@@ -287,6 +304,9 @@ static HRESULT WINAPI filter_Stop(IMediaStreamFilter *iface) ...@@ -287,6 +304,9 @@ static HRESULT WINAPI filter_Stop(IMediaStreamFilter *iface)
EnterCriticalSection(&filter->cs); EnterCriticalSection(&filter->cs);
if (filter->state != State_Stopped)
filter->eos_count = 0;
set_state(filter, State_Stopped); set_state(filter, State_Stopped);
LIST_FOR_EACH_ENTRY(event, &filter->used_events, struct event, entry) LIST_FOR_EACH_ENTRY(event, &filter->used_events, struct event, entry)
...@@ -327,6 +347,10 @@ static HRESULT WINAPI filter_Run(IMediaStreamFilter *iface, REFERENCE_TIME start ...@@ -327,6 +347,10 @@ static HRESULT WINAPI filter_Run(IMediaStreamFilter *iface, REFERENCE_TIME start
EnterCriticalSection(&filter->cs); EnterCriticalSection(&filter->cs);
if (filter->state != State_Running && filter->seekable_stream
&& filter->eos_count == (LONG)filter->nb_streams)
send_ec_complete(filter);
filter->start_time = start; filter->start_time = start;
set_state(filter, State_Running); set_state(filter, State_Running);
...@@ -769,6 +793,9 @@ static HRESULT WINAPI filter_Flush(IMediaStreamFilter *iface, BOOL cancel_eos) ...@@ -769,6 +793,9 @@ static HRESULT WINAPI filter_Flush(IMediaStreamFilter *iface, BOOL cancel_eos)
} }
} }
if (cancel_eos)
--filter->eos_count;
LeaveCriticalSection(&filter->cs); LeaveCriticalSection(&filter->cs);
return S_OK; return S_OK;
...@@ -776,9 +803,20 @@ static HRESULT WINAPI filter_Flush(IMediaStreamFilter *iface, BOOL cancel_eos) ...@@ -776,9 +803,20 @@ static HRESULT WINAPI filter_Flush(IMediaStreamFilter *iface, BOOL cancel_eos)
static HRESULT WINAPI filter_EndOfStream(IMediaStreamFilter *iface) static HRESULT WINAPI filter_EndOfStream(IMediaStreamFilter *iface)
{ {
FIXME("(%p)->(): Stub!\n", iface); struct filter *filter = impl_from_IMediaStreamFilter(iface);
return E_NOTIMPL; TRACE("filter %p.\n", filter);
EnterCriticalSection(&filter->cs);
++filter->eos_count;
if (filter->state == State_Running && filter->seekable_stream &&
filter->eos_count == (LONG)filter->nb_streams)
send_ec_complete(filter);
LeaveCriticalSection(&filter->cs);
return S_OK;
} }
static const IMediaStreamFilterVtbl filter_vtbl = static const IMediaStreamFilterVtbl filter_vtbl =
......
...@@ -6954,9 +6954,9 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -6954,9 +6954,9 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
...@@ -6973,9 +6973,9 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -6973,9 +6973,9 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
...@@ -6994,14 +6994,14 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -6994,14 +6994,14 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
...@@ -7011,9 +7011,9 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7011,9 +7011,9 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
...@@ -7025,12 +7025,12 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7025,12 +7025,12 @@ static void test_mediastreamfilter_end_of_stream(void)
hr = IMediaControl_Run(media_control); hr = IMediaControl_Run(media_control);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaControl_Run(media_control); hr = IMediaControl_Run(media_control);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaControl_Stop(media_control); hr = IMediaControl_Stop(media_control);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
...@@ -7040,9 +7040,9 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7040,9 +7040,9 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
...@@ -7054,7 +7054,7 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7054,7 +7054,7 @@ static void test_mediastreamfilter_end_of_stream(void)
hr = IMediaControl_Run(media_control); hr = IMediaControl_Run(media_control);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaControl_Stop(media_control); hr = IMediaControl_Stop(media_control);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
...@@ -7066,7 +7066,7 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7066,7 +7066,7 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
...@@ -7074,7 +7074,7 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7074,7 +7074,7 @@ static void test_mediastreamfilter_end_of_stream(void)
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
...@@ -7088,7 +7088,7 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7088,7 +7088,7 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Pause(media_control); hr = IMediaControl_Pause(media_control);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
...@@ -7096,29 +7096,29 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7096,29 +7096,29 @@ static void test_mediastreamfilter_end_of_stream(void)
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaControl_Stop(media_control); hr = IMediaControl_Stop(media_control);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
/* EndOfStream count is not reset when Stop() is called on an already stopped filter. */ /* EndOfStream count is not reset when Stop() is called on an already stopped filter. */
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_Stop(filter); hr = IMediaStreamFilter_Stop(filter);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
graph.got_notify = 0; graph.got_notify = 0;
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
...@@ -7130,12 +7130,12 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7130,12 +7130,12 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_Flush(filter, TRUE); hr = IMediaStreamFilter_Flush(filter, TRUE);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
...@@ -7149,19 +7149,19 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7149,19 +7149,19 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaStreamFilter_Flush(filter, TRUE); hr = IMediaStreamFilter_Flush(filter, TRUE);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 2, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 2, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
...@@ -7176,16 +7176,16 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7176,16 +7176,16 @@ static void test_mediastreamfilter_end_of_stream(void)
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
...@@ -7197,14 +7197,14 @@ static void test_mediastreamfilter_end_of_stream(void) ...@@ -7197,14 +7197,14 @@ static void test_mediastreamfilter_end_of_stream(void)
graph.got_notify = 0; graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_Flush(filter, FALSE); hr = IMediaStreamFilter_Flush(filter, FALSE);
hr = IMediaStreamFilter_EndOfStream(filter); hr = IMediaStreamFilter_EndOfStream(filter);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment