ole32: IPersistStream is also implemented by any object that implements IStream.
[wine] / dlls / amstream / amstream.c
1 /*
2  * Implementation of IAMMultiMediaStream Interface
3  *
4  * Copyright 2004 Christian Costa
5  *
6  * This file contains the (internal) driver registration functions,
7  * driver enumeration APIs and DirectDraw creation functions.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include "config.h"
25 #include "wine/debug.h"
26
27 #define COBJMACROS
28
29 #include "winbase.h"
30 #include "wingdi.h"
31
32 #include "amstream_private.h"
33 #include "amstream.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(amstream);
36
37 typedef struct {
38     IAMMultiMediaStream lpVtbl;
39     LONG ref;
40     IGraphBuilder* pFilterGraph;
41     ULONG nbStreams;
42     IMediaStream** pStreams;
43     STREAM_TYPE StreamType;
44 } IAMMultiMediaStreamImpl;
45
46 static const struct IAMMultiMediaStreamVtbl AM_Vtbl;
47
48 HRESULT AM_create(IUnknown *pUnkOuter, LPVOID *ppObj)
49 {
50     IAMMultiMediaStreamImpl* object; 
51
52     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
53
54     if( pUnkOuter )
55         return CLASS_E_NOAGGREGATION;
56
57     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAMMultiMediaStreamImpl));
58
59     object->lpVtbl.lpVtbl = &AM_Vtbl;
60     object->ref = 1;
61
62     *ppObj = object;
63
64     return S_OK;
65 }
66
67 /*** IUnknown methods ***/
68 static HRESULT WINAPI IAMMultiMediaStreamImpl_QueryInterface(IAMMultiMediaStream* iface, REFIID riid, void** ppvObject)
69 {
70     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
71
72     FIXME("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
73
74     if (IsEqualGUID(riid, &IID_IUnknown) ||
75         IsEqualGUID(riid, &IID_IAMMultiMediaStream))
76     {
77         IClassFactory_AddRef(iface);
78         *ppvObject = This;
79         return S_OK;
80     }
81
82     ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
83
84     return E_NOINTERFACE;
85 }
86
87 static ULONG WINAPI IAMMultiMediaStreamImpl_AddRef(IAMMultiMediaStream* iface)
88 {
89     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
90
91     TRACE("(%p/%p)\n", iface, This);
92
93     return InterlockedIncrement(&This->ref);
94 }
95
96 static ULONG WINAPI IAMMultiMediaStreamImpl_Release(IAMMultiMediaStream* iface)
97 {
98     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
99     ULONG ref = InterlockedDecrement(&This->ref);
100
101     TRACE("(%p/%p)\n", iface, This);
102
103     if (!ref)
104         HeapFree(GetProcessHeap(), 0, This);
105
106     return ref;
107 }
108
109 /*** IMultiMediaStream methods ***/
110 static HRESULT WINAPI IAMMultiMediaStreamImpl_GetInformation(IAMMultiMediaStream* iface, char* pdwFlags, STREAM_TYPE* pStreamType)
111 {
112     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
113
114     FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, pdwFlags, pStreamType); 
115
116     return E_NOTIMPL;
117 }
118
119 static HRESULT WINAPI IAMMultiMediaStreamImpl_GetMediaStream(IAMMultiMediaStream* iface, REFMSPID idPurpose, IMediaStream** ppMediaStream)
120 {
121     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
122     MSPID PurposeId;
123     int i;
124
125     TRACE("(%p/%p)->(%p,%p)\n", This, iface, idPurpose, ppMediaStream);
126
127     for (i = 0; i < This->nbStreams; i++)
128     {
129         IMediaStream_GetInformation(This->pStreams[i], &PurposeId, NULL);
130         if (IsEqualIID(&PurposeId, idPurpose))
131         {
132             *ppMediaStream = This->pStreams[i];
133             IMediaStream_AddRef(*ppMediaStream);
134             return S_OK;
135         }
136     }
137
138     return MS_E_NOSTREAM;
139 }
140
141 static HRESULT WINAPI IAMMultiMediaStreamImpl_EnumMediaStreams(IAMMultiMediaStream* iface, long Index, IMediaStream** ppMediaStream)
142 {
143     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
144
145     FIXME("(%p/%p)->(%ld,%p) stub!\n", This, iface, Index, ppMediaStream); 
146
147     return E_NOTIMPL;
148 }
149
150 static HRESULT WINAPI IAMMultiMediaStreamImpl_GetState(IAMMultiMediaStream* iface, STREAM_STATE* pCurrentState)
151 {
152     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
153
154     FIXME("(%p/%p)->(%p) stub!\n", This, iface, pCurrentState); 
155
156     return E_NOTIMPL;
157 }
158
159 static HRESULT WINAPI IAMMultiMediaStreamImpl_SetState(IAMMultiMediaStream* iface, STREAM_STATE NewState)
160 {
161     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
162
163     FIXME("(%p/%p)->() stub!\n", This, iface); 
164
165     return E_NOTIMPL;
166 }
167
168 static HRESULT WINAPI IAMMultiMediaStreamImpl_GetTime(IAMMultiMediaStream* iface, STREAM_TIME* pCurrentTime)
169 {
170     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
171
172     FIXME("(%p/%p)->(%p) stub!\n", This, iface, pCurrentTime); 
173
174     return E_NOTIMPL;
175 }
176
177 static HRESULT WINAPI IAMMultiMediaStreamImpl_GetDuration(IAMMultiMediaStream* iface, STREAM_TIME* pDuration)
178 {
179     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
180
181     FIXME("(%p/%p)->(%p) stub!\n", This, iface, pDuration); 
182
183     return E_NOTIMPL;
184 }
185
186 static HRESULT WINAPI IAMMultiMediaStreamImpl_Seek(IAMMultiMediaStream* iface, STREAM_TIME SeekTime)
187 {
188     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
189
190     FIXME("(%p/%p)->() stub!\n", This, iface); 
191
192     return E_NOTIMPL;
193 }
194
195 static HRESULT WINAPI IAMMultiMediaStreamImpl_GetEndOfStream(IAMMultiMediaStream* iface, HANDLE* phEOS)
196 {
197     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
198
199     FIXME("(%p/%p)->(%p) stub!\n", This, iface, phEOS); 
200
201     return E_NOTIMPL;
202 }
203
204 /*** IAMMultiMediaStream methods ***/
205 static HRESULT WINAPI IAMMultiMediaStreamImpl_Initialize(IAMMultiMediaStream* iface, STREAM_TYPE StreamType, DWORD dwFlags, IGraphBuilder* pFilterGraph)
206 {
207     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
208     HRESULT hr = S_OK;
209
210     FIXME("(%p/%p)->(%lx,%lx,%p) partial stub!\n", This, iface, (DWORD)StreamType, dwFlags, pFilterGraph); 
211
212     if (pFilterGraph)
213     {
214         This->pFilterGraph = pFilterGraph;
215         IGraphBuilder_AddRef(This->pFilterGraph);
216     }
217     else
218     {
219         hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (LPVOID*)&This->pFilterGraph);
220     }
221
222     if (SUCCEEDED(hr))
223     {
224         This->StreamType = StreamType;
225     }
226
227     return hr;
228 }
229
230 static HRESULT WINAPI IAMMultiMediaStreamImpl_GetFilterGraph(IAMMultiMediaStream* iface, IGraphBuilder** ppGraphBuilder)
231 {
232     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
233
234     FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppGraphBuilder); 
235
236     return E_NOTIMPL;
237 }
238
239 static HRESULT WINAPI IAMMultiMediaStreamImpl_GetFilter(IAMMultiMediaStream* iface, IMediaStreamFilter** ppFilter)
240 {
241     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
242
243     FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppFilter); 
244
245     return E_NOTIMPL;
246 }
247
248 static HRESULT WINAPI IAMMultiMediaStreamImpl_AddMediaStream(IAMMultiMediaStream* iface, IUnknown* pStreamObject, const MSPID* PurposeId,
249                                           DWORD dwFlags, IMediaStream** ppNewStream)
250 {
251     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
252     HRESULT hr;
253     IMediaStream* pStream;
254     IMediaStream** pNewStreams;
255
256     FIXME("(%p/%p)->(%p,%p,%lx,%p) partial stub!\n", This, iface, pStreamObject, PurposeId, dwFlags, ppNewStream); 
257
258     hr = MediaStream_create((IMultiMediaStream*)iface, PurposeId, This->StreamType, &pStream);
259     if (SUCCEEDED(hr))
260     {
261         pNewStreams = (IMediaStream**)CoTaskMemAlloc((This->nbStreams+1)*sizeof(IMediaStream*));
262         if (!pNewStreams)
263         {
264             IMediaStream_Release(pStream);
265             return E_OUTOFMEMORY;
266         }
267         if (This->nbStreams)
268             CopyMemory(pNewStreams, This->pStreams, This->nbStreams*sizeof(IMediaStream*));
269         CoTaskMemFree(This->pStreams);
270         This->pStreams = pNewStreams;
271         This->pStreams[This->nbStreams] = pStream;
272         This->nbStreams++;
273
274         if (ppNewStream)
275             *ppNewStream = pStream;
276     }
277
278     return hr;
279 }
280
281 static HRESULT WINAPI IAMMultiMediaStreamImpl_OpenFile(IAMMultiMediaStream* iface, LPCWSTR pszFileName, DWORD dwFlags)
282 {
283     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
284
285     FIXME("(%p/%p)->(%s,%lx) stub!\n", This, iface, debugstr_w(pszFileName), dwFlags);
286
287     return E_NOTIMPL;
288 }
289
290 static HRESULT WINAPI IAMMultiMediaStreamImpl_OpenMoniker(IAMMultiMediaStream* iface, IBindCtx* pCtx, IMoniker* pMoniker, DWORD dwFlags)
291 {
292     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
293
294     FIXME("(%p/%p)->(%p,%p,%lx) stub!\n", This, iface, pCtx, pMoniker, dwFlags); 
295
296     return E_NOTIMPL;
297 }
298
299 static HRESULT WINAPI IAMMultiMediaStreamImpl_Render(IAMMultiMediaStream* iface, DWORD dwFlags)
300 {
301     IAMMultiMediaStreamImpl *This = (IAMMultiMediaStreamImpl *)iface;
302
303     FIXME("(%p/%p)->(%lx) stub!\n", This, iface, dwFlags); 
304
305     return E_NOTIMPL;
306 }
307
308 static const IAMMultiMediaStreamVtbl AM_Vtbl =
309 {
310     IAMMultiMediaStreamImpl_QueryInterface,
311     IAMMultiMediaStreamImpl_AddRef,
312     IAMMultiMediaStreamImpl_Release,
313     IAMMultiMediaStreamImpl_GetInformation,
314     IAMMultiMediaStreamImpl_GetMediaStream,
315     IAMMultiMediaStreamImpl_EnumMediaStreams,
316     IAMMultiMediaStreamImpl_GetState,
317     IAMMultiMediaStreamImpl_SetState,
318     IAMMultiMediaStreamImpl_GetTime,
319     IAMMultiMediaStreamImpl_GetDuration,
320     IAMMultiMediaStreamImpl_Seek,
321     IAMMultiMediaStreamImpl_GetEndOfStream,
322     IAMMultiMediaStreamImpl_Initialize,
323     IAMMultiMediaStreamImpl_GetFilterGraph,
324     IAMMultiMediaStreamImpl_GetFilter,
325     IAMMultiMediaStreamImpl_AddMediaStream,
326     IAMMultiMediaStreamImpl_OpenFile,
327     IAMMultiMediaStreamImpl_OpenMoniker,
328     IAMMultiMediaStreamImpl_Render
329 };