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

Annotation of /api/include/dmoimpl.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Sun Jul 1 20:47:59 2001 UTC (23 years, 5 months ago) by bearsoft
Branch point for: lazy, MAIN
File MIME type: text/plain
Initial revision

1 bearsoft 1.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