ReactOS 0.4.17-dev-966-gf06eace
filtergraph.c File Reference
#include "dshow.h"
#include "wine/strmbase.h"
#include "wine/test.h"
Include dependency graph for filtergraph.c:

Go to the source code of this file.

Classes

struct  testpin
 
struct  testfilter
 
struct  testfilter_cf
 

Macros

#define COBJMACROS
 
#define CONST_VTABLE
 
#define check_interface(a, b, c)   check_interface_(__LINE__, a, b, c)
 
#define check_filter_state(a, b)   check_filter_state_(__LINE__, a, b)
 
#define check_events(a, b, c)   check_events_(__LINE__, a, b, c)
 

Functions

static BOOL compare_time (ULONGLONG x, ULONGLONG y, unsigned int max_diff)
 
static WCHAR * create_file (const WCHAR *name, const char *data, DWORD size)
 
static WCHAR * load_resource (const WCHAR *name)
 
static IFilterGraph2 * create_graph (void)
 
static ULONG get_refcount (void *iface)
 
static void check_interface_ (unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
 
static void test_interfaces (void)
 
static void test_basic_video (IFilterGraph2 *graph)
 
static void test_media_seeking (IFilterGraph2 *graph)
 
static void test_state_change (IFilterGraph2 *graph)
 
static void test_media_event (IFilterGraph2 *graph)
 
static void rungraph (IFilterGraph2 *graph, BOOL video)
 
static HRESULT test_graph_builder_connect_file (WCHAR *filename, BOOL audio, BOOL video)
 
static void test_render_run (const WCHAR *file, BOOL audio, BOOL video)
 
static void test_enum_filters (void)
 
static DWORD WINAPI call_RenderFile_multithread (LPVOID lParam)
 
static void test_render_with_multithread (void)
 
static struct testpin * impl_from_IEnumMediaTypes (IEnumMediaTypes *iface)
 
static HRESULT WINAPI testenummt_QueryInterface (IEnumMediaTypes *iface, REFIID iid, void **out)
 
static ULONG WINAPI testenummt_AddRef (IEnumMediaTypes *iface)
 
static ULONG WINAPI testenummt_Release (IEnumMediaTypes *iface)
 
static HRESULT WINAPI testenummt_Next (IEnumMediaTypes *iface, ULONG count, AM_MEDIA_TYPE **out, ULONG *fetched)
 
static HRESULT WINAPI testenummt_Skip (IEnumMediaTypes *iface, ULONG count)
 
static HRESULT WINAPI testenummt_Reset (IEnumMediaTypes *iface)
 
static HRESULT WINAPI testenummt_Clone (IEnumMediaTypes *iface, IEnumMediaTypes **out)
 
static struct testpin * impl_from_IPin (IPin *iface)
 
static struct testpin * impl_from_IMemInputPin (IMemInputPin *iface)
 
static HRESULT WINAPI testpin_QueryInterface (IPin *iface, REFIID iid, void **out)
 
static ULONG WINAPI testpin_AddRef (IPin *iface)
 
static ULONG WINAPI testpin_Release (IPin *iface)
 
static HRESULT WINAPI testpin_Disconnect (IPin *iface)
 
static HRESULT WINAPI testpin_ConnectedTo (IPin *iface, IPin **peer)
 
static HRESULT WINAPI testpin_ConnectionMediaType (IPin *iface, AM_MEDIA_TYPE *mt)
 
static HRESULT WINAPI testpin_QueryPinInfo (IPin *iface, PIN_INFO *info)
 
static HRESULT WINAPI testpin_QueryDirection (IPin *iface, PIN_DIRECTION *dir)
 
static HRESULT WINAPI testpin_QueryId (IPin *iface, WCHAR **id)
 
static HRESULT WINAPI testpin_QueryAccept (IPin *iface, const AM_MEDIA_TYPE *mt)
 
static HRESULT WINAPI testpin_EnumMediaTypes (IPin *iface, IEnumMediaTypes **out)
 
static HRESULT WINAPI testpin_QueryInternalConnections (IPin *iface, IPin **out, ULONG *count)
 
static HRESULT WINAPI testpin_BeginFlush (IPin *iface)
 
static HRESULT WINAPI testpin_EndFlush (IPin *iface)
 
static HRESULT WINAPI testpin_NewSegment (IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
 
static HRESULT WINAPI testpin_EndOfStream (IPin *iface)
 
static HRESULT WINAPI no_Connect (IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
 
static HRESULT WINAPI no_ReceiveConnection (IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
 
static HRESULT WINAPI no_EnumMediaTypes (IPin *iface, IEnumMediaTypes **out)
 
static HRESULT WINAPI testsink_ReceiveConnection (IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
 
static void testpin_init (struct testpin *pin, const IPinVtbl *vtbl, PIN_DIRECTION dir)
 
static void testsink_init (struct testpin *pin)
 
static HRESULT WINAPI testsource_Connect (IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
 
static void testsource_init (struct testpin *pin, const AM_MEDIA_TYPE *types, int type_count)
 
static struct testfilter * impl_from_IEnumPins (IEnumPins *iface)
 
static HRESULT WINAPI testenumpins_QueryInterface (IEnumPins *iface, REFIID iid, void **out)
 
static ULONG WINAPI testenumpins_AddRef (IEnumPins *iface)
 
static ULONG WINAPI testenumpins_Release (IEnumPins *iface)
 
static HRESULT WINAPI testenumpins_Next (IEnumPins *iface, ULONG count, IPin **out, ULONG *fetched)
 
static HRESULT WINAPI testenumpins_Skip (IEnumPins *iface, ULONG count)
 
static HRESULT WINAPI testenumpins_Reset (IEnumPins *iface)
 
static HRESULT WINAPI testenumpins_Clone (IEnumPins *iface, IEnumPins **out)
 
static struct testfilter * impl_from_IBaseFilter (IBaseFilter *iface)
 
static HRESULT WINAPI testfilter_QueryInterface (IBaseFilter *iface, REFIID iid, void **out)
 
static ULONG WINAPI testfilter_AddRef (IBaseFilter *iface)
 
static ULONG WINAPI testfilter_Release (IBaseFilter *iface)
 
static HRESULT WINAPI testfilter_GetClassID (IBaseFilter *iface, CLSID *clsid)
 
static void check_state_transition (struct testfilter *filter, FILTER_STATE expect)
 
static HRESULT WINAPI testfilter_Stop (IBaseFilter *iface)
 
static HRESULT WINAPI testfilter_Pause (IBaseFilter *iface)
 
static HRESULT WINAPI testfilter_Run (IBaseFilter *iface, REFERENCE_TIME start)
 
static HRESULT WINAPI testfilter_GetState (IBaseFilter *iface, DWORD timeout, FILTER_STATE *state)
 
static HRESULT WINAPI testfilter_SetSyncSource (IBaseFilter *iface, IReferenceClock *clock)
 
static HRESULT WINAPI testfilter_GetSyncSource (IBaseFilter *iface, IReferenceClock **clock)
 
static HRESULT WINAPI testfilter_EnumPins (IBaseFilter *iface, IEnumPins **out)
 
static HRESULT WINAPI testfilter_FindPin (IBaseFilter *iface, const WCHAR *id, IPin **pin)
 
static HRESULT WINAPI testfilter_QueryFilterInfo (IBaseFilter *iface, FILTER_INFO *info)
 
static HRESULT WINAPI testfilter_JoinFilterGraph (IBaseFilter *iface, IFilterGraph *graph, const WCHAR *name)
 
static HRESULT WINAPI testfilter_QueryVendorInfo (IBaseFilter *iface, WCHAR **info)
 
static struct testfilter * impl_from_IAMFilterMiscFlags (IAMFilterMiscFlags *iface)
 
static HRESULT WINAPI testmiscflags_QueryInterface (IAMFilterMiscFlags *iface, REFIID iid, void **out)
 
static ULONG WINAPI testmiscflags_AddRef (IAMFilterMiscFlags *iface)
 
static ULONG WINAPI testmiscflags_Release (IAMFilterMiscFlags *iface)
 
static ULONG WINAPI testmiscflags_GetMiscFlags (IAMFilterMiscFlags *iface)
 
static struct testfilter * impl_from_IMediaSeeking (IMediaSeeking *iface)
 
static HRESULT WINAPI testseek_QueryInterface (IMediaSeeking *iface, REFIID iid, void **out)
 
static ULONG WINAPI testseek_AddRef (IMediaSeeking *iface)
 
static ULONG WINAPI testseek_Release (IMediaSeeking *iface)
 
static HRESULT WINAPI testseek_GetCapabilities (IMediaSeeking *iface, DWORD *caps)
 
static HRESULT WINAPI testseek_CheckCapabilities (IMediaSeeking *iface, DWORD *caps)
 
static HRESULT WINAPI testseek_IsFormatSupported (IMediaSeeking *iface, const GUID *format)
 
static HRESULT WINAPI testseek_QueryPreferredFormat (IMediaSeeking *iface, GUID *format)
 
static HRESULT WINAPI testseek_GetTimeFormat (IMediaSeeking *iface, GUID *format)
 
static HRESULT WINAPI testseek_IsUsingTimeFormat (IMediaSeeking *iface, const GUID *format)
 
static HRESULT WINAPI testseek_SetTimeFormat (IMediaSeeking *iface, const GUID *format)
 
static HRESULT WINAPI testseek_GetDuration (IMediaSeeking *iface, LONGLONG *duration)
 
static HRESULT WINAPI testseek_GetStopPosition (IMediaSeeking *iface, LONGLONG *stop)
 
static HRESULT WINAPI testseek_GetCurrentPosition (IMediaSeeking *iface, LONGLONG *current)
 
static HRESULT WINAPI testseek_ConvertTimeFormat (IMediaSeeking *iface, LONGLONG *target, const GUID *target_format, LONGLONG source, const GUID *source_format)
 
static HRESULT WINAPI testseek_SetPositions (IMediaSeeking *iface, LONGLONG *current, DWORD current_flags, LONGLONG *stop, DWORD stop_flags)
 
static HRESULT WINAPI testseek_GetPositions (IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
 
static HRESULT WINAPI testseek_GetAvailable (IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest)
 
static HRESULT WINAPI testseek_SetRate (IMediaSeeking *iface, double rate)
 
static HRESULT WINAPI testseek_GetRate (IMediaSeeking *iface, double *rate)
 
static HRESULT WINAPI testseek_GetPreroll (IMediaSeeking *iface, LONGLONG *preroll)
 
static struct testfilter * impl_from_IMediaPosition (IMediaPosition *iface)
 
static HRESULT WINAPI testpos_QueryInterface (IMediaPosition *iface, REFIID iid, void **out)
 
static ULONG WINAPI testpos_AddRef (IMediaPosition *iface)
 
static ULONG WINAPI testpos_Release (IMediaPosition *iface)
 
static HRESULT WINAPI testpos_GetTypeInfoCount (IMediaPosition *iface, UINT *count)
 
static HRESULT WINAPI testpos_GetTypeInfo (IMediaPosition *iface, UINT index, LCID lcid, ITypeInfo **typeinfo)
 
static HRESULT WINAPI testpos_GetIDsOfNames (IMediaPosition *iface, REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
 
static HRESULT WINAPI testpos_Invoke (IMediaPosition *iface, DISPID id, REFIID iid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg)
 
static HRESULT WINAPI testpos_get_Duration (IMediaPosition *iface, REFTIME *length)
 
static HRESULT WINAPI testpos_put_CurrentPosition (IMediaPosition *iface, REFTIME time)
 
static HRESULT WINAPI testpos_get_CurrentPosition (IMediaPosition *iface, REFTIME *time)
 
static HRESULT WINAPI testpos_get_StopTime (IMediaPosition *iface, REFTIME *time)
 
static HRESULT WINAPI testpos_put_StopTime (IMediaPosition *iface, REFTIME time)
 
static HRESULT WINAPI testpos_get_PrerollTime (IMediaPosition *iface, REFTIME *time)
 
static HRESULT WINAPI testpos_put_PrerollTime (IMediaPosition *iface, REFTIME time)
 
static HRESULT WINAPI testpos_put_Rate (IMediaPosition *iface, double rate)
 
static HRESULT WINAPI testpos_get_Rate (IMediaPosition *iface, double *rate)
 
static HRESULT WINAPI testpos_CanSeekForward (IMediaPosition *iface, LONG *can_seek_forward)
 
static HRESULT WINAPI testpos_CanSeekBackward (IMediaPosition *iface, LONG *can_seek_backward)
 
static struct testfilter * impl_from_IReferenceClock (IReferenceClock *iface)
 
static HRESULT WINAPI testclock_QueryInterface (IReferenceClock *iface, REFIID iid, void **out)
 
static ULONG WINAPI testclock_AddRef (IReferenceClock *iface)
 
static ULONG WINAPI testclock_Release (IReferenceClock *iface)
 
static HRESULT WINAPI testclock_GetTime (IReferenceClock *iface, REFERENCE_TIME *time)
 
static HRESULT WINAPI testclock_AdviseTime (IReferenceClock *iface, REFERENCE_TIME base, REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie)
 
static HRESULT WINAPI testclock_AdvisePeriodic (IReferenceClock *iface, REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie)
 
static HRESULT WINAPI testclock_Unadvise (IReferenceClock *iface, DWORD_PTR cookie)
 
static struct testfilter * impl_from_IFileSourceFilter (IFileSourceFilter *iface)
 
static HRESULT WINAPI testfilesource_QueryInterface (IFileSourceFilter *iface, REFIID iid, void **out)
 
static ULONG WINAPI testfilesource_AddRef (IFileSourceFilter *iface)
 
static ULONG WINAPI testfilesource_Release (IFileSourceFilter *iface)
 
static HRESULT WINAPI testfilesource_Load (IFileSourceFilter *iface, const WCHAR *filename, const AM_MEDIA_TYPE *mt)
 
static HRESULT WINAPI testfilesource_GetCurFile (IFileSourceFilter *iface, WCHAR **filename, AM_MEDIA_TYPE *mt)
 
static void testfilter_init (struct testfilter *filter, struct testpin *pins, int pin_count)
 
static HRESULT WINAPI testfilter_cf_QueryInterface (IClassFactory *iface, REFIID iid, void **out)
 
static ULONG WINAPI testfilter_cf_AddRef (IClassFactory *iface)
 
static ULONG WINAPI testfilter_cf_Release (IClassFactory *iface)
 
static HRESULT WINAPI testfilter_cf_CreateInstance (IClassFactory *iface, IUnknown *outer, REFIID iid, void **out)
 
static HRESULT WINAPI testfilter_cf_LockServer (IClassFactory *iface, BOOL lock)
 
static void test_graph_builder_render (void)
 
static void test_graph_builder_connect (void)
 
static HRESULT WINAPI outer_QueryInterface (IUnknown *iface, REFIID iid, void **out)
 
static ULONG WINAPI outer_AddRef (IUnknown *iface)
 
static ULONG WINAPI outer_Release (IUnknown *iface)
 
static void test_aggregation (void)
 
static void test_control_delegation (void)
 
static void test_add_remove_filter (void)
 
static HRESULT WINAPI test_connect_direct_Connect (IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
 
static void test_connect_direct_init (struct testpin *pin, PIN_DIRECTION dir)
 
static void test_connect_direct (void)
 
static void test_sync_source (void)
 
static void check_filter_state_ (unsigned int line, IFilterGraph2 *graph, FILTER_STATE expect)
 
static void test_filter_state (void)
 
static HRESULT check_ec_complete (IFilterGraph2 *graph, IBaseFilter *filter)
 
static void test_ec_complete (void)
 
static HRESULT WINAPI mpegtestsink_ReceiveConnection (IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
 
static HRESULT WINAPI mpegtestpin_EndOfStream (IPin *iface)
 
static HRESULT WINAPI mpegtestpin_NewSegment (IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
 
static HRESULT WINAPI meminput_QueryInterface (IMemInputPin *iface, REFIID iid, void **out)
 
static ULONG WINAPI meminput_AddRef (IMemInputPin *iface)
 
static ULONG WINAPI meminput_Release (IMemInputPin *iface)
 
static HRESULT STDMETHODCALLTYPE meminput_GetAllocator (IMemInputPin *iface, IMemAllocator **allocator)
 
static HRESULT STDMETHODCALLTYPE meminput_NotifyAllocator (IMemInputPin *iface, IMemAllocator *allocator, BOOL readonly)
 
static HRESULT STDMETHODCALLTYPE meminput_GetAllocatorRequirements (IMemInputPin *iface, ALLOCATOR_PROPERTIES *props)
 
static HRESULT STDMETHODCALLTYPE meminput_Receive (IMemInputPin *iface, IMediaSample *sample)
 
static HRESULT STDMETHODCALLTYPE meminput_ReceiveMultiple (IMemInputPin *iface, IMediaSample **samples, LONG n_samples, LONG *n_samples_processed)
 
static HRESULT STDMETHODCALLTYPE meminput_ReceiveCanBlock (IMemInputPin *iface)
 
static void test_renderfile_compressed (void)
 
static void test_renderfile_failure (void)
 
static void flush_cached_seeking (IFilterGraph2 *graph, struct testfilter *filter)
 
static void test_graph_seeking (void)
 
static void test_default_sync_source (void)
 
static void test_add_source_filter (void)
 
static HWND get_renderer_hwnd (IFilterGraph2 *graph)
 
static LRESULT CALLBACK parent_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
 
static void test_window_threading (void)
 
static void test_autoplug_uyvy (void)
 
static void test_set_notify_flags (void)
 
static void check_events_ (unsigned int line, IMediaEventEx *media_event, int expected_ec_complete_count, int expected_ec_status_count)
 
static void test_events (void)
 
static void test_event_dispatch (void)
 
 START_TEST (filtergraph)
 

Variables

static const GUID testguid = {0xabbccdde}
 
static const IEnumMediaTypesVtbl testenummt_vtbl
 
static const IPinVtbl testsink_vtbl
 
static const IPinVtbl testsource_vtbl
 
static const IEnumPinsVtbl testenumpins_vtbl
 
static const IBaseFilterVtbl testfilter_vtbl
 
static const IAMFilterMiscFlagsVtbl testmiscflags_vtbl
 
static const IMediaSeekingVtbl testseek_vtbl
 
static const IMediaPositionVtbl testpos_vtbl
 
static const IReferenceClockVtbl testclock_vtbl
 
static const IFileSourceFilterVtbl testfilesource_vtbl
 
static IClassFactoryVtbl testfilter_cf_vtbl
 
static const GUID test_iid = {0x33333333}
 
static LONG outer_ref = 1
 
static const IUnknownVtbl outer_vtbl
 
static IUnknown test_outer = {&outer_vtbl}
 
static const IPinVtbl test_connect_direct_vtbl
 
static const IPinVtbl mpegtestsink_vtbl
 
static const IMemInputPinVtbl mpegtestsink_meminput_vtbl
 
static BOOL expect_parent_message = TRUE
 

Macro Definition Documentation

◆ check_events

#define check_events (   a,
  b,
  c 
)    check_events_(__LINE__, a, b, c)

Definition at line 5732 of file filtergraph.c.

◆ check_filter_state

#define check_filter_state (   a,
  b 
)    check_filter_state_(__LINE__, a, b)

Definition at line 3406 of file filtergraph.c.

◆ check_interface

#define check_interface (   a,
  b,
  c 
)    check_interface_(__LINE__, a, b, c)

Definition at line 82 of file filtergraph.c.

◆ COBJMACROS

#define COBJMACROS

Definition at line 22 of file filtergraph.c.

◆ CONST_VTABLE

#define CONST_VTABLE

Definition at line 23 of file filtergraph.c.

Function Documentation

◆ call_RenderFile_multithread()

static DWORD WINAPI call_RenderFile_multithread ( LPVOID  lParam)
static

Definition at line 786 of file filtergraph.c.

787{
788 WCHAR *filename = load_resource(L"test.avi");
790 HRESULT hr;
791
792 hr = IFilterGraph2_RenderFile(graph, filename, NULL);
793 ok(hr == S_OK, "Got hr %#lx.\n", hr);
794
796
797 return 0;
798}
#define ok(value,...)
Definition: atltest.h:57
LPARAM lParam
Definition: combotst.c:139
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define L(x)
Definition: resources.c:13
#define S_OK
Definition: intsafe.h:52
const char * filename
Definition: ioapi.h:137
#define load_resource(a, b, c)
Definition: font.c:46
static void rungraph(IFilterGraph2 *graph, BOOL video)
Definition: filtergraph.c:546
short WCHAR
Definition: pedump.c:58
Definition: graph.c:32

Referenced by test_render_with_multithread().

◆ check_ec_complete()

static HRESULT check_ec_complete ( IFilterGraph2 *  graph,
IBaseFilter *  filter 
)
static

Definition at line 3988 of file filtergraph.c.

3989{
3990 IMediaEventSink *eventsink;
3991 LONG_PTR param1, param2;
3992 IMediaControl *control;
3993 IMediaEvent *eventsrc;
3994 HRESULT hr, ret_hr;
3995 LONG code;
3996
3997 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3998 IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc);
3999 IFilterGraph2_QueryInterface(graph, &IID_IMediaEventSink, (void **)&eventsink);
4000
4001 IMediaControl_Run(control);
4002
4003 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 0);
4004 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4005
4006 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)filter);
4007 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4008
4009 ret_hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 0);
4010 if (ret_hr == S_OK)
4011 {
4012 ok(code == EC_COMPLETE, "Got code %#lx.\n", code);
4013 ok(param1 == S_OK, "Got param1 %#Ix.\n", param1);
4014 ok(!param2, "Got param2 %#Ix.\n", param2);
4015 hr = IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
4016 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4017
4018 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 0);
4019 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4020 }
4021
4022 IMediaControl_Stop(control);
4023
4024 IMediaControl_Release(control);
4025 IMediaEvent_Release(eventsrc);
4026 IMediaEventSink_Release(eventsink);
4027 return ret_hr;
4028}
#define EC_COMPLETE
Definition: evcode.h:17
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
long LONG
Definition: pedump.c:60
Definition: inflate.c:139
Definition: dialog.c:52
Definition: filter.c:165
#define E_ABORT
Definition: winerror.h:3481

Referenced by test_ec_complete().

◆ check_events_()

static void check_events_ ( unsigned int  line,
IMediaEventEx *  media_event,
int  expected_ec_complete_count,
int  expected_ec_status_count 
)
static

Definition at line 5733 of file filtergraph.c.

5735{
5736 int ec_complete_count = 0;
5737 int ec_status_count = 0;
5738 LONG_PTR param1, param2;
5739 HRESULT hr;
5740 LONG code;
5741 for (;;)
5742 {
5743 hr = IMediaEventEx_GetEvent(media_event, &code, &param1, &param2, 50);
5744 if (hr != S_OK)
5745 break;
5746 if (code == EC_COMPLETE)
5747 ++ec_complete_count;
5748 if (code == EC_STATUS)
5749 ++ec_status_count;
5750 hr = IMediaEventEx_FreeEventParams(media_event, code, param1, param2);
5751 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5752 }
5753 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
5754 ok_(__FILE__, line)(ec_complete_count == expected_ec_complete_count,
5755 "Expected %d EC_COMPLETE events.\n", expected_ec_complete_count);
5756 ok_(__FILE__, line)(ec_status_count == expected_ec_status_count,
5757 "Expected %d EC_STATUS events.\n", expected_ec_status_count);
5758}
#define ok_(x1, x2)
Definition: atltest.h:61
#define EC_STATUS
Definition: evcode.h:68
Definition: parser.c:49

◆ check_filter_state_()

static void check_filter_state_ ( unsigned int  line,
IFilterGraph2 *  graph,
FILTER_STATE  expect 
)
static

Definition at line 3407 of file filtergraph.c.

3408{
3409 IMediaFilter *mediafilter;
3410 IEnumFilters *filterenum;
3411 IMediaControl *control;
3412 OAFilterState oastate;
3414 FILTER_STATE state;
3415 HRESULT hr;
3416
3417 IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&mediafilter);
3418 hr = IMediaFilter_GetState(mediafilter, 1000, &state);
3419 ok_(__FILE__, line)(hr == S_OK, "IMediaFilter_GetState() returned %#lx.\n", hr);
3420 ok_(__FILE__, line)(state == expect, "Expected state %u, got %u.\n", expect, state);
3421 IMediaFilter_Release(mediafilter);
3422
3423 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3424 hr = IMediaControl_GetState(control, 1000, &oastate);
3425 ok_(__FILE__, line)(hr == S_OK, "IMediaControl_GetState() returned %#lx.\n", hr);
3426 ok_(__FILE__, line)(state == expect, "Expected state %u, got %u.\n", expect, state);
3427 IMediaControl_Release(control);
3428
3429 IFilterGraph2_EnumFilters(graph, &filterenum);
3430 while (IEnumFilters_Next(filterenum, 1, &filter, NULL) == S_OK)
3431 {
3432 hr = IBaseFilter_GetState(filter, 1000, &state);
3433 ok_(__FILE__, line)(hr == S_OK, "IBaseFilter_GetState() returned %#lx.\n", hr);
3434 ok_(__FILE__, line)(state == expect, "Expected state %u, got %u.\n", expect, state);
3435 IBaseFilter_Release(filter);
3436 }
3437 IEnumFilters_Release(filterenum);
3438}
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
static int state
Definition: maze.c:121
LONG OAFilterState
Definition: control.idl:30

◆ check_interface_()

static void check_interface_ ( unsigned int  line,
void *  iface_ptr,
REFIID  iid,
BOOL  supported 
)
static

Definition at line 83 of file filtergraph.c.

84{
85 IUnknown *iface = iface_ptr;
87 IUnknown *unk;
88
89 expected_hr = supported ? S_OK : E_NOINTERFACE;
90
91 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
92 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
93 if (SUCCEEDED(hr))
94 IUnknown_Release(unk);
95}
HRESULT expected_hr
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ check_state_transition()

static void check_state_transition ( struct testfilter *  filter,
FILTER_STATE  expect 
)
static

Definition at line 1391 of file filtergraph.c.

1392{
1393 FILTER_STATE state;
1394 unsigned int i;
1395 PIN_INFO info;
1396
1397 for (i = 0; i < filter->pin_count; ++i)
1398 {
1399 if (filter->pins[i].peer)
1400 {
1401 IPin_QueryPinInfo(filter->pins[i].peer, &info);
1402 IBaseFilter_GetState(info.pFilter, 0, &state);
1403 if (filter->pins[i].dir == PINDIR_OUTPUT)
1404 ok(state == expect, "Expected state %d for downstream filter %p, got %d.\n",
1405 expect, info.pFilter, state);
1406 else
1407 ok(state == filter->state, "Expected state %d for upstream filter %p, got %d.\n",
1408 filter->state, info.pFilter, state);
1409 IBaseFilter_Release(info.pFilter);
1410 }
1411 }
1412}
@ PINDIR_OUTPUT
Definition: axcore.idl:42
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FILTER_STATE state
Definition: filter.c:177

Referenced by testfilter_Pause(), testfilter_Run(), and testfilter_Stop().

◆ compare_time()

static BOOL compare_time ( ULONGLONG  x,
ULONGLONG  y,
unsigned int  max_diff 
)
static

Definition at line 31 of file filtergraph.c.

32{
33 ULONGLONG diff = x > y ? x - y : y - x;
34 return diff <= max_diff;
35}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by test_graph_seeking().

◆ create_file()

static WCHAR * create_file ( const WCHAR *  name,
const char *  data,
DWORD  size 
)
static

Definition at line 37 of file filtergraph.c.

38{
39 static WCHAR pathW[MAX_PATH];
40 DWORD written;
42
46 ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %lu.\n",
48 WriteFile(file, data, size, &written, NULL);
49 ok(written == size, "Failed to write file data, error %lu.\n", GetLastError());
51
52 return pathW;
53}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
BOOL WINAPI WriteFile(_In_ HANDLE hFile, _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, _In_ DWORD nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped)
Definition: rw.c:25
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2098
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
#define wine_dbgstr_w
Definition: kernel32.h:34
#define CREATE_ALWAYS
Definition: disk.h:72
static const WCHAR pathW[]
Definition: path.c:2368
#define GENERIC_WRITE
Definition: nt_native.h:90
wcscat
Definition: fci.c:123
Definition: name.c:39
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

◆ create_graph()

◆ flush_cached_seeking()

static void flush_cached_seeking ( IFilterGraph2 *  graph,
struct testfilter *  filter 
)
static

Definition at line 4451 of file filtergraph.c.

4452{
4453 IFilterGraph2_RemoveFilter(graph, &filter->IBaseFilter_iface);
4455 IFilterGraph2_AddFilter(graph, &filter->IBaseFilter_iface, NULL);
4457}
static const IMediaSeekingVtbl testseek_vtbl
Definition: filtergraph.c:1757
IMediaSeeking IMediaSeeking_iface
Definition: filter.c:167

Referenced by test_graph_seeking().

◆ get_refcount()

static ULONG get_refcount ( void *  iface)
static

Definition at line 75 of file filtergraph.c.

76{
77 IUnknown *unknown = iface;
78 IUnknown_AddRef(unknown);
79 return IUnknown_Release(unknown);
80}
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1674

Referenced by test_aggregation().

◆ get_renderer_hwnd()

static HWND get_renderer_hwnd ( IFilterGraph2 *  graph)
static

Definition at line 5395 of file filtergraph.c.

5396{
5400 IOverlay *overlay;
5401 HWND hwnd = NULL;
5402 HRESULT hr;
5403 IPin *pin;
5404
5405 hr = IFilterGraph2_EnumFilters(graph, &enum_filters);
5406 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5407
5408 while (IEnumFilters_Next(enum_filters, 1, &filter, NULL) == S_OK)
5409 {
5410 hr = IBaseFilter_EnumPins(filter, &enum_pins);
5411 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5412 hr = IEnumPins_Next(enum_pins, 1, &pin, NULL);
5413 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5414 IEnumPins_Release(enum_pins);
5415
5416 if (SUCCEEDED(IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay)))
5417 {
5418 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
5419 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5420 IOverlay_Release(overlay);
5421 }
5422
5423 IPin_Release(pin);
5424 IBaseFilter_Release(filter);
5425 }
5426
5427 IEnumFilters_Release(enum_filters);
5428
5429 return hwnd;
5430}
Definition: axcore.idl:92
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023

Referenced by test_window_threading().

◆ impl_from_IAMFilterMiscFlags()

static struct testfilter * impl_from_IAMFilterMiscFlags ( IAMFilterMiscFlags *  iface)
static

Definition at line 1562 of file filtergraph.c.

1563{
1564 return CONTAINING_RECORD(iface, struct testfilter, IAMFilterMiscFlags_iface);
1565}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by testmiscflags_AddRef(), testmiscflags_GetMiscFlags(), testmiscflags_QueryInterface(), and testmiscflags_Release().

◆ impl_from_IBaseFilter()

◆ impl_from_IEnumMediaTypes()

static struct testpin * impl_from_IEnumMediaTypes ( IEnumMediaTypes *  iface)
inlinestatic

Definition at line 880 of file filtergraph.c.

881{
882 return CONTAINING_RECORD(iface, struct testpin, IEnumMediaTypes_iface);
883}

Referenced by testenummt_AddRef(), testenummt_Next(), testenummt_QueryInterface(), testenummt_Release(), and testenummt_Reset().

◆ impl_from_IEnumPins()

static struct testfilter * impl_from_IEnumPins ( IEnumPins *  iface)
inlinestatic

Definition at line 1248 of file filtergraph.c.

1249{
1250 return CONTAINING_RECORD(iface, struct testfilter, IEnumPins_iface);
1251}

Referenced by testenumpins_AddRef(), testenumpins_Next(), testenumpins_Release(), and testenumpins_Reset().

◆ impl_from_IFileSourceFilter()

static struct testfilter * impl_from_IFileSourceFilter ( IFileSourceFilter *  iface)
static

Definition at line 1976 of file filtergraph.c.

1977{
1978 return CONTAINING_RECORD(iface, struct testfilter, IFileSourceFilter_iface);
1979}

Referenced by testfilesource_AddRef(), testfilesource_QueryInterface(), and testfilesource_Release().

◆ impl_from_IMediaPosition()

static struct testfilter * impl_from_IMediaPosition ( IMediaPosition *  iface)
static

Definition at line 1781 of file filtergraph.c.

1782{
1783 return CONTAINING_RECORD(iface, struct testfilter, IMediaPosition_iface);
1784}

◆ impl_from_IMediaSeeking()

static struct testfilter * impl_from_IMediaSeeking ( IMediaSeeking *  iface)
static

Definition at line 1600 of file filtergraph.c.

1601{
1602 return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface);
1603}

◆ impl_from_IMemInputPin()

static struct testpin * impl_from_IMemInputPin ( IMemInputPin *  iface)
inlinestatic

Definition at line 962 of file filtergraph.c.

963{
964 return CONTAINING_RECORD(iface, struct testpin, IMemInputPin_iface);
965}

Referenced by meminput_AddRef(), meminput_QueryInterface(), meminput_Receive(), and meminput_Release().

◆ impl_from_IPin()

◆ impl_from_IReferenceClock()

static struct testfilter * impl_from_IReferenceClock ( IReferenceClock *  iface)
static

Definition at line 1916 of file filtergraph.c.

1917{
1918 return CONTAINING_RECORD(iface, struct testfilter, IReferenceClock_iface);
1919}

Referenced by testclock_AddRef(), testclock_QueryInterface(), and testclock_Release().

◆ load_resource()

static WCHAR * load_resource ( const WCHAR *  name)
static

Definition at line 55 of file filtergraph.c.

56{
57 HRSRC res;
58 void *ptr;
59
61 ok(!!res, "Failed to find resource %s, error %lu.\n", wine_dbgstr_w(name), GetLastError());
64}
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
GLuint res
Definition: glext.h:9613
static PVOID ptr
Definition: dispmode.c:27
#define create_file(name, size)
Definition: asmcache.c:811
#define RT_RCDATA
Definition: pedump.c:372

◆ meminput_AddRef()

static ULONG WINAPI meminput_AddRef ( IMemInputPin *  iface)
static

Definition at line 4287 of file filtergraph.c.

4288{
4289 struct testpin *pin = impl_from_IMemInputPin(iface);
4290 return InterlockedIncrement(&pin->ref);
4291}
#define InterlockedIncrement
Definition: armddk.h:53
static struct testpin * impl_from_IMemInputPin(IMemInputPin *iface)
Definition: filtergraph.c:962
LONG ref
Definition: filtergraph.c:821

◆ meminput_GetAllocator()

static HRESULT STDMETHODCALLTYPE meminput_GetAllocator ( IMemInputPin *  iface,
IMemAllocator **  allocator 
)
static

Definition at line 4299 of file filtergraph.c.

4300{
4301 return VFW_E_NO_ALLOCATOR;
4302}
#define VFW_E_NO_ALLOCATOR
Definition: vfwmsgs.h:49

◆ meminput_GetAllocatorRequirements()

static HRESULT STDMETHODCALLTYPE meminput_GetAllocatorRequirements ( IMemInputPin *  iface,
ALLOCATOR_PROPERTIES *  props 
)
static

Definition at line 4309 of file filtergraph.c.

4310{
4311 return E_NOTIMPL;
4312}
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ meminput_NotifyAllocator()

static HRESULT STDMETHODCALLTYPE meminput_NotifyAllocator ( IMemInputPin *  iface,
IMemAllocator *  allocator,
BOOL  readonly 
)
static

Definition at line 4304 of file filtergraph.c.

4305{
4306 return S_OK;
4307}

◆ meminput_QueryInterface()

static HRESULT WINAPI meminput_QueryInterface ( IMemInputPin *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 4278 of file filtergraph.c.

4279{
4280 struct testpin *pin = impl_from_IMemInputPin(iface);
4281 if (winetest_debug > 1) trace("%p->QueryInterface(%s)\n", pin, wine_dbgstr_guid(iid));
4282
4283 *out = NULL;
4284 return E_NOINTERFACE;
4285}
#define trace
Definition: atltest.h:70
int winetest_debug
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

◆ meminput_Receive()

static HRESULT STDMETHODCALLTYPE meminput_Receive ( IMemInputPin *  iface,
IMediaSample *  sample 
)
static

Definition at line 4314 of file filtergraph.c.

4315{
4316 struct testpin *pin = impl_from_IMemInputPin(iface);
4317 size_t new_bytes;
4318 HRESULT hr;
4319 BYTE *ptr;
4320 long len;
4321
4322 len = IMediaSample_GetActualDataLength(sample);
4323 hr = IMediaSample_GetPointer(sample, &ptr);
4324
4325 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4326 ok(len > 0, "Got %ld.\n", len);
4327
4328 new_bytes = min(sizeof(pin->input) - pin->input_size, len);
4329 if (new_bytes)
4330 {
4331 memcpy(pin->input + pin->input_size, ptr, new_bytes);
4332 pin->input_size += new_bytes;
4333 if (pin->input_size == sizeof(pin->input))
4334 SetEvent(pin->on_input_full);
4335 }
4336
4337 return S_OK;
4338}
GLenum GLsizei len
Definition: glext.h:6722
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define min(a, b)
Definition: monoChain.cc:55
Definition: wave.c:25
HANDLE on_input_full
Definition: filtergraph.c:843
ULONG input_size
Definition: filtergraph.c:842
BYTE input[64]
Definition: filtergraph.c:841
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
unsigned char BYTE
Definition: xxhash.c:193

◆ meminput_ReceiveCanBlock()

static HRESULT STDMETHODCALLTYPE meminput_ReceiveCanBlock ( IMemInputPin *  iface)
static

Definition at line 4346 of file filtergraph.c.

4346{ return S_OK; }

◆ meminput_ReceiveMultiple()

static HRESULT STDMETHODCALLTYPE meminput_ReceiveMultiple ( IMemInputPin *  iface,
IMediaSample **  samples,
LONG  n_samples,
LONG *  n_samples_processed 
)
static

Definition at line 4340 of file filtergraph.c.

4341{
4342 *n_samples_processed = 1;
4343 return IMemInputPin_Receive(iface, samples[0]);
4344}
GLsizei samples
Definition: glext.h:7006

◆ meminput_Release()

static ULONG WINAPI meminput_Release ( IMemInputPin *  iface)
static

Definition at line 4293 of file filtergraph.c.

4294{
4295 struct testpin *pin = impl_from_IMemInputPin(iface);
4296 return InterlockedDecrement(&pin->ref);
4297}
#define InterlockedDecrement
Definition: armddk.h:52

◆ mpegtestpin_EndOfStream()

static HRESULT WINAPI mpegtestpin_EndOfStream ( IPin *  iface)
static

Definition at line 4246 of file filtergraph.c.

4247{
4248 return S_OK;
4249}

◆ mpegtestpin_NewSegment()

static HRESULT WINAPI mpegtestpin_NewSegment ( IPin *  iface,
REFERENCE_TIME  start,
REFERENCE_TIME  stop,
double  rate 
)
static

Definition at line 4251 of file filtergraph.c.

4252{
4253 return S_OK;
4254}

◆ mpegtestsink_ReceiveConnection()

static HRESULT WINAPI mpegtestsink_ReceiveConnection ( IPin *  iface,
IPin *  peer,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 4229 of file filtergraph.c.

4230{
4231 struct testpin *pin = impl_from_IPin(iface);
4232 if (winetest_debug > 1) trace("%p->ReceiveConnection(%p)\n", pin, peer);
4233
4234 if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Video))
4236 if (!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MPEG1Payload))
4238 if (!IsEqualGUID(&mt->formattype, &FORMAT_MPEGVideo))
4240
4241 pin->peer = peer;
4242 IPin_AddRef(peer);
4243 return S_OK;
4244}
static struct testpin * impl_from_IPin(IPin *iface)
Definition: filtergraph.c:957
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
IPin * peer
Definition: filtergraph.c:824
AM_MEDIA_TYPE * mt
Definition: filtergraph.c:825
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81

◆ no_Connect()

static HRESULT WINAPI no_Connect ( IPin *  iface,
IPin *  peer,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 1121 of file filtergraph.c.

1122{
1123 ok(0, "Unexpected call.\n");
1124 return E_NOTIMPL;
1125}

◆ no_EnumMediaTypes()

static HRESULT WINAPI no_EnumMediaTypes ( IPin *  iface,
IEnumMediaTypes **  out 
)
static

Definition at line 1133 of file filtergraph.c.

1134{
1135 ok(0, "Unexpected call.\n");
1136 return E_NOTIMPL;
1137}

◆ no_ReceiveConnection()

static HRESULT WINAPI no_ReceiveConnection ( IPin *  iface,
IPin *  peer,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 1127 of file filtergraph.c.

1128{
1129 ok(0, "Unexpected call.\n");
1130 return E_NOTIMPL;
1131}

◆ outer_AddRef()

static ULONG WINAPI outer_AddRef ( IUnknown *  iface)
static

Definition at line 2746 of file filtergraph.c.

2747{
2749}
static LONG outer_ref
Definition: filtergraph.c:2731

◆ outer_QueryInterface()

static HRESULT WINAPI outer_QueryInterface ( IUnknown *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 2733 of file filtergraph.c.

2734{
2735 if (IsEqualGUID(iid, &IID_IUnknown)
2736 || IsEqualGUID(iid, &IID_IFilterGraph2)
2737 || IsEqualGUID(iid, &test_iid))
2738 {
2739 *out = (IUnknown *)0xdeadbeef;
2740 return S_OK;
2741 }
2742 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
2743 return E_NOINTERFACE;
2744}
const GUID IID_IUnknown
static const GUID test_iid
Definition: filtergraph.c:2730

◆ outer_Release()

static ULONG WINAPI outer_Release ( IUnknown *  iface)
static

Definition at line 2751 of file filtergraph.c.

2752{
2754}

◆ parent_proc()

static LRESULT CALLBACK parent_proc ( HWND  hwnd,
UINT  msg,
WPARAM  wparam,
LPARAM  lparam 
)
static

Definition at line 5434 of file filtergraph.c.

5435{
5436 ok(expect_parent_message, "Got unexpected message %#x.\n", msg);
5437 return DefWindowProcA(hwnd, msg, wparam, lparam);
5438}
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
#define msg(x)
Definition: auth_time.c:54
static BOOL expect_parent_message
Definition: filtergraph.c:5432
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Referenced by test_window_threading().

◆ rungraph()

static void rungraph ( IFilterGraph2 *  graph,
BOOL  video 
)
static

Definition at line 546 of file filtergraph.c.

547{
548 if (video)
553}
static void test_media_event(IFilterGraph2 *graph)
Definition: filtergraph.c:459
static void test_state_change(IFilterGraph2 *graph)
Definition: filtergraph.c:406
static void test_media_seeking(IFilterGraph2 *graph)
Definition: filtergraph.c:338
static void test_basic_video(void)

Referenced by call_RenderFile_multithread(), test_graph_builder_connect_file(), and test_render_run().

◆ START_TEST()

START_TEST ( filtergraph  )

Definition at line 5957 of file filtergraph.c.

5958{
5960
5962 test_render_run(L"test.avi", FALSE, TRUE);
5963 test_render_run(L"test.mpg", TRUE, TRUE);
5964 test_render_run(L"test.mp3", TRUE, FALSE);
5965 test_render_run(L"test.wav", TRUE, FALSE);
5984 test_events();
5986
5989}
#define FALSE
Definition: types.h:117
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(void *reserved, DWORD model)
Definition: combase.c:2803
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
static void test_graph_builder_render(void)
Definition: filtergraph.c:2090
static void test_add_source_filter(void)
Definition: filtergraph.c:5248
static void test_set_notify_flags(void)
Definition: filtergraph.c:5582
static void test_aggregation(void)
Definition: filtergraph.c:2765
static void test_add_remove_filter(void)
Definition: filtergraph.c:2991
static void test_renderfile_compressed(void)
Definition: filtergraph.c:4362
static void test_renderfile_failure(void)
Definition: filtergraph.c:4405
static void test_graph_builder_connect(void)
Definition: filtergraph.c:2337
static void test_default_sync_source(void)
Definition: filtergraph.c:5174
static void test_interfaces(void)
Definition: filtergraph.c:97
static void test_sync_source(void)
Definition: filtergraph.c:3349
static void test_autoplug_uyvy(void)
Definition: filtergraph.c:5539
static void test_ec_complete(void)
Definition: filtergraph.c:4030
static void test_event_dispatch(void)
Definition: filtergraph.c:5923
static void test_events(void)
Definition: filtergraph.c:5760
static void test_control_delegation(void)
Definition: filtergraph.c:2851
static void test_window_threading(void)
Definition: filtergraph.c:5440
static void test_connect_direct(void)
Definition: filtergraph.c:3084
static void test_render_with_multithread(void)
Definition: filtergraph.c:800
static void test_enum_filters(void)
Definition: filtergraph.c:658
static void test_render_run(const WCHAR *file, BOOL audio, BOOL video)
Definition: filtergraph.c:601
static void test_filter_state(void)
Definition: filtergraph.c:3441
static void test_graph_seeking(void)
Definition: filtergraph.c:4459
@ COINIT_MULTITHREADED
Definition: objbase.h:280

◆ test_add_remove_filter()

static void test_add_remove_filter ( void  )
static

Definition at line 2991 of file filtergraph.c.

2992{
2993 struct testfilter filter;
2994
2996 IBaseFilter *ret_filter;
2997 HRESULT hr;
2998 LONG ref;
2999
3001
3002 hr = IFilterGraph2_FindFilterByName(graph, L"testid", &ret_filter);
3003 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
3004 ok(!ret_filter, "Got filter %p.\n", ret_filter);
3005
3006 hr = IFilterGraph2_AddFilter(graph, &filter.IBaseFilter_iface, L"testid");
3007 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3008 ok(filter.graph == (IFilterGraph *)graph, "Got graph %p.\n", filter.graph);
3009 ok(!wcscmp(filter.name, L"testid"), "Got name %s.\n", wine_dbgstr_w(filter.name));
3010
3011 hr = IFilterGraph2_FindFilterByName(graph, L"testid", &ret_filter);
3012 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3013 ok(ret_filter == &filter.IBaseFilter_iface, "Got filter %p.\n", ret_filter);
3014 IBaseFilter_Release(ret_filter);
3015
3016 hr = IFilterGraph2_RemoveFilter(graph, &filter.IBaseFilter_iface);
3017 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3018 ok(!filter.graph, "Got graph %p.\n", filter.graph);
3019 ok(!filter.name, "Got name %s.\n", wine_dbgstr_w(filter.name));
3020 ok(!filter.clock, "Got clock %p,\n", filter.clock);
3021 ok(filter.ref == 1, "Got outstanding refcount %ld.\n", filter.ref);
3022
3023 hr = IFilterGraph2_FindFilterByName(graph, L"testid", &ret_filter);
3024 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
3025 ok(!ret_filter, "Got filter %p.\n", ret_filter);
3026
3027 hr = IFilterGraph2_AddFilter(graph, &filter.IBaseFilter_iface, NULL);
3028 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3029 ok(filter.graph == (IFilterGraph *)graph, "Got graph %p.\n", filter.graph);
3030 ok(!wcscmp(filter.name, L"0001"), "Got name %s.\n", wine_dbgstr_w(filter.name));
3031
3032 hr = IFilterGraph2_FindFilterByName(graph, L"0001", &ret_filter);
3033 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3034 ok(ret_filter == &filter.IBaseFilter_iface, "Got filter %p.\n", ret_filter);
3035 IBaseFilter_Release(ret_filter);
3036
3037 /* test releasing the filter graph while filters are still connected */
3038 ref = IFilterGraph2_Release(graph);
3039 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3040 ok(!filter.graph, "Got graph %p.\n", filter.graph);
3041 ok(!filter.name, "Got name %s.\n", wine_dbgstr_w(filter.name));
3042 ok(!filter.clock, "Got clock %p.\n", filter.clock);
3043 ok(filter.ref == 1, "Got outstanding refcount %ld.\n", filter.ref);
3044}
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
static void testfilter_init(struct testfilter *filter, struct testpin *pins, int pin_count)
Definition: filtergraph.c:2028
static IFilterGraph2 * create_graph(void)
Definition: filtergraph.c:66
IReferenceClock * clock
Definition: filter.c:171
IFilterGraph * graph
Definition: filter.c:173
WCHAR name[128]
Definition: filter.c:172
Definition: send.c:48
#define VFW_E_NOT_FOUND
Definition: vfwmsgs.h:61

Referenced by START_TEST().

◆ test_add_source_filter()

static void test_add_source_filter ( void  )
static

Definition at line 5248 of file filtergraph.c.

5249{
5250 static const char bogus_data[20] = {0xde, 0xad, 0xbe, 0xef};
5251 static const char midi_data[20] = {'M','T','h','d'};
5252
5254 IFileSourceFilter *filesource;
5255 IBaseFilter *filter, *filter2;
5256 FILTER_INFO filter_info;
5257 const WCHAR *filename;
5258 WCHAR *ret_filename;
5259 AM_MEDIA_TYPE mt;
5260 CLSID clsid;
5261 HRESULT hr;
5262 ULONG ref;
5263 BOOL ret;
5264 HKEY key;
5265
5266 /* Test a file which should be registered by extension. */
5267
5268 filename = create_file(L"test.mp3", midi_data, sizeof(midi_data));
5269 hr = IFilterGraph2_AddSourceFilter(graph, filename, L"test", &filter);
5270 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5271
5272 hr = IBaseFilter_GetClassID(filter, &clsid);
5273 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5274 ok(IsEqualGUID(&clsid, &CLSID_AsyncReader), "Got filter %s.\n", wine_dbgstr_guid(&clsid));
5275 hr = IBaseFilter_QueryFilterInfo(filter, &filter_info);
5276 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5277 ok(!wcscmp(filter_info.achName, L"test"), "Got unexpected name %s.\n", wine_dbgstr_w(filter_info.achName));
5278 IFilterGraph_Release(filter_info.pGraph);
5279
5280 hr = IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&filesource);
5281 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5282 hr = IFileSourceFilter_GetCurFile(filesource, &ret_filename, &mt);
5283 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5284 ok(!wcscmp(ret_filename, filename), "Expected filename %s, got %s.\n",
5285 wine_dbgstr_w(filename), wine_dbgstr_w(ret_filename));
5286 ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Stream), "Got major type %s.\n", wine_dbgstr_guid(&mt.majortype));
5287 ok(IsEqualGUID(&mt.subtype, &MEDIASUBTYPE_MPEG1Audio), "Got subtype %s.\n", wine_dbgstr_guid(&mt.subtype));
5288 IFileSourceFilter_Release(filesource);
5289 CoTaskMemFree(ret_filename);
5290 FreeMediaType(&mt);
5291
5292 hr = IFilterGraph2_AddSourceFilter(graph, filename, L"test", &filter2);
5293 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5294 ok(filter2 != filter, "Filters shouldn't match.\n");
5295 hr = IFilterGraph2_RemoveFilter(graph, filter2);
5296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5297 ref = IBaseFilter_Release(filter2);
5298 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5299
5300 hr = IFilterGraph2_RemoveFilter(graph, filter);
5301 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5302 ref = IBaseFilter_Release(filter);
5303 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5305 ok(ret, "Failed to delete %s, error %lu.\n", wine_dbgstr_w(filename), GetLastError());
5306
5307 /* Test a file which should be registered by signature. */
5308
5309 filename = create_file(L"test.avi", midi_data, sizeof(midi_data));
5310 hr = IFilterGraph2_AddSourceFilter(graph, filename, NULL, &filter);
5311 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5312
5313 hr = IBaseFilter_GetClassID(filter, &clsid);
5314 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5315 ok(IsEqualGUID(&clsid, &CLSID_AsyncReader), "Got filter %s.\n", wine_dbgstr_guid(&clsid));
5316 hr = IBaseFilter_QueryFilterInfo(filter, &filter_info);
5317 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5318 todo_wine ok(!wcscmp(filter_info.achName, filename), "Got unexpected name %s.\n", wine_dbgstr_w(filter_info.achName));
5319 IFilterGraph_Release(filter_info.pGraph);
5320
5321 hr = IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&filesource);
5322 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5323 hr = IFileSourceFilter_GetCurFile(filesource, &ret_filename, &mt);
5324 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5325 ok(!wcscmp(ret_filename, filename), "Expected filename %s, got %s.\n",
5326 wine_dbgstr_w(filename), wine_dbgstr_w(ret_filename));
5327 ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Stream), "Got major type %s.\n", wine_dbgstr_guid(&mt.majortype));
5328 ok(IsEqualGUID(&mt.subtype, &MEDIATYPE_Midi), "Got subtype %s.\n", wine_dbgstr_guid(&mt.subtype));
5329 IFileSourceFilter_Release(filesource);
5330 CoTaskMemFree(ret_filename);
5331 FreeMediaType(&mt);
5332
5333 hr = IFilterGraph2_RemoveFilter(graph, filter);
5334 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5335 ref = IBaseFilter_Release(filter);
5336 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5338 ok(ret, "Failed to delete %s, error %lu.\n", wine_dbgstr_w(filename), GetLastError());
5339
5340 if (!RegCreateKeyA(HKEY_CLASSES_ROOT, "Media Type\\{abbccdde-0000-0000-0000-000000000000}"
5341 "\\{bccddeef-0000-0000-0000-000000000000}", &key))
5342 {
5343 static const GUID testfilter_clsid = {0x12345678};
5344 struct testpin testfilter_pin;
5345 struct testfilter testfilter;
5347 DWORD cookie;
5348
5349 testsource_init(&testfilter_pin, NULL, 0);
5350 testfilter_init(&testfilter, &testfilter_pin, 1);
5352
5354 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie);
5355 RegSetValueExA(key, "0", 0, REG_SZ, (const BYTE *)"0,4,,deadbeef", 14);
5356 RegSetValueExA(key, "Source Filter", 0, REG_SZ, (const BYTE *)"{12345678-0000-0000-0000-000000000000}", 39);
5357
5358 filename = create_file(L"test.avi", bogus_data, sizeof(bogus_data));
5359 hr = IFilterGraph2_AddSourceFilter(graph, filename, NULL, &filter);
5360 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5361 ok(filter == &testfilter.IBaseFilter_iface, "Got unexpected filter %p.\n", filter);
5362
5363 hr = IFilterGraph2_RemoveFilter(graph, filter);
5364 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5365 IBaseFilter_Release(filter);
5366 ref = IBaseFilter_Release(&testfilter.IBaseFilter_iface);
5367 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5369 ok(ret, "Failed to delete %s, error %lu.\n", wine_dbgstr_w(filename), GetLastError());
5370 RegDeleteKeyA(HKEY_CLASSES_ROOT, "Media Type\\{abbccdde-0000-0000-0000-000000000000}"
5371 "\\{bccddeef-0000-0000-0000-000000000000}");
5372 RegDeleteKeyA(HKEY_CLASSES_ROOT, "Media Type\\{abbccdde-0000-0000-0000-000000000000}");
5374 }
5375 else
5376 skip("Not enough permission to register media types.\n");
5377
5378 /* Test some failure cases. */
5379
5380 filter = (IBaseFilter *)0xdeadbeef;
5381 hr = IFilterGraph2_AddSourceFilter(graph, L"", NULL, &filter);
5382 /* the BURIKO visual novel engine requires this exact error code */
5383 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
5384 ok(filter == (IBaseFilter *)0xdeadbeef, "Got %p.\n", filter);
5385
5386 filter = (IBaseFilter *)0xdeadbeef;
5387 hr = IFilterGraph2_AddSourceFilter(graph, L"doesnt_exist.mp3", NULL, &filter);
5388 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got hr %#lx.\n", hr);
5389 ok(filter == (IBaseFilter *)0xdeadbeef, "Got %p.\n", filter);
5390
5391 ref = IFilterGraph2_Release(graph);
5392 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5393}
#define REG_SZ
Definition: layer.c:22
#define skip(...)
Definition: atltest.h:64
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1179
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject(DWORD cookie)
Definition: combase.c:3107
HRESULT WINAPI CoRegisterClassObject(REFCLSID rclsid, IUnknown *object, DWORD clscontext, DWORD flags, DWORD *cookie)
Definition: combase.c:2970
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
unsigned int BOOL
Definition: ntddk_ex.h:94
#define todo_wine
Definition: minitest.h:80
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static IClassFactoryVtbl testfilter_cf_vtbl
Definition: filtergraph.c:2081
static void testsource_init(struct testpin *pin, const AM_MEDIA_TYPE *types, int type_count)
Definition: filtergraph.c:1241
static const IFileSourceFilterVtbl testfilesource_vtbl
Definition: filtergraph.c:2013
const CLSID * clsid
Definition: msctf.cpp:50
@ REGCLS_MULTIPLEUSE
Definition: objbase.h:398
void WINAPI FreeMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: mediatype.c:165
IClassFactory IClassFactory_iface
Definition: inetcomm_main.c:69
Definition: cookie.c:34
Definition: copy.c:22
IBaseFilter IBaseFilter_iface
Definition: filtergraph.c:848
IFileSourceFilter IFileSourceFilter_iface
Definition: filtergraph.c:877
uint32_t ULONG
Definition: typedefs.h:59
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10

Referenced by START_TEST().

◆ test_aggregation()

static void test_aggregation ( void  )
static

Definition at line 2765 of file filtergraph.c.

2766{
2767 IFilterGraph2 *graph, *graph2;
2768 IFilterMapper2 *mapper;
2769 IUnknown *unk, *unk2;
2770 HRESULT hr;
2771 ULONG ref;
2772
2773 graph = (IFilterGraph2 *)0xdeadbeef;
2774 hr = CoCreateInstance(&CLSID_FilterGraph, &test_outer, CLSCTX_INPROC_SERVER,
2775 &IID_IFilterGraph2, (void **)&graph);
2776 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
2777 ok(!graph, "Got interface %p.\n", graph);
2778
2779 hr = CoCreateInstance(&CLSID_FilterGraph, &test_outer, CLSCTX_INPROC_SERVER,
2780 &IID_IUnknown, (void **)&unk);
2781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2782 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
2783 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
2784 ref = get_refcount(unk);
2785 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
2786
2787 ref = IUnknown_AddRef(unk);
2788 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
2789 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
2790
2791 ref = IUnknown_Release(unk);
2792 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
2793 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
2794
2795 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
2796 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2797 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
2798 IUnknown_Release(unk2);
2799
2800 hr = IUnknown_QueryInterface(unk, &IID_IFilterGraph2, (void **)&graph);
2801 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2802
2803 hr = IFilterGraph2_QueryInterface(graph, &IID_IUnknown, (void **)&unk2);
2804 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2805 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
2806
2807 hr = IFilterGraph2_QueryInterface(graph, &IID_IFilterGraph2, (void **)&graph2);
2808 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2809 ok(graph2 == (IFilterGraph2 *)0xdeadbeef, "Got unexpected IFilterGraph2 %p.\n", graph2);
2810
2811 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
2812 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
2813 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
2814
2815 hr = IFilterGraph2_QueryInterface(graph, &test_iid, (void **)&unk2);
2816 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2817 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
2818
2819 IFilterGraph2_Release(graph);
2820 ref = IUnknown_Release(unk);
2821 ok(!ref, "Got unexpected refcount %ld.\n", ref);
2822 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
2823
2824 /* Test the aggregated filter mapper. */
2825
2826 graph = create_graph();
2827
2829 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
2830
2831 hr = IFilterGraph2_QueryInterface(graph, &IID_IFilterMapper2, (void **)&mapper);
2832 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2833
2835 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
2836 ref = get_refcount(mapper);
2837 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
2838
2839 hr = IFilterMapper2_QueryInterface(mapper, &IID_IFilterGraph2, (void **)&graph2);
2840 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2841 ok(graph2 == graph, "Got unexpected IFilterGraph2 %p.\n", graph2);
2842 IFilterGraph2_Release(graph2);
2843
2844 IFilterMapper2_Release(mapper);
2845 ref = IFilterGraph2_Release(graph);
2846 ok(!ref, "Got unexpected refcount %ld.\n", ref);
2847}
static ULONG get_refcount(void *iface)
Definition: filtergraph.c:75
static IUnknown test_outer
Definition: filtergraph.c:2763

Referenced by START_TEST().

◆ test_autoplug_uyvy()

static void test_autoplug_uyvy ( void  )
static

Definition at line 5539 of file filtergraph.c.

5540{
5541 static const VIDEOINFOHEADER source_format =
5542 {
5544 .bmiHeader.biWidth = 600,
5545 .bmiHeader.biHeight = 400,
5546 .bmiHeader.biCompression = mmioFOURCC('U','Y','V','Y'),
5547 .bmiHeader.biBitCount = 16,
5548 };
5549 AM_MEDIA_TYPE source_type =
5550 {
5551 .majortype = MEDIATYPE_Video,
5552 .subtype = MEDIASUBTYPE_UYVY,
5553 .formattype = FORMAT_VideoInfo,
5554 .cbFormat = sizeof(source_format),
5555 .pbFormat = (BYTE *)&source_format,
5556 };
5557
5559 struct testpin source_pin;
5560 struct testfilter source;
5561 HRESULT hr;
5562 ULONG ref;
5563
5564 testsource_init(&source_pin, NULL, 0);
5565 testfilter_init(&source, &source_pin, 1);
5566 source_pin.request_mt = &source_type;
5567
5568 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, L"source");
5569
5570 /* Windows 2008 doesn't seem to have an UYVY decoder, and the testbot chalks
5571 * failure to decode up to missing audio hardware, even though we're not
5572 * trying to render audio. */
5573 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
5574 ok(hr == S_OK || hr == VFW_E_NO_AUDIO_HARDWARE, "Got hr %#lx.\n", hr);
5575
5576 ref = IFilterGraph2_Release(graph);
5577 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5578 ok(source.ref == 1, "Got outstanding refcount %ld.\n", source.ref);
5579 ok(source_pin.ref == 1, "Got outstanding refcount %ld.\n", source_pin.ref);
5580}
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
BITMAPINFOHEADER bmiHeader
Definition: amvideo.idl:189
#define VFW_E_NO_AUDIO_HARDWARE
Definition: vfwmsgs.h:109

Referenced by START_TEST().

◆ test_basic_video()

static void test_basic_video ( IFilterGraph2 *  graph)
static

Definition at line 130 of file filtergraph.c.

131{
132 IBasicVideo* pbv;
133 LONG video_width, video_height, window_width;
135 HRESULT hr;
136
137 hr = IFilterGraph2_QueryInterface(graph, &IID_IBasicVideo, (void **)&pbv);
138 ok(hr == S_OK, "Got hr %#lx.\n", hr);
139
140 /* test get video size */
141 hr = IBasicVideo_GetVideoSize(pbv, NULL, NULL);
142 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
143 hr = IBasicVideo_GetVideoSize(pbv, &video_width, NULL);
144 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
145 hr = IBasicVideo_GetVideoSize(pbv, NULL, &video_height);
146 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
147 hr = IBasicVideo_GetVideoSize(pbv, &video_width, &video_height);
148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
149
150 /* test source position */
151 hr = IBasicVideo_GetSourcePosition(pbv, NULL, NULL, NULL, NULL);
152 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
153 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, NULL, NULL);
154 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
155 hr = IBasicVideo_GetSourcePosition(pbv, NULL, NULL, &width, &height);
156 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
157 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
158 ok(hr == S_OK, "Got hr %#lx.\n", hr);
159 ok(left == 0, "Got left %ld.\n", left);
160 ok(top == 0, "Got top %ld.\n", top);
161 ok(width == video_width, "Expected width %ld, got %ld.\n", video_width, width);
162 ok(height == video_height, "Expected height %ld, got %ld.\n", video_height, height);
163
164 hr = IBasicVideo_SetSourcePosition(pbv, 0, 0, 0, 0);
165 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
166 hr = IBasicVideo_SetSourcePosition(pbv, 0, 0, video_width*2, video_height*2);
167 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
168 hr = IBasicVideo_put_SourceTop(pbv, -1);
169 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
170 hr = IBasicVideo_put_SourceTop(pbv, 0);
171 ok(hr == S_OK, "Got hr %#lx.\n", hr);
172 hr = IBasicVideo_put_SourceTop(pbv, 1);
173 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
174
175 hr = IBasicVideo_SetSourcePosition(pbv, video_width, 0, video_width, video_height);
176 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
177 hr = IBasicVideo_SetSourcePosition(pbv, 0, video_height, video_width, video_height);
178 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
179 hr = IBasicVideo_SetSourcePosition(pbv, -1, 0, video_width, video_height);
180 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
181 hr = IBasicVideo_SetSourcePosition(pbv, 0, -1, video_width, video_height);
182 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
183 hr = IBasicVideo_SetSourcePosition(pbv, video_width/2, video_height/2, video_width, video_height);
184 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
185 hr = IBasicVideo_SetSourcePosition(pbv, video_width/2, video_height/2, video_width, video_height);
186 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
187
188 hr = IBasicVideo_SetSourcePosition(pbv, 0, 0, video_width, video_height+1);
189 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
190 hr = IBasicVideo_SetSourcePosition(pbv, 0, 0, video_width+1, video_height);
191 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
192
193 hr = IBasicVideo_SetSourcePosition(pbv, video_width/2, video_height/2, video_width/3+1, video_height/3+1);
194 ok(hr == S_OK, "Got hr %#lx.\n", hr);
195
196 hr = IBasicVideo_get_SourceLeft(pbv, &left);
197 ok(hr == S_OK, "Got hr %#lx.\n", hr);
198 ok(left == video_width / 2, "Expected left %ld, got %ld.\n", video_width / 2, left);
199 hr = IBasicVideo_get_SourceTop(pbv, &top);
200 ok(hr == S_OK, "Got hr %#lx.\n", hr);
201 ok(top == video_height / 2, "Expected top %ld, got %ld.\n", video_height / 2, top);
202 hr = IBasicVideo_get_SourceWidth(pbv, &width);
203 ok(hr == S_OK, "Got hr %#lx.\n", hr);
204 ok(width == video_width / 3 + 1, "Expected width %ld, got %ld.\n", video_width / 3 + 1, width);
205 hr = IBasicVideo_get_SourceHeight(pbv, &height);
206 ok(hr == S_OK, "Got hr %#lx.\n", hr);
207 ok(height == video_height / 3 + 1, "Expected height %ld, got %ld.\n", video_height / 3 + 1, height);
208
209 hr = IBasicVideo_put_SourceLeft(pbv, video_width/3);
210 ok(hr == S_OK, "Got hr %#lx.\n", hr);
211 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
212 ok(hr == S_OK, "Got hr %#lx.\n", hr);
213 ok(left == video_width / 3, "Expected left %ld, got %ld.\n", video_width / 3, left);
214 ok(width == video_width / 3 + 1, "Expected width %ld, got %ld.\n", video_width / 3 + 1, width);
215
216 hr = IBasicVideo_put_SourceTop(pbv, video_height/3);
217 ok(hr == S_OK, "Got hr %#lx.\n", hr);
218 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
219 ok(hr == S_OK, "Got hr %#lx.\n", hr);
220 ok(top == video_height / 3, "Expected top %ld, got %ld.\n", video_height / 3, top);
221 ok(height == video_height / 3 + 1, "Expected height %ld, got %ld.\n", video_height / 3 + 1, height);
222
223 hr = IBasicVideo_put_SourceWidth(pbv, video_width/4+1);
224 ok(hr == S_OK, "Got hr %#lx.\n", hr);
225 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
226 ok(hr == S_OK, "Got hr %#lx.\n", hr);
227 ok(left == video_width / 3, "Expected left %ld, got %ld.\n", video_width / 3, left);
228 ok(width == video_width / 4 + 1, "Expected width %ld, got %ld.\n", video_width / 4 + 1, width);
229
230 hr = IBasicVideo_put_SourceHeight(pbv, video_height/4+1);
231 ok(hr == S_OK, "Got hr %#lx.\n", hr);
232 hr = IBasicVideo_GetSourcePosition(pbv, &left, &top, &width, &height);
233 ok(hr == S_OK, "Got hr %#lx.\n", hr);
234 ok(top == video_height / 3, "Expected top %ld, got %ld.\n", video_height / 3, top);
235 ok(height == video_height / 4 + 1, "Expected height %ld, got %ld.\n", video_height / 4 + 1, height);
236
237 /* test destination rectangle */
238 window_width = max(video_width, GetSystemMetrics(SM_CXMIN) - 2 * GetSystemMetrics(SM_CXFRAME));
239
240 hr = IBasicVideo_GetDestinationPosition(pbv, NULL, NULL, NULL, NULL);
241 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
242 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, NULL, NULL);
243 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
244 hr = IBasicVideo_GetDestinationPosition(pbv, NULL, NULL, &width, &height);
245 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
246 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
247 ok(hr == S_OK, "Got hr %#lx.\n", hr);
248 ok(left == 0, "Got left %ld.\n", left);
249 ok(top == 0, "Got top %ld.\n", top);
250 ok(width == window_width, "Expected width %ld, got %ld.\n", window_width, width);
251 ok(height == video_height, "Expected height %ld, got %ld.\n", video_height, height);
252
253 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, 0, 0);
254 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
255 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, video_width*2, video_height*2);
256 ok(hr == S_OK, "Got hr %#lx.\n", hr);
257
258 hr = IBasicVideo_put_DestinationLeft(pbv, -1);
259 ok(hr == S_OK, "Got hr %#lx.\n", hr);
260 hr = IBasicVideo_put_DestinationLeft(pbv, 0);
261 ok(hr == S_OK, "Got hr %#lx.\n", hr);
262 hr = IBasicVideo_put_DestinationLeft(pbv, 1);
263 ok(hr == S_OK, "Got hr %#lx.\n", hr);
264
265 hr = IBasicVideo_SetDestinationPosition(pbv, video_width, 0, video_width, video_height);
266 ok(hr == S_OK, "Got hr %#lx.\n", hr);
267 hr = IBasicVideo_SetDestinationPosition(pbv, 0, video_height, video_width, video_height);
268 ok(hr == S_OK, "Got hr %#lx.\n", hr);
269 hr = IBasicVideo_SetDestinationPosition(pbv, -1, 0, video_width, video_height);
270 ok(hr == S_OK, "Got hr %#lx.\n", hr);
271 hr = IBasicVideo_SetDestinationPosition(pbv, 0, -1, video_width, video_height);
272 ok(hr == S_OK, "Got hr %#lx.\n", hr);
273 hr = IBasicVideo_SetDestinationPosition(pbv, video_width/2, video_height/2, video_width, video_height);
274 ok(hr == S_OK, "Got hr %#lx.\n", hr);
275 hr = IBasicVideo_SetDestinationPosition(pbv, video_width/2, video_height/2, video_width, video_height);
276 ok(hr == S_OK, "Got hr %#lx.\n", hr);
277
278 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, video_width, video_height+1);
279 ok(hr == S_OK, "Got hr %#lx.\n", hr);
280 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, video_width+1, video_height);
281 ok(hr == S_OK, "Got hr %#lx.\n", hr);
282
283 hr = IBasicVideo_SetDestinationPosition(pbv, video_width/2, video_height/2, video_width/3+1, video_height/3+1);
284 ok(hr == S_OK, "Got hr %#lx.\n", hr);
285
286 hr = IBasicVideo_get_DestinationLeft(pbv, &left);
287 ok(hr == S_OK, "Got hr %#lx.\n", hr);
288 ok(left == video_width / 2, "Expected left %ld, got %ld.\n", video_width / 2, left);
289 hr = IBasicVideo_get_DestinationTop(pbv, &top);
290 ok(hr == S_OK, "Got hr %#lx.\n", hr);
291 ok(top == video_height / 2, "Expected top %ld, got %ld.\n", video_height / 2, top);
292 hr = IBasicVideo_get_DestinationWidth(pbv, &width);
293 ok(hr == S_OK, "Got hr %#lx.\n", hr);
294 ok(width == video_width / 3 + 1, "Expected width %ld, got %ld.\n", video_width / 3 + 1, width);
295 hr = IBasicVideo_get_DestinationHeight(pbv, &height);
296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
297 ok(height == video_height / 3 + 1, "Expected height %ld, got %ld.\n", video_height / 3 + 1, height);
298
299 hr = IBasicVideo_put_DestinationLeft(pbv, video_width/3);
300 ok(hr == S_OK, "Got hr %#lx.\n", hr);
301 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
302 ok(hr == S_OK, "Got hr %#lx.\n", hr);
303 ok(left == video_width / 3, "Expected left %ld, got %ld.\n", video_width / 3, left);
304 ok(width == video_width / 3 + 1, "Expected width %ld, got %ld.\n", video_width / 3 + 1, width);
305
306 hr = IBasicVideo_put_DestinationTop(pbv, video_height/3);
307 ok(hr == S_OK, "Got hr %#lx.\n", hr);
308 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
309 ok(hr == S_OK, "Got hr %#lx.\n", hr);
310 ok(top == video_height / 3, "Expected top %ld, got %ld.\n", video_height / 3, top);
311 ok(height == video_height / 3 + 1, "Expected height %ld, got %ld.\n", video_height / 3 + 1, height);
312
313 hr = IBasicVideo_put_DestinationWidth(pbv, video_width/4+1);
314 ok(hr == S_OK, "Got hr %#lx.\n", hr);
315 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
316 ok(hr == S_OK, "Got hr %#lx.\n", hr);
317 ok(left == video_width / 3, "Expected left %ld, got %ld.\n", video_width / 3, left);
318 ok(width == video_width / 4 + 1, "Expected width %ld, got %ld.\n", video_width / 4 + 1, width);
319
320 hr = IBasicVideo_put_DestinationHeight(pbv, video_height/4+1);
321 ok(hr == S_OK, "Got hr %#lx.\n", hr);
322 hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, &width, &height);
323 ok(hr == S_OK, "Got hr %#lx.\n", hr);
324 ok(top == video_height / 3, "Expected top %ld, got %ld.\n", video_height / 3, top);
325 ok(height == video_height / 4 + 1, "Expected height %ld, got %ld.\n", video_height / 4 + 1, height);
326
327 /* reset source rectangle */
328 hr = IBasicVideo_SetDefaultSourcePosition(pbv);
329 ok(hr == S_OK, "Got hr %#lx.\n", hr);
330
331 /* reset destination position */
332 hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, video_width, video_height);
333 ok(hr == S_OK, "Got hr %#lx.\n", hr);
334
335 IBasicVideo_Release(pbv);
336}
#define E_INVALIDARG
Definition: ddrawi.h:101
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
#define SM_CXFRAME
Definition: winuser.h:1005
#define SM_CXMIN
Definition: winuser.h:1000
int WINAPI GetSystemMetrics(_In_ int)
#define max(a, b)
Definition: svc.c:63
#define E_POINTER
Definition: winerror.h:3480

◆ test_connect_direct()

static void test_connect_direct ( void  )
static

Definition at line 3084 of file filtergraph.c.

3085{
3086 struct testpin source_pin, sink_pin, parser1_pins[2], parser2_pins[2];
3087 struct testfilter source, sink, parser1, parser2;
3088
3090 IMediaControl *control;
3092 HRESULT hr;
3093 ULONG ref;
3094
3096 testfilter_init(&source, &source_pin, 1);
3098 testfilter_init(&sink, &sink_pin, 1);
3099 test_connect_direct_init(&parser1_pins[0], PINDIR_INPUT);
3100 test_connect_direct_init(&parser1_pins[1], PINDIR_OUTPUT);
3101 testfilter_init(&parser1, parser1_pins, 2);
3102 test_connect_direct_init(&parser2_pins[0], PINDIR_INPUT);
3103 test_connect_direct_init(&parser2_pins[1], PINDIR_OUTPUT);
3104 testfilter_init(&parser2, parser2_pins, 2);
3105
3106 hr = IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
3107 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3108
3109 hr = IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
3110 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3111
3112 /* The filter graph does not prevent connection while it is running; only
3113 * individual filters do. */
3114 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3115 hr = IMediaControl_Pause(control);
3116 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3117
3118 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, NULL);
3119 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3120 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3121 ok(!source_pin.mt, "Got mt %p.\n", source_pin.mt);
3122 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3123
3124 hr = IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
3125 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3126 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3127 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3128
3129 hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
3130 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3131 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3132 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3133
3134 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
3135 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3136 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3137 ok(!source_pin.mt, "Got mt %p.\n", source_pin.mt);
3138 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3139
3140 hr = IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
3141 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3142 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3143 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3144
3145 hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
3146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3147 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3148 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3149
3150 /* Swap the pins when connecting. */
3151 hr = IFilterGraph2_ConnectDirect(graph, &sink_pin.IPin_iface, &source_pin.IPin_iface, NULL);
3152 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3153 todo_wine ok(sink_pin.peer == &source_pin.IPin_iface, "Got peer %p.\n", sink_pin.peer);
3154 ok(!sink_pin.mt, "Got mt %p.\n", sink_pin.mt);
3155 todo_wine ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3156
3157 hr = IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
3158 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
3159 todo_wine ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3160 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3161
3162 hr = IFilterGraph2_Connect(graph, &sink_pin.IPin_iface, &source_pin.IPin_iface);
3163 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3164 todo_wine ok(sink_pin.peer == &source_pin.IPin_iface, "Got peer %p.\n", sink_pin.peer);
3165 ok(!sink_pin.mt, "Got mt %p.\n", sink_pin.mt);
3166 todo_wine ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3167
3168 hr = IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
3169 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
3170 todo_wine ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3171 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3172
3173 /* Disconnect() does not disconnect the peer. */
3174 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, NULL);
3175 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3176 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3177 ok(!source_pin.mt, "Got mt %p.\n", source_pin.mt);
3178 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3179
3180 sink_pin.peer = &source_pin.IPin_iface;
3181 IPin_AddRef(sink_pin.peer);
3182
3183 hr = IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
3184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3185 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3186 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3187
3188 hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
3189 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3190 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3191 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3192
3193 /* Test specifying the media type. */
3194 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, &mt);
3195 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3196 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3197 ok(source_pin.mt == &mt, "Got mt %p.\n", source_pin.mt);
3198 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3199 hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
3200 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3201
3202 /* Test Reconnect[Ex](). */
3203
3204 hr = IFilterGraph2_Reconnect(graph, &source_pin.IPin_iface);
3205 todo_wine ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
3206 hr = IFilterGraph2_Reconnect(graph, &sink_pin.IPin_iface);
3207 todo_wine ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
3208
3209 hr = IMediaControl_Stop(control);
3210 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3211
3212 hr = IFilterGraph2_Reconnect(graph, &source_pin.IPin_iface);
3213 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3214 hr = IFilterGraph2_Reconnect(graph, &sink_pin.IPin_iface);
3215 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3216
3217 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, &mt);
3218 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3219 hr = IFilterGraph2_Reconnect(graph, &source_pin.IPin_iface);
3220 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3221 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3222 ok(!source_pin.mt, "Got mt %p.\n", source_pin.mt);
3223 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3224 hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
3225 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3226
3227 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, &mt);
3228 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3229 sink_pin.peer = &source_pin.IPin_iface;
3230 IPin_AddRef(sink_pin.peer);
3231 hr = IFilterGraph2_Reconnect(graph, &sink_pin.IPin_iface);
3232 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3233 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3234 ok(!source_pin.mt, "Got mt %p.\n", source_pin.mt);
3235 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3236 hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
3237 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3238
3239 hr = IFilterGraph2_ReconnectEx(graph, &source_pin.IPin_iface, NULL);
3240 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3241 hr = IFilterGraph2_ReconnectEx(graph, &sink_pin.IPin_iface, NULL);
3242 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3243
3244 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, &mt);
3245 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3246 hr = IFilterGraph2_ReconnectEx(graph, &source_pin.IPin_iface, NULL);
3247 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3248 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3249 ok(!source_pin.mt, "Got mt %p.\n", source_pin.mt);
3250 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3251 hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
3252 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3253
3254 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, &mt);
3255 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3256 hr = IFilterGraph2_ReconnectEx(graph, &source_pin.IPin_iface, &mt);
3257 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3258 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3259 ok(source_pin.mt == &mt, "Got mt %p.\n", source_pin.mt);
3260 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3261 hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
3262 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3263
3264 /* ConnectDirect() protects against cyclical connections. */
3265 hr = IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, NULL);
3266 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3267 hr = IFilterGraph2_AddFilter(graph, &parser2.IBaseFilter_iface, NULL);
3268 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3269
3270 hr = IFilterGraph2_ConnectDirect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface, NULL);
3271 ok(hr == VFW_E_CIRCULAR_GRAPH, "Got hr %#lx.\n", hr);
3272
3273 hr = IFilterGraph2_ConnectDirect(graph, &parser1_pins[1].IPin_iface, &parser2_pins[0].IPin_iface, NULL);
3274 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3275 hr = IFilterGraph2_ConnectDirect(graph, &parser2_pins[1].IPin_iface, &parser1_pins[0].IPin_iface, NULL);
3276 todo_wine ok(hr == VFW_E_CIRCULAR_GRAPH, "Got hr %#lx.\n", hr);
3277 IFilterGraph2_Disconnect(graph, &parser1_pins[1].IPin_iface);
3278 IFilterGraph2_Disconnect(graph, &parser2_pins[0].IPin_iface);
3279
3280 parser1_pins[0].QueryInternalConnections_hr = S_OK;
3281 hr = IFilterGraph2_ConnectDirect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface, NULL);
3282 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
3283 ok(!parser1_pins[0].peer, "Got peer %p.\n", parser1_pins[0].peer);
3284 todo_wine ok(parser1_pins[1].peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", parser1_pins[1].peer);
3285 IFilterGraph2_Disconnect(graph, &parser1_pins[0].IPin_iface);
3286 IFilterGraph2_Disconnect(graph, &parser1_pins[1].IPin_iface);
3287
3288 hr = IFilterGraph2_ConnectDirect(graph, &parser1_pins[1].IPin_iface, &parser2_pins[0].IPin_iface, NULL);
3289 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3290 hr = IFilterGraph2_ConnectDirect(graph, &parser2_pins[1].IPin_iface, &parser1_pins[0].IPin_iface, NULL);
3291 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3292 IFilterGraph2_Disconnect(graph, &parser1_pins[1].IPin_iface);
3293 IFilterGraph2_Disconnect(graph, &parser2_pins[0].IPin_iface);
3294
3295 hr = IFilterGraph2_RemoveFilter(graph, &parser1.IBaseFilter_iface);
3296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3297 hr = IFilterGraph2_RemoveFilter(graph, &parser2.IBaseFilter_iface);
3298 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3299
3300 /* Both pins are disconnected when a filter is removed. */
3301 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, &mt);
3302 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3303 sink_pin.peer = &source_pin.IPin_iface;
3304 IPin_AddRef(sink_pin.peer);
3305 hr = IFilterGraph2_RemoveFilter(graph, &source.IBaseFilter_iface);
3306 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3307 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3308 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3309
3310 /* If the filter cannot be disconnected, then RemoveFilter() fails. */
3311
3312 hr = IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
3313 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3314 hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, &mt);
3315 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3316 sink_pin.peer = &source_pin.IPin_iface;
3317 IPin_AddRef(sink_pin.peer);
3318 hr = IMediaControl_Pause(control);
3319 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3320
3321 source_pin.require_stopped_disconnect = TRUE;
3322 hr = IFilterGraph2_RemoveFilter(graph, &source.IBaseFilter_iface);
3323 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
3324 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3325 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3326
3327 sink_pin.peer = &source_pin.IPin_iface;
3328 IPin_AddRef(sink_pin.peer);
3329 source_pin.require_stopped_disconnect = FALSE;
3330 sink_pin.require_stopped_disconnect = TRUE;
3331 hr = IFilterGraph2_RemoveFilter(graph, &source.IBaseFilter_iface);
3332 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
3333 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
3334 ok(sink_pin.peer == &source_pin.IPin_iface, "Got peer %p.\n", sink_pin.peer);
3335
3336 /* Filters are stopped, and pins disconnected, when the graph is destroyed. */
3337
3338 IMediaControl_Release(control);
3339 ref = IFilterGraph2_Release(graph);
3340 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3341 ok(source.ref == 1, "Got outstanding refcount %ld.\n", source.ref);
3342 ok(sink.ref == 1, "Got outstanding refcount %ld.\n", sink.ref);
3343 ok(source_pin.ref == 1, "Got outstanding refcount %ld.\n", source_pin.ref);
3344 todo_wine ok(sink_pin.ref == 1, "Got outstanding refcount %ld.\n", sink_pin.ref);
3345 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
3346 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
3347}
@ PINDIR_INPUT
Definition: axcore.idl:41
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
static void test_connect_direct_init(struct testpin *pin, PIN_DIRECTION dir)
Definition: filtergraph.c:3079
const AM_MEDIA_TYPE * mt
Definition: avidec.c:799
#define VFW_E_NOT_STOPPED
Definition: vfwmsgs.h:75
#define VFW_E_CIRCULAR_GRAPH
Definition: vfwmsgs.h:88
#define VFW_E_WRONG_STATE
Definition: vfwmsgs.h:78
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48
#define S_FALSE
Definition: winerror.h:3451

Referenced by START_TEST().

◆ test_connect_direct_Connect()

static HRESULT WINAPI test_connect_direct_Connect ( IPin *  iface,
IPin *  peer,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 3046 of file filtergraph.c.

3047{
3048 struct testpin *pin = impl_from_IPin(iface);
3049 if (winetest_debug > 1) trace("%p->Connect()\n", pin);
3050
3051 pin->peer = peer;
3052 IPin_AddRef(peer);
3053 pin->mt = (AM_MEDIA_TYPE *)mt;
3054 return S_OK;
3055}

◆ test_connect_direct_init()

static void test_connect_direct_init ( struct testpin *  pin,
PIN_DIRECTION  dir 
)
static

Definition at line 3079 of file filtergraph.c.

3080{
3082}
unsigned int dir
Definition: maze.c:112
static const IPinVtbl test_connect_direct_vtbl
Definition: filtergraph.c:3057
static void testpin_init(struct testpin *pin, const IPinVtbl *vtbl, PIN_DIRECTION dir)
Definition: filtergraph.c:1177

Referenced by test_connect_direct().

◆ test_control_delegation()

static void test_control_delegation ( void  )
static

Definition at line 2851 of file filtergraph.c.

2852{
2854 IBasicAudio *audio, *filter_audio;
2855 IBaseFilter *renderer;
2856 IVideoWindow *window;
2857 IBasicVideo2 *video;
2859 unsigned int count;
2860 TYPEATTR *typeattr;
2861 HRESULT hr;
2862 LONG val;
2863
2864 /* IBasicAudio */
2865
2866 hr = IFilterGraph2_QueryInterface(graph, &IID_IBasicAudio, (void **)&audio);
2867 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2868
2869 hr = IBasicAudio_GetTypeInfoCount(audio, &count);
2870 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2871 ok(count == 1, "Got count %u.\n", count);
2872
2873 hr = IBasicAudio_put_Volume(audio, -10);
2874 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2875 hr = IBasicAudio_get_Volume(audio, &val);
2876 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2877 hr = IBasicAudio_put_Balance(audio, 10);
2878 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2879 hr = IBasicAudio_get_Balance(audio, &val);
2880 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2881
2882 hr = CoCreateInstance(&CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void **)&renderer);
2884 {
2885 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2886
2887 hr = IFilterGraph2_AddFilter(graph, renderer, NULL);
2888 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2889
2890 hr = IBasicAudio_put_Volume(audio, -10);
2891 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2892 hr = IBasicAudio_get_Volume(audio, &val);
2893 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2894 ok(val == -10, "got %ld\n", val);
2895 hr = IBasicAudio_put_Balance(audio, 10);
2896 ok(hr == S_OK || hr == VFW_E_MONO_AUDIO_HW, "Got hr %#lx.\n", hr);
2897 hr = IBasicAudio_get_Balance(audio, &val);
2898 ok(hr == S_OK || hr == VFW_E_MONO_AUDIO_HW, "Got hr %#lx.\n", hr);
2899 if (hr == S_OK)
2900 ok(val == 10, "got balance %ld\n", val);
2901
2902 hr = IBaseFilter_QueryInterface(renderer, &IID_IBasicAudio, (void **)&filter_audio);
2903 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2904
2905 hr = IBasicAudio_get_Volume(filter_audio, &val);
2906 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2907 ok(val == -10, "got volume %ld\n", val);
2908
2909 hr = IFilterGraph2_RemoveFilter(graph, renderer);
2910 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2911
2912 IBaseFilter_Release(renderer);
2913 IBasicAudio_Release(filter_audio);
2914 }
2915
2916 hr = IBasicAudio_put_Volume(audio, -10);
2917 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2918 hr = IBasicAudio_get_Volume(audio, &val);
2919 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2920 hr = IBasicAudio_put_Balance(audio, 10);
2921 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2922 hr = IBasicAudio_get_Balance(audio, &val);
2923 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2924
2925 IBasicAudio_Release(audio);
2926
2927 /* IBasicVideo and IVideoWindow */
2928
2929 hr = IFilterGraph2_QueryInterface(graph, &IID_IBasicVideo2, (void **)&video);
2930 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2931 hr = IFilterGraph2_QueryInterface(graph, &IID_IVideoWindow, (void **)&window);
2932 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2933
2934 /* Unlike IBasicAudio, these return E_NOINTERFACE. */
2935 hr = IBasicVideo2_get_BitRate(video, &val);
2936 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
2937
2938 hr = IBasicVideo2_GetTypeInfoCount(video, &count);
2939 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2940 ok(count == 1, "Got count %u.\n", count);
2941
2942 hr = IBasicVideo2_GetTypeInfo(video, 0, 0, &typeinfo);
2943 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2944 hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
2945 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2946 ok(typeattr->typekind == TKIND_DISPATCH, "Got kind %u.\n", typeattr->typekind);
2947 ok(IsEqualGUID(&typeattr->guid, &IID_IBasicVideo), "Got IID %s.\n", wine_dbgstr_guid(&typeattr->guid));
2948 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
2949 ITypeInfo_Release(typeinfo);
2950
2951 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
2952 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
2953
2954 hr = IVideoWindow_GetTypeInfoCount(window, &count);
2955 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2956 ok(count == 1, "Got count %u.\n", count);
2957
2958 hr = CoCreateInstance(&CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void **)&renderer);
2959 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2960
2961 hr = IFilterGraph2_AddFilter(graph, renderer, NULL);
2962 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2963
2964 hr = IBasicVideo2_get_BitRate(video, &val);
2965 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2966 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
2967 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2968
2969 val = 0xdeadbeef;
2970 hr = IVideoWindow_get_FullScreenMode(window, &val);
2971 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2972 ok(val == OAFALSE, "Got fullscreen %lu\n", val);
2973
2974 hr = IVideoWindow_put_FullScreenMode(window, OAFALSE);
2975 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2976
2977 hr = IFilterGraph2_RemoveFilter(graph, renderer);
2978 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2979
2980 hr = IBasicVideo2_get_BitRate(video, &val);
2981 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
2982 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
2983 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
2984
2985 IBaseFilter_Release(renderer);
2986 IBasicVideo2_Release(video);
2987 IVideoWindow_Release(window);
2988 IFilterGraph2_Release(graph);
2989}
const GUID IID_IBaseFilter
#define OAFALSE
Definition: dshow.h:53
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLfloat * val
Definition: glext.h:7180
static IHTMLWindow2 * window
Definition: events.c:77
#define VFW_E_MONO_AUDIO_HW
Definition: vfwmsgs.h:107
@ TKIND_DISPATCH
Definition: widltypes.h:238

Referenced by START_TEST().

◆ test_default_sync_source()

static void test_default_sync_source ( void  )
static

Definition at line 5174 of file filtergraph.c.

5175{
5176 struct testpin source_pin, sink1_pin, sink2_pin;
5177 struct testfilter source, sink1, sink2;
5178
5182 HRESULT hr;
5183 ULONG ref;
5184
5185 testsink_init(&sink1_pin);
5186 testsink_init(&sink2_pin);
5187 testsource_init(&source_pin, NULL, 0);
5188 testfilter_init(&source, &source_pin, 1);
5189 testfilter_init(&sink1, &sink1_pin, 1);
5190 testfilter_init(&sink2, &sink2_pin, 1);
5191
5192 IFilterGraph2_AddFilter(graph, &sink1.IBaseFilter_iface, NULL);
5193 IFilterGraph2_AddFilter(graph, &sink2.IBaseFilter_iface, NULL);
5194 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
5195 IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink1_pin.IPin_iface, NULL);
5196
5197 IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
5198
5199 hr = IFilterGraph2_SetDefaultSyncSource(graph);
5200 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5201
5202 hr = IMediaFilter_GetSyncSource(filter, &clock);
5203 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5204 ok(!!clock, "Reference clock not set.\n");
5205 IReferenceClock_Release(clock);
5206
5207 source.IReferenceClock_iface.lpVtbl = &testclock_vtbl;
5208
5209 hr = IFilterGraph2_SetDefaultSyncSource(graph);
5210 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5211
5212 hr = IMediaFilter_GetSyncSource(filter, &clock);
5213 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5214 ok(clock == &source.IReferenceClock_iface, "Got unexpected clock.\n");
5215 IReferenceClock_Release(clock);
5216
5217 /* The documentation says that connected filters are preferred, but this
5218 * does not in fact seem to be the case. */
5219
5220 sink2.IReferenceClock_iface.lpVtbl = &testclock_vtbl;
5221
5222 hr = IFilterGraph2_SetDefaultSyncSource(graph);
5223 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5224
5225 hr = IMediaFilter_GetSyncSource(filter, &clock);
5226 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5227 todo_wine ok(clock == &sink2.IReferenceClock_iface, "Got unexpected clock.\n");
5228 IReferenceClock_Release(clock);
5229
5230 sink1.IReferenceClock_iface.lpVtbl = &testclock_vtbl;
5231
5232 hr = IFilterGraph2_SetDefaultSyncSource(graph);
5233 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5234
5235 hr = IMediaFilter_GetSyncSource(filter, &clock);
5236 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5237 todo_wine ok(clock == &sink1.IReferenceClock_iface, "Got unexpected clock.\n");
5238 IReferenceClock_Release(clock);
5239
5240 IMediaFilter_Release(filter);
5241 ref = IFilterGraph2_Release(graph);
5242 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5243 ok(sink1.ref == 1, "Got outstanding refcount %ld.\n", sink1.ref);
5244 ok(sink2.ref == 1, "Got outstanding refcount %ld.\n", sink2.ref);
5245 ok(source.ref == 1, "Got outstanding refcount %ld.\n", source.ref);
5246}
_ACRTIMP clock_t __cdecl clock(void)
Definition: time.c:698
static void testsink_init(struct testpin *pin)
Definition: filtergraph.c:1191
static const IReferenceClockVtbl testclock_vtbl
Definition: filtergraph.c:1965
struct strmbase_filter filter
Definition: amstream.c:1019

Referenced by START_TEST().

◆ test_ec_complete()

static void test_ec_complete ( void  )
static

Definition at line 4030 of file filtergraph.c.

4031{
4032 struct testpin filter1_pin, filter2_pin, filter3_pin;
4033 struct testfilter filter1, filter2, filter3;
4034
4036 IMediaEventSink *eventsink;
4037 LONG_PTR param1, param2;
4038 IMediaControl *control;
4039 IMediaEvent *eventsrc;
4040 LONG code, ref;
4041 HRESULT hr;
4042
4043 testsink_init(&filter1_pin);
4044 testsink_init(&filter2_pin);
4045 testsink_init(&filter3_pin);
4046 testfilter_init(&filter1, &filter1_pin, 1);
4047 testfilter_init(&filter2, &filter2_pin, 1);
4048 testfilter_init(&filter3, &filter3_pin, 1);
4049
4050 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
4051 IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc);
4052 IFilterGraph2_QueryInterface(graph, &IID_IMediaEventSink, (void **)&eventsink);
4053
4054 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4055 IFilterGraph2_AddFilter(graph, &filter2.IBaseFilter_iface, NULL);
4056 IFilterGraph2_AddFilter(graph, &filter3.IBaseFilter_iface, NULL);
4057
4058 /* EC_COMPLETE is only delivered to the user after all renderers deliver it. */
4059
4060 filter1.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl;
4061 filter2.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl;
4062 filter3.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl;
4063 filter1.misc_flags = filter2.misc_flags = AM_FILTER_MISC_FLAGS_IS_RENDERER;
4064
4065 IMediaControl_Run(control);
4066
4067 filter3.misc_flags = AM_FILTER_MISC_FLAGS_IS_RENDERER;
4068
4069 while ((hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 0)) == S_OK)
4070 {
4071 ok(code != EC_COMPLETE, "Got unexpected EC_COMPLETE.\n");
4072 IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
4073 }
4074 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4075
4076 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter1.IBaseFilter_iface);
4077 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4078
4079 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 50);
4080 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4081
4082 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter2.IBaseFilter_iface);
4083 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4084
4085 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 0);
4086 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4087 ok(code == EC_COMPLETE, "Got code %#lx.\n", code);
4088 ok(param1 == S_OK, "Got param1 %#Ix.\n", param1);
4089 ok(!param2, "Got param2 %#Ix.\n", param2);
4090 hr = IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
4091 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4092
4093 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 50);
4094 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4095
4096 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter3.IBaseFilter_iface);
4097 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4098
4099 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 50);
4100 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4101
4102 IMediaControl_Stop(control);
4103
4104 /* Test CancelDefaultHandling(). */
4105
4106 IMediaControl_Run(control);
4107
4108 hr = IMediaEvent_CancelDefaultHandling(eventsrc, EC_COMPLETE);
4109 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4110
4111 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 50);
4112 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4113
4114 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter1.IBaseFilter_iface);
4115 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4116
4117 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 0);
4118 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4119 ok(code == EC_COMPLETE, "Got code %#lx.\n", code);
4120 ok(param1 == S_OK, "Got param1 %#Ix.\n", param1);
4121 ok(param2 == (LONG_PTR)&filter1.IBaseFilter_iface, "Got param2 %#Ix.\n", param2);
4122 hr = IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
4123 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4124
4125 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 50);
4126 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4127
4128 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter3.IBaseFilter_iface);
4129 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4130
4131 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 0);
4132 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4133 ok(code == EC_COMPLETE, "Got code %#lx.\n", code);
4134 ok(param1 == S_OK, "Got param1 %#Ix.\n", param1);
4135 ok(param2 == (LONG_PTR)&filter3.IBaseFilter_iface, "Got param2 %#Ix.\n", param2);
4136 hr = IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
4137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4138
4139 hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, 50);
4140 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4141
4142 IMediaControl_Stop(control);
4143 hr = IMediaEvent_RestoreDefaultHandling(eventsrc, EC_COMPLETE);
4144 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4145
4146 /* A filter counts as a renderer if it (1) exposes IAMFilterMiscFlags and
4147 * reports itself as a renderer, or (2) exposes IMediaSeeking or
4148 * IMediaPosition and has no output pins. Despite MSDN,
4149 * QueryInternalConnections() does not seem to be used. */
4150
4151 IFilterGraph2_RemoveFilter(graph, &filter1.IBaseFilter_iface);
4152 IFilterGraph2_RemoveFilter(graph, &filter2.IBaseFilter_iface);
4153 IFilterGraph2_RemoveFilter(graph, &filter3.IBaseFilter_iface);
4154 filter1.misc_flags = 0;
4155 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4156
4157 hr = check_ec_complete(graph, &filter1.IBaseFilter_iface);
4158 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4159
4160 IFilterGraph2_RemoveFilter(graph, &filter1.IBaseFilter_iface);
4161 filter1_pin.dir = PINDIR_INPUT;
4162 filter1.IAMFilterMiscFlags_iface.lpVtbl = NULL;
4163 filter1.IMediaSeeking_iface.lpVtbl = &testseek_vtbl;
4164 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4165
4166 hr = check_ec_complete(graph, &filter1.IBaseFilter_iface);
4167 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4168
4169 ok(filter1.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4170 IFilterGraph2_RemoveFilter(graph, &filter1.IBaseFilter_iface);
4171 ok(filter1.seeking_ref == 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4172
4173 filter1_pin.dir = PINDIR_OUTPUT;
4174 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4175
4176 hr = check_ec_complete(graph, &filter1.IBaseFilter_iface);
4177 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4178
4179 ok(filter1.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4180 IFilterGraph2_RemoveFilter(graph, &filter1.IBaseFilter_iface);
4181 ok(filter1.seeking_ref == 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4182
4183 filter1_pin.dir = PINDIR_INPUT;
4184 filter1.support_media_time = FALSE;
4185 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4186
4187 hr = check_ec_complete(graph, &filter1.IBaseFilter_iface);
4188 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4189
4190 ok(filter1.seeking_ref == 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4191 IFilterGraph2_RemoveFilter(graph, &filter1.IBaseFilter_iface);
4192
4193 filter1.IMediaPosition_iface.lpVtbl = &testpos_vtbl;
4194 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4195
4196 hr = check_ec_complete(graph, &filter1.IBaseFilter_iface);
4197 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4198
4199 IFilterGraph2_RemoveFilter(graph, &filter1.IBaseFilter_iface);
4200
4201 filter1.IMediaSeeking_iface.lpVtbl = NULL;
4202 filter1.IMediaPosition_iface.lpVtbl = NULL;
4203 filter1_pin.dir = PINDIR_INPUT;
4204 filter1.pin_count = 1;
4205 filter1_pin.QueryInternalConnections_hr = S_OK;
4206 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4207
4208 hr = check_ec_complete(graph, &filter1.IBaseFilter_iface);
4209 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
4210
4211 IFilterGraph2_RemoveFilter(graph, &filter1.IBaseFilter_iface);
4212
4213 filter1.IMediaPosition_iface.lpVtbl = &testpos_vtbl;
4214 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4215
4216 hr = check_ec_complete(graph, &filter1.IBaseFilter_iface);
4217 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4218
4219 IMediaControl_Release(control);
4220 IMediaEvent_Release(eventsrc);
4221 IMediaEventSink_Release(eventsink);
4222 ref = IFilterGraph2_Release(graph);
4223 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4224 ok(filter1.ref == 1, "Got outstanding refcount %ld.\n", filter1.ref);
4225 ok(filter2.ref == 1, "Got outstanding refcount %ld.\n", filter2.ref);
4226 ok(filter3.ref == 1, "Got outstanding refcount %ld.\n", filter3.ref);
4227}
@ AM_FILTER_MISC_FLAGS_IS_RENDERER
Definition: axextend.idl:1244
static const IMediaPositionVtbl testpos_vtbl
Definition: filtergraph.c:1894
static const IAMFilterMiscFlagsVtbl testmiscflags_vtbl
Definition: filtergraph.c:1592
static HRESULT check_ec_complete(IFilterGraph2 *graph, IBaseFilter *filter)
Definition: filtergraph.c:3988

Referenced by START_TEST().

◆ test_enum_filters()

static void test_enum_filters ( void  )
static

Definition at line 658 of file filtergraph.c.

659{
660 IBaseFilter *filter1, *filter2, *filters[2];
662 IEnumFilters *enum1, *enum2;
663 ULONG count, ref;
664 HRESULT hr;
665
666 CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
667 &IID_IBaseFilter, (void **)&filter1);
668 CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
669 &IID_IBaseFilter, (void **)&filter2);
670
671 hr = IFilterGraph2_EnumFilters(graph, &enum1);
672 ok(hr == S_OK, "Got hr %#lx.\n", hr);
673
674 hr = IEnumFilters_Next(enum1, 1, filters, NULL);
675 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
676
677 hr = IEnumFilters_Skip(enum1, 0);
678 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
679
680 hr = IEnumFilters_Skip(enum1, 1);
681 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
682
683 IFilterGraph2_AddFilter(graph, filter1, NULL);
684 IFilterGraph2_AddFilter(graph, filter2, NULL);
685
686 hr = IEnumFilters_Next(enum1, 1, filters, NULL);
687 ok(hr == VFW_E_ENUM_OUT_OF_SYNC, "Got hr %#lx.\n", hr);
688
689 hr = IEnumFilters_Skip(enum1, 1);
690 ok(hr == VFW_E_ENUM_OUT_OF_SYNC, "Got hr %#lx.\n", hr);
691
692 hr = IEnumFilters_Reset(enum1);
693 ok(hr == S_OK, "Got hr %#lx.\n", hr);
694
695 hr = IEnumFilters_Skip(enum1, 0);
696 ok(hr == S_OK, "Got hr %#lx.\n", hr);
697
698 hr = IEnumFilters_Skip(enum1, 1);
699 ok(hr == S_OK, "Got hr %#lx.\n", hr);
700
701 hr = IEnumFilters_Skip(enum1, 2);
702 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
703
704 hr = IEnumFilters_Skip(enum1, 1);
705 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
706
707 hr = IEnumFilters_Reset(enum1);
708 ok(hr == S_OK, "Got hr %#lx.\n", hr);
709
710 hr = IEnumFilters_Skip(enum1, 2);
711 ok(hr == S_OK, "Got hr %#lx.\n", hr);
712
713 hr = IEnumFilters_Skip(enum1, 1);
714 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
715
716 hr = IEnumFilters_Reset(enum1);
717 ok(hr == S_OK, "Got hr %#lx.\n", hr);
718
719 hr = IEnumFilters_Next(enum1, 1, filters, NULL);
720 ok(hr == S_OK, "Got hr %#lx.\n", hr);
721 ok(filters[0] == filter2, "Got filter %p.\n", filters[0]);
722 IBaseFilter_Release(filters[0]);
723
724 hr = IEnumFilters_Next(enum1, 1, filters, &count);
725 ok(hr == S_OK, "Got hr %#lx.\n", hr);
726 ok(count == 1, "Got count %lu.\n", count);
727 ok(filters[0] == filter1, "Got filter %p.\n", filters[0]);
728 IBaseFilter_Release(filters[0]);
729
730 hr = IEnumFilters_Next(enum1, 1, filters, &count);
731 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
732 ok(count == 0, "Got count %lu.\n", count);
733
734 hr = IEnumFilters_Reset(enum1);
735 ok(hr == S_OK, "Got hr %#lx.\n", hr);
736
737 hr = IEnumFilters_Next(enum1, 2, filters, &count);
738 ok(hr == S_OK, "Got hr %#lx.\n", hr);
739 ok(count == 2, "Got count %lu.\n", count);
740 ok(filters[0] == filter2, "Got filter %p.\n", filters[0]);
741 ok(filters[1] == filter1, "Got filter %p.\n", filters[1]);
742 IBaseFilter_Release(filters[0]);
743 IBaseFilter_Release(filters[1]);
744
745 IFilterGraph2_RemoveFilter(graph, filter1);
746 IFilterGraph2_AddFilter(graph, filter1, NULL);
747
748 hr = IEnumFilters_Next(enum1, 2, filters, &count);
749 ok(hr == VFW_E_ENUM_OUT_OF_SYNC, "Got hr %#lx.\n", hr);
750
751 hr = IEnumFilters_Reset(enum1);
752 ok(hr == S_OK, "Got hr %#lx.\n", hr);
753
754 hr = IEnumFilters_Next(enum1, 2, filters, &count);
755 ok(hr == S_OK, "Got hr %#lx.\n", hr);
756 ok(count == 2, "Got count %lu.\n", count);
757 ok(filters[0] == filter1, "Got filter %p.\n", filters[0]);
758 ok(filters[1] == filter2, "Got filter %p.\n", filters[1]);
759 IBaseFilter_Release(filters[0]);
760 IBaseFilter_Release(filters[1]);
761
762 hr = IEnumFilters_Reset(enum1);
763 ok(hr == S_OK, "Got hr %#lx.\n", hr);
764
765 hr = IEnumFilters_Clone(enum1, &enum2);
766 ok(hr == S_OK, "Got hr %#lx.\n", hr);
767
768 hr = IEnumFilters_Skip(enum2, 1);
769 ok(hr == S_OK, "Got hr %#lx.\n", hr);
770
771 hr = IEnumFilters_Next(enum2, 2, filters, &count);
772 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
773 ok(count == 1, "Got count %lu.\n", count);
774 ok(filters[0] == filter2, "Got filter %p.\n", filters[0]);
775 IBaseFilter_Release(filters[0]);
776
777 hr = IEnumFilters_Skip(enum1, 3);
778 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
779
780 IEnumFilters_Release(enum2);
781 IEnumFilters_Release(enum1);
782 ref = IFilterGraph2_Release(graph);
783 ok(!ref, "Got outstanding refcount %ld.\n", ref);
784}
#define VFW_E_ENUM_OUT_OF_SYNC
Definition: vfwmsgs.h:42

Referenced by START_TEST().

◆ test_event_dispatch()

static void test_event_dispatch ( void  )
static

Definition at line 5923 of file filtergraph.c.

5924{
5926 IMediaEventEx *event_ex;
5928 IMediaEvent *event;
5929 TYPEATTR *typeattr;
5930 unsigned int count;
5931 HRESULT hr;
5932 ULONG ref;
5933
5934 IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&event);
5935 IFilterGraph2_QueryInterface(graph, &IID_IMediaEventEx, (void **)&event_ex);
5936 ok((void *)event == event_ex, "Interface pointers didn't match.\n");
5937 IMediaEventEx_Release(event_ex);
5938
5939 hr = IMediaEvent_GetTypeInfoCount(event, &count);
5940 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5941 ok(count == 1, "Got count %u.\n", count);
5942
5943 hr = IMediaEvent_GetTypeInfo(event, 0, 0, &typeinfo);
5944 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5945 hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
5946 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5947 ok(typeattr->typekind == TKIND_DISPATCH, "Got kind %u.\n", typeattr->typekind);
5948 ok(IsEqualGUID(&typeattr->guid, &IID_IMediaEvent), "Got IID %s.\n", debugstr_guid(&typeattr->guid));
5949 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
5950 ITypeInfo_Release(typeinfo);
5951
5952 IMediaEvent_Release(event);
5953 ref = IFilterGraph2_Release(graph);
5954 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5955}
#define debugstr_guid
Definition: kernel32.h:35
Definition: filter.c:185

Referenced by START_TEST().

◆ test_events()

static void test_events ( void  )
static

Definition at line 5760 of file filtergraph.c.

5761{
5763 IMediaEventSink *media_event_sink;
5764 IMediaControl *media_control;
5765 IMediaEventEx *media_event;
5766 struct testfilter filter;
5767 LONG_PTR param1, param2;
5768 HANDLE event;
5769 BSTR status;
5770 HRESULT hr;
5771 ULONG ref;
5772 LONG code;
5773
5774 status = SysAllocString(L"status");
5775
5776 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
5777 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5778 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEventEx, (void **)&media_event);
5779 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5780 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEventSink, (void **)&media_event_sink);
5781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5782
5784 filter.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl;
5786
5787 hr = IFilterGraph2_AddFilter(graph, &filter.IBaseFilter_iface, NULL);
5788 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5789
5790 hr = IMediaEventEx_GetEventHandle(media_event, (OAEVENT *)&event);
5791 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5792
5793 code = 0xdeadbeef;
5794 param1 = 0xdeadbeef;
5795 param2 = 0xdeadbeef;
5796 hr = IMediaEventEx_GetEvent(media_event, &code, &param1, &param2, 0);
5797 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
5798 ok(!code, "Got code %#lx.\n", code);
5799 todo_wine ok(!param1, "Got param1 %#Ix.\n", param1);
5800 todo_wine ok(!param2, "Got param2 %#Ix.\n", param2);
5801
5802 /* EC_COMPLETE is ignored while in stopped or paused state. */
5803
5804 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5805 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5806 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5807 (LONG_PTR)&filter.IBaseFilter_iface);
5808 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5809 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5810 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5811
5813
5814 hr = IMediaControl_Pause(media_control);
5815 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5816
5817 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5818 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5819 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5820 (LONG_PTR)&filter.IBaseFilter_iface);
5821 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5822 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5823 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5824
5826
5827 hr = IMediaControl_Run(media_control);
5828 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5829
5831
5832 /* Pausing and then running the graph clears pending EC_COMPLETE events.
5833 * This remains true even with default handling canceled. */
5834
5835 hr = IMediaEventEx_CancelDefaultHandling(media_event, EC_COMPLETE);
5836 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5837
5838 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5839 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5840 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5841 (LONG_PTR)&filter.IBaseFilter_iface);
5842 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5843 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5844 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5845
5846 hr = IMediaControl_Stop(media_control);
5847 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5848
5850
5851 hr = IMediaControl_Run(media_control);
5852 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5853
5854 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5855 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5856 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5857 (LONG_PTR)&filter.IBaseFilter_iface);
5858 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5859 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5860 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5861
5862 hr = IMediaControl_Stop(media_control);
5863 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5864 hr = IMediaControl_Run(media_control);
5865 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5866
5868
5869 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5870 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5871 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5872 (LONG_PTR)&filter.IBaseFilter_iface);
5873 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5874 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5875 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5876
5877 hr = IMediaControl_Stop(media_control);
5878 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5879 hr = IMediaControl_Pause(media_control);
5880 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5881
5883
5884 hr = IMediaControl_Run(media_control);
5885 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5886 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5887 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5888 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5889 (LONG_PTR)&filter.IBaseFilter_iface);
5890 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5891 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5892 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5893
5894 hr = IMediaControl_Pause(media_control);
5895 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5896 hr = IMediaControl_Run(media_control);
5897 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5898
5900
5901 /* GetEvent() resets the event object if there are no events available. */
5902
5903 SetEvent(event);
5904
5905 hr = IMediaEventEx_GetEvent(media_event, &code, &param1, &param2, 50);
5906 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
5907
5908 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
5909
5910 hr = IMediaControl_Stop(media_control);
5911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5912
5913 IMediaControl_Release(media_control);
5914 IMediaEventEx_Release(media_event);
5915 IMediaEventSink_Release(media_event_sink);
5916 ref = IFilterGraph2_Release(graph);
5917 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5918 ok(filter.ref == 1, "Got outstanding refcount %ld.\n", filter.ref);
5919
5921}
#define WAIT_TIMEOUT
Definition: dderror.h:14
OLECHAR * BSTR
Definition: compat.h:2293
#define check_events(a, b, c)
Definition: filtergraph.c:5732
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:240
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:273
Definition: ps.c:97
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82

Referenced by START_TEST().

◆ test_filter_state()

static void test_filter_state ( void  )
static

Definition at line 3441 of file filtergraph.c.

3442{
3443 struct testfilter source, sink, dummy;
3444 struct testpin source_pin, sink_pin;
3445
3447 REFERENCE_TIME start_time, time;
3449 IMediaControl *control;
3450 IMediaSeeking *seeking;
3451 FILTER_STATE mf_state;
3454 HRESULT hr;
3455 ULONG ref;
3456
3457 testsource_init(&source_pin, NULL, 0);
3458 testsink_init(&sink_pin);
3459 testfilter_init(&source, &source_pin, 1);
3460 testfilter_init(&sink, &sink_pin, 1);
3462 sink.IMediaSeeking_iface.lpVtbl = &testseek_vtbl;
3463
3464 IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
3465 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3466
3467 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
3468 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
3469 IFilterGraph2_AddFilter(graph, &dummy.IBaseFilter_iface, NULL);
3470 /* Using IPin::Connect instead of IFilterGraph2::ConnectDirect to show that */
3471 /* FilterGraph does not rely on ::ConnectDirect to track filter connections. */
3472 IPin_Connect(&source_pin.IPin_iface, &sink_pin.IPin_iface, NULL);
3473
3474 check_filter_state(graph, State_Stopped);
3475
3476 hr = IMediaControl_Pause(control);
3477 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3478 check_filter_state(graph, State_Paused);
3479
3480 /* Pausing sets the default sync source, if it's not already set. */
3481
3482 hr = IMediaFilter_GetSyncSource(filter, &clock);
3483 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3484 ok(!!clock, "Reference clock not set.\n");
3485 ok(source.clock == clock, "Expected %p, got %p.\n", clock, source.clock);
3486 ok(sink.clock == clock, "Expected %p, got %p.\n", clock, sink.clock);
3487
3488 hr = IReferenceClock_GetTime(clock, &start_time);
3489 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3490 hr = IMediaControl_Run(control);
3491 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3492 check_filter_state(graph, State_Running);
3493 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
3494 ok(source.start_time >= start_time && source.start_time < start_time + 500 * 10000,
3495 "Expected time near %s, got %s.\n",
3496 wine_dbgstr_longlong(start_time), wine_dbgstr_longlong(source.start_time));
3497 ok(sink.start_time == source.start_time, "Expected time %s, got %s.\n",
3498 wine_dbgstr_longlong(source.start_time), wine_dbgstr_longlong(sink.start_time));
3499
3500 hr = IMediaControl_Pause(control);
3501 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3502 check_filter_state(graph, State_Paused);
3503
3504 sink.state = State_Stopped;
3505 hr = IMediaControl_GetState(control, 0, &state);
3506 ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
3507 ok(state == State_Paused, "Got state %lu.\n", state);
3508
3509 sink.state = State_Running;
3510 hr = IMediaControl_GetState(control, 0, &state);
3511 ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
3512 ok(state == State_Paused, "Got state %lu.\n", state);
3513
3514 sink.state = State_Paused;
3515 hr = IMediaControl_GetState(control, 0, &state);
3516 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3517 ok(state == State_Paused, "Got state %lu.\n", state);
3518
3519 hr = IMediaControl_Stop(control);
3520 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3521 check_filter_state(graph, State_Stopped);
3522
3523 hr = IMediaControl_Run(control);
3524 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3525 check_filter_state(graph, State_Running);
3526
3527 sink.state = State_Stopped;
3528 hr = IMediaControl_GetState(control, 0, &state);
3529 ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
3530 ok(state == State_Running, "Got state %lu.\n", state);
3531
3532 sink.state = State_Paused;
3533 hr = IMediaControl_GetState(control, 0, &state);
3534 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
3535 ok(state == State_Running, "Got state %lu.\n", state);
3536
3537 sink.state = State_Running;
3538 hr = IMediaControl_GetState(control, 0, &state);
3539 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3540 ok(state == State_Running, "Got state %lu.\n", state);
3541
3542 hr = IMediaControl_Stop(control);
3543 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3544 check_filter_state(graph, State_Stopped);
3545
3546 sink.state = State_Running;
3547 hr = IMediaControl_GetState(control, 0, &state);
3548 ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
3549 ok(state == State_Stopped, "Got state %lu.\n", state);
3550
3551 sink.state = State_Paused;
3552 hr = IMediaControl_GetState(control, 0, &state);
3553 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
3554 ok(state == State_Stopped, "Got state %lu.\n", state);
3555
3556 sink.state = State_Stopped;
3557 hr = IMediaControl_GetState(control, 0, &state);
3558 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3559 ok(state == State_Stopped, "Got state %lu.\n", state);
3560
3561 hr = IMediaControl_Pause(control);
3562 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3563 check_filter_state(graph, State_Paused);
3564
3565 hr = IMediaControl_StopWhenReady(control);
3566 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3567 check_filter_state(graph, State_Stopped);
3568
3569 hr = IMediaControl_Run(control);
3570 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3571 check_filter_state(graph, State_Running);
3572
3573 hr = IMediaControl_StopWhenReady(control);
3574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3575 check_filter_state(graph, State_Stopped);
3576
3577 hr = IMediaControl_StopWhenReady(control);
3578 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3579 check_filter_state(graph, State_Stopped);
3580
3581 IReferenceClock_Release(clock);
3582 IMediaFilter_Release(filter);
3583 IMediaControl_Release(control);
3584 IFilterGraph2_Release(graph);
3585
3586 /* Test same methods using IMediaFilter. */
3587
3588 graph = create_graph();
3589 IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
3590 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3591 IFilterGraph2_QueryInterface(graph, &IID_IMediaSeeking, (void **)&seeking);
3592
3593 /* Add the filters in reverse order this time. */
3594 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
3595 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
3596 /* Using IPin::Connect instead of IFilterGraph2::ConnectDirect to show that */
3597 /* FilterGraph does not rely on ::ConnectDirect to track filter connections. */
3598 IPin_Connect(&source_pin.IPin_iface, &sink_pin.IPin_iface, NULL);
3599
3600 hr = IMediaFilter_Pause(filter);
3601 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3602 check_filter_state(graph, State_Paused);
3603
3604 hr = IMediaFilter_GetSyncSource(filter, &clock);
3605 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3606 ok(!!clock, "Reference clock not set.\n");
3607 ok(source.clock == clock, "Expected %p, got %p.\n", clock, source.clock);
3608 ok(sink.clock == clock, "Expected %p, got %p.\n", clock, sink.clock);
3609
3610 hr = IMediaFilter_Run(filter, 0xdeadbeef);
3611 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3612 check_filter_state(graph, State_Running);
3613 ok(source.start_time == 0xdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(source.start_time));
3614 ok(sink.start_time == 0xdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(sink.start_time));
3615
3616 hr = IMediaFilter_Pause(filter);
3617 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3618 check_filter_state(graph, State_Paused);
3619
3620 hr = IMediaFilter_Run(filter, 0xdeadf00d);
3621 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3622 check_filter_state(graph, State_Running);
3623 ok(source.start_time == 0xdeadf00d, "Got time %s.\n", wine_dbgstr_longlong(source.start_time));
3624 ok(sink.start_time == 0xdeadf00d, "Got time %s.\n", wine_dbgstr_longlong(sink.start_time));
3625
3626 hr = IMediaFilter_Pause(filter);
3627 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3628 check_filter_state(graph, State_Paused);
3629
3630 hr = IMediaFilter_Stop(filter);
3631 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3632 check_filter_state(graph, State_Stopped);
3633
3634 source.expect_run_prev = sink.expect_run_prev = State_Stopped;
3635 hr = IReferenceClock_GetTime(clock, &start_time);
3636 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3637 hr = IMediaFilter_Run(filter, 0);
3638 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3639 check_filter_state(graph, State_Running);
3640 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
3641 ok(source.start_time >= start_time && source.start_time < start_time + 500 * 10000,
3642 "Expected time near %s, got %s.\n",
3643 wine_dbgstr_longlong(start_time), wine_dbgstr_longlong(source.start_time));
3644 ok(sink.start_time == source.start_time, "Expected time %s, got %s.\n",
3645 wine_dbgstr_longlong(source.start_time), wine_dbgstr_longlong(sink.start_time));
3646
3647 Sleep(600);
3648 hr = IMediaFilter_Pause(filter);
3649 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3650 check_filter_state(graph, State_Paused);
3651
3652 source.expect_run_prev = sink.expect_run_prev = State_Paused;
3653 hr = IMediaFilter_Run(filter, 0);
3654 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3655 check_filter_state(graph, State_Running);
3656 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
3657 ok(source.start_time >= start_time && source.start_time < start_time + 500 * 10000,
3658 "Expected time near %s, got %s.\n",
3659 wine_dbgstr_longlong(start_time), wine_dbgstr_longlong(source.start_time));
3660 ok(sink.start_time == source.start_time, "Expected time %s, got %s.\n",
3661 wine_dbgstr_longlong(source.start_time), wine_dbgstr_longlong(sink.start_time));
3662
3663 hr = IMediaFilter_Pause(filter);
3664 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3665 check_filter_state(graph, State_Paused);
3666 Sleep(600);
3667
3668 start_time += 550 * 10000;
3669 hr = IMediaFilter_Run(filter, 0);
3670 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3671 check_filter_state(graph, State_Running);
3672 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
3673 ok(source.start_time >= start_time && source.start_time < start_time + 500 * 10000,
3674 "Expected time near %s, got %s.\n",
3675 wine_dbgstr_longlong(start_time), wine_dbgstr_longlong(source.start_time));
3676 ok(sink.start_time == source.start_time, "Expected time %s, got %s.\n",
3677 wine_dbgstr_longlong(source.start_time), wine_dbgstr_longlong(sink.start_time));
3678
3679 hr = IMediaFilter_Stop(filter);
3680 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3681 check_filter_state(graph, State_Stopped);
3682
3683 /* Test removing the sync source. */
3684
3685 IReferenceClock_Release(clock);
3686 IMediaFilter_SetSyncSource(filter, NULL);
3687
3688 hr = IMediaControl_Run(control);
3689 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3690 check_filter_state(graph, State_Running);
3691 todo_wine ok(source.start_time > 0 && source.start_time < 500 * 10000,
3692 "Got time %s.\n", wine_dbgstr_longlong(source.start_time));
3693 ok(sink.start_time == source.start_time, "Expected time %s, got %s.\n",
3694 wine_dbgstr_longlong(source.start_time), wine_dbgstr_longlong(sink.start_time));
3695
3696 hr = IMediaControl_Stop(control);
3697 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3698 check_filter_state(graph, State_Stopped);
3699
3700 /* Test asynchronous state change. */
3701
3702 sink.state_hr = S_FALSE;
3703 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3704 hr = IMediaControl_Pause(control);
3705 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3706
3707 hr = IMediaControl_GetState(control, 0, &state);
3708 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
3709 ok(state == State_Paused, "Got state %lu.\n", state);
3710
3711 sink.state_hr = sink.GetState_hr = S_OK;
3712 hr = IMediaControl_GetState(control, 0, &state);
3713 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3714 ok(state == State_Paused, "Got state %lu.\n", state);
3715
3716 sink.state_hr = S_FALSE;
3717 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3718 hr = IMediaControl_Stop(control);
3719 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3720
3721 hr = IMediaControl_GetState(control, 0, &state);
3722 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
3723 ok(state == State_Stopped, "Got state %lu.\n", state);
3724
3725 sink.state_hr = sink.GetState_hr = S_OK;
3726 hr = IMediaControl_GetState(control, 0, &state);
3727 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3728 ok(state == State_Stopped, "Got state %lu.\n", state);
3729
3730 /* Renderers are expected to block completing a state change into paused
3731 * until they receive a sample. Because the graph can transition from
3732 * stopped -> paused -> running in one call, which itself needs to be
3733 * asynchronous, it actually waits on a separate thread for all filters
3734 * to be ready, then calls IMediaFilter::Run() once they are.
3735 *
3736 * However, IMediaControl::GetState() will return VFW_S_STATE_INTERMEDIATE
3737 * if filters haven't caught up to the graph yet. To make matters worse, it
3738 * doesn't take the above into account, meaning that it'll gladly return
3739 * VFW_S_STATE_INTERMEDIATE even if passed an infinite timeout. */
3740
3741 sink.state_hr = S_FALSE;
3742 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3743 hr = IMediaControl_Run(control);
3744 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3745
3746 hr = IMediaControl_GetState(control, 0, &state);
3747 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
3748 ok(state == State_Running, "Got state %lu.\n", state);
3749 ok(sink.state == State_Paused, "Got state %u.\n", sink.state);
3750 ok(source.state == State_Paused, "Got state %u.\n", source.state);
3751
3752 /* SetPositions() does not pause the graph in this case, since it is
3753 * already in a paused state. */
3754 time = 0;
3755 hr = IMediaSeeking_SetPositions(seeking, &time, AM_SEEKING_AbsolutePositioning,
3757 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3758
3759 hr = IMediaControl_Run(control);
3760 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3761
3762 hr = IMediaControl_GetState(control, 0, &state);
3763 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
3764 ok(state == State_Running, "Got state %lu.\n", state);
3765 ok(sink.state == State_Paused, "Got state %u.\n", sink.state);
3766 ok(source.state == State_Paused, "Got state %u.\n", source.state);
3767
3768 sink.state_hr = sink.GetState_hr = S_OK;
3769
3770 while ((hr = IMediaControl_GetState(control, INFINITE, &state)) == VFW_S_STATE_INTERMEDIATE)
3771 {
3772 ok(state == State_Running, "Got state %lu.\n", state);
3773 ok(sink.state == State_Paused, "Got state %u.\n", sink.state);
3774 ok(source.state == State_Paused, "Got state %u.\n", source.state);
3775 Sleep(10);
3776 }
3777 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3778 ok(state == State_Running, "Got state %lu.\n", state);
3779 ok(sink.state == State_Running, "Got state %u.\n", sink.state);
3780 ok(source.state == State_Running, "Got state %u.\n", source.state);
3781
3782 /* The above logic does not apply to the running -> paused -> stopped
3783 * transition. The filter graph will stop a filter regardless of whether
3784 * it's completely paused. Inasmuch as stopping the filter is like flushing
3785 * it—i.e. it has to succeed—this makes sense. */
3786
3787 sink.state_hr = S_FALSE;
3788 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3789 hr = IMediaControl_Stop(control);
3790 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3791 ok(sink.state == State_Stopped, "Got state %u.\n", sink.state);
3792 ok(source.state == State_Stopped, "Got state %u.\n", source.state);
3793
3794 hr = IMediaControl_GetState(control, 0, &state);
3795 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
3796 ok(state == State_Stopped, "Got state %lu.\n", state);
3797
3798 hr = IMediaControl_Stop(control);
3799 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3800
3801 sink.state_hr = sink.GetState_hr = S_OK;
3802 hr = IMediaControl_GetState(control, 0, &state);
3803 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3804 ok(state == State_Stopped, "Got state %lu.\n", state);
3805
3806 /* Try an asynchronous stopped->paused->running transition, but pause or
3807 * stop the graph before our filter is completely paused. */
3808
3809 sink.state_hr = S_FALSE;
3810 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3811 hr = IMediaControl_Run(control);
3812 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3813
3814 hr = IMediaControl_Pause(control);
3815 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3816
3817 sink.state_hr = sink.GetState_hr = S_OK;
3818 hr = IMediaControl_GetState(control, 0, &state);
3819 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3820 ok(state == State_Paused, "Got state %lu.\n", state);
3821 ok(sink.state == State_Paused, "Got state %u.\n", sink.state);
3822 ok(source.state == State_Paused, "Got state %u.\n", source.state);
3823
3824 hr = IMediaControl_Stop(control);
3825 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3826
3827 sink.state_hr = S_FALSE;
3828 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3829 hr = IMediaControl_Run(control);
3830 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3831
3832 hr = IMediaControl_Stop(control);
3833 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3834 ok(sink.state == State_Stopped, "Got state %u.\n", sink.state);
3835 ok(source.state == State_Stopped, "Got state %u.\n", source.state);
3836
3837 sink.state_hr = sink.GetState_hr = S_OK;
3838 hr = IMediaControl_GetState(control, 0, &state);
3839 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3840 ok(state == State_Stopped, "Got state %lu.\n", state);
3841 ok(sink.state == State_Stopped, "Got state %u.\n", sink.state);
3842 ok(source.state == State_Stopped, "Got state %u.\n", source.state);
3843
3844 /* Same, but tear down the graph instead. */
3845
3846 sink.state_hr = S_FALSE;
3847 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3848 hr = IMediaControl_Run(control);
3849 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3850
3851 IMediaFilter_Release(filter);
3852 IMediaControl_Release(control);
3853 IMediaSeeking_Release(seeking);
3854 ref = IFilterGraph2_Release(graph);
3855 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3856
3857 graph = create_graph();
3858 IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
3859 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3860 IFilterGraph2_QueryInterface(graph, &IID_IMediaSeeking, (void **)&seeking);
3861 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
3862 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
3863 IPin_Connect(&source_pin.IPin_iface, &sink_pin.IPin_iface, NULL);
3864
3865 /* This logic doesn't apply when using IMediaFilter methods directly. */
3866
3867 source.expect_run_prev = sink.expect_run_prev = State_Stopped;
3868 sink.state_hr = S_FALSE;
3869 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3870 hr = IMediaFilter_Run(filter, 0);
3871 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3872
3873 hr = IMediaFilter_GetState(filter, 0, &mf_state);
3874 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
3875 ok(mf_state == State_Running, "Got state %u.\n", mf_state);
3876 ok(sink.state == State_Running, "Got state %u.\n", sink.state);
3877 ok(source.state == State_Running, "Got state %u.\n", source.state);
3878
3879 sink.state_hr = sink.GetState_hr = S_OK;
3880 hr = IMediaFilter_GetState(filter, 0, &mf_state);
3881 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3882 ok(mf_state == State_Running, "Got state %u.\n", mf_state);
3883 ok(sink.state == State_Running, "Got state %u.\n", sink.state);
3884 ok(source.state == State_Running, "Got state %u.\n", source.state);
3885
3886 hr = IMediaFilter_Stop(filter);
3887 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3888 ok(sink.state == State_Stopped, "Got state %u.\n", sink.state);
3889 ok(source.state == State_Stopped, "Got state %u.\n", source.state);
3890
3891 source.expect_run_prev = sink.expect_run_prev = State_Paused;
3892
3893 /* Test VFW_S_CANT_CUE. */
3894
3895 sink.GetState_hr = VFW_S_CANT_CUE;
3896 hr = IMediaControl_Pause(control);
3897 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3898
3899 hr = IMediaControl_GetState(control, 0, &state);
3900 ok(hr == VFW_S_CANT_CUE, "Got hr %#lx.\n", hr);
3901 ok(state == State_Paused, "Got state %lu.\n", state);
3902
3903 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3904 source.GetState_hr = VFW_S_CANT_CUE;
3905 hr = IMediaControl_GetState(control, 0, &state);
3906 ok(hr == VFW_S_CANT_CUE, "Got hr %#lx.\n", hr);
3907 ok(state == State_Paused, "Got state %lu.\n", state);
3908
3909 sink.GetState_hr = VFW_S_CANT_CUE;
3910 source.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3911 hr = IMediaControl_GetState(control, 0, &state);
3912 ok(hr == VFW_S_CANT_CUE, "Got hr %#lx.\n", hr);
3913 ok(state == State_Paused, "Got state %lu.\n", state);
3914
3915 sink.GetState_hr = source.GetState_hr = S_OK;
3916
3917 hr = IMediaControl_Stop(control);
3918 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3919
3920 sink.state_hr = S_FALSE;
3921 sink.GetState_hr = VFW_S_STATE_INTERMEDIATE;
3922 source.GetState_hr = VFW_S_CANT_CUE;
3923 hr = IMediaControl_Run(control);
3924 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3925 ok(sink.state == State_Running, "Got state %u.\n", sink.state);
3926 ok(source.state == State_Running, "Got state %u.\n", source.state);
3927
3928 hr = IMediaControl_GetState(control, 0, &state);
3929 ok(hr == VFW_S_CANT_CUE, "Got hr %#lx.\n", hr);
3930 ok(state == State_Running, "Got state %lu.\n", state);
3931 ok(sink.state == State_Running, "Got state %u.\n", sink.state);
3932 ok(source.state == State_Running, "Got state %u.\n", source.state);
3933
3934 sink.state_hr = sink.GetState_hr = source.GetState_hr = S_OK;
3935
3936 hr = IMediaControl_Stop(control);
3937 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3938
3939 /* Add and remove a filter while the graph is running. */
3940
3941 hr = IFilterGraph2_AddFilter(graph, &dummy.IBaseFilter_iface, L"dummy");
3942 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3943 ok(dummy.state == State_Stopped, "Got state %#x.\n", dummy.state);
3944
3945 hr = IMediaControl_Pause(control);
3946 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3947 check_filter_state(graph, State_Paused);
3948 ok(dummy.state == State_Paused, "Got state %#x.\n", dummy.state);
3949
3950 hr = IFilterGraph2_RemoveFilter(graph, &dummy.IBaseFilter_iface);
3951 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3952 ok(dummy.state == State_Paused, "Got state %#x.\n", dummy.state);
3953
3954 hr = IFilterGraph2_AddFilter(graph, &dummy.IBaseFilter_iface, L"dummy");
3955 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3956 ok(dummy.state == State_Paused, "Got state %#x.\n", dummy.state);
3957
3958 hr = IMediaControl_Stop(control);
3959 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3960 check_filter_state(graph, State_Stopped);
3961
3962 hr = IFilterGraph2_RemoveFilter(graph, &dummy.IBaseFilter_iface);
3963 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3964 ok(dummy.state == State_Stopped, "Got state %#x.\n", dummy.state);
3965
3966 /* Destroying the graph while it's running stops all filters. */
3967
3968 hr = IMediaControl_Run(control);
3969 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3970 check_filter_state(graph, State_Running);
3971
3972 source.expect_stop_prev = sink.expect_stop_prev = State_Running;
3973 IMediaFilter_Release(filter);
3974 IMediaControl_Release(control);
3975 IMediaSeeking_Release(seeking);
3976 ref = IFilterGraph2_Release(graph);
3977 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3978 ok(source.ref == 1, "Got outstanding refcount %ld.\n", source.ref);
3979 ok(sink.ref == 1, "Got outstanding refcount %ld.\n", sink.ref);
3980 ok(source_pin.ref == 1, "Got outstanding refcount %ld.\n", source_pin.ref);
3981 ok(sink_pin.ref == 1, "Got outstanding refcount %ld.\n", sink_pin.ref);
3982 ok(source.state == State_Stopped, "Got state %u.\n", source.state);
3983 ok(sink.state == State_Stopped, "Got state %u.\n", sink.state);
3984}
@ AM_SEEKING_NoPositioning
Definition: axcore.idl:591
@ AM_SEEKING_AbsolutePositioning
Definition: axcore.idl:592
#define E_FAIL
Definition: ddrawi.h:102
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
#define INFINITE
Definition: serial.h:102
int winetest_interactive
__u16 time
Definition: mkdosfs.c:8
#define check_filter_state(a, b)
Definition: filtergraph.c:3406
struct testfilter * filter
Definition: filtergraph.c:823
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
#define VFW_S_CANT_CUE
Definition: vfwmsgs.h:33
#define VFW_S_STATE_INTERMEDIATE
Definition: vfwmsgs.h:21

Referenced by START_TEST(), and test_connect_pin().

◆ test_graph_builder_connect()

static void test_graph_builder_connect ( void  )
static

Definition at line 2337 of file filtergraph.c.

2338{
2339 static const GUID parser1_clsid = {0x12345678};
2340 static const GUID parser2_clsid = {0x87654321};
2341 AM_MEDIA_TYPE source_types[2] = {{{0}}}, sink_type = {{0}}, parser3_type = {{0}};
2342 struct testpin source_pin, sink_pin, sink2_pin, parser1_pins[3], parser2_pins[2], parser3_pins[2];
2343 struct testfilter source, sink, sink2, parser1, parser2, parser3;
2344 struct testfilter_cf parser1_cf = { {&testfilter_cf_vtbl}, &parser1 };
2345 struct testfilter_cf parser2_cf = { {&testfilter_cf_vtbl}, &parser2 };
2346
2348 REGFILTERPINS2 regpins[2] = {{0}};
2349 REGPINTYPES regtypes = {0};
2350 REGFILTER2 regfilter = {0};
2351 IFilterMapper2 *mapper;
2352 DWORD cookie1, cookie2;
2353 HRESULT hr;
2354 ULONG ref;
2355
2356 memset(&source_types[0].majortype, 0xcc, sizeof(GUID));
2357 memset(&source_types[1].majortype, 0xdd, sizeof(GUID));
2358 memset(&sink_type.majortype, 0x66, sizeof(GUID));
2359 testsource_init(&source_pin, source_types, 2);
2360 source_pin.request_mt = &source_types[1];
2361 testfilter_init(&source, &source_pin, 1);
2362 testsink_init(&sink_pin);
2363 testfilter_init(&sink, &sink_pin, 1);
2364 testsink_init(&sink2_pin);
2365 testfilter_init(&sink2, &sink2_pin, 1);
2366
2367 testsink_init(&parser1_pins[0]);
2368 testsource_init(&parser1_pins[1], &sink_type, 1);
2369 parser1_pins[1].request_mt = &sink_type;
2370 testsource_init(&parser1_pins[2], &sink_type, 1);
2371 parser1_pins[2].request_mt = &sink_type;
2372 testfilter_init(&parser1, parser1_pins, 3);
2373 parser1.pin_count = 2;
2374
2375 testsource_init(&parser2_pins[0], &sink_type, 1);
2376 testsink_init(&parser2_pins[1]);
2377 parser2_pins[0].request_mt = &sink_type;
2378 testfilter_init(&parser2, parser2_pins, 2);
2379
2380 testsink_init(&parser3_pins[0]);
2381 testsource_init(&parser3_pins[1], &sink_type, 1);
2382 parser3_pins[1].request_mt = &parser3_type;
2383 testfilter_init(&parser3, parser3_pins, 2);
2384
2385 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2386 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
2387
2388 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2389 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2390 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2391 IFilterGraph2_Disconnect(graph, source_pin.peer);
2392 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2393
2394 for (source_pin.Connect_hr = 0x00040200; source_pin.Connect_hr <= 0x000402ff;
2395 ++source_pin.Connect_hr)
2396 {
2397 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2398 ok(hr == source_pin.Connect_hr, "Got hr %#lx for Connect() hr %#lx.\n",
2399 hr, source_pin.Connect_hr);
2400 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2401 IFilterGraph2_Disconnect(graph, source_pin.peer);
2402 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2403 }
2404 source_pin.Connect_hr = S_OK;
2405
2406 sink_pin.accept_mt = &sink_type;
2407 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2408 ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#lx.\n", hr);
2409 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
2410
2411 for (source_pin.Connect_hr = 0x80040200; source_pin.Connect_hr <= 0x800402ff;
2412 ++source_pin.Connect_hr)
2413 {
2414 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2415 if (source_pin.Connect_hr == VFW_E_NOT_CONNECTED
2416 || source_pin.Connect_hr == VFW_E_NO_AUDIO_HARDWARE)
2417 ok(hr == source_pin.Connect_hr, "Got hr %#lx for Connect() hr %#lx.\n",
2418 hr, source_pin.Connect_hr);
2419 else
2420 ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#lx for Connect() hr %#lx.\n",
2421 hr, source_pin.Connect_hr);
2422 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
2423 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
2424 }
2425 source_pin.Connect_hr = S_OK;
2426
2427 for (source_pin.EnumMediaTypes_hr = 0x80040200; source_pin.EnumMediaTypes_hr <= 0x800402ff;
2428 ++source_pin.EnumMediaTypes_hr)
2429 {
2430 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2431 ok(hr == source_pin.EnumMediaTypes_hr, "Got hr %#lx for EnumMediaTypes() hr %#lx.\n",
2432 hr, source_pin.EnumMediaTypes_hr);
2433 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
2434 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
2435 }
2436 source_pin.EnumMediaTypes_hr = S_OK;
2437
2438 /* Test usage of intermediate filters. Similarly to Render(), filters are
2439 * simply tried in enumeration order. */
2440
2441 IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, NULL);
2442 IFilterGraph2_AddFilter(graph, &parser2.IBaseFilter_iface, NULL);
2443
2444 sink_pin.accept_mt = NULL;
2445 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2446 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2447 ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2448 IFilterGraph2_Disconnect(graph, source_pin.peer);
2449 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2450
2451 sink_pin.accept_mt = &sink_type;
2452 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2453 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2454 ok(source_pin.peer == &parser2_pins[1].IPin_iface, "Got peer %p.\n", source_pin.peer);
2455 ok(sink_pin.peer == &parser2_pins[0].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2456 IFilterGraph2_Disconnect(graph, source_pin.peer);
2457 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2458 IFilterGraph2_Disconnect(graph, sink_pin.peer);
2459 IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
2460
2461 for (source_pin.Connect_hr = 0x00040200; source_pin.Connect_hr <= 0x000402ff;
2462 ++source_pin.Connect_hr)
2463 {
2464 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2465 ok(hr == S_OK, "Got hr %#lx for Connect() hr %#lx.\n", hr, source_pin.Connect_hr);
2466 ok(source_pin.peer == &parser2_pins[1].IPin_iface, "Got peer %p.\n", source_pin.peer);
2467 ok(sink_pin.peer == &parser2_pins[0].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2468 IFilterGraph2_Disconnect(graph, source_pin.peer);
2469 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2470 IFilterGraph2_Disconnect(graph, sink_pin.peer);
2471 IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
2472 }
2473 source_pin.Connect_hr = S_OK;
2474
2475 IFilterGraph2_RemoveFilter(graph, &parser1.IBaseFilter_iface);
2476 IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, NULL);
2477
2478 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2479 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2480 ok(source_pin.peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2481 ok(sink_pin.peer == &parser1_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2482 IFilterGraph2_Disconnect(graph, source_pin.peer);
2483 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2484 IFilterGraph2_Disconnect(graph, sink_pin.peer);
2485 IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
2486
2487 /* No preference is given to smaller chains. */
2488
2489 IFilterGraph2_AddFilter(graph, &parser3.IBaseFilter_iface, NULL);
2490 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2491 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2492 ok(source_pin.peer == &parser3_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2493 ok(parser3_pins[1].peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", parser3_pins[1].peer);
2494 ok(sink_pin.peer == &parser1_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2495 IFilterGraph2_Disconnect(graph, source_pin.peer);
2496 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2497 IFilterGraph2_Disconnect(graph, parser3_pins[0].peer);
2498 IFilterGraph2_Disconnect(graph, &parser3_pins[0].IPin_iface);
2499 IFilterGraph2_Disconnect(graph, sink_pin.peer);
2500 IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
2501
2502 IFilterGraph2_RemoveFilter(graph, &parser3.IBaseFilter_iface);
2503 IFilterGraph2_RemoveFilter(graph, &parser2.IBaseFilter_iface);
2504
2505 /* Extra source pins on an intermediate filter are not rendered. */
2506
2507 IFilterGraph2_RemoveFilter(graph, &parser1.IBaseFilter_iface);
2508 parser1.pin_count = 3;
2509 IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, NULL);
2510 IFilterGraph2_AddFilter(graph, &sink2.IBaseFilter_iface, NULL);
2511
2512 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2513 todo_wine ok(hr == VFW_S_PARTIAL_RENDER, "Got hr %#lx.\n", hr);
2514 ok(source_pin.peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2515 ok(sink_pin.peer == &parser1_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2516 ok(!parser1_pins[2].peer, "Got peer %p.\n", parser1_pins[2].peer);
2517 IFilterGraph2_Disconnect(graph, source_pin.peer);
2518 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2519 IFilterGraph2_Disconnect(graph, sink_pin.peer);
2520 IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
2521 parser1.pin_count = 2;
2522
2523 /* QueryInternalConnections is not used to find output pins. */
2524
2525 parser1_pins[1].QueryInternalConnections_hr = S_OK;
2526 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2527 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2528 ok(source_pin.peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2529 ok(sink_pin.peer == &parser1_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2530 IFilterGraph2_Disconnect(graph, source_pin.peer);
2531 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2532 IFilterGraph2_Disconnect(graph, sink_pin.peer);
2533 IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
2534 parser1_pins[1].QueryInternalConnections_hr = E_NOTIMPL;
2535
2536 /* A pin whose name (not ID) begins with a tilde is not connected. */
2537
2538 parser1_pins[1].name[0] = '~';
2539 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2540 ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#lx.\n", hr);
2541 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
2542
2543 parser1.pin_count = 3;
2544 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2545 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2546 ok(source_pin.peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2547 ok(sink_pin.peer == &parser1_pins[2].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2548 IFilterGraph2_Disconnect(graph, source_pin.peer);
2549 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2550 IFilterGraph2_Disconnect(graph, sink_pin.peer);
2551 IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
2552 parser1.pin_count = 2;
2553
2554 parser1_pins[1].name[0] = 0;
2555 parser1_pins[1].id[0] = '~';
2556 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2557 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2558 ok(source_pin.peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2559 ok(sink_pin.peer == &parser1_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2560 IFilterGraph2_Disconnect(graph, source_pin.peer);
2561 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2562 IFilterGraph2_Disconnect(graph, sink_pin.peer);
2563 IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
2564
2565 hr = IFilterGraph2_Connect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface);
2566 ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#lx.\n", hr);
2567
2568 parser1_pins[0].QueryInternalConnections_hr = S_OK;
2569 hr = IFilterGraph2_Connect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface);
2570 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
2571 parser1_pins[0].QueryInternalConnections_hr = E_NOTIMPL;
2572
2573 ref = IFilterGraph2_Release(graph);
2574 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2575
2576 /* The graph connects from source to sink, not from sink to source. */
2577
2578 graph = create_graph();
2579 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, L"source");
2580 IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, L"parser");
2581 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, L"sink");
2582
2583 parser1_pins[0].require_connected_pin = &parser1_pins[1];
2584
2585 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2586 ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#lx.\n", hr);
2587 ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
2588 ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
2589
2590 parser1_pins[0].require_connected_pin = NULL;
2591 parser1_pins[1].require_connected_pin = &parser1_pins[0];
2592
2593 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2594 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2595 ok(source_pin.peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2596 ok(sink_pin.peer == &parser1_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2597
2598 parser1_pins[1].require_connected_pin = NULL;
2599
2600 ref = IFilterGraph2_Release(graph);
2601 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2602
2603 /* Test enumeration of filters from the registry. */
2604
2605 graph = create_graph();
2606 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2607 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
2608
2609 CoRegisterClassObject(&parser1_clsid, (IUnknown *)&parser1_cf.IClassFactory_iface,
2610 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie1);
2611 CoRegisterClassObject(&parser2_clsid, (IUnknown *)&parser2_cf.IClassFactory_iface,
2612 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie2);
2613
2614 CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
2615 &IID_IFilterMapper2, (void **)&mapper);
2616
2617 regfilter.dwVersion = 2;
2618 regfilter.dwMerit = MERIT_UNLIKELY;
2619 regfilter.cPins2 = 2;
2620 regfilter.rgPins2 = regpins;
2621 regpins[0].dwFlags = 0;
2622 regpins[0].cInstances = 1;
2623 regpins[0].nMediaTypes = 1;
2624 regpins[0].lpMediaType = &regtypes;
2625 regpins[1].dwFlags = REG_PINFLAG_B_OUTPUT;
2626 regpins[1].cInstances = 1;
2627 regpins[1].nMediaTypes = 1;
2628 regpins[1].lpMediaType = &regtypes;
2629 regtypes.clsMajorType = &source_types[1].majortype;
2630 regtypes.clsMinorType = &MEDIASUBTYPE_NULL;
2631 hr = IFilterMapper2_RegisterFilter(mapper, &parser1_clsid, L"test", NULL, NULL, NULL, &regfilter);
2632 if (hr == E_ACCESSDENIED)
2633 {
2634 skip("Not enough permission to register filters.\n");
2635 goto out;
2636 }
2637 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2638
2639 IFilterMapper2_RegisterFilter(mapper, &parser2_clsid, L"test", NULL, NULL, NULL, &regfilter);
2640
2641 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2642 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2643 ok(source_pin.peer == &parser1_pins[0].IPin_iface
2644 || source_pin.peer == &parser2_pins[1].IPin_iface, "Got peer %p.\n", source_pin.peer);
2645 ok(sink_pin.peer == &parser1_pins[1].IPin_iface
2646 || sink_pin.peer == &parser2_pins[0].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2647
2648 ref = IFilterGraph2_Release(graph);
2649 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2650
2651 /* Preference is given to filters already in the graph. */
2652
2653 graph = create_graph();
2654 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2655 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
2656 IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, NULL);
2657
2658 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2659 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2660 ok(source_pin.peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2661 ok(sink_pin.peer == &parser1_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2662
2663 ref = IFilterGraph2_Release(graph);
2664 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2665
2666 /* Preference is given to filters with higher merit. */
2667
2668 graph = create_graph();
2669 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2670 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
2671
2672 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &parser1_clsid);
2673 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &parser2_clsid);
2674
2675 regfilter.dwMerit = MERIT_UNLIKELY;
2676 IFilterMapper2_RegisterFilter(mapper, &parser1_clsid, L"test", NULL, NULL, NULL, &regfilter);
2677 regfilter.dwMerit = MERIT_PREFERRED;
2678 IFilterMapper2_RegisterFilter(mapper, &parser2_clsid, L"test", NULL, NULL, NULL, &regfilter);
2679
2680 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2682 ok(source_pin.peer == &parser2_pins[1].IPin_iface, "Got peer %p.\n", source_pin.peer);
2683 ok(sink_pin.peer == &parser2_pins[0].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2684
2685 ref = IFilterGraph2_Release(graph);
2686 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2687
2688 graph = create_graph();
2689 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2690 IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL);
2691
2692 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &parser1_clsid);
2693 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &parser2_clsid);
2694
2695 regfilter.dwMerit = MERIT_PREFERRED;
2696 IFilterMapper2_RegisterFilter(mapper, &parser1_clsid, L"test", NULL, NULL, NULL, &regfilter);
2697 regfilter.dwMerit = MERIT_UNLIKELY;
2698 IFilterMapper2_RegisterFilter(mapper, &parser2_clsid, L"test", NULL, NULL, NULL, &regfilter);
2699
2700 hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
2701 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2702 ok(source_pin.peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2703 ok(sink_pin.peer == &parser1_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
2704
2705 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &parser1_clsid);
2706 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &parser2_clsid);
2707
2708out:
2709 CoRevokeClassObject(cookie1);
2710 CoRevokeClassObject(cookie2);
2711 IFilterMapper2_Release(mapper);
2712 ref = IFilterGraph2_Release(graph);
2713 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2714 ok(source.ref == 1, "Got outstanding refcount %ld.\n", source.ref);
2715 ok(source_pin.ref == 1, "Got outstanding refcount %ld.\n", source_pin.ref);
2716 ok(sink.ref == 1, "Got outstanding refcount %ld.\n", sink.ref);
2717 ok(sink_pin.ref == 1, "Got outstanding refcount %ld.\n", sink_pin.ref);
2718 ok(parser1.ref == 1, "Got outstanding refcount %ld.\n", parser1.ref);
2719 ok(parser1_pins[0].ref == 1, "Got outstanding refcount %ld.\n", parser1_pins[0].ref);
2720 ok(parser1_pins[1].ref == 1, "Got outstanding refcount %ld.\n", parser1_pins[1].ref);
2721 ok(parser1_pins[2].ref == 1, "Got outstanding refcount %ld.\n", parser1_pins[2].ref);
2722 ok(parser2.ref == 1, "Got outstanding refcount %ld.\n", parser2.ref);
2723 ok(parser2_pins[0].ref == 1, "Got outstanding refcount %ld.\n", parser2_pins[0].ref);
2724 ok(parser2_pins[1].ref == 1, "Got outstanding refcount %ld.\n", parser2_pins[1].ref);
2725 ok(parser3.ref == 1, "Got outstanding refcount %ld.\n", parser3.ref);
2726 ok(parser3_pins[0].ref == 1, "Got outstanding refcount %ld.\n", parser3_pins[0].ref);
2727 ok(parser3_pins[1].ref == 1, "Got outstanding refcount %ld.\n", parser3_pins[1].ref);
2728}
REGPINTYPES
Definition: axextend.idl:194
@ REG_PINFLAG_B_OUTPUT
Definition: axextend.idl:221
#define memset(x, y, z)
Definition: compat.h:39
DWORD dwVersion
Definition: axextend.idl:238
DWORD dwMerit
Definition: axextend.idl:239
const REGFILTERPINS2 * rgPins2
Definition: axextend.idl:253
ULONG cPins2
Definition: axextend.idl:252
const REGPINTYPES * lpMediaType
Definition: axextend.idl:230
char * name
Definition: wpp.c:52
IClassFactory IClassFactory_iface
Definition: filtergraph.c:2024
#define MEDIASUBTYPE_NULL
Definition: uuids.h:25
#define VFW_S_PARTIAL_RENDER
Definition: vfwmsgs.h:22
#define VFW_E_CANNOT_CONNECT
Definition: vfwmsgs.h:62
#define E_ACCESSDENIED
Definition: winerror.h:4116

Referenced by START_TEST().

◆ test_graph_builder_connect_file()

static HRESULT test_graph_builder_connect_file ( WCHAR *  filename,
BOOL  audio,
BOOL  video 
)
static

Definition at line 555 of file filtergraph.c.

556{
557 IBaseFilter *source_filter, *renderer;
558 IPin *pin_in, *pin_out;
560 IEnumPins *enumpins;
561 HRESULT hr;
562
563 if (video)
564 hr = CoCreateInstance(&CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
565 &IID_IBaseFilter, (void **)&renderer);
566 else
567 hr = CoCreateInstance(&CLSID_AudioRender, NULL, CLSCTX_INPROC_SERVER,
568 &IID_IBaseFilter, (void **)&renderer);
571 ok(hr == S_OK, "Got hr %#lx.\n", hr);
572
574
575 IBaseFilter_EnumPins(renderer, &enumpins);
576 IEnumPins_Next(enumpins, 1, &pin_in, NULL);
577 IEnumPins_Release(enumpins);
578
579 hr = IFilterGraph2_AddSourceFilter(graph, filename, NULL, &source_filter);
580 ok(hr == S_OK, "Got hr %#lx.\n", hr);
581
582 hr = IFilterGraph2_AddFilter(graph, renderer, NULL);
583 ok(hr == S_OK, "Got hr %#lx.\n", hr);
584
585 hr = IBaseFilter_FindPin(source_filter, L"Output", &pin_out);
586 ok(hr == S_OK, "Got hr %#lx.\n", hr);
587 hr = IFilterGraph2_Connect(graph, pin_out, pin_in);
588
589 if (SUCCEEDED(hr))
590 rungraph(graph, video);
591
592 IPin_Release(pin_in);
593 IPin_Release(pin_out);
594 IBaseFilter_Release(source_filter);
595 IBaseFilter_Release(renderer);
596 IFilterGraph2_Release(graph);
597
598 return hr;
599}

Referenced by test_render_run().

◆ test_graph_builder_render()

static void test_graph_builder_render ( void  )
static

Definition at line 2090 of file filtergraph.c.

2091{
2092 static const GUID sink1_clsid = {0x12345678};
2093 static const GUID sink2_clsid = {0x87654321};
2094 AM_MEDIA_TYPE source_type = {{0}};
2095 struct testpin source_pin, sink1_pin, sink2_pin, parser_pins[2];
2096 struct testfilter source, sink1, sink2, parser;
2097 struct testfilter_cf sink1_cf = { {&testfilter_cf_vtbl}, &sink1 };
2098 struct testfilter_cf sink2_cf = { {&testfilter_cf_vtbl}, &sink2 };
2099
2101 REGFILTERPINS2 regpins = {0};
2102 REGPINTYPES regtypes = {0};
2103 REGFILTER2 regfilter = {0};
2104 IFilterMapper2 *mapper;
2105 DWORD cookie1, cookie2;
2106 HRESULT hr;
2107 ULONG ref;
2108
2109 memset(&source_type.majortype, 0xcc, sizeof(GUID));
2110 testsource_init(&source_pin, &source_type, 1);
2111 testfilter_init(&source, &source_pin, 1);
2112 testsink_init(&sink1_pin);
2113 testfilter_init(&sink1, &sink1_pin, 1);
2114 testsink_init(&sink2_pin);
2115 testfilter_init(&sink2, &sink2_pin, 1);
2116 testsink_init(&parser_pins[0]);
2117 testsource_init(&parser_pins[1], &source_type, 1);
2118 testfilter_init(&parser, parser_pins, 2);
2119
2120 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2121 IFilterGraph2_AddFilter(graph, &sink1.IBaseFilter_iface, NULL);
2122 IFilterGraph2_AddFilter(graph, &sink2.IBaseFilter_iface, NULL);
2123
2124 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2125 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2126 ok(source_pin.peer == &sink2_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2127 IFilterGraph2_Disconnect(graph, source_pin.peer);
2128 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2129
2130 IFilterGraph2_RemoveFilter(graph, &sink1.IBaseFilter_iface);
2131 IFilterGraph2_AddFilter(graph, &sink1.IBaseFilter_iface, NULL);
2132
2133 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2134 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2135 ok(source_pin.peer == &sink1_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2136
2137 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2138 IFilterGraph2_Disconnect(graph, &sink1_pin.IPin_iface);
2139
2140 /* No preference is given to smaller chains. */
2141
2142 IFilterGraph2_AddFilter(graph, &parser.IBaseFilter_iface, NULL);
2143
2144 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2145 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2146 ok(source_pin.peer == &parser_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2147 ok(parser_pins[1].peer == &sink1_pin.IPin_iface, "Got peer %p.\n", parser_pins[1].peer);
2148 IFilterGraph2_Disconnect(graph, source_pin.peer);
2149 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2150 IFilterGraph2_Disconnect(graph, parser_pins[0].peer);
2151 IFilterGraph2_Disconnect(graph, &parser_pins[0].IPin_iface);
2152
2153 IFilterGraph2_RemoveFilter(graph, &sink1.IBaseFilter_iface);
2154 IFilterGraph2_AddFilter(graph, &sink1.IBaseFilter_iface, NULL);
2155
2156 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2157 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2158 ok(source_pin.peer == &sink1_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2159 IFilterGraph2_Disconnect(graph, source_pin.peer);
2160 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2161
2162 /* A pin whose name (not ID) begins with a tilde is not rendered. */
2163
2164 IFilterGraph2_RemoveFilter(graph, &sink2.IBaseFilter_iface);
2165 IFilterGraph2_RemoveFilter(graph, &parser.IBaseFilter_iface);
2166 IFilterGraph2_AddFilter(graph, &parser.IBaseFilter_iface, NULL);
2167
2168 parser_pins[1].name[0] = '~';
2169 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2170 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2171 ok(source_pin.peer == &parser_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2172 ok(!parser_pins[1].peer, "Got peer %p.\n", parser_pins[1].peer);
2173 ok(!sink1_pin.peer, "Got peer %p.\n", sink1_pin.peer);
2174 IFilterGraph2_Disconnect(graph, source_pin.peer);
2175 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2176
2177 parser_pins[1].name[0] = 0;
2178 parser_pins[1].id[0] = '~';
2179 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2180 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2181 ok(source_pin.peer == &parser_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
2182 ok(parser_pins[1].peer == &sink1_pin.IPin_iface, "Got peer %p.\n", parser_pins[1].peer);
2183 IFilterGraph2_Disconnect(graph, source_pin.peer);
2184 IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
2185
2186 ref = IFilterGraph2_Release(graph);
2187 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2188
2189 /* Test enumeration of filters from the registry. */
2190
2191 CoRegisterClassObject(&sink1_clsid, (IUnknown *)&sink1_cf.IClassFactory_iface,
2192 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie1);
2193 CoRegisterClassObject(&sink2_clsid, (IUnknown *)&sink2_cf.IClassFactory_iface,
2194 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie2);
2195
2196 CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
2197 &IID_IFilterMapper2, (void **)&mapper);
2198
2199 regfilter.dwVersion = 2;
2200 regfilter.dwMerit = MERIT_UNLIKELY;
2201 regfilter.cPins2 = 1;
2202 regfilter.rgPins2 = &regpins;
2203 regpins.dwFlags = 0;
2204 regpins.cInstances = 1;
2205 regpins.nMediaTypes = 1;
2206 regpins.lpMediaType = &regtypes;
2207 regtypes.clsMajorType = &source_type.majortype;
2208 regtypes.clsMinorType = &MEDIASUBTYPE_NULL;
2209 hr = IFilterMapper2_RegisterFilter(mapper, &sink1_clsid, L"test", NULL, NULL, NULL, &regfilter);
2210 if (hr == E_ACCESSDENIED)
2211 {
2212 skip("Not enough permission to register filters.\n");
2213 goto out;
2214 }
2215 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2216
2217 graph = create_graph();
2218 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2219
2221 IFilterMapper2_RegisterFilter(mapper, &sink2_clsid, L"test", NULL, NULL, NULL, &regfilter);
2222
2223 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2224 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2225 ok(source_pin.peer == &sink2_pin.IPin_iface || source_pin.peer == &sink1_pin.IPin_iface,
2226 "Got peer %p.\n", source_pin.peer);
2227
2228 ref = IFilterGraph2_Release(graph);
2229 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2230
2231 /* Preference is given to filters already in the graph. */
2232
2233 graph = create_graph();
2234 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2235 IFilterGraph2_AddFilter(graph, &sink2.IBaseFilter_iface, NULL);
2236
2237 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2238 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2239 ok(source_pin.peer == &sink2_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2240
2241 ref = IFilterGraph2_Release(graph);
2242 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2243
2244 /* No preference is given to renderer filters. */
2245
2246 graph = create_graph();
2247 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2248
2249 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &sink1_clsid);
2250 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &sink2_clsid);
2251
2252 IFilterMapper2_RegisterFilter(mapper, &sink1_clsid, L"test", NULL, NULL, NULL, &regfilter);
2253 regpins.dwFlags = 0;
2254 IFilterMapper2_RegisterFilter(mapper, &sink2_clsid, L"test", NULL, NULL, NULL, &regfilter);
2255
2256 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2257 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2258 ok(source_pin.peer == &sink2_pin.IPin_iface || source_pin.peer == &sink1_pin.IPin_iface,
2259 "Got peer %p.\n", source_pin.peer);
2260
2261 ref = IFilterGraph2_Release(graph);
2262 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2263
2264 /* Preference is given to filters with higher merit. */
2265
2266 graph = create_graph();
2267 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2268
2269 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &sink1_clsid);
2270 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &sink2_clsid);
2271
2272 regfilter.dwMerit = MERIT_UNLIKELY;
2273 IFilterMapper2_RegisterFilter(mapper, &sink1_clsid, L"test", NULL, NULL, NULL, &regfilter);
2274 regfilter.dwMerit = MERIT_PREFERRED;
2275 IFilterMapper2_RegisterFilter(mapper, &sink2_clsid, L"test", NULL, NULL, NULL, &regfilter);
2276
2277 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2278 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2279 ok(source_pin.peer == &sink2_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2280
2281 ref = IFilterGraph2_Release(graph);
2282 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2283
2284 graph = create_graph();
2285 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2286
2287 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &sink1_clsid);
2288 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &sink2_clsid);
2289
2290 regfilter.dwMerit = MERIT_PREFERRED;
2291 IFilterMapper2_RegisterFilter(mapper, &sink1_clsid, L"test", NULL, NULL, NULL, &regfilter);
2292 regfilter.dwMerit = MERIT_UNLIKELY;
2293 IFilterMapper2_RegisterFilter(mapper, &sink2_clsid, L"test", NULL, NULL, NULL, &regfilter);
2294
2295 hr = IFilterGraph2_Render(graph, &source_pin.IPin_iface);
2296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2297 ok(source_pin.peer == &sink1_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2298
2299 ref = IFilterGraph2_Release(graph);
2300 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2301
2302 /* Test AM_RENDEREX_RENDERTOEXISTINGRENDERERS. */
2303
2304 graph = create_graph();
2305 IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL);
2306
2307 hr = IFilterGraph2_RenderEx(graph, &source_pin.IPin_iface, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);
2308 ok(hr == VFW_E_CANNOT_RENDER, "Got hr %#lx.\n", hr);
2309
2310 IFilterGraph2_AddFilter(graph, &sink1.IBaseFilter_iface, NULL);
2311
2312 hr = IFilterGraph2_RenderEx(graph, &source_pin.IPin_iface, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);
2313 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2314 ok(source_pin.peer == &sink1_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
2315
2316 ref = IFilterGraph2_Release(graph);
2317 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2318
2319 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &sink1_clsid);
2320 IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &sink2_clsid);
2321
2322out:
2323 CoRevokeClassObject(cookie1);
2324 CoRevokeClassObject(cookie2);
2325 IFilterMapper2_Release(mapper);
2326 ok(source.ref == 1, "Got outstanding refcount %ld.\n", source.ref);
2327 ok(source_pin.ref == 1, "Got outstanding refcount %ld.\n", source_pin.ref);
2328 ok(sink1.ref == 1, "Got outstanding refcount %ld.\n", sink1.ref);
2329 ok(sink1_pin.ref == 1, "Got outstanding refcount %ld.\n", sink1_pin.ref);
2330 ok(sink2.ref == 1, "Got outstanding refcount %ld.\n", sink2.ref);
2331 ok(sink2_pin.ref == 1, "Got outstanding refcount %ld.\n", sink2_pin.ref);
2332 ok(parser.ref == 1, "Got outstanding refcount %ld.\n", parser.ref);
2333 ok(parser_pins[0].ref == 1, "Got outstanding refcount %ld.\n", parser_pins[0].ref);
2334 ok(parser_pins[1].ref == 1, "Got outstanding refcount %ld.\n", parser_pins[1].ref);
2335}
@ REG_PINFLAG_B_RENDERER
Definition: axextend.idl:219
@ AM_RENDEREX_RENDERTOEXISTINGRENDERERS
Definition: axextend.idl:860
Definition: import.c:81
#define VFW_E_CANNOT_RENDER
Definition: vfwmsgs.h:63

Referenced by START_TEST().

◆ test_graph_seeking()

static void test_graph_seeking ( void  )
static

Definition at line 4459 of file filtergraph.c.

4460{
4461 struct testfilter filter1, filter2;
4462
4463 LONGLONG time, current, stop, earliest, latest;
4465 IMediaEventSink *eventsink;
4466 IMediaControl *control;
4467 IMediaSeeking *seeking;
4469 unsigned int i;
4470 double rate;
4471 GUID format;
4472 HRESULT hr;
4473 DWORD caps;
4474 ULONG ref;
4475
4476 static const GUID *const all_formats[] =
4477 {
4478 NULL,
4479 &TIME_FORMAT_NONE,
4480 &TIME_FORMAT_FRAME,
4481 &TIME_FORMAT_SAMPLE,
4482 &TIME_FORMAT_FIELD,
4483 &TIME_FORMAT_BYTE,
4484 &TIME_FORMAT_MEDIA_TIME,
4485 &testguid,
4486 };
4487
4488 static const GUID *const unsupported_formats[] =
4489 {
4490 &TIME_FORMAT_FRAME,
4491 &TIME_FORMAT_SAMPLE,
4492 &TIME_FORMAT_FIELD,
4493 &TIME_FORMAT_BYTE,
4494 &testguid,
4495 };
4496
4497 testfilter_init(&filter1, NULL, 0);
4498 testfilter_init(&filter2, NULL, 0);
4499
4500 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
4501 IFilterGraph2_QueryInterface(graph, &IID_IMediaSeeking, (void **)&seeking);
4502 IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
4503 IFilterGraph2_QueryInterface(graph, &IID_IMediaEventSink, (void **)&eventsink);
4504
4505 hr = IMediaSeeking_GetCapabilities(seeking, &caps);
4506 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4507 todo_wine ok(!caps, "Got caps %#lx.\n", caps);
4508
4509 caps = 0;
4510 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
4511 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
4512 ok(!caps, "Got caps %#lx.\n", caps);
4513
4515 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
4516 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
4517 todo_wine ok(!caps, "Got caps %#lx.\n", caps);
4518
4519 hr = IMediaSeeking_IsFormatSupported(seeking, NULL);
4520 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4521
4522 for (i = 0; i < ARRAY_SIZE(all_formats); ++i)
4523 {
4524 hr = IMediaSeeking_IsFormatSupported(seeking, all_formats[i]);
4525 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx for format %s.\n", hr, wine_dbgstr_guid(all_formats[i]));
4526 }
4527
4528 hr = IMediaSeeking_QueryPreferredFormat(seeking, NULL);
4529 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4530 hr = IMediaSeeking_QueryPreferredFormat(seeking, &format);
4531 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4532 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4533
4534 hr = IMediaSeeking_GetTimeFormat(seeking, NULL);
4535 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4536 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
4537 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4538 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4539
4540 hr = IMediaSeeking_IsUsingTimeFormat(seeking, NULL);
4541 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4542 hr = IMediaSeeking_IsUsingTimeFormat(seeking, &TIME_FORMAT_MEDIA_TIME);
4543 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4544 hr = IMediaSeeking_IsUsingTimeFormat(seeking, &TIME_FORMAT_NONE);
4545 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
4546
4547 hr = IMediaSeeking_SetTimeFormat(seeking, &TIME_FORMAT_NONE);
4548 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4549
4550 hr = IMediaSeeking_QueryPreferredFormat(seeking, &format);
4551 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4552 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4553
4554 hr = IMediaSeeking_IsUsingTimeFormat(seeking, &TIME_FORMAT_MEDIA_TIME);
4555 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4556 hr = IMediaSeeking_IsUsingTimeFormat(seeking, &TIME_FORMAT_NONE);
4557 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
4558
4559 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
4560 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4561 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4562
4563 hr = IMediaSeeking_SetTimeFormat(seeking, &TIME_FORMAT_MEDIA_TIME);
4564 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4565
4566 for (i = 0; i < ARRAY_SIZE(unsupported_formats); ++i)
4567 {
4568 hr = IMediaSeeking_SetTimeFormat(seeking, unsupported_formats[i]);
4569 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx for format %s.\n", hr, wine_dbgstr_guid(unsupported_formats[i]));
4570 }
4571
4572 time = 0xdeadbeef;
4573 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, NULL, 0x123456789a, NULL);
4574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4575 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
4576
4577 time = 0xdeadbeef;
4578 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &TIME_FORMAT_MEDIA_TIME, 0x123456789a, NULL);
4579 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4580 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
4581
4582 time = 0xdeadbeef;
4583 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, NULL, 0x123456789a, &TIME_FORMAT_MEDIA_TIME);
4584 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4585 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
4586
4587 time = 0xdeadbeef;
4588 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &TIME_FORMAT_MEDIA_TIME, 0x123456789a, &TIME_FORMAT_MEDIA_TIME);
4589 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4590 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
4591
4592 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &TIME_FORMAT_NONE, 0x123456789a, &TIME_FORMAT_MEDIA_TIME);
4593 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4594 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &TIME_FORMAT_NONE, 0x123456789a, NULL);
4595 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4596 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &TIME_FORMAT_MEDIA_TIME, 0x123456789a, &TIME_FORMAT_NONE);
4597 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4598 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, NULL, 0x123456789a, &TIME_FORMAT_NONE);
4599 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4600
4601 time = 0xdeadbeef;
4602 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &TIME_FORMAT_NONE, 0x123456789a, &TIME_FORMAT_NONE);
4603 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4604 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
4605
4606 time = 0xdeadbeef;
4607 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &testguid, 0x123456789a, &testguid);
4608 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4609 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
4610
4611 hr = IMediaSeeking_GetDuration(seeking, NULL);
4612 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4613 hr = IMediaSeeking_GetDuration(seeking, &time);
4614 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4615
4616 hr = IMediaSeeking_GetStopPosition(seeking, NULL);
4617 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4618 hr = IMediaSeeking_GetStopPosition(seeking, &time);
4619 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4620
4621 hr = IMediaSeeking_SetPositions(seeking, &current, 0, &stop, 0);
4622 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4623
4624 hr = IMediaSeeking_GetPositions(seeking, NULL, NULL);
4625 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4626 hr = IMediaSeeking_GetPositions(seeking, NULL, &stop);
4627 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4628 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
4629 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4630 current = 0xdeadbeef;
4631 hr = IMediaSeeking_GetPositions(seeking, &current, NULL);
4632 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4633 ok(!current, "Got time %s.\n", wine_dbgstr_longlong(time));
4634
4635 hr = IMediaSeeking_GetCurrentPosition(seeking, NULL);
4636 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4637 current = 0xdeadbeef;
4638 hr = IMediaSeeking_GetCurrentPosition(seeking, &current);
4639 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4640 ok(!current, "Got time %s.\n", wine_dbgstr_longlong(time));
4641
4642 hr = IMediaSeeking_GetAvailable(seeking, &earliest, &latest);
4643 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4644
4645 hr = IMediaSeeking_SetRate(seeking, 1.0);
4646 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4647 hr = IMediaSeeking_SetRate(seeking, 2.0);
4648 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4649
4650 hr = IMediaSeeking_GetRate(seeking, &rate);
4651 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4652 ok(rate == 1.0, "Got rate %.16e.\n", rate);
4653
4654 hr = IMediaSeeking_GetPreroll(seeking, &time);
4655 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4656
4657 /* Try with filters added. Note that a filter need only expose
4658 * IMediaSeeking—no other heuristics are used to determine if it is a
4659 * renderer. */
4660
4661 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4662 filter1.IMediaSeeking_iface.lpVtbl = &testseek_vtbl;
4663 filter1.support_media_time = FALSE;
4664 filter1.support_testguid = TRUE;
4665
4666 hr = IMediaSeeking_GetDuration(seeking, &time);
4667 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4668
4669 hr = IMediaSeeking_SetTimeFormat(seeking, &testguid);
4670 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4671
4672 IFilterGraph2_RemoveFilter(graph, &filter1.IBaseFilter_iface);
4673 filter1.support_media_time = TRUE;
4674 filter1.support_testguid = FALSE;
4675
4676 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
4677 IFilterGraph2_AddFilter(graph, &filter2.IBaseFilter_iface, NULL);
4678 filter1.IMediaSeeking_iface.lpVtbl = &testseek_vtbl;
4679 filter2.IMediaSeeking_iface.lpVtbl = &testseek_vtbl;
4680
4683 hr = IMediaSeeking_GetCapabilities(seeking, &caps);
4684 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4685 ok(caps == AM_SEEKING_CanDoSegments, "Got caps %#lx.\n", caps);
4686 ok(filter1.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4687 ok(filter2.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter2.seeking_ref);
4688
4689 flush_cached_seeking(graph, &filter1);
4690 flush_cached_seeking(graph, &filter2);
4691
4693 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
4694 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
4695 ok(caps == AM_SEEKING_CanDoSegments, "Got caps %#lx.\n", caps);
4696
4698 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
4699 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4700 ok(caps == AM_SEEKING_CanDoSegments, "Got caps %#lx.\n", caps);
4701
4703 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
4704 ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
4705 ok(!caps, "Got caps %#lx.\n", caps);
4706
4707 flush_cached_seeking(graph, &filter1);
4708 flush_cached_seeking(graph, &filter2);
4709
4710 hr = IMediaSeeking_IsFormatSupported(seeking, &testguid);
4711 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
4712
4713 filter1.support_testguid = TRUE;
4714 hr = IMediaSeeking_IsFormatSupported(seeking, &testguid);
4715 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4716
4717 filter1.support_testguid = FALSE;
4718 filter2.support_testguid = TRUE;
4719 hr = IMediaSeeking_IsFormatSupported(seeking, &testguid);
4720 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4721
4722 /* Filters are not consulted about preferred formats. */
4723 hr = IMediaSeeking_QueryPreferredFormat(seeking, &format);
4724 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4725 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4726
4727 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
4728 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4729 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4730
4731 filter2.support_testguid = FALSE;
4732 hr = IMediaSeeking_SetTimeFormat(seeking, &testguid);
4733 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
4734
4735 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
4736 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4737 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4738
4739 filter1.support_testguid = TRUE;
4740 hr = IMediaSeeking_SetTimeFormat(seeking, &testguid);
4741 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4742 todo_wine ok(IsEqualGUID(&filter1.time_format, &testguid), "Got format %s.\n",
4743 debugstr_guid(&filter1.time_format));
4744 ok(IsEqualGUID(&filter2.time_format, &TIME_FORMAT_MEDIA_TIME),
4745 "Got format %s.\n", debugstr_guid(&filter2.time_format));
4746
4747 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
4748 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4749 todo_wine ok(IsEqualGUID(&format, &testguid), "Got format %s.\n", wine_dbgstr_guid(&format));
4750
4751 hr = IMediaSeeking_QueryPreferredFormat(seeking, &format);
4752 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4753 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4754
4755 hr = IMediaSeeking_IsUsingTimeFormat(seeking, &TIME_FORMAT_MEDIA_TIME);
4756 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
4757 hr = IMediaSeeking_IsUsingTimeFormat(seeking, &testguid);
4758 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4759
4760 hr = IMediaSeeking_GetCapabilities(seeking, &caps);
4761 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4762 ok(caps == AM_SEEKING_CanDoSegments, "Got caps %#lx.\n", caps);
4763 ok(filter1.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4764 ok(filter2.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter2.seeking_ref);
4765
4766 filter2.support_testguid = TRUE;
4767 hr = IMediaSeeking_SetTimeFormat(seeking, &testguid);
4768 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4769 ok(IsEqualGUID(&filter1.time_format, &TIME_FORMAT_MEDIA_TIME),
4770 "Got format %s.\n", debugstr_guid(&filter1.time_format));
4771 todo_wine ok(IsEqualGUID(&filter2.time_format, &testguid),
4772 "Got format %s.\n", debugstr_guid(&filter2.time_format));
4773
4774 filter1.support_media_time = FALSE;
4775 flush_cached_seeking(graph, &filter1);
4776
4777 hr = IMediaSeeking_GetCapabilities(seeking, &caps);
4778 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4779 ok(caps == (AM_SEEKING_CanDoSegments | AM_SEEKING_CanGetDuration), "Got caps %#lx.\n", caps);
4780 ok(!filter1.seeking_ref, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4781 ok(filter2.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter2.seeking_ref);
4782
4783 filter1.support_media_time = TRUE;
4784 filter1.support_testguid = FALSE;
4785 flush_cached_seeking(graph, &filter1);
4786
4787 hr = IMediaSeeking_GetCapabilities(seeking, &caps);
4788 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4789 ok(caps == AM_SEEKING_CanDoSegments, "Got caps %#lx.\n", caps);
4790 ok(filter1.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
4791 ok(filter2.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter2.seeking_ref);
4792
4793 ok(IsEqualGUID(&filter1.time_format, &TIME_FORMAT_MEDIA_TIME),
4794 "Got format %s.\n", debugstr_guid(&filter1.time_format));
4795 todo_wine ok(IsEqualGUID(&filter2.time_format, &testguid),
4796 "Got format %s.\n", debugstr_guid(&filter2.time_format));
4797 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
4798 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4799 todo_wine ok(IsEqualGUID(&format, &testguid), "Got format %s.\n", wine_dbgstr_guid(&format));
4800
4801 hr = IMediaSeeking_SetTimeFormat(seeking, &TIME_FORMAT_NONE);
4802 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4803
4804 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
4805 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4806 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
4807
4808 time = 0xdeadbeef;
4809 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &testguid, 0x123456789a, &testguid);
4810 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4811 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
4812
4813 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &testguid, 0x123456789a, &TIME_FORMAT_NONE);
4814 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4815
4816 flush_cached_seeking(graph, &filter1);
4817 flush_cached_seeking(graph, &filter2);
4818
4819 filter1.seek_duration = 0x12345;
4820 filter2.seek_duration = 0x23456;
4821 hr = IMediaSeeking_GetDuration(seeking, &time);
4822 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4823 ok(time == 0x23456, "Got time %s.\n", wine_dbgstr_longlong(time));
4824
4825 filter2.seek_duration = 0x12345;
4826 filter1.seek_duration = 0x23456;
4827 hr = IMediaSeeking_GetDuration(seeking, &time);
4828 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4829 ok(time == 0x23456, "Got time %s.\n", wine_dbgstr_longlong(time));
4830
4831 filter1.seek_hr = filter2.seek_hr = 0xbeef;
4832 hr = IMediaSeeking_GetDuration(seeking, &time);
4833 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4834 ok(time == 0x23456, "Got time %s.\n", wine_dbgstr_longlong(time));
4835
4836 filter1.seek_hr = E_NOTIMPL;
4837 filter2.seek_hr = S_OK;
4838 hr = IMediaSeeking_GetDuration(seeking, &time);
4839 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4840 ok(time == 0x12345, "Got time %s.\n", wine_dbgstr_longlong(time));
4841
4842 filter1.seek_hr = 0xdeadbeef;
4843 hr = IMediaSeeking_GetDuration(seeking, &time);
4844 ok(hr == 0xdeadbeef, "Got hr %#lx.\n", hr);
4845
4846 filter1.seek_hr = filter2.seek_hr = E_NOTIMPL;
4847 hr = IMediaSeeking_GetDuration(seeking, &time);
4848 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4849 filter1.seek_hr = filter2.seek_hr = S_OK;
4850
4851 flush_cached_seeking(graph, &filter1);
4852 flush_cached_seeking(graph, &filter2);
4853
4854 filter1.seek_stop = 0x54321;
4855 filter2.seek_stop = 0x65432;
4856 hr = IMediaSeeking_GetStopPosition(seeking, &time);
4857 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4858 ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time));
4859
4860 filter2.seek_stop = 0x54321;
4861 filter1.seek_stop = 0x65432;
4862 hr = IMediaSeeking_GetStopPosition(seeking, &time);
4863 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4864 ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time));
4865
4866 filter1.seek_hr = filter2.seek_hr = 0xbeef;
4867 hr = IMediaSeeking_GetStopPosition(seeking, &time);
4868 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4869 ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time));
4870
4871 filter1.seek_hr = E_NOTIMPL;
4872 filter2.seek_hr = S_OK;
4873 hr = IMediaSeeking_GetStopPosition(seeking, &time);
4874 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4875 ok(time == 0x54321, "Got time %s.\n", wine_dbgstr_longlong(time));
4876
4877 filter1.seek_hr = 0xdeadbeef;
4878 hr = IMediaSeeking_GetStopPosition(seeking, &time);
4879 ok(hr == 0xdeadbeef, "Got hr %#lx.\n", hr);
4880
4881 filter1.seek_hr = filter2.seek_hr = E_NOTIMPL;
4882 hr = IMediaSeeking_GetStopPosition(seeking, &time);
4883 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4884 filter1.seek_hr = filter2.seek_hr = S_OK;
4885
4886 flush_cached_seeking(graph, &filter1);
4887 flush_cached_seeking(graph, &filter2);
4888
4889 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
4890 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4891 ok(!time, "Got time %s.\n", wine_dbgstr_longlong(time));
4892
4893 flush_cached_seeking(graph, &filter1);
4894 flush_cached_seeking(graph, &filter2);
4895
4896 current = stop = 0xdeadbeef;
4897 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
4898 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4899 ok(!current, "Got time %s.\n", wine_dbgstr_longlong(current));
4900 ok(stop == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(stop));
4901
4902 flush_cached_seeking(graph, &filter1);
4903 flush_cached_seeking(graph, &filter2);
4904
4905 current = 0x123;
4906 stop = 0x321;
4907 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
4909 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4910 ok(current == 0x123, "Got time %s.\n", wine_dbgstr_longlong(current));
4911 ok(stop == 0x321, "Got time %s.\n", wine_dbgstr_longlong(stop));
4912 ok(filter1.seek_current == 0x123, "Got time %s.\n", wine_dbgstr_longlong(filter1.seek_current));
4913 ok(filter1.seek_stop == 0x321, "Got time %s.\n", wine_dbgstr_longlong(filter1.seek_stop));
4914 ok(filter2.seek_current == 0x123, "Got time %s.\n", wine_dbgstr_longlong(filter2.seek_current));
4915 ok(filter2.seek_stop == 0x321, "Got time %s.\n", wine_dbgstr_longlong(filter2.seek_stop));
4916
4917 filter1.seek_hr = filter2.seek_hr = 0xbeef;
4918 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
4920 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4921
4922 filter1.seek_hr = E_NOTIMPL;
4923 filter2.seek_hr = S_OK;
4924 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
4926 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4927
4928 filter1.seek_hr = 0xdeadbeef;
4929 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
4931 ok(hr == 0xdeadbeef, "Got hr %#lx.\n", hr);
4932
4933 filter1.seek_hr = filter2.seek_hr = E_NOTIMPL;
4934 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
4936 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
4937 filter1.seek_hr = filter2.seek_hr = S_OK;
4938
4939 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
4940 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4941 ok(time == 12340000, "Got time %s.\n", wine_dbgstr_longlong(time));
4942
4943 current = stop = 0xdeadbeef;
4944 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
4945 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4946 ok(current == 12340000, "Got time %s.\n", wine_dbgstr_longlong(current));
4947 ok(stop == 0x321, "Got time %s.\n", wine_dbgstr_longlong(stop));
4948
4949 current = 0x123;
4950 stop = 0x321;
4951 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning | AM_SEEKING_ReturnTime,
4953 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4954 ok(current == 12340000, "Got time %s.\n", wine_dbgstr_longlong(current));
4955 ok(stop == 0x321, "Got time %s.\n", wine_dbgstr_longlong(stop));
4956 ok(filter1.seek_current == 12340000, "Got time %s.\n", wine_dbgstr_longlong(filter1.seek_current));
4957 ok(filter1.seek_stop == 0x321, "Got time %s.\n", wine_dbgstr_longlong(filter1.seek_stop));
4958 ok(filter2.seek_current == 0x123, "Got time %s.\n", wine_dbgstr_longlong(filter2.seek_current));
4959 ok(filter2.seek_stop == 0x321, "Got time %s.\n", wine_dbgstr_longlong(filter2.seek_stop));
4960
4961 current = 0x123;
4962 stop = 0x321;
4963 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
4965 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4966 ok(current == 0x123, "Got time %s.\n", wine_dbgstr_longlong(current));
4967 ok(stop == 43210000, "Got time %s.\n", wine_dbgstr_longlong(stop));
4968 ok(filter1.seek_current == 0x123, "Got time %s.\n", wine_dbgstr_longlong(filter1.seek_current));
4969 ok(filter1.seek_stop == 43210000, "Got time %s.\n", wine_dbgstr_longlong(filter1.seek_stop));
4970 ok(filter2.seek_current == 0x123, "Got time %s.\n", wine_dbgstr_longlong(filter2.seek_current));
4971 ok(filter2.seek_stop == 0x321, "Got time %s.\n", wine_dbgstr_longlong(filter2.seek_stop));
4972
4973 flush_cached_seeking(graph, &filter1);
4974 flush_cached_seeking(graph, &filter2);
4975
4976 hr = IMediaSeeking_SetRate(seeking, 2.0);
4977 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4978 todo_wine ok(filter1.seek_rate == 2.0, "Got rate %.16e.\n", filter1.seek_rate);
4979 todo_wine ok(filter2.seek_rate == 2.0, "Got rate %.16e.\n", filter2.seek_rate);
4980
4981 hr = IMediaSeeking_SetRate(seeking, 1.0);
4982 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4983 todo_wine ok(filter1.seek_rate == 1.0, "Got rate %.16e.\n", filter1.seek_rate);
4984 todo_wine ok(filter2.seek_rate == 1.0, "Got rate %.16e.\n", filter2.seek_rate);
4985
4986 hr = IMediaSeeking_SetRate(seeking, -1.0);
4987 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4988 todo_wine ok(filter1.seek_rate == -1.0, "Got rate %.16e.\n", filter1.seek_rate);
4989 todo_wine ok(filter2.seek_rate == -1.0, "Got rate %.16e.\n", filter2.seek_rate);
4990
4991 flush_cached_seeking(graph, &filter1);
4992 flush_cached_seeking(graph, &filter2);
4993
4994 hr = IMediaSeeking_GetRate(seeking, &rate);
4995 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4996 todo_wine ok(rate == -1.0, "Got rate %.16e.\n", rate);
4997
4998 hr = IMediaSeeking_SetRate(seeking, 1.0);
4999 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5000
5001 /* Test how retrieving the current position behaves while the graph is
5002 * running. Apparently the graph caches the last position returned by
5003 * SetPositions() and then adds the clock offset to the stream start. */
5004
5005 hr = IMediaControl_Run(control);
5006 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5007
5008 /* Note that if the graph is running, it is paused while seeking. */
5009 current = 0;
5010 stop = 9000 * 10000;
5011 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
5013 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5014
5015 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5016 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5017 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
5018 ok(compare_time(time, 1234 * 10000, 40 * 10000),
5019 "Expected about 1234ms, got %s.\n", wine_dbgstr_longlong(time));
5020 current = stop = 0xdeadbeef;
5021 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
5022 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5023 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
5024 ok(compare_time(current, 1234 * 10000, 40 * 10000),
5025 "Expected about 1234ms, got %s.\n", wine_dbgstr_longlong(current));
5026 ok(stop == 9000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
5027
5028 /* This remains true even if NoFlush is specified. */
5029 current = 1000 * 10000;
5030 stop = 8000 * 10000;
5031 hr = IMediaSeeking_SetPositions(seeking, &current,
5034 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5035
5036 Sleep(100);
5037
5038 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5039 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5040 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
5041 ok(compare_time(time, 1334 * 10000, 80 * 10000),
5042 "Expected about 1334ms, got %s.\n", wine_dbgstr_longlong(time));
5043 current = stop = 0xdeadbeef;
5044 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
5045 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5046 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
5047 ok(compare_time(current, 1334 * 10000, 80 * 10000),
5048 "Expected about 1334ms, got %s.\n", wine_dbgstr_longlong(current));
5049 ok(stop == 8000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
5050
5051 hr = IMediaControl_Pause(control);
5052 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5053
5054 Sleep(100);
5055 hr = IMediaControl_Run(control);
5056 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5057
5058 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5059 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5060 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
5061 ok(compare_time(time, 1334 * 10000, 80 * 10000),
5062 "Expected about 1334ms, got %s.\n", wine_dbgstr_longlong(time));
5063 current = stop = 0xdeadbeef;
5064 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
5065 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5066 if (winetest_interactive) /* Timing problems make this test too liable to fail. */
5067 ok(compare_time(current, 1334 * 10000, 80 * 10000),
5068 "Expected about 1334ms, got %s.\n", wine_dbgstr_longlong(current));
5069 ok(stop == 8000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
5070
5071 hr = IMediaControl_Stop(control);
5072 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5073 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5074 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5075 ok(time == 12340000, "Got time %s.\n", wine_dbgstr_longlong(time));
5076
5077 hr = IMediaFilter_SetSyncSource(filter, NULL);
5078 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5079
5080 hr = IMediaControl_Run(control);
5081 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5082
5083 Sleep(100);
5084 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5085 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5086 todo_wine ok(!time, "Got time %s.\n", wine_dbgstr_longlong(time));
5087 current = stop = 0xdeadbeef;
5088 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
5089 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5090 todo_wine ok(!current, "Got time %s.\n", wine_dbgstr_longlong(current));
5091 ok(!stop, "Got time %s.\n", wine_dbgstr_longlong(stop));
5092
5093 hr = IMediaControl_Stop(control);
5094 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5095
5096 /* GetCurrentPositions() will return the stop position once all renderers
5097 * report EC_COMPLETE. Atelier Sophie depends on this behaviour. */
5098
5099 hr = IFilterGraph2_SetDefaultSyncSource(graph);
5100 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5101
5102 filter1.seek_stop = 5000 * 10000;
5103 filter2.seek_stop = 6000 * 10000;
5104
5105 hr = IMediaControl_Run(control);
5106 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5107
5108 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5109 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5110 ok(time < 5000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(time));
5111
5112 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter1.IBaseFilter_iface);
5113 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5114
5115 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5116 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5117 ok(time < 5000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(time));
5118
5119 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter2.IBaseFilter_iface);
5120 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5121
5122 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5123 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5124 ok(time == 6000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(time));
5125
5126 hr = IMediaControl_Stop(control);
5127 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5128
5129 filter1.seek_hr = filter2.seek_hr = E_NOTIMPL;
5130 filter1.seek_stop = filter2.seek_stop = 0xdeadbeef;
5131
5132 hr = IMediaControl_Run(control);
5133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5134
5135 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5136 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5137 ok(time < 5000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(time));
5138
5139 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter1.IBaseFilter_iface);
5140 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5141
5142 hr = IMediaEventSink_Notify(eventsink, EC_COMPLETE, S_OK, (LONG_PTR)&filter2.IBaseFilter_iface);
5143 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5144
5145 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
5146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5147 ok(time == 6000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(time));
5148
5149 hr = IMediaSeeking_SetTimeFormat(seeking, &TIME_FORMAT_MEDIA_TIME);
5150 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5151
5152 hr = IMediaSeeking_SetTimeFormat(seeking, &TIME_FORMAT_NONE);
5153 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
5154
5155 hr = IMediaControl_Stop(control);
5156 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5157
5158 IMediaFilter_Release(filter);
5159 IMediaControl_Release(control);
5160 IMediaSeeking_Release(seeking);
5161 IMediaEventSink_Release(eventsink);
5162
5163 ok(filter1.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
5164 ok(filter2.seeking_ref > 0, "Unexpected seeking refcount %ld.\n", filter2.seeking_ref);
5165
5166 ref = IFilterGraph2_Release(graph);
5167 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5168 ok(filter1.ref == 1, "Got outstanding refcount %ld.\n", filter1.ref);
5169 ok(filter2.ref == 1, "Got outstanding refcount %ld.\n", filter2.ref);
5170 ok(filter1.seeking_ref == 0, "Unexpected seeking refcount %ld.\n", filter1.seeking_ref);
5171 ok(filter2.seeking_ref == 0, "Unexpected seeking refcount %ld.\n", filter2.seeking_ref);
5172}
unsigned int rate
Definition: audiorecord.c:87
@ AM_SEEKING_CanGetDuration
Definition: axcore.idl:609
@ AM_SEEKING_CanGetCurrentPos
Definition: axcore.idl:607
@ AM_SEEKING_CanDoSegments
Definition: axcore.idl:611
@ AM_SEEKING_CanSeekAbsolute
Definition: axcore.idl:604
@ AM_SEEKING_NoFlush
Definition: axcore.idl:599
@ AM_SEEKING_ReturnTime
Definition: axcore.idl:597
struct task_struct * current
Definition: linux.c:32
static BOOL compare_time(ULONGLONG x, ULONGLONG y, unsigned int max_diff)
Definition: filtergraph.c:31
static void flush_cached_seeking(IFilterGraph2 *graph, struct testfilter *filter)
Definition: filtergraph.c:4451
static const GUID testguid
Definition: filtergraph.c:29
int64_t LONGLONG
Definition: typedefs.h:68

Referenced by START_TEST().

◆ test_interfaces()

static void test_interfaces ( void  )
static

Definition at line 97 of file filtergraph.c.

98{
100
101 check_interface(graph, &IID_IBasicAudio, TRUE);
102 check_interface(graph, &IID_IBasicVideo, TRUE);
103 check_interface(graph, &IID_IBasicVideo2, TRUE);
104 check_interface(graph, &IID_IFilterGraph, TRUE);
105 check_interface(graph, &IID_IFilterGraph2, TRUE);
106 check_interface(graph, &IID_IFilterMapper, TRUE);
107 check_interface(graph, &IID_IFilterMapper2, TRUE);
108 check_interface(graph, &IID_IFilterMapper3, TRUE);
109 check_interface(graph, &IID_IGraphBuilder, TRUE);
110 check_interface(graph, &IID_IGraphConfig, TRUE);
111 check_interface(graph, &IID_IGraphVersion, TRUE);
112 check_interface(graph, &IID_IMediaControl, TRUE);
113 check_interface(graph, &IID_IMediaEvent, TRUE);
114 check_interface(graph, &IID_IMediaEventEx, TRUE);
115 check_interface(graph, &IID_IMediaEventSink, TRUE);
116 check_interface(graph, &IID_IMediaFilter, TRUE);
117 check_interface(graph, &IID_IMediaPosition, TRUE);
118 check_interface(graph, &IID_IMediaSeeking, TRUE);
120 check_interface(graph, &IID_IVideoFrameStep, TRUE);
121 check_interface(graph, &IID_IVideoWindow, TRUE);
123
126
127 IFilterGraph2_Release(graph);
128}
const IID IID_IObjectWithSite
#define check_interface(a, b, c)
Definition: filtergraph.c:82
const GUID IID_IDispatch

Referenced by START_TEST().

◆ test_media_event()

static void test_media_event ( IFilterGraph2 *  graph)
static

Definition at line 459 of file filtergraph.c.

460{
461 IMediaEvent *media_event;
462 IMediaSeeking *seeking;
463 IMediaControl *control;
465 LONG_PTR lparam1, lparam2;
466 LONGLONG current, stop;
468 int got_eos = 0;
470 HRESULT hr;
471 LONG code;
472
473 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
474 ok(hr == S_OK, "Got hr %#lx.\n", hr);
475
476 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
477 ok(hr == S_OK, "Got hr %#lx.\n", hr);
478
479 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&media_event);
480 ok(hr == S_OK, "Got hr %#lx.\n", hr);
481
482 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaSeeking, (void **)&seeking);
483 ok(hr == S_OK, "Got hr %#lx.\n", hr);
484
485 hr = IMediaControl_Stop(control);
486 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
487 hr = IMediaControl_GetState(control, 1000, &state);
488 ok(hr == S_OK, "GetState() timed out\n");
489
490 hr = IMediaSeeking_GetDuration(seeking, &stop);
491 ok(hr == S_OK, "Got hr %#lx.\n", hr);
492 current = 0;
493 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning, &stop, AM_SEEKING_AbsolutePositioning);
494 ok(hr == S_OK, "Got hr %#lx.\n", hr);
495
496 hr = IMediaFilter_SetSyncSource(filter, NULL);
497 ok(hr == S_OK, "Got hr %#lx.\n", hr);
498
499 hr = IMediaEvent_GetEventHandle(media_event, (OAEVENT *)&event);
500 ok(hr == S_OK, "Got hr %#lx.\n", hr);
501
502 /* flush existing events */
503 while ((hr = IMediaEvent_GetEvent(media_event, &code, &lparam1, &lparam2, 0)) == S_OK);
504
505 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "event should not be signaled\n");
506
507 hr = IMediaControl_Run(control);
508 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
509
510 while (!got_eos)
511 {
513 break;
514
515 while ((hr = IMediaEvent_GetEvent(media_event, &code, &lparam1, &lparam2, 0)) == S_OK)
516 {
517 if (code == EC_COMPLETE)
518 {
519 got_eos = 1;
520 break;
521 }
522 }
523 }
525 ok(got_eos, "didn't get EOS\n");
526
527 hr = IMediaSeeking_GetCurrentPosition(seeking, &current);
528 ok(hr == S_OK, "Got hr %#lx.\n", hr);
530 ok(current == stop, "expected %s, got %s\n", wine_dbgstr_longlong(stop), wine_dbgstr_longlong(current));
531
532 hr = IMediaControl_Stop(control);
533 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
534 hr = IMediaControl_GetState(control, 1000, &state);
535 ok(hr == S_OK, "GetState() timed out\n");
536
537 hr = IFilterGraph2_SetDefaultSyncSource(graph);
538 ok(hr == S_OK, "Got hr %#lx.\n", hr);
539
540 IMediaSeeking_Release(seeking);
541 IMediaEvent_Release(media_event);
542 IMediaControl_Release(control);
543 IMediaFilter_Release(filter);
544}
#define flaky_wine
Definition: test.h:167

Referenced by rungraph().

◆ test_media_seeking()

static void test_media_seeking ( IFilterGraph2 *  graph)
static

Definition at line 338 of file filtergraph.c.

339{
340 IMediaSeeking *seeking;
342 LONGLONG pos, stop, duration;
343 GUID format;
344 HRESULT hr;
345
346 IFilterGraph2_SetDefaultSyncSource(graph);
347 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaSeeking, (void **)&seeking);
348 ok(hr == S_OK, "Got hr %#lx.\n", hr);
349
350 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
351 ok(hr == S_OK, "Got hr %#lx.\n", hr);
352
354 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
355 ok(hr == S_OK, "Got hr %#lx.\n", hr);
356 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "got %s\n", wine_dbgstr_guid(&format));
357
358 pos = 0xdeadbeef;
359 hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, NULL, 0x123456789a, NULL);
360 ok(hr == S_OK, "Got hr %#lx.\n", hr);
361 ok(pos == 0x123456789a, "got %s\n", wine_dbgstr_longlong(pos));
362
363 pos = 0xdeadbeef;
364 hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, &TIME_FORMAT_MEDIA_TIME, 0x123456789a, NULL);
365 ok(hr == S_OK, "Got hr %#lx.\n", hr);
366 ok(pos == 0x123456789a, "got %s\n", wine_dbgstr_longlong(pos));
367
368 pos = 0xdeadbeef;
369 hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, NULL, 0x123456789a, &TIME_FORMAT_MEDIA_TIME);
370 ok(hr == S_OK, "Got hr %#lx.\n", hr);
371 ok(pos == 0x123456789a, "got %s\n", wine_dbgstr_longlong(pos));
372
373 hr = IMediaSeeking_GetCurrentPosition(seeking, &pos);
374 ok(hr == S_OK, "Got hr %#lx.\n", hr);
375 ok(pos == 0, "got %s\n", wine_dbgstr_longlong(pos));
376
377 hr = IMediaSeeking_GetDuration(seeking, &duration);
378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
379 ok(duration > 0, "got %s\n", wine_dbgstr_longlong(duration));
380
381 hr = IMediaSeeking_GetStopPosition(seeking, &stop);
382 ok(hr == S_OK, "Got hr %#lx.\n", hr);
383 ok(stop == duration || stop == duration + 1, "expected %s, got %s\n",
385
386 hr = IMediaSeeking_SetPositions(seeking, NULL, AM_SEEKING_ReturnTime, NULL, AM_SEEKING_NoPositioning);
387 ok(hr == S_OK, "Got hr %#lx.\n", hr);
388 hr = IMediaSeeking_SetPositions(seeking, NULL, AM_SEEKING_NoPositioning, NULL, AM_SEEKING_ReturnTime);
389 ok(hr == S_OK, "Got hr %#lx.\n", hr);
390
391 pos = 0;
392 hr = IMediaSeeking_SetPositions(seeking, &pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
393 ok(hr == S_OK, "Got hr %#lx.\n", hr);
394
395 IMediaFilter_SetSyncSource(filter, NULL);
396 pos = 0xdeadbeef;
397 hr = IMediaSeeking_GetCurrentPosition(seeking, &pos);
398 ok(hr == S_OK, "Got hr %#lx.\n", hr);
399 ok(pos == 0, "Position != 0 (%s)\n", wine_dbgstr_longlong(pos));
400 IFilterGraph2_SetDefaultSyncSource(graph);
401
402 IMediaSeeking_Release(seeking);
403 IMediaFilter_Release(filter);
404}
#define GUID_NULL
Definition: ks.h:106

Referenced by rungraph().

◆ test_render_run()

static void test_render_run ( const WCHAR *  file,
BOOL  audio,
BOOL  video 
)
static

Definition at line 601 of file filtergraph.c.

602{
604 HANDLE h;
605 HRESULT hr;
606 LONG refs;
608
610 if (h == INVALID_HANDLE_VALUE) {
611 skip("Could not read test file %s, skipping test\n", wine_dbgstr_w(file));
613 return;
614 }
615 CloseHandle(h);
616
617 trace("running %s\n", wine_dbgstr_w(file));
618
620
621 hr = IFilterGraph2_RenderFile(graph, filename, NULL);
622 if (FAILED(hr))
623 {
624 skip("%s: codec not supported; skipping test\n", wine_dbgstr_w(file));
625
626 refs = IFilterGraph2_Release(graph);
627 ok(!refs, "Got outsanding refcount %ld.\n", refs);
628
630 ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#lx.\n", hr);
631 }
632 else
633 {
634 if (audio)
635 ok(hr == S_OK || hr == VFW_S_AUDIO_NOT_RENDERED, "Got hr %#lx.\n", hr);
636 else
637 ok(hr == S_OK, "Got hr %#lx.\n", hr);
638 rungraph(graph, video);
639
640 refs = IFilterGraph2_Release(graph);
641 ok(!refs, "Got outsanding refcount %ld.\n", refs);
642
644 if (audio && video)
645 todo_wine ok(hr == VFW_S_PARTIAL_RENDER, "Got hr %#lx.\n", hr);
646 else
647 ok(hr == S_OK, "Got hr %#lx.\n", hr);
648 }
649
650 /* check reference leaks */
652 ok(h != INVALID_HANDLE_VALUE, "CreateFile failed: err=%ld\n", GetLastError());
653 CloseHandle(h);
654
656}
#define OPEN_EXISTING
Definition: compat.h:775
LONG refs
Definition: port.c:62
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define FAILED(hr)
Definition: intsafe.h:51
static HRESULT test_graph_builder_connect_file(WCHAR *filename, BOOL audio, BOOL video)
Definition: filtergraph.c:555
#define VFW_S_AUDIO_NOT_RENDERED
Definition: vfwmsgs.h:28

Referenced by START_TEST().

◆ test_render_with_multithread()

static void test_render_with_multithread ( void  )
static

Definition at line 800 of file filtergraph.c.

801{
804
806
808
810
811 ok(!WaitForSingleObject(thread, 10000), "Wait timed out.\n");
812 IFilterGraph2_Release(graph);
815}
static HANDLE thread
Definition: service.c:33
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
static DWORD WINAPI call_RenderFile_multithread(LPVOID lParam)
Definition: filtergraph.c:786
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:279

Referenced by START_TEST().

◆ test_renderfile_compressed()

static void test_renderfile_compressed ( void  )
static

Definition at line 4362 of file filtergraph.c.

4363{
4364 WCHAR *filename = load_resource(L"test.mpg");
4365 struct testpin sink_pin;
4366 struct testfilter sink;
4367 IMediaControl *control;
4369 HRESULT hr;
4370 DWORD ret;
4371
4372 graph = create_graph();
4374 sink_pin.IMemInputPin_iface.lpVtbl = &mpegtestsink_meminput_vtbl;
4375 testfilter_init(&sink, &sink_pin, 1);
4376
4377 hr = IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, L"sink");
4378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4379
4380 hr = IFilterGraph2_RenderFile(graph, filename, NULL);
4381 ok(hr == S_OK || hr == VFW_S_AUDIO_NOT_RENDERED, "Got hr %#lx.\n", hr);
4382
4383 ok(sink_pin.peer != NULL, "Expected connection.\n");
4384
4385 sink_pin.on_input_full = CreateEventW(NULL, FALSE, FALSE, NULL);
4386
4387 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
4388 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4389 hr = IMediaControl_Pause(control);
4390 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
4391
4392 ret = WaitForSingleObject(sink_pin.on_input_full, 1000);
4393 ok(ret == WAIT_OBJECT_0, "Got %#lx.\n", ret);
4394
4395 ok(sink_pin.input[0] == 0x00, "Expected MPEG sequence header.\n");
4396 ok(sink_pin.input[1] == 0x00, "Expected MPEG sequence header.\n");
4397 ok(sink_pin.input[2] == 0x01, "Expected MPEG sequence header.\n");
4398 ok(sink_pin.input[3] == 0xB3, "Expected MPEG sequence header.\n");
4399
4400 IMediaControl_Stop(control);
4401 IFilterGraph2_Release(graph);
4403}
static const IMemInputPinVtbl mpegtestsink_meminput_vtbl
Definition: filtergraph.c:4348
static const IPinVtbl mpegtestsink_vtbl
Definition: filtergraph.c:4256
IFilterGraph * graph
Definition: filtergraph.c:850
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
#define WAIT_OBJECT_0
Definition: winbase.h:383

Referenced by START_TEST().

◆ test_renderfile_failure()

static void test_renderfile_failure ( void  )
static

Definition at line 4405 of file filtergraph.c.

4406{
4407 static const char bogus_data[20] = {0xde, 0xad, 0xbe, 0xef};
4408
4409 struct testfilter testfilter;
4410 IEnumFilters *filterenum;
4411 const WCHAR *filename;
4414 HRESULT hr;
4415 ULONG ref;
4416 BOOL ret;
4417
4418 /* Windows removes the source filter from the graph if a RenderFile
4419 * call fails. It leaves the rest of the graph intact. */
4420
4421 graph = create_graph();
4423 hr = IFilterGraph2_AddFilter(graph, &testfilter.IBaseFilter_iface, L"dummy");
4424 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4425
4426 filename = create_file(L"test.nonsense", bogus_data, sizeof(bogus_data));
4427 hr = IFilterGraph2_RenderFile(graph, filename, NULL);
4428 todo_wine ok(hr == VFW_E_UNSUPPORTED_STREAM, "Got hr %#lx.\n", hr);
4429
4430 hr = IFilterGraph2_EnumFilters(graph, &filterenum);
4431 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4432
4433 hr = IEnumFilters_Next(filterenum, 1, &filter, NULL);
4434 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4435 ok(filter == &testfilter.IBaseFilter_iface, "Got unexpected filter %p.\n", filter);
4436
4437 hr = IEnumFilters_Next(filterenum, 1, &filter, NULL);
4438 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
4439
4440 IEnumFilters_Release(filterenum);
4441
4442 ref = IFilterGraph2_Release(graph);
4443 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4445 ok(ret, "Failed to delete %s, error %lu.\n", debugstr_w(filename), GetLastError());
4446}
#define debugstr_w
Definition: kernel32.h:32
#define VFW_E_UNSUPPORTED_STREAM
Definition: vfwmsgs.h:119

Referenced by START_TEST().

◆ test_set_notify_flags()

static void test_set_notify_flags ( void  )
static

Definition at line 5582 of file filtergraph.c.

5583{
5585 IMediaEventSink *media_event_sink;
5586 IMediaControl *media_control;
5587 IMediaEventEx *media_event;
5588 struct testfilter filter;
5589 LONG_PTR param1, param2;
5590 LONG code, flags;
5591 HANDLE event;
5592 HWND window;
5593 BSTR status;
5594 HRESULT hr;
5595 ULONG ref;
5596 MSG msg;
5597
5599 50, 50, 150, 150, NULL, NULL, NULL, NULL);
5600 ok(!!window, "Failed to create window.\n");
5601 status = SysAllocString(L"status");
5602
5603 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
5604 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5605 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEventEx, (void **)&media_event);
5606 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5607 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEventSink, (void **)&media_event_sink);
5608 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5609
5611 filter.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl;
5613
5614 hr = IFilterGraph2_AddFilter(graph, &filter.IBaseFilter_iface, NULL);
5615 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5616
5617 hr = IMediaEventEx_GetEventHandle(media_event, (OAEVENT *)&event);
5618 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5619
5620 hr = IMediaEventEx_SetNotifyWindow(media_event, (OAHWND)window, WM_USER, 0);
5621 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5622
5623 hr = IMediaControl_Run(media_control);
5624 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5625
5626 ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
5627
5629
5630 hr = IMediaEventEx_SetNotifyFlags(media_event, 2);
5631 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
5632
5633 hr = IMediaEventEx_GetNotifyFlags(media_event, NULL);
5634 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
5635
5636 flags = 0xdeadbeef;
5637 hr = IMediaEventEx_GetNotifyFlags(media_event, &flags);
5638 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5639 ok(!flags, "Got flags %#lx\n", flags);
5640
5641 hr = IMediaEventEx_SetNotifyFlags(media_event, AM_MEDIAEVENT_NONOTIFY);
5642 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5643
5644 flags = 0xdeadbeef;
5645 hr = IMediaEventEx_GetNotifyFlags(media_event, &flags);
5646 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5647 ok(flags == AM_MEDIAEVENT_NONOTIFY, "Got flags %#lx\n", flags);
5648
5649 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
5650
5651 hr = IMediaEventEx_GetEvent(media_event, &code, &param1, &param2, 50);
5652 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
5653
5654 hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status);
5655 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5656
5657 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
5658
5659 ok(!PeekMessageA(&msg, window, WM_USER, WM_USER, PM_REMOVE), "Window should not be notified.\n");
5660
5661 hr = IMediaEventEx_GetEvent(media_event, &code, &param1, &param2, 50);
5662 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
5663
5664 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5665 (LONG_PTR)&filter.IBaseFilter_iface);
5666 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5667
5668 ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
5669
5670 hr = IMediaControl_Stop(media_control);
5671 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5672
5673 ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
5674
5675 hr = IMediaControl_Pause(media_control);
5676 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5677
5678 ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
5679
5680 hr = IMediaControl_Run(media_control);
5681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5682
5683 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
5684
5685 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5686 (LONG_PTR)&filter.IBaseFilter_iface);
5687 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5688
5689 ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
5690
5691 hr = IMediaEventEx_GetEvent(media_event, &code, &param1, &param2, 50);
5692 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
5693
5694 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
5695
5696 hr = IMediaEventEx_SetNotifyFlags(media_event, 0);
5697 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5698
5699 flags = 0xdeadbeef;
5700 hr = IMediaEventEx_GetNotifyFlags(media_event, &flags);
5701 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5702 ok(!flags, "Got flags %#lx\n", flags);
5703
5704 hr = IMediaControl_Stop(media_control);
5705 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5706 hr = IMediaControl_Run(media_control);
5707 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5708
5709 hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK,
5710 (LONG_PTR)&filter.IBaseFilter_iface);
5711 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5712
5713 hr = IMediaEventEx_SetNotifyFlags(media_event, AM_MEDIAEVENT_NONOTIFY);
5714 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5715
5716 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
5717
5718 hr = IMediaControl_Stop(media_control);
5719 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5720
5721 IMediaControl_Release(media_control);
5722 IMediaEventEx_Release(media_event);
5723 IMediaEventSink_Release(media_event_sink);
5724 ref = IFilterGraph2_Release(graph);
5725 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5726 ok(filter.ref == 1, "Got outstanding refcount %ld.\n", filter.ref);
5727
5730}
@ AM_MEDIAEVENT_NONOTIFY
Definition: axcore.idl:670
GLbitfield flags
Definition: glext.h:7161
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4469
#define PM_REMOVE
Definition: winuser.h:1207
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_USER
Definition: winuser.h:1923
BOOL WINAPI DestroyWindow(_In_ HWND)
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829

Referenced by START_TEST().

◆ test_state_change()

static void test_state_change ( IFilterGraph2 *  graph)
static

Definition at line 406 of file filtergraph.c.

407{
408 IMediaControl *control;
410 HRESULT hr;
411
412 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
413 ok(hr == S_OK, "Got hr %#lx.\n", hr);
414
415 hr = IMediaControl_GetState(control, 1000, &state);
416 ok(hr == S_OK, "Got hr %#lx.\n", hr);
417 ok(state == State_Stopped, "Got state %ld.\n", state);
418
419 hr = IMediaControl_Run(control);
420 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
421 hr = IMediaControl_GetState(control, INFINITE, &state);
422 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
423 ok(state == State_Running, "Got state %ld.\n", state);
424
425 hr = IMediaControl_Stop(control);
426 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
427 hr = IMediaControl_GetState(control, 1000, &state);
428 ok(hr == S_OK, "Got hr %#lx.\n", hr);
429 ok(state == State_Stopped, "Got state %ld.\n", state);
430
431 hr = IMediaControl_Pause(control);
432 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
433 hr = IMediaControl_GetState(control, 1000, &state);
435 ok(hr == S_OK, "Got hr %#lx.\n", hr);
436 ok(state == State_Paused, "Got state %ld.\n", state);
437
438 hr = IMediaControl_Run(control);
439 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
440 hr = IMediaControl_GetState(control, 1000, &state);
441 ok(hr == S_OK, "Got hr %#lx.\n", hr);
442 ok(state == State_Running, "Got state %ld.\n", state);
443
444 hr = IMediaControl_Pause(control);
445 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
446 hr = IMediaControl_GetState(control, 1000, &state);
447 ok(hr == S_OK, "Got hr %#lx.\n", hr);
448 ok(state == State_Paused, "Got state %ld.\n", state);
449
450 hr = IMediaControl_Stop(control);
451 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
452 hr = IMediaControl_GetState(control, 1000, &state);
453 ok(hr == S_OK, "Got hr %#lx.\n", hr);
454 ok(state == State_Stopped, "Got state %ld.\n", state);
455
456 IMediaControl_Release(control);
457}

Referenced by rungraph().

◆ test_sync_source()

static void test_sync_source ( void  )
static

Definition at line 3349 of file filtergraph.c.

3350{
3351 struct testfilter filter1, filter2, filter3;
3352
3354 IReferenceClock *systemclock, *clock;
3356 HRESULT hr;
3357 ULONG ref;
3358
3359 IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter);
3360
3361 testfilter_init(&filter1, NULL, 0);
3362 testfilter_init(&filter2, NULL, 0);
3363 testfilter_init(&filter3, NULL, 0);
3364
3365 IFilterGraph2_AddFilter(graph, &filter1.IBaseFilter_iface, NULL);
3366 IFilterGraph2_AddFilter(graph, &filter2.IBaseFilter_iface, NULL);
3367
3368 ok(!filter1.clock, "Got clock %p.\n", filter1.clock);
3369 ok(!filter2.clock, "Got clock %p.\n", filter2.clock);
3370
3371 CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER,
3372 &IID_IReferenceClock, (void **)&systemclock);
3373
3374 hr = IMediaFilter_SetSyncSource(filter, systemclock);
3375 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3376 ok(filter1.clock == systemclock, "Got clock %p.\n", filter1.clock);
3377 ok(filter2.clock == systemclock, "Got clock %p.\n", filter2.clock);
3378
3379 hr = IMediaFilter_GetSyncSource(filter, &clock);
3380 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3381 ok(clock == systemclock, "Got clock %p.\n", clock);
3382 IReferenceClock_Release(clock);
3383
3384 IFilterGraph2_AddFilter(graph, &filter3.IBaseFilter_iface, NULL);
3385 ok(filter3.clock == systemclock, "Got clock %p.\n", filter3.clock);
3386
3387 hr = IMediaFilter_SetSyncSource(filter, NULL);
3388 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3389 ok(!filter1.clock, "Got clock %p.\n", filter1.clock);
3390 ok(!filter2.clock, "Got clock %p.\n", filter2.clock);
3391 ok(!filter3.clock, "Got clock %p.\n", filter3.clock);
3392
3393 hr = IMediaFilter_GetSyncSource(filter, &clock);
3394 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3395 ok(!clock, "Got clock %p.\n", clock);
3396
3397 IReferenceClock_Release(systemclock);
3398 IMediaFilter_Release(filter);
3399 ref = IFilterGraph2_Release(graph);
3400 ok(!ref, "Got outstanding refcount %ld\n", ref);
3401 ok(filter1.ref == 1, "Got outstanding refcount %ld.\n", filter1.ref);
3402 ok(filter2.ref == 1, "Got outstanding refcount %ld.\n", filter2.ref);
3403 ok(filter3.ref == 1, "Got outstanding refcount %ld.\n", filter3.ref);
3404}

Referenced by START_TEST().

◆ test_window_threading()

static void test_window_threading ( void  )
static

Definition at line 5440 of file filtergraph.c.

5441{
5442 static const WNDCLASSA class =
5443 {
5445 .lpszClassName = "quartz_test_parent",
5446 };
5447 WCHAR *filename = load_resource(L"test.avi");
5449 HWND hwnd, hwnd2, parent;
5450 IFilterGraph2 *graph2;
5451 IVideoWindow *window;
5452 DWORD tid, tid2;
5453 HRESULT hr;
5454 ULONG ref;
5455 BOOL ret;
5456
5457 RegisterClassA(&class);
5458
5459 parent = CreateWindowA("quartz_test_parent", NULL, WS_OVERLAPPEDWINDOW,
5460 50, 50, 150, 150, NULL, NULL, NULL, NULL);
5461 ok(!!parent, "Failed to create parent window.\n");
5462
5463 hr = IFilterGraph2_RenderFile(graph, filename, NULL);
5464 if (FAILED(hr))
5465 {
5466 skip("Cannot render test file, hr %#lx.\n", hr);
5467 IFilterGraph2_Release(graph);
5469 return;
5470 }
5471 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5472
5473 if ((hwnd = get_renderer_hwnd(graph)))
5474 {
5476 ok(tid != GetCurrentThreadId(), "Window should have been created on a separate thread.\n");
5477
5478 /* The thread should be processing messages, or this will hang. */
5479 SendMessageA(hwnd, WM_NULL, 0, 0);
5480
5481 /* Media Player Classic deadlocks if the parent is sent any messages
5482 * while the video window is released. In particular, we must not send
5483 * WM_PARENTNOTIFY. This is not achieved through window styles. */
5484 hr = IFilterGraph2_QueryInterface(graph, &IID_IVideoWindow, (void **)&window);
5485 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5486 hr = IVideoWindow_put_Owner(window, (OAHWND)parent);
5487 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5488 IVideoWindow_Release(window);
5489 ok(!(GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_NOPARENTNOTIFY), "Window has WS_EX_NOPARENTNOTIFY.\n");
5490
5491 graph2 = create_graph();
5492 hr = IFilterGraph2_RenderFile(graph2, filename, NULL);
5493 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5494 hwnd2 = get_renderer_hwnd(graph);
5495 ok(!!hwnd2, "Failed to get renderer window.\n");
5497 ok(tid2 == tid, "Expected thread to be shared.\n");
5498
5499 ref = IFilterGraph2_Release(graph2);
5500 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5501 }
5502 else
5503 skip("Could not find renderer window.\n");
5504
5507 ref = IFilterGraph2_Release(graph);
5508 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5510
5512 ok(hwnd == parent, "Parent window lost focus, active window %p.\n", hwnd);
5513
5514 hr = CoCreateInstance(&CLSID_FilterGraphNoThread, NULL, CLSCTX_INPROC_SERVER,
5515 &IID_IFilterGraph2, (void **)&graph);
5516 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5517
5518 hr = IFilterGraph2_RenderFile(graph, filename, NULL);
5519 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5520
5521 if ((hwnd = get_renderer_hwnd(graph)))
5522 {
5524 ok(tid == GetCurrentThreadId(), "Window should be created on main thread.\n");
5525 }
5526 else
5527 skip("Could not find renderer window.\n");
5528
5529 ref = IFilterGraph2_Release(graph);
5530 ok(!ref, "Got outstanding refcount %ld.\n", ref);
5531
5533 UnregisterClassA("quartz_test_parent", GetModuleHandleA(NULL));
5535 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
5536}
r parent
Definition: btrfs.c:3010
static TfClientId tid
static LRESULT CALLBACK parent_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: filtergraph.c:5434
static HWND get_renderer_hwnd(IFilterGraph2 *graph)
Definition: filtergraph.c:5395
#define WS_EX_NOPARENTNOTIFY
Definition: pedump.c:646
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
HWND WINAPI SetActiveWindow(_In_ HWND)
#define WM_NULL
Definition: winuser.h:1635
#define GWL_EXSTYLE
Definition: winuser.h:862
WNDPROC lpfnWndProc
Definition: winuser.h:3272
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)

Referenced by START_TEST().

◆ testclock_AddRef()

static ULONG WINAPI testclock_AddRef ( IReferenceClock *  iface)
static

Definition at line 1927 of file filtergraph.c.

1928{
1930 return InterlockedIncrement(&filter->ref);
1931}
static struct testfilter * impl_from_IReferenceClock(IReferenceClock *iface)
Definition: filtergraph.c:1916

◆ testclock_AdvisePeriodic()

static HRESULT WINAPI testclock_AdvisePeriodic ( IReferenceClock *  iface,
REFERENCE_TIME  start,
REFERENCE_TIME  period,
HSEMAPHORE  semaphore,
DWORD_PTR *  cookie 
)
static

Definition at line 1952 of file filtergraph.c.

1954{
1955 ok(0, "Unexpected call.\n");
1956 return E_NOTIMPL;
1957}

◆ testclock_AdviseTime()

static HRESULT WINAPI testclock_AdviseTime ( IReferenceClock *  iface,
REFERENCE_TIME  base,
REFERENCE_TIME  offset,
HEVENT  event,
DWORD_PTR *  cookie 
)
static

Definition at line 1945 of file filtergraph.c.

1947{
1948 ok(0, "Unexpected call.\n");
1949 return E_NOTIMPL;
1950}

◆ testclock_GetTime()

static HRESULT WINAPI testclock_GetTime ( IReferenceClock *  iface,
REFERENCE_TIME *  time 
)
static

Definition at line 1939 of file filtergraph.c.

1940{
1941 ok(0, "Unexpected call.\n");
1942 return E_NOTIMPL;
1943}

◆ testclock_QueryInterface()

static HRESULT WINAPI testclock_QueryInterface ( IReferenceClock *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 1921 of file filtergraph.c.

1922{
1924 return IBaseFilter_QueryInterface(&filter->IBaseFilter_iface, iid, out);
1925}

◆ testclock_Release()

static ULONG WINAPI testclock_Release ( IReferenceClock *  iface)
static

Definition at line 1933 of file filtergraph.c.

1934{
1936 return InterlockedDecrement(&filter->ref);
1937}

◆ testclock_Unadvise()

static HRESULT WINAPI testclock_Unadvise ( IReferenceClock *  iface,
DWORD_PTR  cookie 
)
static

Definition at line 1959 of file filtergraph.c.

1960{
1961 ok(0, "Unexpected call.\n");
1962 return E_NOTIMPL;
1963}

◆ testenummt_AddRef()

static ULONG WINAPI testenummt_AddRef ( IEnumMediaTypes *  iface)
static

Definition at line 894 of file filtergraph.c.

895{
896 struct testpin *pin = impl_from_IEnumMediaTypes(iface);
897 return InterlockedIncrement(&pin->ref);
898}
static struct testpin * impl_from_IEnumMediaTypes(IEnumMediaTypes *iface)
Definition: filtergraph.c:880

◆ testenummt_Clone()

static HRESULT WINAPI testenummt_Clone ( IEnumMediaTypes *  iface,
IEnumMediaTypes **  out 
)
static

Definition at line 940 of file filtergraph.c.

941{
942 ok(0, "Unexpected call.\n");
943 return E_NOTIMPL;
944}

◆ testenummt_Next()

static HRESULT WINAPI testenummt_Next ( IEnumMediaTypes *  iface,
ULONG  count,
AM_MEDIA_TYPE **  out,
ULONG *  fetched 
)
static

Definition at line 906 of file filtergraph.c.

907{
908 struct testpin *pin = impl_from_IEnumMediaTypes(iface);
909 unsigned int i;
910
911 for (i = 0; i < count; ++i)
912 {
913 if (pin->enum_idx + i >= pin->type_count)
914 break;
915
916 out[i] = CoTaskMemAlloc(sizeof(*out[i]));
917 *out[i] = pin->types[pin->enum_idx + i];
918 }
919
920 if (fetched)
921 *fetched = i;
922 pin->enum_idx += i;
923
924 return (i == count) ? S_OK : S_FALSE;
925}
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
unsigned int enum_idx
Definition: filtergraph.c:831
unsigned int type_count
Definition: filtergraph.c:831
const AM_MEDIA_TYPE * types
Definition: filtergraph.c:830

◆ testenummt_QueryInterface()

static HRESULT WINAPI testenummt_QueryInterface ( IEnumMediaTypes *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 885 of file filtergraph.c.

886{
887 struct testpin *pin = impl_from_IEnumMediaTypes(iface);
888 if (winetest_debug > 1) trace("%p->QueryInterface(%s)\n", pin, wine_dbgstr_guid(iid));
889
890 *out = NULL;
891 return E_NOINTERFACE;
892}

◆ testenummt_Release()

static ULONG WINAPI testenummt_Release ( IEnumMediaTypes *  iface)
static

Definition at line 900 of file filtergraph.c.

901{
902 struct testpin *pin = impl_from_IEnumMediaTypes(iface);
903 return InterlockedDecrement(&pin->ref);
904}

◆ testenummt_Reset()

static HRESULT WINAPI testenummt_Reset ( IEnumMediaTypes *  iface)
static

Definition at line 933 of file filtergraph.c.

934{
935 struct testpin *pin = impl_from_IEnumMediaTypes(iface);
936 pin->enum_idx = 0;
937 return S_OK;
938}

◆ testenummt_Skip()

static HRESULT WINAPI testenummt_Skip ( IEnumMediaTypes *  iface,
ULONG  count 
)
static

Definition at line 927 of file filtergraph.c.

928{
929 ok(0, "Unexpected call.\n");
930 return E_NOTIMPL;
931}

◆ testenumpins_AddRef()

static ULONG WINAPI testenumpins_AddRef ( IEnumPins *  iface)
static

Definition at line 1259 of file filtergraph.c.

1260{
1261 struct testfilter *filter = impl_from_IEnumPins(iface);
1262 return InterlockedIncrement(&filter->ref);
1263}
static struct testfilter * impl_from_IEnumPins(IEnumPins *iface)
Definition: filtergraph.c:1248

◆ testenumpins_Clone()

static HRESULT WINAPI testenumpins_Clone ( IEnumPins *  iface,
IEnumPins **  out 
)
static

Definition at line 1305 of file filtergraph.c.

1306{
1307 ok(0, "Unexpected call.\n");
1308 return E_NOTIMPL;
1309}

◆ testenumpins_Next()

static HRESULT WINAPI testenumpins_Next ( IEnumPins *  iface,
ULONG  count,
IPin **  out,
ULONG *  fetched 
)
static

Definition at line 1271 of file filtergraph.c.

1272{
1273 struct testfilter *filter = impl_from_IEnumPins(iface);
1274 unsigned int i;
1275
1276 for (i = 0; i < count; ++i)
1277 {
1278 if (filter->enum_idx + i >= filter->pin_count)
1279 break;
1280
1281 out[i] = &filter->pins[filter->enum_idx + i].IPin_iface;
1282 IPin_AddRef(out[i]);
1283 }
1284
1285 if (fetched)
1286 *fetched = i;
1287 filter->enum_idx += i;
1288
1289 return (i == count) ? S_OK : S_FALSE;
1290}

◆ testenumpins_QueryInterface()

static HRESULT WINAPI testenumpins_QueryInterface ( IEnumPins *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 1253 of file filtergraph.c.

1254{
1255 ok(0, "Unexpected iid %s.\n", wine_dbgstr_guid(iid));
1256 return E_NOINTERFACE;
1257}

◆ testenumpins_Release()

static ULONG WINAPI testenumpins_Release ( IEnumPins *  iface)
static

Definition at line 1265 of file filtergraph.c.

1266{
1267 struct testfilter *filter = impl_from_IEnumPins(iface);
1268 return InterlockedDecrement(&filter->ref);
1269}

◆ testenumpins_Reset()

static HRESULT WINAPI testenumpins_Reset ( IEnumPins *  iface)
static

Definition at line 1298 of file filtergraph.c.

1299{
1300 struct testfilter *filter = impl_from_IEnumPins(iface);
1301 filter->enum_idx = 0;
1302 return S_OK;
1303}

◆ testenumpins_Skip()

static HRESULT WINAPI testenumpins_Skip ( IEnumPins *  iface,
ULONG  count 
)
static

Definition at line 1292 of file filtergraph.c.

1293{
1294 ok(0, "Unexpected call.\n");
1295 return E_NOTIMPL;
1296}

◆ testfilesource_AddRef()

static ULONG WINAPI testfilesource_AddRef ( IFileSourceFilter *  iface)
static

Definition at line 1987 of file filtergraph.c.

1988{
1990 return InterlockedIncrement(&filter->ref);
1991}
static struct testfilter * impl_from_IFileSourceFilter(IFileSourceFilter *iface)
Definition: filtergraph.c:1976

◆ testfilesource_GetCurFile()

static HRESULT WINAPI testfilesource_GetCurFile ( IFileSourceFilter *  iface,
WCHAR **  filename,
AM_MEDIA_TYPE *  mt 
)
static

Definition at line 2006 of file filtergraph.c.

2008{
2009 ok(0, "Unexpected call.\n");
2010 return E_NOTIMPL;
2011}

◆ testfilesource_Load()

static HRESULT WINAPI testfilesource_Load ( IFileSourceFilter *  iface,
const WCHAR *  filename,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 1999 of file filtergraph.c.

2001{
2002 if (winetest_debug > 1) trace("%p->Load(%ls)\n", iface, filename);
2003 return S_OK;
2004}

◆ testfilesource_QueryInterface()

static HRESULT WINAPI testfilesource_QueryInterface ( IFileSourceFilter *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 1981 of file filtergraph.c.

1982{
1984 return IBaseFilter_QueryInterface(&filter->IBaseFilter_iface, iid, out);
1985}

◆ testfilesource_Release()

static ULONG WINAPI testfilesource_Release ( IFileSourceFilter *  iface)
static

Definition at line 1993 of file filtergraph.c.

1994{
1996 return InterlockedDecrement(&filter->ref);
1997}

◆ testfilter_AddRef()

static ULONG WINAPI testfilter_AddRef ( IBaseFilter *  iface)
static

Definition at line 1369 of file filtergraph.c.

1370{
1371 struct testfilter *filter = impl_from_IBaseFilter(iface);
1372 return InterlockedIncrement(&filter->ref);
1373}
static struct testfilter * impl_from_IBaseFilter(IBaseFilter *iface)
Definition: filtergraph.c:1322

◆ testfilter_cf_AddRef()

static ULONG WINAPI testfilter_cf_AddRef ( IClassFactory *  iface)
static

Definition at line 2059 of file filtergraph.c.

2060{
2061 return 2;
2062}

◆ testfilter_cf_CreateInstance()

static HRESULT WINAPI testfilter_cf_CreateInstance ( IClassFactory *  iface,
IUnknown *  outer,
REFIID  iid,
void **  out 
)
static

Definition at line 2069 of file filtergraph.c.

2070{
2072
2073 return IBaseFilter_QueryInterface(&factory->filter->IBaseFilter_iface, iid, out);
2074}
Definition: main.c:439

◆ testfilter_cf_LockServer()

static HRESULT WINAPI testfilter_cf_LockServer ( IClassFactory *  iface,
BOOL  lock 
)
static

Definition at line 2076 of file filtergraph.c.

2077{
2078 return E_NOTIMPL;
2079}

◆ testfilter_cf_QueryInterface()

static HRESULT WINAPI testfilter_cf_QueryInterface ( IClassFactory *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 2047 of file filtergraph.c.

2048{
2050 {
2051 *out = iface;
2052 return S_OK;
2053 }
2054
2055 *out = NULL;
2056 return E_NOINTERFACE;
2057}
const GUID IID_IClassFactory

◆ testfilter_cf_Release()

static ULONG WINAPI testfilter_cf_Release ( IClassFactory *  iface)
static

Definition at line 2064 of file filtergraph.c.

2065{
2066 return 1;
2067}

◆ testfilter_EnumPins()

static HRESULT WINAPI testfilter_EnumPins ( IBaseFilter *  iface,
IEnumPins **  out 
)
static

Definition at line 1483 of file filtergraph.c.

1484{
1485 struct testfilter *filter = impl_from_IBaseFilter(iface);
1486 if (winetest_debug > 1) trace("%p->EnumPins()\n", filter);
1487
1488 *out = &filter->IEnumPins_iface;
1489 IEnumPins_AddRef(*out);
1490 filter->enum_idx = 0;
1491 return S_OK;
1492}

◆ testfilter_FindPin()

static HRESULT WINAPI testfilter_FindPin ( IBaseFilter *  iface,
const WCHAR *  id,
IPin **  pin 
)
static

Definition at line 1494 of file filtergraph.c.

1495{
1496 struct testfilter *filter = impl_from_IBaseFilter(iface);
1497 int i;
1498 if (winetest_debug > 1) trace("%p->FindPin(%ls)\n", filter, id);
1499
1500 for (i = 0; i < filter->pin_count; ++i)
1501 {
1502 if (!wcscmp(id, filter->pins[i].id))
1503 {
1504 *pin = &filter->pins[i].IPin_iface;
1505 IPin_AddRef(*pin);
1506 return S_OK;
1507 }
1508 }
1509 return VFW_E_NOT_FOUND;
1510}

◆ testfilter_GetClassID()

static HRESULT WINAPI testfilter_GetClassID ( IBaseFilter *  iface,
CLSID *  clsid 
)
static

Definition at line 1381 of file filtergraph.c.

1382{
1383 if (winetest_debug > 1) trace("%p->GetClassID()\n", iface);
1384 memset(clsid, 0xde, sizeof(*clsid));
1385 return S_OK;
1386}

◆ testfilter_GetState()

static HRESULT WINAPI testfilter_GetState ( IBaseFilter *  iface,
DWORD  timeout,
FILTER_STATE *  state 
)
static

Definition at line 1455 of file filtergraph.c.

1456{
1457 struct testfilter *filter = impl_from_IBaseFilter(iface);
1458 if (winetest_debug > 1) trace("%p->GetState(%lu)\n", filter, timeout);
1459
1460 *state = filter->state;
1461 return filter->GetState_hr;
1462}
Definition: dhcpd.h:248

◆ testfilter_GetSyncSource()

static HRESULT WINAPI testfilter_GetSyncSource ( IBaseFilter *  iface,
IReferenceClock **  clock 
)
static

Definition at line 1477 of file filtergraph.c.

1478{
1479 ok(0, "Unexpected call.\n");
1480 return E_NOTIMPL;
1481}

◆ testfilter_init()

static void testfilter_init ( struct testfilter *  filter,
struct testpin *  pins,
int  pin_count 
)
static

Definition at line 2028 of file filtergraph.c.

2029{
2030 unsigned int i;
2031
2032 memset(filter, 0, sizeof(*filter));
2033 filter->IBaseFilter_iface.lpVtbl = &testfilter_vtbl;
2034 filter->IEnumPins_iface.lpVtbl = &testenumpins_vtbl;
2035 filter->ref = 1;
2036 filter->pins = pins;
2037 filter->pin_count = pin_count;
2038 for (i = 0; i < pin_count; i++)
2039 pins[i].filter = filter;
2040
2041 filter->state = State_Stopped;
2042 filter->expect_stop_prev = filter->expect_run_prev = State_Paused;
2043 filter->support_media_time = TRUE;
2044 filter->time_format = TIME_FORMAT_MEDIA_TIME;
2045}
static const IEnumPinsVtbl testenumpins_vtbl
Definition: filtergraph.c:1311
static const IBaseFilterVtbl testfilter_vtbl
Definition: filtergraph.c:1543

Referenced by test_add_remove_filter(), test_add_source_filter(), test_autoplug_uyvy(), test_connect_direct(), test_default_sync_source(), test_ec_complete(), test_events(), test_filter_state(), test_graph_builder_connect(), test_graph_builder_render(), test_graph_seeking(), test_renderfile_compressed(), test_renderfile_failure(), test_set_notify_flags(), and test_sync_source().

◆ testfilter_JoinFilterGraph()

static HRESULT WINAPI testfilter_JoinFilterGraph ( IBaseFilter *  iface,
IFilterGraph *  graph,
const WCHAR *  name 
)
static

Definition at line 1527 of file filtergraph.c.

1528{
1529 struct testfilter *filter = impl_from_IBaseFilter(iface);
1530 if (winetest_debug > 1) trace("%p->JoinFilterGraph(%p, %s)\n", filter, graph, wine_dbgstr_w(name));
1531
1532 filter->graph = graph;
1533 free(filter->name);
1534 filter->name = wcsdup(name);
1535 return S_OK;
1536}
#define free
Definition: debug_ros.c:5
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94

◆ testfilter_Pause()

static HRESULT WINAPI testfilter_Pause ( IBaseFilter *  iface)
static

Definition at line 1429 of file filtergraph.c.

1430{
1431 struct testfilter *filter = impl_from_IBaseFilter(iface);
1432 if (winetest_debug > 1) trace("%p->Pause()\n", filter);
1433
1434 check_state_transition(filter, State_Paused);
1435
1436 filter->state = State_Paused;
1437 return filter->state_hr;
1438}
static void check_state_transition(struct testfilter *filter, FILTER_STATE expect)
Definition: filtergraph.c:1391

◆ testfilter_QueryFilterInfo()

static HRESULT WINAPI testfilter_QueryFilterInfo ( IBaseFilter *  iface,
FILTER_INFO *  info 
)
static

Definition at line 1512 of file filtergraph.c.

1513{
1514 struct testfilter *filter = impl_from_IBaseFilter(iface);
1515 if (winetest_debug > 1) trace("%p->QueryFilterInfo()\n", filter);
1516
1517 info->pGraph = filter->graph;
1518 if (filter->graph)
1519 IFilterGraph_AddRef(filter->graph);
1520 if (filter->name)
1521 wcscpy(info->achName, filter->name);
1522 else
1523 info->achName[0] = 0;
1524 return S_OK;
1525}
wcscpy

◆ testfilter_QueryInterface()

static HRESULT WINAPI testfilter_QueryInterface ( IBaseFilter *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 1327 of file filtergraph.c.

1328{
1329 struct testfilter *filter = impl_from_IBaseFilter(iface);
1330 if (winetest_debug > 1) trace("%p->QueryInterface(%s)\n", filter, wine_dbgstr_guid(iid));
1331
1332 if (IsEqualGUID(iid, &IID_IUnknown)
1333 || IsEqualGUID(iid, &IID_IPersist)
1334 || IsEqualGUID(iid, &IID_IMediaFilter)
1335 || IsEqualGUID(iid, &IID_IBaseFilter))
1336 {
1337 *out = &filter->IBaseFilter_iface;
1338 }
1339 else if (IsEqualGUID(iid, &IID_IAMFilterMiscFlags) && filter->IAMFilterMiscFlags_iface.lpVtbl)
1340 {
1341 *out = &filter->IAMFilterMiscFlags_iface;
1342 }
1343 else if (IsEqualGUID(iid, &IID_IMediaSeeking) && filter->IMediaSeeking_iface.lpVtbl)
1344 {
1346 }
1347 else if (IsEqualGUID(iid, &IID_IMediaPosition) && filter->IMediaPosition_iface.lpVtbl)
1348 {
1349 *out = &filter->IMediaPosition_iface;
1350 }
1351 else if (IsEqualGUID(iid, &IID_IReferenceClock) && filter->IReferenceClock_iface.lpVtbl)
1352 {
1353 *out = &filter->IReferenceClock_iface;
1354 }
1355 else if (IsEqualGUID(iid, &IID_IFileSourceFilter) && filter->IFileSourceFilter_iface.lpVtbl)
1356 {
1357 *out = &filter->IFileSourceFilter_iface;
1358 }
1359 else
1360 {
1361 *out = NULL;
1362 return E_NOINTERFACE;
1363 }
1364
1365 IUnknown_AddRef((IUnknown *)*out);
1366 return S_OK;
1367}
const GUID IID_IPersist
Definition: proxy.cpp:14

◆ testfilter_QueryVendorInfo()

static HRESULT WINAPI testfilter_QueryVendorInfo ( IBaseFilter *  iface,
WCHAR **  info 
)
static

Definition at line 1538 of file filtergraph.c.

1539{
1540 return E_NOTIMPL;
1541}

◆ testfilter_Release()

static ULONG WINAPI testfilter_Release ( IBaseFilter *  iface)
static

Definition at line 1375 of file filtergraph.c.

1376{
1377 struct testfilter *filter = impl_from_IBaseFilter(iface);
1378 return InterlockedDecrement(&filter->ref);
1379}

◆ testfilter_Run()

static HRESULT WINAPI testfilter_Run ( IBaseFilter *  iface,
REFERENCE_TIME  start 
)
static

Definition at line 1440 of file filtergraph.c.

1441{
1442 struct testfilter *filter = impl_from_IBaseFilter(iface);
1443 if (winetest_debug > 1) trace("%p->Run(%s)\n", filter, wine_dbgstr_longlong(start));
1444
1445 ok(filter->state == filter->expect_run_prev, "Expected previous state %#x, got %#x.\n",
1446 filter->expect_run_prev, filter->state);
1447
1448 check_state_transition(filter, State_Running);
1449
1450 filter->state = State_Running;
1452 return filter->state_hr;
1453}
GLuint start
Definition: gl.h:1545
REFERENCE_TIME start_time
Definition: filter.c:178

◆ testfilter_SetSyncSource()

static HRESULT WINAPI testfilter_SetSyncSource ( IBaseFilter *  iface,
IReferenceClock *  clock 
)
static

Definition at line 1464 of file filtergraph.c.

1465{
1466 struct testfilter *filter = impl_from_IBaseFilter(iface);
1467 if (winetest_debug > 1) trace("%p->SetSyncSource(%p)\n", filter, clock);
1468
1469 if (filter->clock)
1470 IReferenceClock_Release(filter->clock);
1471 if (clock)
1472 IReferenceClock_AddRef(clock);
1473 filter->clock = clock;
1474 return S_OK;
1475}

◆ testfilter_Stop()

static HRESULT WINAPI testfilter_Stop ( IBaseFilter *  iface)
static

Definition at line 1414 of file filtergraph.c.

1415{
1416 struct testfilter *filter = impl_from_IBaseFilter(iface);
1417 if (winetest_debug > 1) trace("%p->Stop()\n", filter);
1418
1419 todo_wine_if (filter->expect_stop_prev == State_Running)
1420 ok(filter->state == filter->expect_stop_prev, "Expected previous state %#x, got %#x.\n",
1421 filter->expect_stop_prev, filter->state);
1422
1423 check_state_transition(filter, State_Stopped);
1424
1425 filter->state = State_Stopped;
1426 return filter->state_hr;
1427}
#define todo_wine_if(is_todo)
Definition: minitest.h:81

◆ testmiscflags_AddRef()

static ULONG WINAPI testmiscflags_AddRef ( IAMFilterMiscFlags *  iface)
static

Definition at line 1573 of file filtergraph.c.

1574{
1576 return InterlockedIncrement(&filter->ref);
1577}
static struct testfilter * impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
Definition: filtergraph.c:1562

◆ testmiscflags_GetMiscFlags()

static ULONG WINAPI testmiscflags_GetMiscFlags ( IAMFilterMiscFlags *  iface)
static

Definition at line 1585 of file filtergraph.c.

1586{
1588 if (winetest_debug > 1) trace("%p->GetMiscFlags()\n", filter);
1589 return filter->misc_flags;
1590}

◆ testmiscflags_QueryInterface()

static HRESULT WINAPI testmiscflags_QueryInterface ( IAMFilterMiscFlags *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 1567 of file filtergraph.c.

1568{
1570 return IBaseFilter_QueryInterface(&filter->IBaseFilter_iface, iid, out);
1571}

◆ testmiscflags_Release()

static ULONG WINAPI testmiscflags_Release ( IAMFilterMiscFlags *  iface)
static

Definition at line 1579 of file filtergraph.c.

1580{
1582 return InterlockedDecrement(&filter->ref);
1583}

◆ testpin_AddRef()

static ULONG WINAPI testpin_AddRef ( IPin *  iface)
static

Definition at line 989 of file filtergraph.c.

990{
991 struct testpin *pin = impl_from_IPin(iface);
992 return InterlockedIncrement(&pin->ref);
993}

◆ testpin_BeginFlush()

static HRESULT WINAPI testpin_BeginFlush ( IPin *  iface)
static

Definition at line 1097 of file filtergraph.c.

1098{
1099 ok(0, "Unexpected call.\n");
1100 return E_NOTIMPL;
1101}

◆ testpin_ConnectedTo()

static HRESULT WINAPI testpin_ConnectedTo ( IPin *  iface,
IPin **  peer 
)
static

Definition at line 1017 of file filtergraph.c.

1018{
1019 struct testpin *pin = impl_from_IPin(iface);
1020 if (winetest_debug > 1) trace("%p->ConnectedTo()\n", pin);
1021
1022 *peer = pin->peer;
1023 if (*peer)
1024 {
1025 IPin_AddRef(*peer);
1026 return S_OK;
1027 }
1028 return VFW_E_NOT_CONNECTED;
1029}

◆ testpin_ConnectionMediaType()

static HRESULT WINAPI testpin_ConnectionMediaType ( IPin *  iface,
AM_MEDIA_TYPE *  mt 
)
static

Definition at line 1031 of file filtergraph.c.

1032{
1033 ok(0, "Unexpected call.\n");
1034 return E_NOTIMPL;
1035}

◆ testpin_Disconnect()

static HRESULT WINAPI testpin_Disconnect ( IPin *  iface)
static

Definition at line 1001 of file filtergraph.c.

1002{
1003 struct testpin *pin = impl_from_IPin(iface);
1004 if (winetest_debug > 1) trace("%p->Disconnect()\n", pin);
1005
1006 if (!pin->peer)
1007 return S_FALSE;
1008
1009 if (pin->require_stopped_disconnect && pin->filter->state != State_Stopped)
1010 return VFW_E_NOT_STOPPED;
1011
1012 IPin_Release(pin->peer);
1013 pin->peer = NULL;
1014 return S_OK;
1015}
BOOL require_stopped_disconnect
Definition: filtergraph.c:835

◆ testpin_EndFlush()

static HRESULT WINAPI testpin_EndFlush ( IPin *  iface)
static

Definition at line 1103 of file filtergraph.c.

1104{
1105 ok(0, "Unexpected call.\n");
1106 return E_NOTIMPL;
1107}

◆ testpin_EndOfStream()

static HRESULT WINAPI testpin_EndOfStream ( IPin *  iface)
static

Definition at line 1115 of file filtergraph.c.

1116{
1117 ok(0, "Unexpected call.\n");
1118 return E_NOTIMPL;
1119}

◆ testpin_EnumMediaTypes()

static HRESULT WINAPI testpin_EnumMediaTypes ( IPin *  iface,
IEnumMediaTypes **  out 
)
static

Definition at line 1074 of file filtergraph.c.

1075{
1076 struct testpin *pin = impl_from_IPin(iface);
1077 if (winetest_debug > 1) trace("%p->EnumMediaTypes()\n", pin);
1078
1079 if (FAILED(pin->EnumMediaTypes_hr))
1080 return pin->EnumMediaTypes_hr;
1081
1082 *out = &pin->IEnumMediaTypes_iface;
1083 IEnumMediaTypes_AddRef(*out);
1084 pin->enum_idx = 0;
1085 return S_OK;
1086}
IEnumMediaTypes IEnumMediaTypes_iface
Definition: filtergraph.c:829
HRESULT EnumMediaTypes_hr
Definition: filtergraph.c:838

◆ testpin_init()

static void testpin_init ( struct testpin *  pin,
const IPinVtbl *  vtbl,
PIN_DIRECTION  dir 
)
static

Definition at line 1177 of file filtergraph.c.

1178{
1179 memset(pin, 0, sizeof(*pin));
1180 pin->IPin_iface.lpVtbl = vtbl;
1182 pin->ref = 1;
1183 pin->dir = dir;
1184 pin->Connect_hr = S_OK;
1185 pin->EnumMediaTypes_hr = S_OK;
1187 wsprintfW(pin->name, L"name%.4x", 0xFFFF&(intptr_t)pin);
1188 wsprintfW(pin->id, L"id%.4x", 0xFFFF&(intptr_t)pin);
1189}
int intptr_t
Definition: corecrt.h:176
static const IEnumMediaTypesVtbl testenummt_vtbl
Definition: filtergraph.c:946
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
HRESULT QueryInternalConnections_hr
Definition: filtergraph.c:839
WCHAR name[10]
Definition: filtergraph.c:826
IPin IPin_iface
Definition: filtergraph.c:819
PIN_DIRECTION dir
Definition: filtergraph.c:822
WCHAR id[10]
Definition: filtergraph.c:827
HRESULT Connect_hr
Definition: filtergraph.c:837

Referenced by test_connect_direct_init(), test_renderfile_compressed(), testsink_init(), and testsource_init().

◆ testpin_NewSegment()

static HRESULT WINAPI testpin_NewSegment ( IPin *  iface,
REFERENCE_TIME  start,
REFERENCE_TIME  stop,
double  rate 
)
static

Definition at line 1109 of file filtergraph.c.

1110{
1111 ok(0, "Unexpected call.\n");
1112 return E_NOTIMPL;
1113}

◆ testpin_QueryAccept()

static HRESULT WINAPI testpin_QueryAccept ( IPin *  iface,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 1068 of file filtergraph.c.

1069{
1070 ok(0, "Unexpected call.\n");
1071 return E_NOTIMPL;
1072}

◆ testpin_QueryDirection()

static HRESULT WINAPI testpin_QueryDirection ( IPin *  iface,
PIN_DIRECTION *  dir 
)
static

Definition at line 1050 of file filtergraph.c.

1051{
1052 struct testpin *pin = impl_from_IPin(iface);
1053 if (winetest_debug > 1) trace("%p->QueryDirection()\n", pin);
1054
1055 *dir = pin->dir;
1056 return S_OK;
1057}

◆ testpin_QueryId()

static HRESULT WINAPI testpin_QueryId ( IPin *  iface,
WCHAR **  id 
)
static

Definition at line 1059 of file filtergraph.c.

1060{
1061 struct testpin *pin = impl_from_IPin(iface);
1062 if (winetest_debug > 1) trace("%p->QueryId()\n", iface);
1063 *id = CoTaskMemAlloc(sizeof(WCHAR)*11);
1064 wcscpy(*id, pin->id);
1065 return S_OK;
1066}

◆ testpin_QueryInterface()

static HRESULT WINAPI testpin_QueryInterface ( IPin *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 967 of file filtergraph.c.

968{
969 struct testpin *pin = impl_from_IPin(iface);
970 if (winetest_debug > 1) trace("%p->QueryInterface(%s)\n", pin, wine_dbgstr_guid(iid));
971
972 if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IPin))
973 {
974 *out = &pin->IPin_iface;
975 IPin_AddRef(*out);
976 return S_OK;
977 }
978 if (pin->IMemInputPin_iface.lpVtbl && IsEqualGUID(iid, &IID_IMemInputPin))
979 {
980 *out = &pin->IMemInputPin_iface;
981 IMemInputPin_AddRef(*out);
982 return S_OK;
983 }
984
985 *out = NULL;
986 return E_NOINTERFACE;
987}
const GUID IID_IPin
Definition: pincontrol.cpp:15
IMemInputPin IMemInputPin_iface
Definition: filtergraph.c:820

◆ testpin_QueryInternalConnections()

static HRESULT WINAPI testpin_QueryInternalConnections ( IPin *  iface,
IPin **  out,
ULONG *  count 
)
static

Definition at line 1088 of file filtergraph.c.

1089{
1090 struct testpin *pin = impl_from_IPin(iface);
1091 if (winetest_debug > 1) trace("%p->QueryInternalConnections()\n", pin);
1092
1093 *count = 0;
1094 return pin->QueryInternalConnections_hr;
1095}

◆ testpin_QueryPinInfo()

static HRESULT WINAPI testpin_QueryPinInfo ( IPin *  iface,
PIN_INFO *  info 
)
static

Definition at line 1037 of file filtergraph.c.

1038{
1039 struct testpin *pin = impl_from_IPin(iface);
1040 if (winetest_debug > 1) trace("%p->QueryPinInfo()\n", pin);
1041
1042 info->pFilter = &pin->filter->IBaseFilter_iface;
1043 IBaseFilter_AddRef(info->pFilter);
1044 info->dir = pin->dir;
1045 wcscpy(info->achName, pin->name);
1046 return S_OK;
1047}

◆ testpin_Release()

static ULONG WINAPI testpin_Release ( IPin *  iface)
static

Definition at line 995 of file filtergraph.c.

996{
997 struct testpin *pin = impl_from_IPin(iface);
998 return InterlockedDecrement(&pin->ref);
999}

◆ testpos_AddRef()

static ULONG WINAPI testpos_AddRef ( IMediaPosition *  iface)
static

Definition at line 1792 of file filtergraph.c.

1793{
1795 return IBaseFilter_AddRef(&filter->IBaseFilter_iface);
1796}
static struct filter_graph * impl_from_IMediaPosition(IMediaPosition *iface)
Definition: filtergraph.c:2578

◆ testpos_CanSeekBackward()

static HRESULT WINAPI testpos_CanSeekBackward ( IMediaPosition *  iface,
LONG *  can_seek_backward 
)
static

Definition at line 1888 of file filtergraph.c.

1889{
1890 ok(0, "Unexpected call.\n");
1891 return E_NOTIMPL;
1892}

◆ testpos_CanSeekForward()

static HRESULT WINAPI testpos_CanSeekForward ( IMediaPosition *  iface,
LONG *  can_seek_forward 
)
static

Definition at line 1882 of file filtergraph.c.

1883{
1884 ok(0, "Unexpected call.\n");
1885 return E_NOTIMPL;
1886}

◆ testpos_get_CurrentPosition()

static HRESULT WINAPI testpos_get_CurrentPosition ( IMediaPosition *  iface,
REFTIME *  time 
)
static

Definition at line 1840 of file filtergraph.c.

1841{
1842 ok(0, "Unexpected call.\n");
1843 return E_NOTIMPL;
1844}

◆ testpos_get_Duration()

static HRESULT WINAPI testpos_get_Duration ( IMediaPosition *  iface,
REFTIME *  length 
)
static

Definition at line 1828 of file filtergraph.c.

1829{
1830 if (winetest_debug > 1) trace("%p->get_Duration()\n", iface);
1831 return E_NOTIMPL;
1832}

◆ testpos_get_PrerollTime()

static HRESULT WINAPI testpos_get_PrerollTime ( IMediaPosition *  iface,
REFTIME *  time 
)
static

Definition at line 1858 of file filtergraph.c.

1859{
1860 if (winetest_debug > 1) trace("%p->get_PrerollTime()\n", iface);
1861 return E_NOTIMPL;
1862}

◆ testpos_get_Rate()

static HRESULT WINAPI testpos_get_Rate ( IMediaPosition *  iface,
double *  rate 
)
static

Definition at line 1876 of file filtergraph.c.

1877{
1878 if (winetest_debug > 1) trace("%p->get_Rate()\n", iface);
1879 return E_NOTIMPL;
1880}

◆ testpos_get_StopTime()

static HRESULT WINAPI testpos_get_StopTime ( IMediaPosition *  iface,
REFTIME *  time 
)
static

Definition at line 1846 of file filtergraph.c.

1847{
1848 if (winetest_debug > 1) trace("%p->get_StopTime()\n", iface);
1849 return E_NOTIMPL;
1850}

◆ testpos_GetIDsOfNames()

static HRESULT WINAPI testpos_GetIDsOfNames ( IMediaPosition *  iface,
REFIID  riid,
LPOLESTR *  names,
UINT  count,
LCID  lcid,
DISPID *  ids 
)
static

Definition at line 1816 of file filtergraph.c.

1817{
1818 ok(0, "Unexpected call.\n");
1819 return E_NOTIMPL;
1820}

◆ testpos_GetTypeInfo()

static HRESULT WINAPI testpos_GetTypeInfo ( IMediaPosition *  iface,
UINT  index,
LCID  lcid,
ITypeInfo **  typeinfo 
)
static

Definition at line 1810 of file filtergraph.c.

1811{
1812 ok(0, "Unexpected call.\n");
1813 return E_NOTIMPL;
1814}

◆ testpos_GetTypeInfoCount()

static HRESULT WINAPI testpos_GetTypeInfoCount ( IMediaPosition *  iface,
UINT *  count 
)
static

Definition at line 1804 of file filtergraph.c.

1805{
1806 ok(0, "Unexpected call.\n");
1807 return E_NOTIMPL;
1808}

◆ testpos_Invoke()

static HRESULT WINAPI testpos_Invoke ( IMediaPosition *  iface,
DISPID  id,
REFIID  iid,
LCID  lcid,
WORD  flags,
DISPPARAMS *  params,
VARIANT *  result,
EXCEPINFO *  excepinfo,
UINT *  error_arg 
)
static

Definition at line 1822 of file filtergraph.c.

1823{
1824 ok(0, "Unexpected call.\n");
1825 return E_NOTIMPL;
1826}

◆ testpos_put_CurrentPosition()

static HRESULT WINAPI testpos_put_CurrentPosition ( IMediaPosition *  iface,
REFTIME  time 
)
static

Definition at line 1834 of file filtergraph.c.

1835{
1836 if (winetest_debug > 1) trace("%p->put_CurrentPosition(%f)\n", iface, time);
1837 return E_NOTIMPL;
1838}

◆ testpos_put_PrerollTime()

static HRESULT WINAPI testpos_put_PrerollTime ( IMediaPosition *  iface,
REFTIME  time 
)
static

Definition at line 1864 of file filtergraph.c.

1865{
1866 ok(0, "Unexpected call.\n");
1867 return E_NOTIMPL;
1868}

◆ testpos_put_Rate()

static HRESULT WINAPI testpos_put_Rate ( IMediaPosition *  iface,
double  rate 
)
static

Definition at line 1870 of file filtergraph.c.

1871{
1872 ok(0, "Unexpected call.\n");
1873 return E_NOTIMPL;
1874}

◆ testpos_put_StopTime()

static HRESULT WINAPI testpos_put_StopTime ( IMediaPosition *  iface,
REFTIME  time 
)
static

Definition at line 1852 of file filtergraph.c.

1853{
1854 ok(0, "Unexpected call.\n");
1855 return E_NOTIMPL;
1856}

◆ testpos_QueryInterface()

static HRESULT WINAPI testpos_QueryInterface ( IMediaPosition *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 1786 of file filtergraph.c.

1787{
1789 return IBaseFilter_QueryInterface(&filter->IBaseFilter_iface, iid, out);
1790}

◆ testpos_Release()

static ULONG WINAPI testpos_Release ( IMediaPosition *  iface)
static

Definition at line 1798 of file filtergraph.c.

1799{
1801 return IBaseFilter_Release(&filter->IBaseFilter_iface);
1802}

◆ testseek_AddRef()

static ULONG WINAPI testseek_AddRef ( IMediaSeeking *  iface)
static

Definition at line 1611 of file filtergraph.c.

1612{
1613 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1614 InterlockedIncrement(&filter->seeking_ref);
1615 return InterlockedIncrement(&filter->ref);
1616}
static struct filter_graph * impl_from_IMediaSeeking(IMediaSeeking *iface)
Definition: filtergraph.c:2102

◆ testseek_CheckCapabilities()

static HRESULT WINAPI testseek_CheckCapabilities ( IMediaSeeking *  iface,
DWORD *  caps 
)
static

Definition at line 1633 of file filtergraph.c.

1634{
1635 ok(0, "Unexpected call.\n");
1636 return E_NOTIMPL;
1637}

◆ testseek_ConvertTimeFormat()

static HRESULT WINAPI testseek_ConvertTimeFormat ( IMediaSeeking *  iface,
LONGLONG *  target,
const GUID *  target_format,
LONGLONG  source,
const GUID *  source_format 
)
static

Definition at line 1704 of file filtergraph.c.

1706{
1707 ok(0, "Unexpected call.\n");
1708 return E_NOTIMPL;
1709}

◆ testseek_GetAvailable()

static HRESULT WINAPI testseek_GetAvailable ( IMediaSeeking *  iface,
LONGLONG *  earliest,
LONGLONG *  latest 
)
static

Definition at line 1731 of file filtergraph.c.

1732{
1733 ok(0, "Unexpected call.\n");
1734 return E_NOTIMPL;
1735}

◆ testseek_GetCapabilities()

static HRESULT WINAPI testseek_GetCapabilities ( IMediaSeeking *  iface,
DWORD *  caps 
)
static

Definition at line 1625 of file filtergraph.c.

1626{
1627 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1628 if (winetest_debug > 1) trace("%p->GetCapabilities()\n", iface);
1629 *caps = filter->seek_caps;
1630 return S_OK;
1631}

◆ testseek_GetCurrentPosition()

static HRESULT WINAPI testseek_GetCurrentPosition ( IMediaSeeking *  iface,
LONGLONG *  current 
)
static

Definition at line 1695 of file filtergraph.c.

1696{
1697 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1698 if (winetest_debug > 1) trace("%p->GetCurrentPosition()\n", iface);
1699 ok(!filter->clock, "GetCurrentPosition() should only be called if there is no sync source.\n");
1700 *current = 0xdeadbeef;
1701 return S_OK;
1702}

◆ testseek_GetDuration()

static HRESULT WINAPI testseek_GetDuration ( IMediaSeeking *  iface,
LONGLONG *  duration 
)
static

Definition at line 1679 of file filtergraph.c.

1680{
1681 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1682 if (winetest_debug > 1) trace("%p->GetDuration()\n", iface);
1683 *duration = filter->seek_duration;
1684 return filter->seek_hr;
1685}

◆ testseek_GetPositions()

static HRESULT WINAPI testseek_GetPositions ( IMediaSeeking *  iface,
LONGLONG *  current,
LONGLONG *  stop 
)
static

Definition at line 1725 of file filtergraph.c.

1726{
1727 ok(0, "Unexpected call.\n");
1728 return E_NOTIMPL;
1729}

◆ testseek_GetPreroll()

static HRESULT WINAPI testseek_GetPreroll ( IMediaSeeking *  iface,
LONGLONG *  preroll 
)
static

Definition at line 1751 of file filtergraph.c.

1752{
1753 if (winetest_debug > 1) trace("%p->GetPreroll()\n", iface);
1754 return E_NOTIMPL;
1755}

◆ testseek_GetRate()

static HRESULT WINAPI testseek_GetRate ( IMediaSeeking *  iface,
double *  rate 
)
static

Definition at line 1745 of file filtergraph.c.

1746{
1747 ok(0, "Unexpected call.\n");
1748 return E_NOTIMPL;
1749}

◆ testseek_GetStopPosition()

static HRESULT WINAPI testseek_GetStopPosition ( IMediaSeeking *  iface,
LONGLONG *  stop 
)
static

Definition at line 1687 of file filtergraph.c.

1688{
1689 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1690 if (winetest_debug > 1) trace("%p->GetStopPosition()\n", iface);
1691 *stop = filter->seek_stop;
1692 return filter->seek_hr;
1693}

◆ testseek_GetTimeFormat()

static HRESULT WINAPI testseek_GetTimeFormat ( IMediaSeeking *  iface,
GUID *  format 
)
static

Definition at line 1656 of file filtergraph.c.

1657{
1658 if (winetest_debug > 1) trace("%p->GetTimeFormat()\n", iface);
1659 return E_NOTIMPL;
1660}

◆ testseek_IsFormatSupported()

static HRESULT WINAPI testseek_IsFormatSupported ( IMediaSeeking *  iface,
const GUID *  format 
)
static

Definition at line 1639 of file filtergraph.c.

1640{
1641 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1642 if (winetest_debug > 1) trace("%p->IsFormatSupported(%s)\n", iface, wine_dbgstr_guid(format));
1643 if (IsEqualGUID(format, &testguid) && !filter->support_testguid)
1644 return S_FALSE;
1645 if (IsEqualGUID(format, &TIME_FORMAT_MEDIA_TIME) && !filter->support_media_time)
1646 return S_FALSE;
1647 return S_OK;
1648}

◆ testseek_IsUsingTimeFormat()

static HRESULT WINAPI testseek_IsUsingTimeFormat ( IMediaSeeking *  iface,
const GUID *  format 
)
static

Definition at line 1662 of file filtergraph.c.

1663{
1664 if (winetest_debug > 1) trace("%p->IsUsingTimeFormat(%s)\n", iface, wine_dbgstr_guid(format));
1665 return S_OK;
1666}

◆ testseek_QueryInterface()

static HRESULT WINAPI testseek_QueryInterface ( IMediaSeeking *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 1605 of file filtergraph.c.

1606{
1607 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1608 return IBaseFilter_QueryInterface(&filter->IBaseFilter_iface, iid, out);
1609}

◆ testseek_QueryPreferredFormat()

static HRESULT WINAPI testseek_QueryPreferredFormat ( IMediaSeeking *  iface,
GUID *  format 
)
static

Definition at line 1650 of file filtergraph.c.

1651{
1652 if (winetest_debug > 1) trace("%p->QueryPreferredFormat()\n", iface);
1653 return E_NOTIMPL;
1654}

◆ testseek_Release()

static ULONG WINAPI testseek_Release ( IMediaSeeking *  iface)
static

Definition at line 1618 of file filtergraph.c.

1619{
1620 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1621 InterlockedDecrement(&filter->seeking_ref);
1622 return InterlockedDecrement(&filter->ref);
1623}

◆ testseek_SetPositions()

static HRESULT WINAPI testseek_SetPositions ( IMediaSeeking *  iface,
LONGLONG *  current,
DWORD  current_flags,
LONGLONG *  stop,
DWORD  stop_flags 
)
static

Definition at line 1711 of file filtergraph.c.

1713{
1714 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1715 if (winetest_debug > 1) trace("%p->SetPositions(%s, %#lx, %s, %#lx)\n",
1716 iface, wine_dbgstr_longlong(*current), current_flags, wine_dbgstr_longlong(*stop), stop_flags);
1717 ok(filter->state != State_Running, "Filter should be paused or stopped while seeking.\n");
1718 filter->seek_current = *current;
1719 filter->seek_stop = *stop;
1720 *current = 12340000;
1721 *stop = 43210000;
1722 return filter->seek_hr;
1723}

◆ testseek_SetRate()

static HRESULT WINAPI testseek_SetRate ( IMediaSeeking *  iface,
double  rate 
)
static

Definition at line 1737 of file filtergraph.c.

1738{
1739 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1740 if (winetest_debug > 1) trace("%p->SetRate(%.16e)\n", iface, rate);
1741 filter->seek_rate = rate;
1742 return S_OK;
1743}

◆ testseek_SetTimeFormat()

static HRESULT WINAPI testseek_SetTimeFormat ( IMediaSeeking *  iface,
const GUID *  format 
)
static

Definition at line 1668 of file filtergraph.c.

1669{
1670 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1671 if (winetest_debug > 1) trace("%p->SetTimeFormat(%s)\n", iface, wine_dbgstr_guid(format));
1672 ok(!IsEqualGUID(format, &GUID_NULL), "Got unexpected GUID_NULL.\n");
1673 if (IsEqualGUID(format, &testguid) && !filter->support_testguid)
1674 return E_INVALIDARG;
1675 filter->time_format = *format;
1676 return S_OK;
1677}

◆ testsink_init()

static void testsink_init ( struct testpin *  pin)
static

Definition at line 1191 of file filtergraph.c.

1192{
1194}
static const IPinVtbl testsink_vtbl
Definition: filtergraph.c:1155

Referenced by test_default_sync_source(), test_ec_complete(), test_filter_state(), test_graph_builder_connect(), and test_graph_builder_render().

◆ testsink_ReceiveConnection()

static HRESULT WINAPI testsink_ReceiveConnection ( IPin *  iface,
IPin *  peer,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 1139 of file filtergraph.c.

1140{
1141 struct testpin *pin = impl_from_IPin(iface);
1142 if (winetest_debug > 1) trace("%p->ReceiveConnection(%p)\n", pin, peer);
1143
1144 if (pin->accept_mt && memcmp(pin->accept_mt, mt, sizeof(*mt)))
1146
1147 if (pin->require_connected_pin && !pin->require_connected_pin->peer)
1149
1150 pin->peer = peer;
1151 IPin_AddRef(peer);
1152 return S_OK;
1153}
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
AM_MEDIA_TYPE * accept_mt
Definition: filtergraph.c:832
const struct testpin * require_connected_pin
Definition: filtergraph.c:833

◆ testsource_Connect()

static HRESULT WINAPI testsource_Connect ( IPin *  iface,
IPin *  peer,
const AM_MEDIA_TYPE *  mt 
)
static

Definition at line 1196 of file filtergraph.c.

1197{
1198 struct testpin *pin = impl_from_IPin(iface);
1199 HRESULT hr;
1200 if (winetest_debug > 1) trace("%p->Connect(%p)\n", pin, peer);
1201
1202 if (FAILED(pin->Connect_hr))
1203 return pin->Connect_hr;
1204
1205 if (pin->require_connected_pin && !pin->require_connected_pin->peer)
1207
1208 ok(!mt, "Got media type %p.\n", mt);
1209
1210 if (SUCCEEDED(hr = IPin_ReceiveConnection(peer, &pin->IPin_iface, pin->request_mt)))
1211 {
1212 pin->peer = peer;
1213 IPin_AddRef(peer);
1214 return pin->Connect_hr;
1215 }
1216 return hr;
1217}
AM_MEDIA_TYPE * request_mt
Definition: filtergraph.c:832
#define VFW_E_NO_ACCEPTABLE_TYPES
Definition: vfwmsgs.h:46

◆ testsource_init()

static void testsource_init ( struct testpin *  pin,
const AM_MEDIA_TYPE *  types,
int  type_count 
)
static

Definition at line 1241 of file filtergraph.c.

1242{
1244 pin->types = types;
1245 pin->type_count = type_count;
1246}
static const IPinVtbl testsource_vtbl
Definition: filtergraph.c:1219
Definition: cmds.c:130

Referenced by test_add_source_filter(), test_autoplug_uyvy(), test_default_sync_source(), test_filter_state(), test_graph_builder_connect(), and test_graph_builder_render().

Variable Documentation

◆ expect_parent_message

BOOL expect_parent_message = TRUE
static

Definition at line 5432 of file filtergraph.c.

Referenced by parent_proc(), and test_window_threading().

◆ mpegtestsink_meminput_vtbl

const IMemInputPinVtbl mpegtestsink_meminput_vtbl
static
Initial value:
=
{
}
static HRESULT STDMETHODCALLTYPE meminput_Receive(IMemInputPin *iface, IMediaSample *sample)
Definition: filtergraph.c:4314
static HRESULT STDMETHODCALLTYPE meminput_ReceiveCanBlock(IMemInputPin *iface)
Definition: filtergraph.c:4346
static HRESULT WINAPI meminput_QueryInterface(IMemInputPin *iface, REFIID iid, void **out)
Definition: filtergraph.c:4278
static HRESULT STDMETHODCALLTYPE meminput_GetAllocator(IMemInputPin *iface, IMemAllocator **allocator)
Definition: filtergraph.c:4299
static HRESULT STDMETHODCALLTYPE meminput_NotifyAllocator(IMemInputPin *iface, IMemAllocator *allocator, BOOL readonly)
Definition: filtergraph.c:4304
static HRESULT STDMETHODCALLTYPE meminput_GetAllocatorRequirements(IMemInputPin *iface, ALLOCATOR_PROPERTIES *props)
Definition: filtergraph.c:4309
static ULONG WINAPI meminput_Release(IMemInputPin *iface)
Definition: filtergraph.c:4293
static ULONG WINAPI meminput_AddRef(IMemInputPin *iface)
Definition: filtergraph.c:4287
static HRESULT STDMETHODCALLTYPE meminput_ReceiveMultiple(IMemInputPin *iface, IMediaSample **samples, LONG n_samples, LONG *n_samples_processed)
Definition: filtergraph.c:4340

Definition at line 4348 of file filtergraph.c.

Referenced by test_renderfile_compressed().

◆ mpegtestsink_vtbl

const IPinVtbl mpegtestsink_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testpin_Disconnect(IPin *iface)
Definition: filtergraph.c:1001
static HRESULT WINAPI testpin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mt)
Definition: filtergraph.c:1068
static HRESULT WINAPI mpegtestsink_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: filtergraph.c:4229
static HRESULT WINAPI no_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: filtergraph.c:1121
static HRESULT WINAPI testpin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *mt)
Definition: filtergraph.c:1031
static HRESULT WINAPI testpin_QueryPinInfo(IPin *iface, PIN_INFO *info)
Definition: filtergraph.c:1037
static ULONG WINAPI testpin_AddRef(IPin *iface)
Definition: filtergraph.c:989
static HRESULT WINAPI testpin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **out)
Definition: filtergraph.c:1074
static HRESULT WINAPI testpin_QueryId(IPin *iface, WCHAR **id)
Definition: filtergraph.c:1059
static HRESULT WINAPI mpegtestpin_EndOfStream(IPin *iface)
Definition: filtergraph.c:4246
static HRESULT WINAPI testpin_QueryInterface(IPin *iface, REFIID iid, void **out)
Definition: filtergraph.c:967
static HRESULT WINAPI testpin_QueryInternalConnections(IPin *iface, IPin **out, ULONG *count)
Definition: filtergraph.c:1088
static HRESULT WINAPI testpin_QueryDirection(IPin *iface, PIN_DIRECTION *dir)
Definition: filtergraph.c:1050
static HRESULT WINAPI testpin_BeginFlush(IPin *iface)
Definition: filtergraph.c:1097
static HRESULT WINAPI testpin_EndFlush(IPin *iface)
Definition: filtergraph.c:1103
static HRESULT WINAPI mpegtestpin_NewSegment(IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
Definition: filtergraph.c:4251
static HRESULT WINAPI testpin_ConnectedTo(IPin *iface, IPin **peer)
Definition: filtergraph.c:1017
static ULONG WINAPI testpin_Release(IPin *iface)
Definition: filtergraph.c:995

Definition at line 4256 of file filtergraph.c.

Referenced by test_renderfile_compressed().

◆ outer_ref

LONG outer_ref = 1
static

Definition at line 2731 of file filtergraph.c.

Referenced by outer_AddRef(), outer_Release(), and test_aggregation().

◆ outer_vtbl

const IUnknownVtbl outer_vtbl
static
Initial value:
=
{
}
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: filtergraph.c:2746
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: filtergraph.c:2733
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: filtergraph.c:2751

Definition at line 2756 of file filtergraph.c.

◆ test_connect_direct_vtbl

const IPinVtbl test_connect_direct_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI no_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: filtergraph.c:1127
static HRESULT WINAPI no_EnumMediaTypes(IPin *iface, IEnumMediaTypes **out)
Definition: filtergraph.c:1133
static HRESULT WINAPI testpin_EndOfStream(IPin *iface)
Definition: filtergraph.c:1115
static HRESULT WINAPI test_connect_direct_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: filtergraph.c:3046
static HRESULT WINAPI testpin_NewSegment(IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
Definition: filtergraph.c:1109

Definition at line 3057 of file filtergraph.c.

Referenced by test_connect_direct_init().

◆ test_iid

const GUID test_iid = {0x33333333}
static

Definition at line 2730 of file filtergraph.c.

Referenced by outer_QueryInterface(), and test_aggregation().

◆ test_outer

IUnknown test_outer = {&outer_vtbl}
static

Definition at line 2763 of file filtergraph.c.

Referenced by test_aggregation().

◆ testclock_vtbl

const IReferenceClockVtbl testclock_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testclock_AdvisePeriodic(IReferenceClock *iface, REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie)
Definition: filtergraph.c:1952
static ULONG WINAPI testclock_Release(IReferenceClock *iface)
Definition: filtergraph.c:1933
static ULONG WINAPI testclock_AddRef(IReferenceClock *iface)
Definition: filtergraph.c:1927
static HRESULT WINAPI testclock_GetTime(IReferenceClock *iface, REFERENCE_TIME *time)
Definition: filtergraph.c:1939
static HRESULT WINAPI testclock_Unadvise(IReferenceClock *iface, DWORD_PTR cookie)
Definition: filtergraph.c:1959
static HRESULT WINAPI testclock_QueryInterface(IReferenceClock *iface, REFIID iid, void **out)
Definition: filtergraph.c:1921
static HRESULT WINAPI testclock_AdviseTime(IReferenceClock *iface, REFERENCE_TIME base, REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie)
Definition: filtergraph.c:1945

Definition at line 1965 of file filtergraph.c.

Referenced by test_default_sync_source().

◆ testenummt_vtbl

const IEnumMediaTypesVtbl testenummt_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testenummt_Skip(IEnumMediaTypes *iface, ULONG count)
Definition: filtergraph.c:927
static HRESULT WINAPI testenummt_Next(IEnumMediaTypes *iface, ULONG count, AM_MEDIA_TYPE **out, ULONG *fetched)
Definition: filtergraph.c:906
static ULONG WINAPI testenummt_AddRef(IEnumMediaTypes *iface)
Definition: filtergraph.c:894
static HRESULT WINAPI testenummt_QueryInterface(IEnumMediaTypes *iface, REFIID iid, void **out)
Definition: filtergraph.c:885
static ULONG WINAPI testenummt_Release(IEnumMediaTypes *iface)
Definition: filtergraph.c:900
static HRESULT WINAPI testenummt_Clone(IEnumMediaTypes *iface, IEnumMediaTypes **out)
Definition: filtergraph.c:940
static HRESULT WINAPI testenummt_Reset(IEnumMediaTypes *iface)
Definition: filtergraph.c:933

Definition at line 946 of file filtergraph.c.

Referenced by testpin_init().

◆ testenumpins_vtbl

const IEnumPinsVtbl testenumpins_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testenumpins_Next(IEnumPins *iface, ULONG count, IPin **out, ULONG *fetched)
Definition: filtergraph.c:1271
static HRESULT WINAPI testenumpins_Clone(IEnumPins *iface, IEnumPins **out)
Definition: filtergraph.c:1305
static HRESULT WINAPI testenumpins_Skip(IEnumPins *iface, ULONG count)
Definition: filtergraph.c:1292
static HRESULT WINAPI testenumpins_Reset(IEnumPins *iface)
Definition: filtergraph.c:1298
static HRESULT WINAPI testenumpins_QueryInterface(IEnumPins *iface, REFIID iid, void **out)
Definition: filtergraph.c:1253
static ULONG WINAPI testenumpins_Release(IEnumPins *iface)
Definition: filtergraph.c:1265
static ULONG WINAPI testenumpins_AddRef(IEnumPins *iface)
Definition: filtergraph.c:1259

Definition at line 1311 of file filtergraph.c.

Referenced by testfilter_init().

◆ testfilesource_vtbl

const IFileSourceFilterVtbl testfilesource_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testfilesource_Load(IFileSourceFilter *iface, const WCHAR *filename, const AM_MEDIA_TYPE *mt)
Definition: filtergraph.c:1999
static HRESULT WINAPI testfilesource_GetCurFile(IFileSourceFilter *iface, WCHAR **filename, AM_MEDIA_TYPE *mt)
Definition: filtergraph.c:2006
static ULONG WINAPI testfilesource_AddRef(IFileSourceFilter *iface)
Definition: filtergraph.c:1987
static ULONG WINAPI testfilesource_Release(IFileSourceFilter *iface)
Definition: filtergraph.c:1993
static HRESULT WINAPI testfilesource_QueryInterface(IFileSourceFilter *iface, REFIID iid, void **out)
Definition: filtergraph.c:1981

Definition at line 2013 of file filtergraph.c.

Referenced by test_add_source_filter().

◆ testfilter_cf_vtbl

IClassFactoryVtbl testfilter_cf_vtbl
static
Initial value:
=
{
}
static ULONG WINAPI testfilter_cf_AddRef(IClassFactory *iface)
Definition: filtergraph.c:2059
static HRESULT WINAPI testfilter_cf_LockServer(IClassFactory *iface, BOOL lock)
Definition: filtergraph.c:2076
static HRESULT WINAPI testfilter_cf_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
Definition: filtergraph.c:2047
static HRESULT WINAPI testfilter_cf_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out)
Definition: filtergraph.c:2069
static ULONG WINAPI testfilter_cf_Release(IClassFactory *iface)
Definition: filtergraph.c:2064

Definition at line 2081 of file filtergraph.c.

Referenced by test_add_source_filter(), test_graph_builder_connect(), and test_graph_builder_render().

◆ testfilter_vtbl

const IBaseFilterVtbl testfilter_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testfilter_GetState(IBaseFilter *iface, DWORD timeout, FILTER_STATE *state)
Definition: filtergraph.c:1455
static HRESULT WINAPI testfilter_Run(IBaseFilter *iface, REFERENCE_TIME start)
Definition: filtergraph.c:1440
static HRESULT WINAPI testfilter_GetClassID(IBaseFilter *iface, CLSID *clsid)
Definition: filtergraph.c:1381
static HRESULT WINAPI testfilter_FindPin(IBaseFilter *iface, const WCHAR *id, IPin **pin)
Definition: filtergraph.c:1494
static ULONG WINAPI testfilter_Release(IBaseFilter *iface)
Definition: filtergraph.c:1375
static HRESULT WINAPI testfilter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *info)
Definition: filtergraph.c:1512
static HRESULT WINAPI testfilter_Pause(IBaseFilter *iface)
Definition: filtergraph.c:1429
static ULONG WINAPI testfilter_AddRef(IBaseFilter *iface)
Definition: filtergraph.c:1369
static HRESULT WINAPI testfilter_Stop(IBaseFilter *iface)
Definition: filtergraph.c:1414
static HRESULT WINAPI testfilter_GetSyncSource(IBaseFilter *iface, IReferenceClock **clock)
Definition: filtergraph.c:1477
static HRESULT WINAPI testfilter_EnumPins(IBaseFilter *iface, IEnumPins **out)
Definition: filtergraph.c:1483
static HRESULT WINAPI testfilter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *graph, const WCHAR *name)
Definition: filtergraph.c:1527
static HRESULT WINAPI testfilter_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock)
Definition: filtergraph.c:1464
static HRESULT WINAPI testfilter_QueryVendorInfo(IBaseFilter *iface, WCHAR **info)
Definition: filtergraph.c:1538
static HRESULT WINAPI testfilter_QueryInterface(IBaseFilter *iface, REFIID iid, void **out)
Definition: filtergraph.c:1327

Definition at line 1543 of file filtergraph.c.

Referenced by testfilter_init().

◆ testguid

const GUID testguid = {0xabbccdde}
static

◆ testmiscflags_vtbl

const IAMFilterMiscFlagsVtbl testmiscflags_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testmiscflags_QueryInterface(IAMFilterMiscFlags *iface, REFIID iid, void **out)
Definition: filtergraph.c:1567
static ULONG WINAPI testmiscflags_Release(IAMFilterMiscFlags *iface)
Definition: filtergraph.c:1579
static ULONG WINAPI testmiscflags_AddRef(IAMFilterMiscFlags *iface)
Definition: filtergraph.c:1573
static ULONG WINAPI testmiscflags_GetMiscFlags(IAMFilterMiscFlags *iface)
Definition: filtergraph.c:1585

Definition at line 1592 of file filtergraph.c.

Referenced by test_ec_complete(), test_events(), and test_set_notify_flags().

◆ testpos_vtbl

const IMediaPositionVtbl testpos_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testpos_QueryInterface(IMediaPosition *iface, REFIID iid, void **out)
Definition: filtergraph.c:1786
static HRESULT WINAPI testpos_Invoke(IMediaPosition *iface, DISPID id, REFIID iid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg)
Definition: filtergraph.c:1822
static HRESULT WINAPI testpos_CanSeekBackward(IMediaPosition *iface, LONG *can_seek_backward)
Definition: filtergraph.c:1888
static HRESULT WINAPI testpos_get_StopTime(IMediaPosition *iface, REFTIME *time)
Definition: filtergraph.c:1846
static HRESULT WINAPI testpos_put_CurrentPosition(IMediaPosition *iface, REFTIME time)
Definition: filtergraph.c:1834
static ULONG WINAPI testpos_Release(IMediaPosition *iface)
Definition: filtergraph.c:1798
static HRESULT WINAPI testpos_get_CurrentPosition(IMediaPosition *iface, REFTIME *time)
Definition: filtergraph.c:1840
static HRESULT WINAPI testpos_GetTypeInfo(IMediaPosition *iface, UINT index, LCID lcid, ITypeInfo **typeinfo)
Definition: filtergraph.c:1810
static HRESULT WINAPI testpos_get_Duration(IMediaPosition *iface, REFTIME *length)
Definition: filtergraph.c:1828
static HRESULT WINAPI testpos_GetTypeInfoCount(IMediaPosition *iface, UINT *count)
Definition: filtergraph.c:1804
static HRESULT WINAPI testpos_get_PrerollTime(IMediaPosition *iface, REFTIME *time)
Definition: filtergraph.c:1858
static HRESULT WINAPI testpos_CanSeekForward(IMediaPosition *iface, LONG *can_seek_forward)
Definition: filtergraph.c:1882
static HRESULT WINAPI testpos_put_PrerollTime(IMediaPosition *iface, REFTIME time)
Definition: filtergraph.c:1864
static HRESULT WINAPI testpos_get_Rate(IMediaPosition *iface, double *rate)
Definition: filtergraph.c:1876
static HRESULT WINAPI testpos_GetIDsOfNames(IMediaPosition *iface, REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
Definition: filtergraph.c:1816
static ULONG WINAPI testpos_AddRef(IMediaPosition *iface)
Definition: filtergraph.c:1792
static HRESULT WINAPI testpos_put_Rate(IMediaPosition *iface, double rate)
Definition: filtergraph.c:1870
static HRESULT WINAPI testpos_put_StopTime(IMediaPosition *iface, REFTIME time)
Definition: filtergraph.c:1852

Definition at line 1894 of file filtergraph.c.

Referenced by test_ec_complete().

◆ testseek_vtbl

const IMediaSeekingVtbl testseek_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI testseek_CheckCapabilities(IMediaSeeking *iface, DWORD *caps)
Definition: filtergraph.c:1633
static ULONG WINAPI testseek_Release(IMediaSeeking *iface)
Definition: filtergraph.c:1618
static ULONG WINAPI testseek_AddRef(IMediaSeeking *iface)
Definition: filtergraph.c:1611
static HRESULT WINAPI testseek_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
Definition: filtergraph.c:1605
static HRESULT WINAPI testseek_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop)
Definition: filtergraph.c:1687
static HRESULT WINAPI testseek_IsFormatSupported(IMediaSeeking *iface, const GUID *format)
Definition: filtergraph.c:1639
static HRESULT WINAPI testseek_SetRate(IMediaSeeking *iface, double rate)
Definition: filtergraph.c:1737
static HRESULT WINAPI testseek_GetDuration(IMediaSeeking *iface, LONGLONG *duration)
Definition: filtergraph.c:1679
static HRESULT WINAPI testseek_SetPositions(IMediaSeeking *iface, LONGLONG *current, DWORD current_flags, LONGLONG *stop, DWORD stop_flags)
Definition: filtergraph.c:1711
static HRESULT WINAPI testseek_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target, const GUID *target_format, LONGLONG source, const GUID *source_format)
Definition: filtergraph.c:1704
static HRESULT WINAPI testseek_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format)
Definition: filtergraph.c:1662
static HRESULT WINAPI testseek_QueryPreferredFormat(IMediaSeeking *iface, GUID *format)
Definition: filtergraph.c:1650
static HRESULT WINAPI testseek_GetCapabilities(IMediaSeeking *iface, DWORD *caps)
Definition: filtergraph.c:1625
static HRESULT WINAPI testseek_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest)
Definition: filtergraph.c:1731
static HRESULT WINAPI testseek_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current)
Definition: filtergraph.c:1695
static HRESULT WINAPI testseek_SetTimeFormat(IMediaSeeking *iface, const GUID *format)
Definition: filtergraph.c:1668
static HRESULT WINAPI testseek_GetTimeFormat(IMediaSeeking *iface, GUID *format)
Definition: filtergraph.c:1656
static HRESULT WINAPI testseek_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll)
Definition: filtergraph.c:1751
static HRESULT WINAPI testseek_GetRate(IMediaSeeking *iface, double *rate)
Definition: filtergraph.c:1745
static HRESULT WINAPI testseek_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
Definition: filtergraph.c:1725

Definition at line 1757 of file filtergraph.c.

Referenced by flush_cached_seeking(), test_ec_complete(), test_filter_state(), and test_graph_seeking().

◆ testsink_vtbl

◆ testsource_vtbl