/[cvs]/api/include/dmoimpl.h
ViewVC logotype

Contents of /api/include/dmoimpl.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Sun Jul 1 20:47:59 2001 UTC (22 years, 10 months ago) by bearsoft
Branch: lazy, MAIN
CVS Tags: start, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/plain
First import

1 //------------------------------------------------------------------------------
2 // File: DMOImpl.h
3 //
4 // Desc: Classes to implement a DMO.
5 //
6 // Copyright (c) 2000, Microsoft Corporation. All rights reserved.
7 //------------------------------------------------------------------------------
8
9
10 #ifndef _dmoimpl_h_
11 #define _dmoimpl_h_
12
13 #ifdef _DEBUG
14 #include <crtdbg.h>
15 #endif
16
17 // Class to implement a DMO
18 //
19 //
20 // Assumes the number of input and output streams is fixed
21 // (these are template parameters)
22 //
23 // Provides following services:
24 //
25 // Basic parameter checking and locking
26 // Fully implements :
27 // GetStreamCount
28 // SetInputType
29 // SetOutputType
30 // GetCurrentInputType
31 // GetCurrentOutputType
32 //
33 // Checks if all types are set before streaming
34 // Automatically calls AllocateStreamingResources before streaming
35 // if it's not been called already
36 // Prevents streaming until the types on all non-optional streams
37 // have been set
38 //
39 //
40 // Derived class implements the following methods :
41 //
42 /*
43 HRESULT InternalGetInputStreamInfo(DWORD dwInputStreamIndex, DWORD *pdwFlags);
44 HRESULT InternalGetOutputStreamInfo(DWORD dwOutputStreamIndex, DWORD *pdwFlags);
45 HRESULT InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt);
46 HRESULT InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt);
47 HRESULT InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex,
48 DMO_MEDIA_TYPE *pmt);
49 HRESULT InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex,
50 DMO_MEDIA_TYPE *pmt);
51 HRESULT InternalGetInputSizeInfo(DWORD dwInputStreamIndex, DWORD *pcbSize,
52 DWORD *pcbMaxLookahead, DWORD *pcbAlignment);
53 HRESULT InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
54 DWORD *pcbAlignment);
55 HRESULT InternalGetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency);
56 HRESULT InternalSetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency);
57 HRESULT InternalFlush();
58 HRESULT InternalDiscontinuity(DWORD dwInputStreamIndex);
59 HRESULT InternalAllocateStreamingResources();
60 HRESULT InternalFreeStreamingResources();
61 HRESULT InternalProcessInput(DWORD dwInputStreamIndex, IMediaBuffer *pBuffer,
62 DWORD dwFlags, REFERENCE_TIME rtTimestamp,
63 REFERENCE_TIME rtTimelength);
64 HRESULT InternalProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount,
65 DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
66 DWORD *pdwStatus);
67 HRESULT InternalAcceptingInput(DWORD dwInputStreamIndex);
68 void Lock();
69 void Unlock();
70
71 Notes:
72 The derived class is meant to do most work to initialize streaming
73 in AllocateStreamingResources rather than when types are set.
74
75 This centralizes the work to one
76 clear place based on the types set for all streams.
77
78 The derived class implements locking.
79
80 The derived class implements the IUnknown methods
81
82 Usage example (1 input and 1 output) :
83 class CMyDMO : public IMediaObjectImpl<CMyDmo, 1, 1>,
84 ...
85 */
86
87
88 #define INTERNAL_CALL(_T_, _X_) \
89 static_cast<_T_ *>(this)->Internal##_X_
90
91 template <class _DERIVED_, int NUMBEROFINPUTS, int NUMBEROFOUTPUTS>
92 class IMediaObjectImpl : public IMediaObject
93 {
94 private:
95 // Member variables
96 struct {
97 DWORD fTypeSet:1;
98 DWORD fIncomplete:1;
99 DMO_MEDIA_TYPE CurrentMediaType;
100 } m_InputInfo[NUMBEROFINPUTS], m_OutputInfo[NUMBEROFOUTPUTS];
101
102 bool m_fTypesSet;
103 bool m_fFlushed;
104 bool m_fResourcesAllocated;
105
106 protected:
107
108 // Helpers
109 bool InputTypeSet(DWORD ulInputStreamIndex) const
110 {
111 _ASSERTE(ulInputStreamIndex < NUMBEROFINPUTS);
112 return 0 != m_InputInfo[ulInputStreamIndex].fTypeSet;
113 }
114
115 bool OutputTypeSet(DWORD ulOutputStreamIndex) const
116 {
117 _ASSERTE(ulOutputStreamIndex < NUMBEROFOUTPUTS);
118 return 0 != m_OutputInfo[ulOutputStreamIndex].fTypeSet;
119 }
120 const DMO_MEDIA_TYPE *InputType(DWORD ulInputStreamIndex)
121 {
122 if (!InputTypeSet(ulInputStreamIndex)) {
123 return NULL;
124 }
125 return &m_InputInfo[ulInputStreamIndex].CurrentMediaType;
126 }
127 const DMO_MEDIA_TYPE *OutputType(DWORD ulOutputStreamIndex)
128 {
129 if (!OutputTypeSet(ulOutputStreamIndex)) {
130 return NULL;
131 }
132 return &m_OutputInfo[ulOutputStreamIndex].CurrentMediaType;
133 }
134
135
136 class LockIt
137 {
138 public:
139 LockIt(_DERIVED_ *p) : m_p(p)
140 {
141 static_cast<_DERIVED_ *>(m_p)->Lock();
142 }
143 ~LockIt()
144 {
145 static_cast<_DERIVED_ *>(m_p)->Unlock();
146 }
147 _DERIVED_ *const m_p;
148 };
149
150 bool CheckTypesSet()
151 {
152 m_fTypesSet = false;
153 DWORD dw;
154 for (dw = 0; dw < NUMBEROFINPUTS; dw++) {
155 if (!InputTypeSet(dw)) {
156 return false;
157 }
158 }
159 for (dw = 0; dw < NUMBEROFOUTPUTS; dw++) {
160 if (!OutputTypeSet(dw)) {
161 // Check if it's optional
162 DWORD dwFlags;
163 #ifdef _DEBUG
164 dwFlags = 0xFFFFFFFF;
165 #endif
166 INTERNAL_CALL(_DERIVED_, GetOutputStreamInfo)(dw, &dwFlags);
167 _ASSERTE(0 == (dwFlags & ~(DMO_OUTPUT_STREAMF_WHOLE_SAMPLES |
168 DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
169 DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE |
170 DMO_OUTPUT_STREAMF_DISCARDABLE |
171 DMO_OUTPUT_STREAMF_OPTIONAL)));
172 if (!(dwFlags & DMO_OUTPUT_STREAMF_OPTIONAL)) {
173 return false;
174 }
175 }
176 }
177 m_fTypesSet = true;
178 return true;
179 }
180
181
182 IMediaObjectImpl() :
183 m_fTypesSet(false),
184 m_fFlushed(true),
185 m_fResourcesAllocated(false)
186 {
187 ZeroMemory(&m_InputInfo, sizeof(m_InputInfo));
188 ZeroMemory(&m_OutputInfo, sizeof(m_OutputInfo));
189 }
190
191 virtual ~IMediaObjectImpl() {
192 DWORD dwCurrentType;
193
194 for (dwCurrentType = 0; dwCurrentType < NUMBEROFINPUTS; dwCurrentType++) {
195 if(InputTypeSet(dwCurrentType)) {
196 MoFreeMediaType(&m_InputInfo[dwCurrentType].CurrentMediaType);
197 }
198 }
199
200 for (dwCurrentType = 0; dwCurrentType < NUMBEROFOUTPUTS; dwCurrentType++) {
201 if(OutputTypeSet(dwCurrentType)) {
202 MoFreeMediaType(&m_OutputInfo[dwCurrentType].CurrentMediaType);
203 }
204 }
205 }
206
207
208 // IMediaObject methods
209
210
211 //
212 // IMediaObject methods
213 //
214 STDMETHODIMP GetStreamCount(unsigned long *pulNumberOfInputStreams, unsigned long *pulNumberOfOutputStreams)
215 {
216 LockIt lck(static_cast<_DERIVED_ *>(this));
217 if (pulNumberOfInputStreams == NULL ||
218 pulNumberOfOutputStreams == NULL) {
219 return E_POINTER;
220 }
221 *pulNumberOfInputStreams = NUMBEROFINPUTS;
222 *pulNumberOfOutputStreams = NUMBEROFOUTPUTS;
223 return S_OK;
224 }
225 STDMETHODIMP GetInputStreamInfo(ULONG ulStreamIndex, DWORD *pdwFlags)
226 {
227 LockIt lck(static_cast<_DERIVED_ *>(this));
228 if (ulStreamIndex >= NUMBEROFINPUTS) {
229 return DMO_E_INVALIDSTREAMINDEX;
230 }
231 if (pdwFlags == NULL) {
232 return E_POINTER;
233 }
234 HRESULT hr = INTERNAL_CALL(_DERIVED_, GetInputStreamInfo)(ulStreamIndex, pdwFlags);
235 _ASSERTE(0 == (*pdwFlags & ~(DMO_INPUT_STREAMF_WHOLE_SAMPLES |
236 DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
237 DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE |
238 DMO_INPUT_STREAMF_HOLDS_BUFFERS)));
239 return hr;
240 }
241 STDMETHODIMP GetOutputStreamInfo(ULONG ulStreamIndex, DWORD *pdwFlags)
242 {
243 LockIt lck(static_cast<_DERIVED_ *>(this));
244 if (ulStreamIndex >= NUMBEROFOUTPUTS) {
245 return DMO_E_INVALIDSTREAMINDEX;
246 }
247 if (pdwFlags == NULL) {
248 return E_POINTER;
249 }
250 HRESULT hr = INTERNAL_CALL(_DERIVED_, GetOutputStreamInfo)(ulStreamIndex, pdwFlags);
251 _ASSERTE(0 == (*pdwFlags & ~(DMO_OUTPUT_STREAMF_WHOLE_SAMPLES |
252 DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
253 DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE |
254 DMO_OUTPUT_STREAMF_DISCARDABLE |
255 DMO_OUTPUT_STREAMF_OPTIONAL)));
256 return hr;
257 }
258 STDMETHODIMP GetInputType(ULONG ulStreamIndex, ULONG ulTypeIndex, DMO_MEDIA_TYPE *pmt) {
259 if (ulStreamIndex >= NUMBEROFINPUTS) {
260 return DMO_E_INVALIDSTREAMINDEX;
261 }
262 LockIt lck(static_cast<_DERIVED_ *>(this));
263 return INTERNAL_CALL(_DERIVED_, GetInputType)(ulStreamIndex, ulTypeIndex, pmt);
264 }
265 STDMETHODIMP GetOutputType(ULONG ulStreamIndex, ULONG ulTypeIndex, DMO_MEDIA_TYPE *pmt) {
266 if (ulStreamIndex >= NUMBEROFOUTPUTS) {
267 return DMO_E_INVALIDSTREAMINDEX;
268 }
269 LockIt lck(static_cast<_DERIVED_ *>(this));
270 return INTERNAL_CALL(_DERIVED_, GetOutputType)(ulStreamIndex, ulTypeIndex, pmt);
271 }
272 STDMETHODIMP GetInputCurrentType(ULONG ulStreamIndex, DMO_MEDIA_TYPE *pmt) {
273 if (ulStreamIndex >= NUMBEROFINPUTS) {
274 return DMO_E_INVALIDSTREAMINDEX;
275 }
276 if (NULL == pmt) {
277 return E_POINTER;
278 }
279 LockIt lck(static_cast<_DERIVED_ *>(this));
280 if (InputTypeSet(ulStreamIndex))
281 return MoCopyMediaType(pmt,
282 &m_InputInfo[ulStreamIndex].CurrentMediaType);
283 else
284 return DMO_E_TYPE_NOT_SET;
285 }
286 STDMETHODIMP GetOutputCurrentType(ULONG ulStreamIndex, DMO_MEDIA_TYPE *pmt) {
287 if (ulStreamIndex >= NUMBEROFOUTPUTS) {
288 return DMO_E_INVALIDSTREAMINDEX;
289 }
290 if (NULL == pmt) {
291 return E_POINTER;
292 }
293 LockIt lck(static_cast<_DERIVED_ *>(this));
294 if (OutputTypeSet(ulStreamIndex))
295 return MoCopyMediaType(pmt,
296 &m_OutputInfo[ulStreamIndex].CurrentMediaType);
297 else
298 return DMO_E_TYPE_NOT_SET;
299 }
300 STDMETHODIMP GetInputSizeInfo(ULONG ulStreamIndex, ULONG *pulSize, ULONG *pcbMaxLookahead, ULONG *pulAlignment) {
301 if (ulStreamIndex >= NUMBEROFINPUTS) {
302 return DMO_E_INVALIDSTREAMINDEX;
303 }
304 if (NULL == pulSize || NULL == pulAlignment ||
305 NULL == pcbMaxLookahead) {
306 return E_POINTER;
307 }
308 LockIt lck(static_cast<_DERIVED_ *>(this));
309 if (!InputTypeSet(ulStreamIndex)) {
310 return DMO_E_TYPE_NOT_SET;
311 }
312 return INTERNAL_CALL(_DERIVED_, GetInputSizeInfo)(ulStreamIndex, pulSize, pcbMaxLookahead, pulAlignment);
313 }
314 STDMETHODIMP GetOutputSizeInfo(ULONG ulStreamIndex, ULONG *pulSize, ULONG *pulAlignment) {
315 if (ulStreamIndex >= NUMBEROFOUTPUTS) {
316 return DMO_E_INVALIDSTREAMINDEX;
317 }
318 if (NULL == pulSize || NULL == pulAlignment) {
319 return E_POINTER;
320 }
321 LockIt lck(static_cast<_DERIVED_ *>(this));
322 if (!m_fTypesSet || !OutputTypeSet(ulStreamIndex)) {
323 return DMO_E_TYPE_NOT_SET;
324 }
325 return INTERNAL_CALL(_DERIVED_, GetOutputSizeInfo)(ulStreamIndex, pulSize, pulAlignment);
326 }
327 STDMETHODIMP SetInputType(ULONG ulStreamIndex, const DMO_MEDIA_TYPE *pmt, DWORD dwFlags) {
328 if (ulStreamIndex >= NUMBEROFINPUTS) {
329 return DMO_E_INVALIDSTREAMINDEX;
330 }
331 if (dwFlags & ~ (DMO_SET_TYPEF_CLEAR | DMO_SET_TYPEF_TEST_ONLY)) {
332 return E_INVALIDARG;
333 }
334
335 LockIt lck(static_cast<_DERIVED_ *>(this));
336
337 if (dwFlags & DMO_SET_TYPEF_CLEAR) {
338 MoFreeMediaType(&m_InputInfo[ulStreamIndex].CurrentMediaType);
339 m_InputInfo[ulStreamIndex].fTypeSet = FALSE;
340 if (!CheckTypesSet()) {
341 Flush();
342 FreeStreamingResources();
343 }
344 return NOERROR;
345 }
346 if (NULL == pmt) {
347 return E_POINTER;
348 }
349 HRESULT hr = INTERNAL_CALL(_DERIVED_, CheckInputType)(ulStreamIndex, pmt);
350 if (FAILED(hr))
351 return hr;
352
353 if (dwFlags & DMO_SET_TYPEF_TEST_ONLY) {
354 return NOERROR;
355 }
356
357
358 // actually set the type
359 DMO_MEDIA_TYPE mtTemp;
360 if (S_OK == MoCopyMediaType(&mtTemp, pmt)) {
361 // Free any previous mediatype
362 if (InputTypeSet(ulStreamIndex)) {
363 MoFreeMediaType(&m_InputInfo[ulStreamIndex].CurrentMediaType);
364 }
365 m_InputInfo[ulStreamIndex].CurrentMediaType = mtTemp;
366 m_InputInfo[ulStreamIndex].fTypeSet = TRUE;
367 CheckTypesSet();
368 } else {
369 return E_OUTOFMEMORY;
370 }
371
372 return NOERROR;
373 }
374
375 STDMETHODIMP SetOutputType(ULONG ulStreamIndex, const DMO_MEDIA_TYPE *pmt, DWORD dwFlags) {
376 if (ulStreamIndex >= NUMBEROFOUTPUTS) {
377 return DMO_E_INVALIDSTREAMINDEX;
378 }
379 if (dwFlags & ~ (DMO_SET_TYPEF_CLEAR | DMO_SET_TYPEF_TEST_ONLY)) {
380 return E_INVALIDARG;
381 }
382
383 LockIt lck(static_cast<_DERIVED_ *>(this));
384
385 if (dwFlags & DMO_SET_TYPEF_CLEAR) {
386 MoFreeMediaType(&m_OutputInfo[ulStreamIndex].CurrentMediaType);
387 m_OutputInfo[ulStreamIndex].fTypeSet = FALSE;
388 if (!CheckTypesSet()) {
389 Flush();
390 FreeStreamingResources();
391 }
392 return NOERROR;
393 }
394 if (NULL == pmt) {
395 return E_POINTER;
396 }
397 HRESULT hr = INTERNAL_CALL(_DERIVED_, CheckOutputType)(ulStreamIndex, pmt);
398 if (FAILED(hr)) {
399 return hr;
400 }
401
402 if (dwFlags & DMO_SET_TYPEF_TEST_ONLY) {
403 return NOERROR;
404 }
405
406
407 // actually set the type
408 DMO_MEDIA_TYPE mtTemp;
409 if (S_OK == MoCopyMediaType(&mtTemp, pmt)) {
410 // Free any previous mediatype
411 if (OutputTypeSet(ulStreamIndex)) {
412 MoFreeMediaType(&m_OutputInfo[ulStreamIndex].CurrentMediaType);
413 }
414 m_OutputInfo[ulStreamIndex].CurrentMediaType = mtTemp;
415 m_OutputInfo[ulStreamIndex].fTypeSet = TRUE;
416 CheckTypesSet();
417 } else {
418 return E_OUTOFMEMORY;
419 }
420
421 return NOERROR;
422 }
423 STDMETHODIMP GetInputStatus(
424 ULONG ulStreamIndex,
425 DWORD *pdwStatus
426 ) {
427 if (ulStreamIndex >= NUMBEROFINPUTS) {
428 return DMO_E_INVALIDSTREAMINDEX;
429 }
430 if (NULL == pdwStatus) {
431 return E_POINTER;
432 }
433 *pdwStatus = 0;
434
435 LockIt lck(static_cast<_DERIVED_ *>(this));
436
437 if (!m_fTypesSet) {
438 return DMO_E_TYPE_NOT_SET;
439 }
440
441 if (INTERNAL_CALL(_DERIVED_, AcceptingInput)(ulStreamIndex) == S_OK) {
442 *pdwStatus |= DMO_INPUT_STATUSF_ACCEPT_DATA;
443 }
444 return NOERROR;
445 }
446 STDMETHODIMP GetInputMaxLatency(unsigned long ulStreamIndex, REFERENCE_TIME *prtLatency) {
447
448 if (prtLatency == NULL) {
449 return E_POINTER;
450 }
451 if (ulStreamIndex >= NUMBEROFINPUTS) {
452 return DMO_E_INVALIDSTREAMINDEX;
453 }
454
455 LockIt lck(static_cast<_DERIVED_ *>(this));
456
457 return INTERNAL_CALL(_DERIVED_, GetInputMaxLatency)(ulStreamIndex, prtLatency);
458 }
459 STDMETHODIMP SetInputMaxLatency(unsigned long ulStreamIndex, REFERENCE_TIME rtLatency) {
460 if (ulStreamIndex >= NUMBEROFINPUTS) {
461 return DMO_E_INVALIDSTREAMINDEX;
462 }
463
464 LockIt lck(static_cast<_DERIVED_ *>(this));
465
466 return INTERNAL_CALL(_DERIVED_, SetInputMaxLatency)(ulStreamIndex, rtLatency);
467 }
468 STDMETHODIMP Discontinuity(ULONG ulStreamIndex) {
469 if (ulStreamIndex >= NUMBEROFINPUTS) {
470 return DMO_E_INVALIDSTREAMINDEX;
471 }
472
473 LockIt lck(static_cast<_DERIVED_ *>(this));
474
475 if (!m_fTypesSet) {
476 return DMO_E_TYPE_NOT_SET;
477 }
478
479 if (S_OK != INTERNAL_CALL(_DERIVED_, AcceptingInput)(ulStreamIndex)) {
480 return DMO_E_NOTACCEPTING;
481 }
482
483 return INTERNAL_CALL(_DERIVED_, Discontinuity)(ulStreamIndex);
484 }
485
486 STDMETHODIMP Flush()
487 {
488 LockIt lck(static_cast<_DERIVED_ *>(this));
489
490 if (!m_fTypesSet) {
491 return S_OK;
492 }
493 if (m_fFlushed) {
494 return S_OK;
495 }
496 HRESULT hr = INTERNAL_CALL(_DERIVED_, Flush)();
497 m_fFlushed = true;
498 return hr;
499 }
500
501 STDMETHODIMP AllocateStreamingResources() {
502 LockIt lck(static_cast<_DERIVED_ *>(this));
503 if (!m_fTypesSet) {
504 return DMO_E_TYPE_NOT_SET;
505 }
506 if (m_fResourcesAllocated) {
507 return S_OK;
508 }
509 HRESULT hr = INTERNAL_CALL(_DERIVED_, AllocateStreamingResources)();
510 if (SUCCEEDED(hr)) {
511 m_fResourcesAllocated = true;
512 }
513 return hr;
514 }
515 STDMETHODIMP FreeStreamingResources()
516 {
517 LockIt lck(static_cast<_DERIVED_ *>(this));
518 if (m_fResourcesAllocated) {
519 m_fResourcesAllocated = false;
520 INTERNAL_CALL(_DERIVED_, Flush)();
521 return INTERNAL_CALL(_DERIVED_, FreeStreamingResources)();
522 }
523 return S_OK;
524 }
525
526 //
527 // Processing methods - public entry points
528 //
529 STDMETHODIMP ProcessInput(
530 DWORD ulStreamIndex,
531 IMediaBuffer *pBuffer, // [in], must not be NULL
532 DWORD dwFlags, // [in] - discontinuity, timestamp, etc.
533 REFERENCE_TIME rtTimestamp, // [in], valid if flag set
534 REFERENCE_TIME rtTimelength // [in], valid if flag set
535 ) {
536 if (!pBuffer) {
537 return E_POINTER;
538 }
539 if (ulStreamIndex >= NUMBEROFINPUTS) {
540 return DMO_E_INVALIDSTREAMINDEX;
541 }
542 if (dwFlags & ~(DMO_INPUT_DATA_BUFFERF_SYNCPOINT |
543 DMO_INPUT_DATA_BUFFERF_TIME |
544 DMO_INPUT_DATA_BUFFERF_TIMELENGTH)) {
545 return E_INVALIDARG;
546 }
547
548 LockIt lck(static_cast<_DERIVED_ *>(this));
549
550 // Make sure all streams have media types set and resources are allocated
551 HRESULT hr = AllocateStreamingResources();
552 if (FAILED(hr)) {
553 return hr;
554 }
555 if (INTERNAL_CALL(_DERIVED_, AcceptingInput)(ulStreamIndex) != S_OK) {
556 return DMO_E_NOTACCEPTING;
557 }
558
559 m_fFlushed = false;
560
561 return INTERNAL_CALL(_DERIVED_, ProcessInput)(
562 ulStreamIndex,
563 pBuffer,
564 dwFlags,
565 rtTimestamp,
566 rtTimelength);
567 }
568
569 STDMETHODIMP ProcessOutput(
570 DWORD dwFlags,
571 DWORD ulOutputBufferCount,
572 DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
573 DWORD *pdwStatus)
574 {
575 if (pdwStatus == NULL) {
576 return E_POINTER;
577 }
578
579
580 if (ulOutputBufferCount != NUMBEROFOUTPUTS || (dwFlags & ~DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER)) {
581 return E_INVALIDARG;
582 }
583
584 if (NUMBEROFOUTPUTS != 0 && pOutputBuffers == NULL) {
585 return E_POINTER;
586 }
587
588 *pdwStatus = 0;
589
590 LockIt lck(static_cast<_DERIVED_ *>(this));
591
592 HRESULT hr = AllocateStreamingResources();
593 if (FAILED(hr)) {
594 return hr;
595 }
596
597 for (DWORD dw = 0; dw < NUMBEROFOUTPUTS; dw++) {
598 pOutputBuffers[dw].dwStatus = 0;
599 }
600
601 hr = INTERNAL_CALL(_DERIVED_, ProcessOutput)(
602 dwFlags,
603 ulOutputBufferCount,
604 pOutputBuffers,
605 pdwStatus);
606
607 // remember the DMO's incomplete status
608 for (dw = 0; dw < NUMBEROFOUTPUTS; dw++) {
609 if (pOutputBuffers[dw].dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE) {
610 m_OutputInfo[dw].fIncomplete = TRUE;
611 } else {
612 m_OutputInfo[dw].fIncomplete = FALSE;
613 }
614 }
615
616 return hr;
617 }
618
619 STDMETHODIMP DMOLock(LONG lLock)
620 {
621 if (lLock) {
622 static_cast<_DERIVED_ *>(this)->Lock();
623 } else {
624 static_cast<_DERIVED_ *>(this)->Unlock();
625 }
626 return S_OK;
627 }
628 };
629
630 #endif // _dmoimpl_h_
631

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26