Implemented IMemAllocator.
[wine/multimedia.git] / dlls / quartz / fgraph.c
blob0b66264dde71243d9701457498c67f32c4e3ca99
1 /*
2 * Implementation of CLSID_FilterGraph.
4 * hidenori@a2.ctktv.ne.jp
5 */
7 #include "config.h"
9 #include "windef.h"
10 #include "winbase.h"
11 #include "wingdi.h"
12 #include "winuser.h"
13 #include "winerror.h"
14 #include "wine/obj_base.h"
15 #include "wine/obj_oleaut.h"
16 #include "strmif.h"
17 #include "control.h"
18 #include "uuids.h"
20 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(quartz);
23 #include "quartz_private.h"
24 #include "fgraph.h"
26 /* can I use offsetof safely? - FIXME? */
27 static QUARTZ_IFEntry IFEntries[] =
29 { &IID_IPersist, offsetof(CFilterGraph,persist)-offsetof(CFilterGraph,unk) },
30 { &IID_IDispatch, offsetof(CFilterGraph,disp)-offsetof(CFilterGraph,unk) },
31 { &IID_IFilterGraph, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
32 { &IID_IGraphBuilder, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
33 { &IID_IFilterGraph2, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
34 { &IID_IGraphVersion, offsetof(CFilterGraph,graphversion)-offsetof(CFilterGraph,unk) },
35 { &IID_IMediaControl, offsetof(CFilterGraph,mediacontrol)-offsetof(CFilterGraph,unk) },
36 { &IID_IMediaFilter, offsetof(CFilterGraph,mediafilter)-offsetof(CFilterGraph,unk) },
37 { &IID_IMediaEvent, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
38 { &IID_IMediaEventEx, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
39 { &IID_IMediaEventSink, offsetof(CFilterGraph,mediaeventsink)-offsetof(CFilterGraph,unk) },
40 { &IID_IMediaPosition, offsetof(CFilterGraph,mediaposition)-offsetof(CFilterGraph,unk) },
41 { &IID_IMediaSeeking, offsetof(CFilterGraph,mediaseeking)-offsetof(CFilterGraph,unk) },
42 { &IID_IBasicVideo, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) },
43 { &IID_IBasicVideo2, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) },
44 { &IID_IBasicAudio, offsetof(CFilterGraph,basaud)-offsetof(CFilterGraph,unk) },
45 { &IID_IVideoWindow, offsetof(CFilterGraph,vidwin)-offsetof(CFilterGraph,unk) },
49 struct FGInitEntry
51 HRESULT (*pInit)(CFilterGraph*);
52 void (*pUninit)(CFilterGraph*);
55 static const struct FGInitEntry FGRAPH_Init[] =
57 #define FGENT(a) {&CFilterGraph_Init##a,&CFilterGraph_Uninit##a},
59 FGENT(IPersist)
60 FGENT(IDispatch)
61 FGENT(IFilterGraph2)
62 FGENT(IGraphVersion)
63 FGENT(IMediaControl)
64 FGENT(IMediaFilter)
65 FGENT(IMediaEventEx)
66 FGENT(IMediaEventSink)
67 FGENT(IMediaPosition)
68 FGENT(IMediaSeeking)
69 FGENT(IBasicVideo2)
70 FGENT(IBasicAudio)
71 FGENT(IVideoWindow)
73 #undef FGENT
74 { NULL, NULL },
78 static void QUARTZ_DestroyFilterGraph(IUnknown* punk)
80 CFilterGraph_THIS(punk,unk);
81 int i;
83 /* At first, call Stop. */
84 IMediaControl_Stop( CFilterGraph_IMediaControl(This) );
85 IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
87 i = 0;
88 while ( FGRAPH_Init[i].pInit != NULL )
90 FGRAPH_Init[i].pUninit( This );
91 i++;
94 TRACE( "succeeded.\n" );
97 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj)
99 CFilterGraph* pfg;
100 HRESULT hr;
101 int i;
103 TRACE("(%p,%p)\n",punkOuter,ppobj);
105 pfg = (CFilterGraph*)QUARTZ_AllocObj( sizeof(CFilterGraph) );
106 if ( pfg == NULL )
107 return E_OUTOFMEMORY;
109 QUARTZ_IUnkInit( &pfg->unk, punkOuter );
111 i = 0;
112 hr = NOERROR;
113 while ( FGRAPH_Init[i].pInit != NULL )
115 hr = FGRAPH_Init[i].pInit( pfg );
116 if ( FAILED(hr) )
117 break;
118 i++;
121 if ( FAILED(hr) )
123 while ( --i >= 0 )
124 FGRAPH_Init[i].pUninit( pfg );
125 QUARTZ_FreeObj( pfg );
126 return hr;
129 pfg->unk.pEntries = IFEntries;
130 pfg->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
131 pfg->unk.pOnFinalRelease = QUARTZ_DestroyFilterGraph;
133 *ppobj = (void*)(&pfg->unk);
135 return S_OK;