quartz/tests: Improve tests for AVI splitter filter state.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4f8c54b5e9
commit
d749d50ada
|
@ -1015,6 +1015,58 @@ static void testfilter_init(struct testfilter *filter)
|
|||
filter->IAsyncReader_iface.lpVtbl = &async_reader_vtbl;
|
||||
}
|
||||
|
||||
static void test_filter_state(IMediaControl *control)
|
||||
{
|
||||
OAFilterState state;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IMediaControl_GetState(control, 0, &state);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(state == State_Stopped, "Got state %u.\n", state);
|
||||
|
||||
hr = IMediaControl_Pause(control);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IMediaControl_GetState(control, 0, &state);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(state == State_Paused, "Got state %u.\n", state);
|
||||
|
||||
hr = IMediaControl_Run(control);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IMediaControl_GetState(control, 0, &state);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(state == State_Running, "Got state %u.\n", state);
|
||||
|
||||
hr = IMediaControl_Pause(control);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IMediaControl_GetState(control, 0, &state);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(state == State_Paused, "Got state %u.\n", state);
|
||||
|
||||
hr = IMediaControl_Stop(control);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IMediaControl_GetState(control, 0, &state);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(state == State_Stopped, "Got state %u.\n", state);
|
||||
|
||||
hr = IMediaControl_Run(control);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IMediaControl_GetState(control, 0, &state);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(state == State_Running, "Got state %u.\n", state);
|
||||
|
||||
hr = IMediaControl_Stop(control);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IMediaControl_GetState(control, 0, &state);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(state == State_Stopped, "Got state %u.\n", state);
|
||||
}
|
||||
|
||||
static void test_connect_pin(void)
|
||||
{
|
||||
AM_MEDIA_TYPE req_mt =
|
||||
|
@ -1030,6 +1082,7 @@ static void test_connect_pin(void)
|
|||
AM_MEDIA_TYPE mt, *source_mt;
|
||||
IPin *sink, *source, *peer;
|
||||
IEnumMediaTypes *enummt;
|
||||
IMediaControl *control;
|
||||
IFilterGraph2 *graph;
|
||||
HRESULT hr;
|
||||
ULONG ref;
|
||||
|
@ -1043,6 +1096,7 @@ static void test_connect_pin(void)
|
|||
IFilterGraph2_AddFilter(graph, &testsource.filter.IBaseFilter_iface, L"source");
|
||||
IFilterGraph2_AddFilter(graph, filter, L"splitter");
|
||||
IBaseFilter_FindPin(filter, L"input pin", &sink);
|
||||
IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
|
||||
|
||||
CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IBaseFilter, (void **)&reader);
|
||||
|
@ -1108,6 +1162,8 @@ static void test_connect_pin(void)
|
|||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
test_filter_state(control);
|
||||
|
||||
hr = IPin_ConnectedTo(source, &peer);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(peer == &testsink.sink.pin.IPin_iface, "Got peer %p.\n", peer);
|
||||
|
@ -1235,6 +1291,7 @@ static void test_connect_pin(void)
|
|||
|
||||
IAsyncReader_Release(testsource.reader);
|
||||
IPin_Release(sink);
|
||||
IMediaControl_Release(control);
|
||||
ref = IFilterGraph2_Release(graph);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
ref = IBaseFilter_Release(reader);
|
||||
|
@ -1249,248 +1306,6 @@ static void test_connect_pin(void)
|
|||
ok(ret, "Failed to delete file, error %u.\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_filter_graph(void)
|
||||
{
|
||||
IFileSourceFilter *pfile = NULL;
|
||||
IBaseFilter *preader = NULL, *pavi = create_avi_splitter();
|
||||
IEnumPins *enumpins = NULL;
|
||||
IPin *filepin = NULL, *avipin = NULL;
|
||||
HRESULT hr;
|
||||
HANDLE file = NULL;
|
||||
PIN_DIRECTION dir = PINDIR_OUTPUT;
|
||||
char buffer[13];
|
||||
DWORD readbytes;
|
||||
FILTER_STATE state;
|
||||
|
||||
WCHAR *filename = load_resource(L"test.avi");
|
||||
|
||||
file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
skip("Could not read test file \"%s\", skipping test\n", wine_dbgstr_w(filename));
|
||||
DeleteFileW(filename);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buffer, 0, 13);
|
||||
readbytes = 12;
|
||||
ReadFile(file, buffer, readbytes, &readbytes, NULL);
|
||||
CloseHandle(file);
|
||||
if (strncmp(buffer, "RIFF", 4) || strcmp(buffer + 8, "AVI "))
|
||||
{
|
||||
skip("%s is not an avi riff file, not doing the avi splitter test\n",
|
||||
wine_dbgstr_w(filename));
|
||||
DeleteFileW(filename);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IUnknown_QueryInterface(pavi, &IID_IFileSourceFilter,
|
||||
(void **)&pfile);
|
||||
ok(hr == E_NOINTERFACE,
|
||||
"Avi splitter returns unexpected error: %08x\n", hr);
|
||||
if (pfile)
|
||||
IFileSourceFilter_Release(pfile);
|
||||
pfile = NULL;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IBaseFilter, (LPVOID*)&preader);
|
||||
ok(hr == S_OK, "Could not create asynchronous reader: %08x\n", hr);
|
||||
if (hr != S_OK)
|
||||
goto fail;
|
||||
|
||||
hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter,
|
||||
(void**)&pfile);
|
||||
ok(hr == S_OK, "Could not get IFileSourceFilter: %08x\n", hr);
|
||||
if (hr != S_OK)
|
||||
goto fail;
|
||||
|
||||
hr = IFileSourceFilter_Load(pfile, filename, NULL);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
trace("Could not load file: %08x\n", hr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = IBaseFilter_EnumPins(preader, &enumpins);
|
||||
ok(hr == S_OK, "No enumpins: %08x\n", hr);
|
||||
if (hr != S_OK)
|
||||
goto fail;
|
||||
|
||||
hr = IEnumPins_Next(enumpins, 1, &filepin, NULL);
|
||||
ok(hr == S_OK, "No pin: %08x\n", hr);
|
||||
if (hr != S_OK)
|
||||
goto fail;
|
||||
|
||||
IEnumPins_Release(enumpins);
|
||||
enumpins = NULL;
|
||||
|
||||
hr = IBaseFilter_EnumPins(pavi, &enumpins);
|
||||
ok(hr == S_OK, "No enumpins: %08x\n", hr);
|
||||
if (hr != S_OK)
|
||||
goto fail;
|
||||
|
||||
hr = IEnumPins_Next(enumpins, 1, &avipin, NULL);
|
||||
ok(hr == S_OK, "No pin: %08x\n", hr);
|
||||
if (hr != S_OK)
|
||||
goto fail;
|
||||
|
||||
hr = IPin_Connect(filepin, avipin, NULL);
|
||||
ok(hr == S_OK, "Could not connect: %08x\n", hr);
|
||||
if (hr != S_OK)
|
||||
goto fail;
|
||||
|
||||
IPin_Release(avipin);
|
||||
avipin = NULL;
|
||||
|
||||
IEnumPins_Reset(enumpins);
|
||||
|
||||
/* Windows puts the pins in the order: Outputpins - Inputpin,
|
||||
* wine does the reverse, just don't test it for now
|
||||
* Hate to admit it, but windows way makes more sense
|
||||
*/
|
||||
while (IEnumPins_Next(enumpins, 1, &avipin, NULL) == S_OK)
|
||||
{
|
||||
IPin_QueryDirection(avipin, &dir);
|
||||
if (dir == PINDIR_OUTPUT)
|
||||
{
|
||||
/* Well, connect it to a null renderer! */
|
||||
IBaseFilter *pnull = NULL;
|
||||
IEnumPins *nullenum = NULL;
|
||||
IPin *nullpin = NULL;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_NullRenderer, NULL,
|
||||
CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pnull);
|
||||
if (hr == REGDB_E_CLASSNOTREG)
|
||||
{
|
||||
win_skip("Null renderer not registered, skipping\n");
|
||||
break;
|
||||
}
|
||||
ok(hr == S_OK, "Could not create null renderer: %08x\n", hr);
|
||||
|
||||
hr = IBaseFilter_EnumPins(pnull, &nullenum);
|
||||
ok(hr == S_OK, "Failed to enum pins, hr %#x.\n", hr);
|
||||
hr = IEnumPins_Next(nullenum, 1, &nullpin, NULL);
|
||||
ok(hr == S_OK, "Failed to get next pin, hr %#x.\n", hr);
|
||||
IEnumPins_Release(nullenum);
|
||||
IPin_QueryDirection(nullpin, &dir);
|
||||
|
||||
hr = IPin_Connect(avipin, nullpin, NULL);
|
||||
ok(hr == S_OK, "Failed to connect output pin: %08x\n", hr);
|
||||
IPin_Release(nullpin);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
IBaseFilter_Release(pnull);
|
||||
break;
|
||||
}
|
||||
IBaseFilter_Run(pnull, 0);
|
||||
}
|
||||
|
||||
IPin_Release(avipin);
|
||||
avipin = NULL;
|
||||
}
|
||||
|
||||
if (avipin)
|
||||
IPin_Release(avipin);
|
||||
avipin = NULL;
|
||||
|
||||
if (hr != S_OK)
|
||||
goto fail2;
|
||||
/* At this point there is a minimalistic connected avi splitter that can
|
||||
* be used for all sorts of source filter tests. However that still needs
|
||||
* to be written at a later time.
|
||||
*
|
||||
* Interesting tests:
|
||||
* - Can you disconnect an output pin while running?
|
||||
* Expecting: Yes
|
||||
* - Can you disconnect the pullpin while running?
|
||||
* Expecting: No
|
||||
* - Is the reference count incremented during playback or when connected?
|
||||
* Does this happen once for every output pin? Or is there something else
|
||||
* going on.
|
||||
* Expecting: You tell me
|
||||
*/
|
||||
|
||||
IBaseFilter_Run(preader, 0);
|
||||
IBaseFilter_Run(pavi, 0);
|
||||
IBaseFilter_GetState(pavi, INFINITE, &state);
|
||||
|
||||
IBaseFilter_Pause(pavi);
|
||||
IBaseFilter_Pause(preader);
|
||||
IBaseFilter_Stop(pavi);
|
||||
IBaseFilter_Stop(preader);
|
||||
IBaseFilter_GetState(pavi, INFINITE, &state);
|
||||
IBaseFilter_GetState(preader, INFINITE, &state);
|
||||
|
||||
fail2:
|
||||
IEnumPins_Reset(enumpins);
|
||||
while (IEnumPins_Next(enumpins, 1, &avipin, NULL) == S_OK)
|
||||
{
|
||||
IPin *to = NULL;
|
||||
|
||||
IPin_QueryDirection(avipin, &dir);
|
||||
IPin_ConnectedTo(avipin, &to);
|
||||
if (to)
|
||||
{
|
||||
IPin_Release(to);
|
||||
|
||||
if (dir == PINDIR_OUTPUT)
|
||||
{
|
||||
PIN_INFO info;
|
||||
|
||||
hr = IPin_QueryPinInfo(to, &info);
|
||||
ok(hr == S_OK, "Failed to query pin info, hr %#x.\n", hr);
|
||||
|
||||
/* Release twice: Once normal, second from the
|
||||
* previous while loop
|
||||
*/
|
||||
IBaseFilter_Stop(info.pFilter);
|
||||
IPin_Disconnect(to);
|
||||
IPin_Disconnect(avipin);
|
||||
IBaseFilter_Release(info.pFilter);
|
||||
IBaseFilter_Release(info.pFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPin_Disconnect(to);
|
||||
IPin_Disconnect(avipin);
|
||||
}
|
||||
}
|
||||
IPin_Release(avipin);
|
||||
avipin = NULL;
|
||||
}
|
||||
|
||||
fail:
|
||||
if (hr != S_OK)
|
||||
skip("Prerequisites not matched, skipping remainder of test\n");
|
||||
if (enumpins)
|
||||
IEnumPins_Release(enumpins);
|
||||
|
||||
if (avipin)
|
||||
IPin_Release(avipin);
|
||||
if (filepin)
|
||||
{
|
||||
IPin *to = NULL;
|
||||
|
||||
IPin_ConnectedTo(filepin, &to);
|
||||
if (to)
|
||||
{
|
||||
IPin_Disconnect(filepin);
|
||||
IPin_Disconnect(to);
|
||||
}
|
||||
IPin_Release(filepin);
|
||||
}
|
||||
|
||||
if (preader)
|
||||
IBaseFilter_Release(preader);
|
||||
if (pavi)
|
||||
IBaseFilter_Release(pavi);
|
||||
if (pfile)
|
||||
IFileSourceFilter_Release(pfile);
|
||||
|
||||
DeleteFileW(filename);
|
||||
}
|
||||
|
||||
static void test_unconnected_filter_state(void)
|
||||
{
|
||||
IBaseFilter *filter = create_avi_splitter();
|
||||
|
@ -1570,7 +1385,6 @@ START_TEST(avisplit)
|
|||
test_media_types();
|
||||
test_enum_media_types();
|
||||
test_unconnected_filter_state();
|
||||
test_filter_graph();
|
||||
test_connect_pin();
|
||||
|
||||
CoUninitialize();
|
||||
|
|
Loading…
Reference in New Issue