mirror of
https://github.com/halpz/re3.git
synced 2025-06-26 22:06:22 +00:00
skeleton updated, windows specific stuff added
This commit is contained in:
645
dxsdk/Include/dmoimpl.h
Normal file
645
dxsdk/Include/dmoimpl.h
Normal file
@ -0,0 +1,645 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: DMOImpl.h
|
||||
//
|
||||
// Desc: Classes to implement a DMO.
|
||||
//
|
||||
// Copyright (c) 2000-2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef _dmoimpl_h_
|
||||
#define _dmoimpl_h_
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
// Class to implement a DMO
|
||||
//
|
||||
//
|
||||
// Assumes the number of input and output streams is fixed
|
||||
// (these are template parameters)
|
||||
//
|
||||
// Provides following services:
|
||||
//
|
||||
// Basic parameter checking and locking
|
||||
// Fully implements :
|
||||
// GetStreamCount
|
||||
// SetInputType
|
||||
// SetOutputType
|
||||
// GetCurrentInputType
|
||||
// GetCurrentOutputType
|
||||
//
|
||||
// Checks if all types are set before streaming
|
||||
// Automatically calls AllocateStreamingResources before streaming
|
||||
// if it's not been called already
|
||||
// Prevents streaming until the types on all non-optional streams
|
||||
// have been set
|
||||
//
|
||||
//
|
||||
// Derived class implements the following methods :
|
||||
//
|
||||
/*
|
||||
HRESULT InternalGetInputStreamInfo(DWORD dwInputStreamIndex, DWORD *pdwFlags);
|
||||
HRESULT InternalGetOutputStreamInfo(DWORD dwOutputStreamIndex, DWORD *pdwFlags);
|
||||
HRESULT InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt);
|
||||
HRESULT InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt);
|
||||
HRESULT InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex,
|
||||
DMO_MEDIA_TYPE *pmt);
|
||||
HRESULT InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex,
|
||||
DMO_MEDIA_TYPE *pmt);
|
||||
HRESULT InternalGetInputSizeInfo(DWORD dwInputStreamIndex, DWORD *pcbSize,
|
||||
DWORD *pcbMaxLookahead, DWORD *pcbAlignment);
|
||||
HRESULT InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
|
||||
DWORD *pcbAlignment);
|
||||
HRESULT InternalGetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency);
|
||||
HRESULT InternalSetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency);
|
||||
HRESULT InternalFlush();
|
||||
HRESULT InternalDiscontinuity(DWORD dwInputStreamIndex);
|
||||
HRESULT InternalAllocateStreamingResources();
|
||||
HRESULT InternalFreeStreamingResources();
|
||||
HRESULT InternalProcessInput(DWORD dwInputStreamIndex, IMediaBuffer *pBuffer,
|
||||
DWORD dwFlags, REFERENCE_TIME rtTimestamp,
|
||||
REFERENCE_TIME rtTimelength);
|
||||
HRESULT InternalProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount,
|
||||
DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
|
||||
DWORD *pdwStatus);
|
||||
HRESULT InternalAcceptingInput(DWORD dwInputStreamIndex);
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
Notes:
|
||||
The derived class is meant to do most work to initialize streaming
|
||||
in AllocateStreamingResources rather than when types are set.
|
||||
|
||||
This centralizes the work to one
|
||||
clear place based on the types set for all streams.
|
||||
|
||||
The derived class implements locking.
|
||||
|
||||
The derived class implements the IUnknown methods
|
||||
|
||||
Usage example (1 input and 1 output) :
|
||||
class CMyDMO : public IMediaObjectImpl<CMyDmo, 1, 1>,
|
||||
...
|
||||
*/
|
||||
|
||||
|
||||
#define INTERNAL_CALL(_T_, _X_) \
|
||||
static_cast<_T_ *>(this)->Internal##_X_
|
||||
|
||||
template <class _DERIVED_, int NUMBEROFINPUTS, int NUMBEROFOUTPUTS>
|
||||
class IMediaObjectImpl : public IMediaObject
|
||||
{
|
||||
private:
|
||||
// Member variables
|
||||
struct {
|
||||
DWORD fTypeSet:1;
|
||||
DWORD fIncomplete:1;
|
||||
DMO_MEDIA_TYPE CurrentMediaType;
|
||||
} m_InputInfo[NUMBEROFINPUTS], m_OutputInfo[NUMBEROFOUTPUTS];
|
||||
|
||||
bool m_fTypesSet;
|
||||
bool m_fFlushed;
|
||||
bool m_fResourcesAllocated;
|
||||
|
||||
protected:
|
||||
|
||||
// Helpers
|
||||
bool InputTypeSet(DWORD ulInputStreamIndex) const
|
||||
{
|
||||
_ASSERTE(ulInputStreamIndex < NUMBEROFINPUTS);
|
||||
return 0 != m_InputInfo[ulInputStreamIndex].fTypeSet;
|
||||
}
|
||||
|
||||
bool OutputTypeSet(DWORD ulOutputStreamIndex) const
|
||||
{
|
||||
_ASSERTE(ulOutputStreamIndex < NUMBEROFOUTPUTS);
|
||||
return 0 != m_OutputInfo[ulOutputStreamIndex].fTypeSet;
|
||||
}
|
||||
const DMO_MEDIA_TYPE *InputType(DWORD ulInputStreamIndex)
|
||||
{
|
||||
if (!InputTypeSet(ulInputStreamIndex)) {
|
||||
return NULL;
|
||||
}
|
||||
return &m_InputInfo[ulInputStreamIndex].CurrentMediaType;
|
||||
}
|
||||
const DMO_MEDIA_TYPE *OutputType(DWORD ulOutputStreamIndex)
|
||||
{
|
||||
if (!OutputTypeSet(ulOutputStreamIndex)) {
|
||||
return NULL;
|
||||
}
|
||||
return &m_OutputInfo[ulOutputStreamIndex].CurrentMediaType;
|
||||
}
|
||||
|
||||
|
||||
class LockIt
|
||||
{
|
||||
public:
|
||||
LockIt(_DERIVED_ *p) : m_p(p)
|
||||
{
|
||||
static_cast<_DERIVED_ *>(m_p)->Lock();
|
||||
}
|
||||
~LockIt()
|
||||
{
|
||||
static_cast<_DERIVED_ *>(m_p)->Unlock();
|
||||
}
|
||||
_DERIVED_ *const m_p;
|
||||
};
|
||||
|
||||
bool CheckTypesSet()
|
||||
{
|
||||
m_fTypesSet = false;
|
||||
DWORD dw;
|
||||
for (dw = 0; dw < NUMBEROFINPUTS; dw++) {
|
||||
if (!InputTypeSet(dw)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (dw = 0; dw < NUMBEROFOUTPUTS; dw++) {
|
||||
if (!OutputTypeSet(dw)) {
|
||||
// Check if it's optional
|
||||
DWORD dwFlags;
|
||||
#ifdef _DEBUG
|
||||
dwFlags = 0xFFFFFFFF;
|
||||
#endif
|
||||
INTERNAL_CALL(_DERIVED_, GetOutputStreamInfo)(dw, &dwFlags);
|
||||
_ASSERTE(0 == (dwFlags & ~(DMO_OUTPUT_STREAMF_WHOLE_SAMPLES |
|
||||
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
|
||||
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE |
|
||||
DMO_OUTPUT_STREAMF_DISCARDABLE |
|
||||
DMO_OUTPUT_STREAMF_OPTIONAL)));
|
||||
if (!(dwFlags & DMO_OUTPUT_STREAMF_OPTIONAL)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_fTypesSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IMediaObjectImpl() :
|
||||
m_fTypesSet(false),
|
||||
m_fFlushed(true),
|
||||
m_fResourcesAllocated(false)
|
||||
{
|
||||
ZeroMemory(&m_InputInfo, sizeof(m_InputInfo));
|
||||
ZeroMemory(&m_OutputInfo, sizeof(m_OutputInfo));
|
||||
}
|
||||
|
||||
virtual ~IMediaObjectImpl() {
|
||||
DWORD dwCurrentType;
|
||||
|
||||
for (dwCurrentType = 0; dwCurrentType < NUMBEROFINPUTS; dwCurrentType++) {
|
||||
if(InputTypeSet(dwCurrentType)) {
|
||||
MoFreeMediaType(&m_InputInfo[dwCurrentType].CurrentMediaType);
|
||||
}
|
||||
}
|
||||
|
||||
for (dwCurrentType = 0; dwCurrentType < NUMBEROFOUTPUTS; dwCurrentType++) {
|
||||
if(OutputTypeSet(dwCurrentType)) {
|
||||
MoFreeMediaType(&m_OutputInfo[dwCurrentType].CurrentMediaType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// IMediaObject methods
|
||||
|
||||
|
||||
//
|
||||
// IMediaObject methods
|
||||
//
|
||||
STDMETHODIMP GetStreamCount(unsigned long *pulNumberOfInputStreams, unsigned long *pulNumberOfOutputStreams)
|
||||
{
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (pulNumberOfInputStreams == NULL ||
|
||||
pulNumberOfOutputStreams == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
*pulNumberOfInputStreams = NUMBEROFINPUTS;
|
||||
*pulNumberOfOutputStreams = NUMBEROFOUTPUTS;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetInputStreamInfo(ULONG ulStreamIndex, DWORD *pdwFlags)
|
||||
{
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (pdwFlags == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
HRESULT hr = INTERNAL_CALL(_DERIVED_, GetInputStreamInfo)(ulStreamIndex, pdwFlags);
|
||||
_ASSERTE(0 == (*pdwFlags & ~(DMO_INPUT_STREAMF_WHOLE_SAMPLES |
|
||||
DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
|
||||
DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE |
|
||||
DMO_INPUT_STREAMF_HOLDS_BUFFERS)));
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetOutputStreamInfo(ULONG ulStreamIndex, DWORD *pdwFlags)
|
||||
{
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (ulStreamIndex >= NUMBEROFOUTPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (pdwFlags == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
HRESULT hr = INTERNAL_CALL(_DERIVED_, GetOutputStreamInfo)(ulStreamIndex, pdwFlags);
|
||||
_ASSERTE(0 == (*pdwFlags & ~(DMO_OUTPUT_STREAMF_WHOLE_SAMPLES |
|
||||
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
|
||||
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE |
|
||||
DMO_OUTPUT_STREAMF_DISCARDABLE |
|
||||
DMO_OUTPUT_STREAMF_OPTIONAL)));
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetInputType(ULONG ulStreamIndex, ULONG ulTypeIndex, DMO_MEDIA_TYPE *pmt) {
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
return INTERNAL_CALL(_DERIVED_, GetInputType)(ulStreamIndex, ulTypeIndex, pmt);
|
||||
}
|
||||
|
||||
STDMETHODIMP GetOutputType(ULONG ulStreamIndex, ULONG ulTypeIndex, DMO_MEDIA_TYPE *pmt) {
|
||||
if (ulStreamIndex >= NUMBEROFOUTPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
return INTERNAL_CALL(_DERIVED_, GetOutputType)(ulStreamIndex, ulTypeIndex, pmt);
|
||||
}
|
||||
|
||||
STDMETHODIMP GetInputCurrentType(ULONG ulStreamIndex, DMO_MEDIA_TYPE *pmt) {
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (NULL == pmt) {
|
||||
return E_POINTER;
|
||||
}
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (InputTypeSet(ulStreamIndex))
|
||||
return MoCopyMediaType(pmt,
|
||||
&m_InputInfo[ulStreamIndex].CurrentMediaType);
|
||||
else
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetOutputCurrentType(ULONG ulStreamIndex, DMO_MEDIA_TYPE *pmt) {
|
||||
if (ulStreamIndex >= NUMBEROFOUTPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (NULL == pmt) {
|
||||
return E_POINTER;
|
||||
}
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (OutputTypeSet(ulStreamIndex))
|
||||
return MoCopyMediaType(pmt,
|
||||
&m_OutputInfo[ulStreamIndex].CurrentMediaType);
|
||||
else
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetInputSizeInfo(ULONG ulStreamIndex, ULONG *pulSize, ULONG *pcbMaxLookahead, ULONG *pulAlignment) {
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (NULL == pulSize || NULL == pulAlignment ||
|
||||
NULL == pcbMaxLookahead) {
|
||||
return E_POINTER;
|
||||
}
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (!InputTypeSet(ulStreamIndex)) {
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
}
|
||||
return INTERNAL_CALL(_DERIVED_, GetInputSizeInfo)(ulStreamIndex, pulSize, pcbMaxLookahead, pulAlignment);
|
||||
}
|
||||
|
||||
STDMETHODIMP GetOutputSizeInfo(ULONG ulStreamIndex, ULONG *pulSize, ULONG *pulAlignment) {
|
||||
if (ulStreamIndex >= NUMBEROFOUTPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (NULL == pulSize || NULL == pulAlignment) {
|
||||
return E_POINTER;
|
||||
}
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (!m_fTypesSet || !OutputTypeSet(ulStreamIndex)) {
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
}
|
||||
return INTERNAL_CALL(_DERIVED_, GetOutputSizeInfo)(ulStreamIndex, pulSize, pulAlignment);
|
||||
}
|
||||
|
||||
STDMETHODIMP SetInputType(ULONG ulStreamIndex, const DMO_MEDIA_TYPE *pmt, DWORD dwFlags) {
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (dwFlags & ~ (DMO_SET_TYPEF_CLEAR | DMO_SET_TYPEF_TEST_ONLY)) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
if (dwFlags & DMO_SET_TYPEF_CLEAR) {
|
||||
MoFreeMediaType(&m_InputInfo[ulStreamIndex].CurrentMediaType);
|
||||
m_InputInfo[ulStreamIndex].fTypeSet = FALSE;
|
||||
if (!CheckTypesSet()) {
|
||||
Flush();
|
||||
FreeStreamingResources();
|
||||
}
|
||||
return NOERROR;
|
||||
}
|
||||
if (NULL == pmt) {
|
||||
return E_POINTER;
|
||||
}
|
||||
HRESULT hr = INTERNAL_CALL(_DERIVED_, CheckInputType)(ulStreamIndex, pmt);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (dwFlags & DMO_SET_TYPEF_TEST_ONLY) {
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
// actually set the type
|
||||
DMO_MEDIA_TYPE mtTemp;
|
||||
if (S_OK == MoCopyMediaType(&mtTemp, pmt)) {
|
||||
// Free any previous mediatype
|
||||
if (InputTypeSet(ulStreamIndex)) {
|
||||
MoFreeMediaType(&m_InputInfo[ulStreamIndex].CurrentMediaType);
|
||||
}
|
||||
m_InputInfo[ulStreamIndex].CurrentMediaType = mtTemp;
|
||||
m_InputInfo[ulStreamIndex].fTypeSet = TRUE;
|
||||
CheckTypesSet();
|
||||
} else {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
STDMETHODIMP SetOutputType(ULONG ulStreamIndex, const DMO_MEDIA_TYPE *pmt, DWORD dwFlags) {
|
||||
if (ulStreamIndex >= NUMBEROFOUTPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (dwFlags & ~ (DMO_SET_TYPEF_CLEAR | DMO_SET_TYPEF_TEST_ONLY)) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
if (dwFlags & DMO_SET_TYPEF_CLEAR) {
|
||||
MoFreeMediaType(&m_OutputInfo[ulStreamIndex].CurrentMediaType);
|
||||
m_OutputInfo[ulStreamIndex].fTypeSet = FALSE;
|
||||
if (!CheckTypesSet()) {
|
||||
Flush();
|
||||
FreeStreamingResources();
|
||||
}
|
||||
return NOERROR;
|
||||
}
|
||||
if (NULL == pmt) {
|
||||
return E_POINTER;
|
||||
}
|
||||
HRESULT hr = INTERNAL_CALL(_DERIVED_, CheckOutputType)(ulStreamIndex, pmt);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (dwFlags & DMO_SET_TYPEF_TEST_ONLY) {
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
// actually set the type
|
||||
DMO_MEDIA_TYPE mtTemp;
|
||||
if (S_OK == MoCopyMediaType(&mtTemp, pmt)) {
|
||||
// Free any previous mediatype
|
||||
if (OutputTypeSet(ulStreamIndex)) {
|
||||
MoFreeMediaType(&m_OutputInfo[ulStreamIndex].CurrentMediaType);
|
||||
}
|
||||
m_OutputInfo[ulStreamIndex].CurrentMediaType = mtTemp;
|
||||
m_OutputInfo[ulStreamIndex].fTypeSet = TRUE;
|
||||
CheckTypesSet();
|
||||
} else {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetInputStatus(
|
||||
ULONG ulStreamIndex,
|
||||
DWORD *pdwStatus
|
||||
) {
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (NULL == pdwStatus) {
|
||||
return E_POINTER;
|
||||
}
|
||||
*pdwStatus = 0;
|
||||
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
if (!m_fTypesSet) {
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
}
|
||||
|
||||
if (INTERNAL_CALL(_DERIVED_, AcceptingInput)(ulStreamIndex) == S_OK) {
|
||||
*pdwStatus |= DMO_INPUT_STATUSF_ACCEPT_DATA;
|
||||
}
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetInputMaxLatency(unsigned long ulStreamIndex, REFERENCE_TIME *prtLatency) {
|
||||
|
||||
if (prtLatency == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
return INTERNAL_CALL(_DERIVED_, GetInputMaxLatency)(ulStreamIndex, prtLatency);
|
||||
}
|
||||
|
||||
STDMETHODIMP SetInputMaxLatency(unsigned long ulStreamIndex, REFERENCE_TIME rtLatency) {
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
return INTERNAL_CALL(_DERIVED_, SetInputMaxLatency)(ulStreamIndex, rtLatency);
|
||||
}
|
||||
|
||||
STDMETHODIMP Discontinuity(ULONG ulStreamIndex) {
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
if (!m_fTypesSet) {
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
}
|
||||
|
||||
if (S_OK != INTERNAL_CALL(_DERIVED_, AcceptingInput)(ulStreamIndex)) {
|
||||
return DMO_E_NOTACCEPTING;
|
||||
}
|
||||
|
||||
return INTERNAL_CALL(_DERIVED_, Discontinuity)(ulStreamIndex);
|
||||
}
|
||||
|
||||
STDMETHODIMP Flush()
|
||||
{
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
if (!m_fTypesSet) {
|
||||
return S_OK;
|
||||
}
|
||||
if (m_fFlushed) {
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT hr = INTERNAL_CALL(_DERIVED_, Flush)();
|
||||
m_fFlushed = true;
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP AllocateStreamingResources() {
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (!m_fTypesSet) {
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
}
|
||||
if (m_fResourcesAllocated) {
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT hr = INTERNAL_CALL(_DERIVED_, AllocateStreamingResources)();
|
||||
if (SUCCEEDED(hr)) {
|
||||
m_fResourcesAllocated = true;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP FreeStreamingResources()
|
||||
{
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
if (m_fResourcesAllocated) {
|
||||
m_fResourcesAllocated = false;
|
||||
INTERNAL_CALL(_DERIVED_, Flush)();
|
||||
return INTERNAL_CALL(_DERIVED_, FreeStreamingResources)();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Processing methods - public entry points
|
||||
//
|
||||
STDMETHODIMP ProcessInput(
|
||||
DWORD ulStreamIndex,
|
||||
IMediaBuffer *pBuffer, // [in], must not be NULL
|
||||
DWORD dwFlags, // [in] - discontinuity, timestamp, etc.
|
||||
REFERENCE_TIME rtTimestamp, // [in], valid if flag set
|
||||
REFERENCE_TIME rtTimelength // [in], valid if flag set
|
||||
) {
|
||||
if (!pBuffer) {
|
||||
return E_POINTER;
|
||||
}
|
||||
if (ulStreamIndex >= NUMBEROFINPUTS) {
|
||||
return DMO_E_INVALIDSTREAMINDEX;
|
||||
}
|
||||
if (dwFlags & ~(DMO_INPUT_DATA_BUFFERF_SYNCPOINT |
|
||||
DMO_INPUT_DATA_BUFFERF_TIME |
|
||||
DMO_INPUT_DATA_BUFFERF_TIMELENGTH)) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
// Make sure all streams have media types set and resources are allocated
|
||||
HRESULT hr = AllocateStreamingResources();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
if (INTERNAL_CALL(_DERIVED_, AcceptingInput)(ulStreamIndex) != S_OK) {
|
||||
return DMO_E_NOTACCEPTING;
|
||||
}
|
||||
|
||||
m_fFlushed = false;
|
||||
|
||||
return INTERNAL_CALL(_DERIVED_, ProcessInput)(
|
||||
ulStreamIndex,
|
||||
pBuffer,
|
||||
dwFlags,
|
||||
rtTimestamp,
|
||||
rtTimelength);
|
||||
}
|
||||
|
||||
STDMETHODIMP ProcessOutput(
|
||||
DWORD dwFlags,
|
||||
DWORD ulOutputBufferCount,
|
||||
DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
|
||||
DWORD *pdwStatus)
|
||||
{
|
||||
if (pdwStatus == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
|
||||
if (ulOutputBufferCount != NUMBEROFOUTPUTS || (dwFlags & ~DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER)) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NUMBEROFOUTPUTS != 0 && pOutputBuffers == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
*pdwStatus = 0;
|
||||
|
||||
LockIt lck(static_cast<_DERIVED_ *>(this));
|
||||
|
||||
HRESULT hr = AllocateStreamingResources();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
for (DWORD dw = 0; dw < NUMBEROFOUTPUTS; dw++) {
|
||||
pOutputBuffers[dw].dwStatus = 0;
|
||||
}
|
||||
|
||||
hr = INTERNAL_CALL(_DERIVED_, ProcessOutput)(
|
||||
dwFlags,
|
||||
ulOutputBufferCount,
|
||||
pOutputBuffers,
|
||||
pdwStatus);
|
||||
|
||||
// remember the DMO's incomplete status
|
||||
for (dw = 0; dw < NUMBEROFOUTPUTS; dw++) {
|
||||
if (pOutputBuffers[dw].dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE) {
|
||||
m_OutputInfo[dw].fIncomplete = TRUE;
|
||||
} else {
|
||||
m_OutputInfo[dw].fIncomplete = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP DMOLock(LONG lLock)
|
||||
{
|
||||
if (lLock) {
|
||||
static_cast<_DERIVED_ *>(this)->Lock();
|
||||
} else {
|
||||
static_cast<_DERIVED_ *>(this)->Unlock();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _dmoimpl_h_
|
||||
|
Reference in New Issue
Block a user