00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "stdafx.h"
00033 #include "abstractaudiodecodeoutputpin.h"
00034
00035 AbstractAudioDecodeOutputPin::AbstractAudioDecodeOutputPin(AbstractAudioDecodeFilter* inParentFilter, CCritSec* inFilterLock, CHAR* inObjectName, LPCWSTR inPinDisplayName)
00036 : CBaseOutputPin(inObjectName, inParentFilter, inFilterLock, &mHR, inPinDisplayName)
00037 , mParentFilter(inParentFilter)
00038
00039 , mDataQueue(NULL)
00040 {
00041
00042 }
00043 AbstractAudioDecodeOutputPin::~AbstractAudioDecodeOutputPin(void)
00044 {
00045 ReleaseDelegate();
00046 delete mDataQueue;
00047 mDataQueue = NULL;
00048 }
00049
00050 STDMETHODIMP AbstractAudioDecodeOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) {
00051 if (riid == IID_IMediaSeeking) {
00052 *ppv = (IMediaSeeking*)this;
00053 ((IUnknown*)*ppv)->AddRef();
00054 return NOERROR;
00055 }
00056
00057 return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
00058 }
00059
00060 HRESULT AbstractAudioDecodeOutputPin::DecideBufferSize(IMemAllocator* inAllocator, ALLOCATOR_PROPERTIES* inPropertyRequest) {
00061
00062
00063
00064 HRESULT locHR = S_OK;
00065
00066 ALLOCATOR_PROPERTIES locReqAlloc;
00067 ALLOCATOR_PROPERTIES locActualAlloc;
00068
00069 const unsigned long MIN_BUFFER_SIZE = 1096;
00070 const unsigned long DEFAULT_BUFFER_SIZE = 32192;
00071 const unsigned long MIN_NUM_BUFFERS = 10;
00072 const unsigned long DEFAULT_NUM_BUFFERS = 20;
00073
00074
00075
00076
00077 if (inPropertyRequest->cbAlign <= 0) {
00078 locReqAlloc.cbAlign = 1;
00079 } else {
00080 locReqAlloc.cbAlign = inPropertyRequest->cbAlign;
00081 }
00082
00083
00084 if (inPropertyRequest->cbBuffer < MIN_BUFFER_SIZE) {
00085 locReqAlloc.cbBuffer = DEFAULT_BUFFER_SIZE;
00086 } else {
00087 locReqAlloc.cbBuffer = inPropertyRequest->cbBuffer;
00088 }
00089
00090
00091 if (inPropertyRequest->cbPrefix < 0) {
00092 locReqAlloc.cbPrefix = 0;
00093 } else {
00094 locReqAlloc.cbPrefix = inPropertyRequest->cbPrefix;
00095 }
00096
00097
00098 if (inPropertyRequest->cBuffers < MIN_NUM_BUFFERS) {
00099 locReqAlloc.cBuffers = DEFAULT_NUM_BUFFERS;
00100 } else {
00101 locReqAlloc.cBuffers = inPropertyRequest->cBuffers;
00102 }
00103
00104
00105 locHR = inAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00106
00107 if (locHR != S_OK) {
00108 return locHR;
00109 }
00110
00111
00112
00113 locHR = inAllocator->Commit();
00114
00115 return locHR;
00116 }
00117 HRESULT AbstractAudioDecodeOutputPin::CheckMediaType(const CMediaType *inMediaType) {
00118 if ( (inMediaType->majortype == MEDIATYPE_Audio) &&
00119 (inMediaType->subtype == MEDIASUBTYPE_PCM) &&
00120 (inMediaType->formattype == FORMAT_WaveFormatEx)) {
00121 return S_OK;
00122 } else {
00123 return S_FALSE;
00124 }
00125
00126 }
00127
00128 void AbstractAudioDecodeOutputPin::FillMediaType(CMediaType* outMediaType) {
00129 outMediaType->SetType(&MEDIATYPE_Audio);
00130 outMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
00131 outMediaType->SetFormatType(&FORMAT_WaveFormatEx);
00132 outMediaType->SetTemporalCompression(FALSE);
00133 outMediaType->SetSampleSize(0);
00134
00135 }
00136 HRESULT AbstractAudioDecodeOutputPin::GetMediaType(int inPosition, CMediaType *outMediaType) {
00137
00138 if (inPosition < 0) {
00139 return E_INVALIDARG;
00140 }
00141
00142 if (inPosition == 0) {
00143 FillMediaType(outMediaType);
00144 WAVEFORMATEX* locWaveFormat = (WAVEFORMATEX*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
00145 FillWaveFormatExBuffer(locWaveFormat);
00146 return S_OK;
00147 } else {
00148 return VFW_S_NO_MORE_ITEMS;
00149 }
00150 }
00151
00152 HRESULT AbstractAudioDecodeOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) {
00153
00154 mDataQueue->NewSegment(tStart, tStop, dRate);
00155 return S_OK;
00156 }
00157 HRESULT AbstractAudioDecodeOutputPin::DeliverEndOfStream(void) {
00158
00159 mDataQueue->EOS();
00160 return S_OK;
00161 }
00162
00163 HRESULT AbstractAudioDecodeOutputPin::DeliverEndFlush(void) {
00164 CAutoLock locLock(m_pLock);
00165
00166 mDataQueue->EndFlush();
00167 return S_OK;
00168 }
00169
00170 HRESULT AbstractAudioDecodeOutputPin::DeliverBeginFlush(void) {
00171 CAutoLock locLock(m_pLock);
00172
00173
00174 mDataQueue->BeginFlush();
00175 return S_OK;
00176
00177 }
00178
00179 HRESULT AbstractAudioDecodeOutputPin::CompleteConnect (IPin *inReceivePin) {
00180 CAutoLock locLock(m_pLock);
00181 HRESULT locHR = S_OK;
00182
00183
00184
00185
00186 IMediaSeeking* locSeeker = NULL;
00187 mParentFilter->mInputPin->NonDelegatingQueryInterface(IID_IMediaSeeking, (void**)&locSeeker);
00188 SetDelegate(locSeeker);
00189
00190 mDataQueue = new COutputQueue (inReceivePin, &locHR, FALSE, FALSE, 1, TRUE, 20);
00191
00192 if (FAILED(locHR)) {
00193
00194
00195 }
00196
00197 return CBaseOutputPin::CompleteConnect(inReceivePin);
00198 }
00199
00200 HRESULT AbstractAudioDecodeOutputPin::BreakConnect(void) {
00201 CAutoLock locLock(m_pLock);
00202
00203 delete mDataQueue;
00204 mDataQueue = NULL;
00205
00206 HRESULT locHR = CBaseOutputPin::BreakConnect();
00207 ReleaseDelegate();
00208
00209 return locHR;
00210 }