1 | /*
|
---|
2 | * Audio Renderer (CLSID_AudioRender)
|
---|
3 | *
|
---|
4 | * FIXME
|
---|
5 | * - implements IRefereneceClock.
|
---|
6 | * - implements seeking.
|
---|
7 | *
|
---|
8 | * hidenori@a2.ctktv.ne.jp
|
---|
9 | */
|
---|
10 |
|
---|
11 | #include "config.h"
|
---|
12 |
|
---|
13 | #include "windef.h"
|
---|
14 | #include "winbase.h"
|
---|
15 | #include "wingdi.h"
|
---|
16 | #include "winuser.h"
|
---|
17 | #include "mmsystem.h"
|
---|
18 | #include "winerror.h"
|
---|
19 | #include "wine/obj_base.h"
|
---|
20 | #include "wine/obj_oleaut.h"
|
---|
21 | #include "strmif.h"
|
---|
22 | #include "control.h"
|
---|
23 | #include "vfwmsgs.h"
|
---|
24 | #include "uuids.h"
|
---|
25 |
|
---|
26 | #include "debugtools.h"
|
---|
27 | DEFAULT_DEBUG_CHANNEL(quartz);
|
---|
28 |
|
---|
29 | #include "quartz_private.h"
|
---|
30 | #include "audren.h"
|
---|
31 |
|
---|
32 |
|
---|
33 | static const WCHAR QUARTZ_AudioRender_Name[] =
|
---|
34 | { 'A','u','d','i','o',' ','R','e','n','d','e','r',0 };
|
---|
35 | static const WCHAR QUARTZ_AudioRenderPin_Name[] =
|
---|
36 | { 'I','n',0 };
|
---|
37 |
|
---|
38 |
|
---|
39 |
|
---|
40 | /***************************************************************************
|
---|
41 | *
|
---|
42 | * CAudioRendererImpl waveOut methods (internal)
|
---|
43 | *
|
---|
44 | */
|
---|
45 |
|
---|
46 | static
|
---|
47 | HRESULT QUARTZ_HRESULT_From_MMRESULT( MMRESULT mr )
|
---|
48 | {
|
---|
49 | HRESULT hr = E_FAIL;
|
---|
50 |
|
---|
51 | switch ( mr )
|
---|
52 | {
|
---|
53 | case MMSYSERR_NOERROR:
|
---|
54 | hr = S_OK;
|
---|
55 | break;
|
---|
56 | case MMSYSERR_NOMEM:
|
---|
57 | hr = E_OUTOFMEMORY;
|
---|
58 | break;
|
---|
59 | }
|
---|
60 |
|
---|
61 | return hr;
|
---|
62 | }
|
---|
63 |
|
---|
64 | void CAudioRendererImpl_waveOutEventCallback(
|
---|
65 | HWAVEOUT hwo, UINT uMsg,
|
---|
66 | DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
|
---|
67 | {
|
---|
68 | CAudioRendererImpl* This = (CAudioRendererImpl*)dwInstance;
|
---|
69 |
|
---|
70 | if ( uMsg == WOM_DONE )
|
---|
71 | SetEvent( This->m_hEventRender );
|
---|
72 | }
|
---|
73 |
|
---|
74 | static
|
---|
75 | void CAudioRendererImpl_waveOutReset(
|
---|
76 | CAudioRendererImpl* This )
|
---|
77 | {
|
---|
78 | if ( !This->m_fWaveOutInit )
|
---|
79 | return;
|
---|
80 |
|
---|
81 | waveOutReset( This->m_hWaveOut );
|
---|
82 | SetEvent( This->m_hEventRender );
|
---|
83 | }
|
---|
84 |
|
---|
85 | static
|
---|
86 | void CAudioRendererImpl_waveOutUninit(
|
---|
87 | CAudioRendererImpl* This )
|
---|
88 | {
|
---|
89 | DWORD i;
|
---|
90 |
|
---|
91 | TRACE("(%p)\n",This);
|
---|
92 |
|
---|
93 | if ( !This->m_fWaveOutInit )
|
---|
94 | return;
|
---|
95 |
|
---|
96 | waveOutReset( This->m_hWaveOut );
|
---|
97 | SetEvent( This->m_hEventRender );
|
---|
98 |
|
---|
99 | for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
|
---|
100 | {
|
---|
101 | if ( This->m_hdr[i].dwFlags & WHDR_PREPARED )
|
---|
102 | {
|
---|
103 | waveOutUnprepareHeader(
|
---|
104 | This->m_hWaveOut,
|
---|
105 | &This->m_hdr[i], sizeof(WAVEHDR) );
|
---|
106 | This->m_hdr[i].dwFlags = 0;
|
---|
107 | }
|
---|
108 | if ( This->m_hdr[i].lpData != NULL )
|
---|
109 | {
|
---|
110 | QUARTZ_FreeMem( This->m_hdr[i].lpData );
|
---|
111 | This->m_hdr[i].lpData = NULL;
|
---|
112 | }
|
---|
113 | }
|
---|
114 |
|
---|
115 | waveOutClose( This->m_hWaveOut );
|
---|
116 | This->m_hWaveOut = (HWAVEOUT)NULL;
|
---|
117 | if ( This->m_hEventRender != (HANDLE)NULL )
|
---|
118 | {
|
---|
119 | CloseHandle( This->m_hEventRender );
|
---|
120 | This->m_hEventRender = (HANDLE)NULL;
|
---|
121 | }
|
---|
122 |
|
---|
123 | This->m_fWaveOutInit = FALSE;
|
---|
124 | }
|
---|
125 |
|
---|
126 | static
|
---|
127 | HRESULT CAudioRendererImpl_waveOutInit(
|
---|
128 | CAudioRendererImpl* This, WAVEFORMATEX* pwfx )
|
---|
129 | {
|
---|
130 | MMRESULT mr;
|
---|
131 | HRESULT hr;
|
---|
132 | DWORD i;
|
---|
133 | DWORD dwBlockSize;
|
---|
134 |
|
---|
135 | if ( This->m_fWaveOutInit )
|
---|
136 | return E_UNEXPECTED;
|
---|
137 |
|
---|
138 | if ( pwfx == NULL )
|
---|
139 | return E_POINTER;
|
---|
140 | if ( pwfx->nBlockAlign == 0 )
|
---|
141 | return E_INVALIDARG;
|
---|
142 |
|
---|
143 | This->m_hEventRender = (HANDLE)NULL;
|
---|
144 | This->m_hWaveOut = (HWAVEOUT)NULL;
|
---|
145 | This->m_dwBlockSize = 0;
|
---|
146 | This->m_phdrCur = NULL;
|
---|
147 | ZeroMemory( &This->m_hdr, sizeof(This->m_hdr) );
|
---|
148 |
|
---|
149 |
|
---|
150 | mr = waveOutOpen(
|
---|
151 | &This->m_hWaveOut, WAVE_MAPPER, pwfx,
|
---|
152 | (DWORD)CAudioRendererImpl_waveOutEventCallback, (DWORD)This,
|
---|
153 | CALLBACK_FUNCTION );
|
---|
154 | hr = QUARTZ_HRESULT_From_MMRESULT( mr );
|
---|
155 | if ( FAILED(hr) )
|
---|
156 | return hr;
|
---|
157 | This->m_fWaveOutInit = TRUE;
|
---|
158 |
|
---|
159 | This->m_hEventRender = CreateEventA(
|
---|
160 | NULL, TRUE, TRUE, NULL );
|
---|
161 | if ( This->m_hEventRender == (HANDLE)NULL )
|
---|
162 | {
|
---|
163 | hr = E_OUTOFMEMORY;
|
---|
164 | goto err;
|
---|
165 | }
|
---|
166 |
|
---|
167 | dwBlockSize = pwfx->nAvgBytesPerSec / pwfx->nBlockAlign;
|
---|
168 | if ( dwBlockSize == 0 )
|
---|
169 | dwBlockSize = 1;
|
---|
170 | dwBlockSize *= pwfx->nBlockAlign;
|
---|
171 | This->m_dwBlockSize = dwBlockSize;
|
---|
172 |
|
---|
173 | for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
|
---|
174 | {
|
---|
175 | This->m_hdr[i].lpData = (CHAR*)QUARTZ_AllocMem( dwBlockSize );
|
---|
176 | if ( This->m_hdr[i].lpData == NULL )
|
---|
177 | {
|
---|
178 | hr = E_OUTOFMEMORY;
|
---|
179 | goto err;
|
---|
180 | }
|
---|
181 | mr = waveOutPrepareHeader(
|
---|
182 | This->m_hWaveOut,
|
---|
183 | &This->m_hdr[i], sizeof(WAVEHDR) );
|
---|
184 | hr = QUARTZ_HRESULT_From_MMRESULT( mr );
|
---|
185 | if ( FAILED(hr) )
|
---|
186 | goto err;
|
---|
187 | This->m_hdr[i].dwFlags |= WHDR_DONE;
|
---|
188 | This->m_hdr[i].dwBufferLength = dwBlockSize;
|
---|
189 | This->m_hdr[i].dwUser = i;
|
---|
190 | }
|
---|
191 |
|
---|
192 | return S_OK;
|
---|
193 | err:
|
---|
194 | CAudioRendererImpl_waveOutUninit(This);
|
---|
195 | return hr;
|
---|
196 | }
|
---|
197 |
|
---|
198 | static
|
---|
199 | WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
|
---|
200 | CAudioRendererImpl* This )
|
---|
201 | {
|
---|
202 | DWORD i;
|
---|
203 |
|
---|
204 | if ( !This->m_fWaveOutInit )
|
---|
205 | return NULL;
|
---|
206 |
|
---|
207 | if ( This->m_phdrCur != NULL )
|
---|
208 | return This->m_phdrCur;
|
---|
209 |
|
---|
210 | for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
|
---|
211 | {
|
---|
212 | if ( This->m_hdr[i].dwFlags & WHDR_DONE )
|
---|
213 | {
|
---|
214 | This->m_phdrCur = &(This->m_hdr[i]);
|
---|
215 | This->m_phdrCur->dwFlags &= ~WHDR_DONE;
|
---|
216 | This->m_phdrCur->dwBufferLength = 0;
|
---|
217 | return This->m_phdrCur;
|
---|
218 | }
|
---|
219 | }
|
---|
220 |
|
---|
221 | return NULL;
|
---|
222 | }
|
---|
223 |
|
---|
224 | static
|
---|
225 | HRESULT CAudioRendererImpl_waveOutWriteData(
|
---|
226 | CAudioRendererImpl* This,
|
---|
227 | const BYTE* pData, DWORD cbData, DWORD* pcbWritten )
|
---|
228 | {
|
---|
229 | DWORD cbAvail;
|
---|
230 |
|
---|
231 | *pcbWritten = 0;
|
---|
232 |
|
---|
233 | if ( !This->m_fWaveOutInit )
|
---|
234 | return E_UNEXPECTED;
|
---|
235 |
|
---|
236 | if ( cbData == 0 )
|
---|
237 | return S_OK;
|
---|
238 |
|
---|
239 | if ( CAudioRendererImpl_waveOutGetBuffer(This) == NULL )
|
---|
240 | return S_FALSE;
|
---|
241 |
|
---|
242 | cbAvail = This->m_dwBlockSize - This->m_phdrCur->dwBufferLength;
|
---|
243 | if ( cbAvail > cbData )
|
---|
244 | cbAvail = cbData;
|
---|
245 | memcpy( This->m_phdrCur->lpData, pData, cbAvail );
|
---|
246 | pData += cbAvail;
|
---|
247 | cbData -= cbAvail;
|
---|
248 | This->m_phdrCur->dwBufferLength += cbAvail;
|
---|
249 |
|
---|
250 | *pcbWritten = cbAvail;
|
---|
251 |
|
---|
252 | return S_OK;
|
---|
253 | }
|
---|
254 |
|
---|
255 | static
|
---|
256 | HRESULT CAudioRendererImpl_waveOutFlush(
|
---|
257 | CAudioRendererImpl* This )
|
---|
258 | {
|
---|
259 | MMRESULT mr;
|
---|
260 | HRESULT hr;
|
---|
261 |
|
---|
262 | if ( !This->m_fWaveOutInit )
|
---|
263 | return E_UNEXPECTED;
|
---|
264 | if ( This->m_phdrCur == NULL )
|
---|
265 | return E_UNEXPECTED;
|
---|
266 |
|
---|
267 | if ( This->m_phdrCur->dwBufferLength == 0 )
|
---|
268 | return S_OK;
|
---|
269 |
|
---|
270 | mr = waveOutWrite(
|
---|
271 | This->m_hWaveOut,
|
---|
272 | This->m_phdrCur, sizeof(WAVEHDR) );
|
---|
273 | hr = QUARTZ_HRESULT_From_MMRESULT( mr );
|
---|
274 | if ( FAILED(hr) )
|
---|
275 | return hr;
|
---|
276 |
|
---|
277 | This->m_phdrCur = NULL;
|
---|
278 | return S_OK;
|
---|
279 | }
|
---|
280 |
|
---|
281 | static
|
---|
282 | HRESULT CAudioRendererImpl_waveOutGetVolume(
|
---|
283 | CAudioRendererImpl* This,
|
---|
284 | DWORD* pdwLeft, DWORD* pdwRight )
|
---|
285 | {
|
---|
286 | MMRESULT mr;
|
---|
287 | HRESULT hr;
|
---|
288 | DWORD dwVol;
|
---|
289 |
|
---|
290 | if ( !This->m_fWaveOutInit )
|
---|
291 | return E_UNEXPECTED;
|
---|
292 |
|
---|
293 | mr = waveOutGetVolume(
|
---|
294 | This->m_hWaveOut, &dwVol );
|
---|
295 | hr = QUARTZ_HRESULT_From_MMRESULT( mr );
|
---|
296 | if ( FAILED(hr) )
|
---|
297 | return hr;
|
---|
298 |
|
---|
299 | *pdwLeft = LOWORD(dwVol);
|
---|
300 | *pdwRight = HIWORD(dwVol);
|
---|
301 |
|
---|
302 | return NOERROR;
|
---|
303 | }
|
---|
304 |
|
---|
305 | static
|
---|
306 | HRESULT CAudioRendererImpl_waveOutSetVolume(
|
---|
307 | CAudioRendererImpl* This,
|
---|
308 | DWORD dwLeft, DWORD dwRight )
|
---|
309 | {
|
---|
310 | MMRESULT mr;
|
---|
311 | DWORD dwVol;
|
---|
312 |
|
---|
313 | if ( !This->m_fWaveOutInit )
|
---|
314 | return E_UNEXPECTED;
|
---|
315 |
|
---|
316 | dwVol = dwLeft | (dwRight<<16);
|
---|
317 |
|
---|
318 | mr = waveOutSetVolume(
|
---|
319 | This->m_hWaveOut, dwVol );
|
---|
320 | return QUARTZ_HRESULT_From_MMRESULT( mr );
|
---|
321 | }
|
---|
322 |
|
---|
323 | /***************************************************************************
|
---|
324 | *
|
---|
325 | * CAudioRendererImpl methods
|
---|
326 | *
|
---|
327 | */
|
---|
328 |
|
---|
329 |
|
---|
330 | static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
|
---|
331 | {
|
---|
332 | CAudioRendererImpl_THIS(pImpl,basefilter);
|
---|
333 | WAVEFORMATEX* pwfx;
|
---|
334 |
|
---|
335 | FIXME( "(%p)\n", This );
|
---|
336 |
|
---|
337 | if ( This->pPin->pin.pmtConn == NULL )
|
---|
338 | return NOERROR;
|
---|
339 |
|
---|
340 | pwfx = (WAVEFORMATEX*)This->pPin->pin.pmtConn->pbFormat;
|
---|
341 | if ( pwfx == NULL )
|
---|
342 | return E_FAIL;
|
---|
343 |
|
---|
344 | This->m_fInFlush = FALSE;
|
---|
345 |
|
---|
346 | return CAudioRendererImpl_waveOutInit(This,pwfx);
|
---|
347 | }
|
---|
348 |
|
---|
349 | static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
|
---|
350 | {
|
---|
351 | CAudioRendererImpl_THIS(pImpl,basefilter);
|
---|
352 |
|
---|
353 | FIXME( "(%p)\n", This );
|
---|
354 |
|
---|
355 | CAudioRendererImpl_waveOutUninit(This);
|
---|
356 |
|
---|
357 | This->m_fInFlush = FALSE;
|
---|
358 |
|
---|
359 | TRACE("returned\n" );
|
---|
360 |
|
---|
361 | return NOERROR;
|
---|
362 | }
|
---|
363 |
|
---|
364 | static const CBaseFilterHandlers filterhandlers =
|
---|
365 | {
|
---|
366 | CAudioRendererImpl_OnActive, /* pOnActive */
|
---|
367 | CAudioRendererImpl_OnInactive, /* pOnInactive */
|
---|
368 | };
|
---|
369 |
|
---|
370 | /***************************************************************************
|
---|
371 | *
|
---|
372 | * CAudioRendererPinImpl methods
|
---|
373 | *
|
---|
374 | */
|
---|
375 |
|
---|
376 | static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
|
---|
377 | {
|
---|
378 | CAudioRendererPinImpl_THIS(pImpl,pin);
|
---|
379 | const WAVEFORMATEX* pwfx;
|
---|
380 |
|
---|
381 | TRACE( "(%p,%p)\n",This,pmt );
|
---|
382 |
|
---|
383 | if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) )
|
---|
384 | return E_FAIL;
|
---|
385 | if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
|
---|
386 | return E_FAIL;
|
---|
387 | if ( !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
|
---|
388 | return E_FAIL;
|
---|
389 | if ( pmt->cbFormat < (sizeof(WAVEFORMATEX)-sizeof(WORD)) )
|
---|
390 | return E_FAIL;
|
---|
391 |
|
---|
392 | pwfx = (const WAVEFORMATEX*)pmt->pbFormat;
|
---|
393 | if ( pwfx == NULL )
|
---|
394 | return E_FAIL;
|
---|
395 | if ( pwfx->wFormatTag != 1 )
|
---|
396 | return E_FAIL;
|
---|
397 |
|
---|
398 | return NOERROR;
|
---|
399 | }
|
---|
400 |
|
---|
401 | static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
|
---|
402 | {
|
---|
403 | CAudioRendererPinImpl_THIS(pImpl,pin);
|
---|
404 | HRESULT hr;
|
---|
405 | BYTE* pData = NULL;
|
---|
406 | DWORD dwDataLength;
|
---|
407 | DWORD dwWritten;
|
---|
408 |
|
---|
409 | FIXME( "(%p,%p)\n",This,pSample );
|
---|
410 |
|
---|
411 | if ( !This->pRender->m_fWaveOutInit )
|
---|
412 | return E_UNEXPECTED;
|
---|
413 | if ( This->pRender->m_fInFlush )
|
---|
414 | return S_FALSE;
|
---|
415 | if ( pSample == NULL )
|
---|
416 | return E_POINTER;
|
---|
417 |
|
---|
418 | hr = IMediaSample_GetPointer( pSample, &pData );
|
---|
419 | if ( FAILED(hr) )
|
---|
420 | return hr;
|
---|
421 | dwDataLength = (DWORD)IMediaSample_GetActualDataLength( pSample );
|
---|
422 |
|
---|
423 | while ( 1 )
|
---|
424 | {
|
---|
425 | TRACE("trying to write %lu bytes\n",dwDataLength);
|
---|
426 |
|
---|
427 | ResetEvent( This->pRender->m_hEventRender );
|
---|
428 | hr = CAudioRendererImpl_waveOutWriteData(
|
---|
429 | This->pRender,pData,dwDataLength,&dwWritten);
|
---|
430 | if ( FAILED(hr) )
|
---|
431 | break;
|
---|
432 | if ( hr == S_FALSE )
|
---|
433 | {
|
---|
434 | WaitForSingleObject( This->pRender->m_hEventRender, INFINITE );
|
---|
435 | continue;
|
---|
436 | }
|
---|
437 | pData += dwWritten;
|
---|
438 | dwDataLength -= dwWritten;
|
---|
439 | hr = CAudioRendererImpl_waveOutFlush(This->pRender);
|
---|
440 | if ( FAILED(hr) )
|
---|
441 | break;
|
---|
442 | if ( dwDataLength == 0 )
|
---|
443 | break;
|
---|
444 | }
|
---|
445 |
|
---|
446 | return hr;
|
---|
447 | }
|
---|
448 |
|
---|
449 | static HRESULT CAudioRendererPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
|
---|
450 | {
|
---|
451 | CAudioRendererPinImpl_THIS(pImpl,pin);
|
---|
452 |
|
---|
453 | TRACE( "(%p)\n", This );
|
---|
454 |
|
---|
455 | /* might block. */
|
---|
456 | return S_OK;
|
---|
457 | }
|
---|
458 |
|
---|
459 | static HRESULT CAudioRendererPinImpl_EndOfStream( CPinBaseImpl* pImpl )
|
---|
460 | {
|
---|
461 | CAudioRendererPinImpl_THIS(pImpl,pin);
|
---|
462 |
|
---|
463 | FIXME( "(%p)\n", This );
|
---|
464 |
|
---|
465 | This->pRender->m_fInFlush = FALSE;
|
---|
466 | /* IMediaEventSink::Notify(EC_COMPLETE) */
|
---|
467 |
|
---|
468 | return NOERROR;
|
---|
469 | }
|
---|
470 |
|
---|
471 | static HRESULT CAudioRendererPinImpl_BeginFlush( CPinBaseImpl* pImpl )
|
---|
472 | {
|
---|
473 | CAudioRendererPinImpl_THIS(pImpl,pin);
|
---|
474 |
|
---|
475 | FIXME( "(%p)\n", This );
|
---|
476 |
|
---|
477 | This->pRender->m_fInFlush = TRUE;
|
---|
478 | CAudioRendererImpl_waveOutReset(This->pRender);
|
---|
479 |
|
---|
480 | return NOERROR;
|
---|
481 | }
|
---|
482 |
|
---|
483 | static HRESULT CAudioRendererPinImpl_EndFlush( CPinBaseImpl* pImpl )
|
---|
484 | {
|
---|
485 | CAudioRendererPinImpl_THIS(pImpl,pin);
|
---|
486 |
|
---|
487 | FIXME( "(%p)\n", This );
|
---|
488 |
|
---|
489 | This->pRender->m_fInFlush = FALSE;
|
---|
490 |
|
---|
491 | return NOERROR;
|
---|
492 | }
|
---|
493 |
|
---|
494 | static HRESULT CAudioRendererPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
|
---|
495 | {
|
---|
496 | CAudioRendererPinImpl_THIS(pImpl,pin);
|
---|
497 |
|
---|
498 | FIXME( "(%p)\n", This );
|
---|
499 |
|
---|
500 | return NOERROR;
|
---|
501 | }
|
---|
502 |
|
---|
503 | static const CBasePinHandlers pinhandlers =
|
---|
504 | {
|
---|
505 | CAudioRendererPinImpl_CheckMediaType, /* pCheckMediaType */
|
---|
506 | NULL, /* pQualityNotify */
|
---|
507 | CAudioRendererPinImpl_Receive, /* pReceive */
|
---|
508 | CAudioRendererPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
|
---|
509 | CAudioRendererPinImpl_EndOfStream, /* pEndOfStream */
|
---|
510 | CAudioRendererPinImpl_BeginFlush, /* pBeginFlush */
|
---|
511 | CAudioRendererPinImpl_EndFlush, /* pEndFlush */
|
---|
512 | CAudioRendererPinImpl_NewSegment, /* pNewSegment */
|
---|
513 | };
|
---|
514 |
|
---|
515 |
|
---|
516 | /***************************************************************************
|
---|
517 | *
|
---|
518 | * new/delete CAudioRendererImpl
|
---|
519 | *
|
---|
520 | */
|
---|
521 |
|
---|
522 | /* can I use offsetof safely? - FIXME? */
|
---|
523 | static QUARTZ_IFEntry FilterIFEntries[] =
|
---|
524 | {
|
---|
525 | { &IID_IPersist, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
|
---|
526 | { &IID_IMediaFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
|
---|
527 | { &IID_IBaseFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
|
---|
528 | { &IID_IBasicAudio, offsetof(CAudioRendererImpl,basaud)-offsetof(CAudioRendererImpl,unk) },
|
---|
529 | };
|
---|
530 |
|
---|
531 | static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
|
---|
532 | {
|
---|
533 | CAudioRendererImpl_THIS(punk,unk);
|
---|
534 |
|
---|
535 | TRACE( "(%p)\n", This );
|
---|
536 |
|
---|
537 | if ( This->pPin != NULL )
|
---|
538 | {
|
---|
539 | IUnknown_Release(This->pPin->unk.punkControl);
|
---|
540 | This->pPin = NULL;
|
---|
541 | }
|
---|
542 |
|
---|
543 | CAudioRendererImpl_UninitIBasicAudio(This);
|
---|
544 | CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
|
---|
545 | }
|
---|
546 |
|
---|
547 | HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
|
---|
548 | {
|
---|
549 | CAudioRendererImpl* This = NULL;
|
---|
550 | HRESULT hr;
|
---|
551 |
|
---|
552 | TRACE("(%p,%p)\n",punkOuter,ppobj);
|
---|
553 |
|
---|
554 | This = (CAudioRendererImpl*)
|
---|
555 | QUARTZ_AllocObj( sizeof(CAudioRendererImpl) );
|
---|
556 | if ( This == NULL )
|
---|
557 | return E_OUTOFMEMORY;
|
---|
558 | This->pPin = NULL;
|
---|
559 | This->m_fInFlush = FALSE;
|
---|
560 | This->m_fWaveOutInit = FALSE;
|
---|
561 | This->m_hEventRender = (HANDLE)NULL;
|
---|
562 |
|
---|
563 | QUARTZ_IUnkInit( &This->unk, punkOuter );
|
---|
564 |
|
---|
565 | hr = CBaseFilterImpl_InitIBaseFilter(
|
---|
566 | &This->basefilter,
|
---|
567 | This->unk.punkControl,
|
---|
568 | &CLSID_AudioRender,
|
---|
569 | QUARTZ_AudioRender_Name,
|
---|
570 | &filterhandlers );
|
---|
571 | if ( SUCCEEDED(hr) )
|
---|
572 | {
|
---|
573 | hr = CAudioRendererImpl_InitIBasicAudio(This);
|
---|
574 | if ( FAILED(hr) )
|
---|
575 | {
|
---|
576 | CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
|
---|
577 | }
|
---|
578 | }
|
---|
579 |
|
---|
580 | if ( FAILED(hr) )
|
---|
581 | {
|
---|
582 | QUARTZ_FreeObj(This);
|
---|
583 | return hr;
|
---|
584 | }
|
---|
585 |
|
---|
586 | This->unk.pEntries = FilterIFEntries;
|
---|
587 | This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
|
---|
588 | This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRenderer;
|
---|
589 |
|
---|
590 | hr = QUARTZ_CreateAudioRendererPin(
|
---|
591 | This,
|
---|
592 | &This->basefilter.csFilter,
|
---|
593 | &This->pPin );
|
---|
594 | if ( SUCCEEDED(hr) )
|
---|
595 | hr = QUARTZ_CompList_AddComp(
|
---|
596 | This->basefilter.pInPins,
|
---|
597 | (IUnknown*)&This->pPin->pin,
|
---|
598 | NULL, 0 );
|
---|
599 | if ( FAILED(hr) )
|
---|
600 | {
|
---|
601 | IUnknown_Release( This->unk.punkControl );
|
---|
602 | return hr;
|
---|
603 | }
|
---|
604 |
|
---|
605 | *ppobj = (void*)&(This->unk);
|
---|
606 |
|
---|
607 | return S_OK;
|
---|
608 | }
|
---|
609 |
|
---|
610 |
|
---|
611 | /***************************************************************************
|
---|
612 | *
|
---|
613 | * new/delete CAudioRendererPinImpl
|
---|
614 | *
|
---|
615 | */
|
---|
616 |
|
---|
617 | /* can I use offsetof safely? - FIXME? */
|
---|
618 | static QUARTZ_IFEntry PinIFEntries[] =
|
---|
619 | {
|
---|
620 | { &IID_IPin, offsetof(CAudioRendererPinImpl,pin)-offsetof(CAudioRendererPinImpl,unk) },
|
---|
621 | { &IID_IMemInputPin, offsetof(CAudioRendererPinImpl,meminput)-offsetof(CAudioRendererPinImpl,unk) },
|
---|
622 | };
|
---|
623 |
|
---|
624 | static void QUARTZ_DestroyAudioRendererPin(IUnknown* punk)
|
---|
625 | {
|
---|
626 | CAudioRendererPinImpl_THIS(punk,unk);
|
---|
627 |
|
---|
628 | TRACE( "(%p)\n", This );
|
---|
629 |
|
---|
630 | CPinBaseImpl_UninitIPin( &This->pin );
|
---|
631 | CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
|
---|
632 | }
|
---|
633 |
|
---|
634 | HRESULT QUARTZ_CreateAudioRendererPin(
|
---|
635 | CAudioRendererImpl* pFilter,
|
---|
636 | CRITICAL_SECTION* pcsPin,
|
---|
637 | CAudioRendererPinImpl** ppPin)
|
---|
638 | {
|
---|
639 | CAudioRendererPinImpl* This = NULL;
|
---|
640 | HRESULT hr;
|
---|
641 |
|
---|
642 | TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
|
---|
643 |
|
---|
644 | This = (CAudioRendererPinImpl*)
|
---|
645 | QUARTZ_AllocObj( sizeof(CAudioRendererPinImpl) );
|
---|
646 | if ( This == NULL )
|
---|
647 | return E_OUTOFMEMORY;
|
---|
648 |
|
---|
649 | QUARTZ_IUnkInit( &This->unk, NULL );
|
---|
650 | This->pRender = pFilter;
|
---|
651 |
|
---|
652 | hr = CPinBaseImpl_InitIPin(
|
---|
653 | &This->pin,
|
---|
654 | This->unk.punkControl,
|
---|
655 | pcsPin,
|
---|
656 | &pFilter->basefilter,
|
---|
657 | QUARTZ_AudioRenderPin_Name,
|
---|
658 | FALSE,
|
---|
659 | &pinhandlers );
|
---|
660 |
|
---|
661 | if ( SUCCEEDED(hr) )
|
---|
662 | {
|
---|
663 | hr = CMemInputPinBaseImpl_InitIMemInputPin(
|
---|
664 | &This->meminput,
|
---|
665 | This->unk.punkControl,
|
---|
666 | &This->pin );
|
---|
667 | if ( FAILED(hr) )
|
---|
668 | {
|
---|
669 | CPinBaseImpl_UninitIPin( &This->pin );
|
---|
670 | }
|
---|
671 | }
|
---|
672 |
|
---|
673 | if ( FAILED(hr) )
|
---|
674 | {
|
---|
675 | QUARTZ_FreeObj(This);
|
---|
676 | return hr;
|
---|
677 | }
|
---|
678 |
|
---|
679 | This->unk.pEntries = PinIFEntries;
|
---|
680 | This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
|
---|
681 | This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRendererPin;
|
---|
682 |
|
---|
683 | *ppPin = This;
|
---|
684 |
|
---|
685 | TRACE("returned successfully.\n");
|
---|
686 |
|
---|
687 | return S_OK;
|
---|
688 | }
|
---|
689 |
|
---|
690 |
|
---|
691 | /***************************************************************************
|
---|
692 | *
|
---|
693 | * CAudioRendererImpl::IBasicAudio
|
---|
694 | *
|
---|
695 | */
|
---|
696 |
|
---|
697 | static HRESULT WINAPI
|
---|
698 | IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
|
---|
699 | {
|
---|
700 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
701 |
|
---|
702 | TRACE("(%p)->()\n",This);
|
---|
703 |
|
---|
704 | return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
|
---|
705 | }
|
---|
706 |
|
---|
707 | static ULONG WINAPI
|
---|
708 | IBasicAudio_fnAddRef(IBasicAudio* iface)
|
---|
709 | {
|
---|
710 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
711 |
|
---|
712 | TRACE("(%p)->()\n",This);
|
---|
713 |
|
---|
714 | return IUnknown_AddRef(This->unk.punkControl);
|
---|
715 | }
|
---|
716 |
|
---|
717 | static ULONG WINAPI
|
---|
718 | IBasicAudio_fnRelease(IBasicAudio* iface)
|
---|
719 | {
|
---|
720 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
721 |
|
---|
722 | TRACE("(%p)->()\n",This);
|
---|
723 |
|
---|
724 | return IUnknown_Release(This->unk.punkControl);
|
---|
725 | }
|
---|
726 |
|
---|
727 | static HRESULT WINAPI
|
---|
728 | IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo)
|
---|
729 | {
|
---|
730 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
731 |
|
---|
732 | FIXME("(%p)->()\n",This);
|
---|
733 |
|
---|
734 | return E_NOTIMPL;
|
---|
735 | }
|
---|
736 |
|
---|
737 | static HRESULT WINAPI
|
---|
738 | IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
|
---|
739 | {
|
---|
740 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
741 |
|
---|
742 | FIXME("(%p)->()\n",This);
|
---|
743 |
|
---|
744 | return E_NOTIMPL;
|
---|
745 | }
|
---|
746 |
|
---|
747 | static HRESULT WINAPI
|
---|
748 | IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
|
---|
749 | {
|
---|
750 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
751 |
|
---|
752 | FIXME("(%p)->()\n",This);
|
---|
753 |
|
---|
754 | return E_NOTIMPL;
|
---|
755 | }
|
---|
756 |
|
---|
757 | static HRESULT WINAPI
|
---|
758 | IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
|
---|
759 | {
|
---|
760 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
761 |
|
---|
762 | FIXME("(%p)->()\n",This);
|
---|
763 |
|
---|
764 | return E_NOTIMPL;
|
---|
765 | }
|
---|
766 |
|
---|
767 |
|
---|
768 | static HRESULT WINAPI
|
---|
769 | IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
|
---|
770 | {
|
---|
771 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
772 |
|
---|
773 | FIXME("(%p)->()\n",This);
|
---|
774 |
|
---|
775 | return E_NOTIMPL;
|
---|
776 | }
|
---|
777 |
|
---|
778 | static HRESULT WINAPI
|
---|
779 | IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
|
---|
780 | {
|
---|
781 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
782 |
|
---|
783 | FIXME("(%p)->()\n",This);
|
---|
784 |
|
---|
785 | return E_NOTIMPL;
|
---|
786 | }
|
---|
787 |
|
---|
788 | static HRESULT WINAPI
|
---|
789 | IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
|
---|
790 | {
|
---|
791 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
792 |
|
---|
793 | FIXME("(%p)->()\n",This);
|
---|
794 |
|
---|
795 | return E_NOTIMPL;
|
---|
796 | }
|
---|
797 |
|
---|
798 | static HRESULT WINAPI
|
---|
799 | IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
|
---|
800 | {
|
---|
801 | CAudioRendererImpl_THIS(iface,basaud);
|
---|
802 |
|
---|
803 | FIXME("(%p)->()\n",This);
|
---|
804 |
|
---|
805 | return E_NOTIMPL;
|
---|
806 | }
|
---|
807 |
|
---|
808 |
|
---|
809 | static ICOM_VTABLE(IBasicAudio) ibasicaudio =
|
---|
810 | {
|
---|
811 | ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
---|
812 | /* IUnknown fields */
|
---|
813 | IBasicAudio_fnQueryInterface,
|
---|
814 | IBasicAudio_fnAddRef,
|
---|
815 | IBasicAudio_fnRelease,
|
---|
816 | /* IDispatch fields */
|
---|
817 | IBasicAudio_fnGetTypeInfoCount,
|
---|
818 | IBasicAudio_fnGetTypeInfo,
|
---|
819 | IBasicAudio_fnGetIDsOfNames,
|
---|
820 | IBasicAudio_fnInvoke,
|
---|
821 | /* IBasicAudio fields */
|
---|
822 | IBasicAudio_fnput_Volume,
|
---|
823 | IBasicAudio_fnget_Volume,
|
---|
824 | IBasicAudio_fnput_Balance,
|
---|
825 | IBasicAudio_fnget_Balance,
|
---|
826 | };
|
---|
827 |
|
---|
828 |
|
---|
829 | HRESULT CAudioRendererImpl_InitIBasicAudio( CAudioRendererImpl* This )
|
---|
830 | {
|
---|
831 | TRACE("(%p)\n",This);
|
---|
832 | ICOM_VTBL(&This->basaud) = &ibasicaudio;
|
---|
833 |
|
---|
834 | return NOERROR;
|
---|
835 | }
|
---|
836 |
|
---|
837 | void CAudioRendererImpl_UninitIBasicAudio( CAudioRendererImpl* This )
|
---|
838 | {
|
---|
839 | TRACE("(%p)\n",This);
|
---|
840 | }
|
---|
841 |
|
---|