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 #include "stdafx.h"
00032 #include ".\NativeFLACSourcePin.h"
00033
00034 NativeFLACSourcePin::NativeFLACSourcePin(NativeFLACSourceFilter* inParentFilter, CCritSec* inFilterLock)
00035 : CBaseOutputPin(NAME("Native FLAC Source Pin"), inParentFilter, inFilterLock, &mFilterHR, L"PCM Out")
00036 , mParentFilter(inParentFilter)
00037 , mDataQueue(NULL)
00038
00039 {
00040
00041
00042 IMediaSeeking* locSeeker = NULL;
00043 locSeeker = (IMediaSeeking*)mParentFilter;
00044 SetDelegate(locSeeker);
00045 }
00046
00047 NativeFLACSourcePin::~NativeFLACSourcePin(void)
00048 {
00049 SetDelegate(NULL);
00050 delete mDataQueue;
00051 mDataQueue = NULL;
00052 }
00053
00054 STDMETHODIMP NativeFLACSourcePin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00055 {
00056 if (riid == IID_IMediaSeeking) {
00057 *ppv = (IMediaSeeking*)this;
00058 ((IUnknown*)*ppv)->AddRef();
00059 return NOERROR;
00060 }
00061 return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
00062 }
00063
00064 HRESULT NativeFLACSourcePin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
00065 {
00066 mDataQueue->NewSegment(tStart, tStop, dRate);
00067
00068 return S_OK;
00069 }
00070 HRESULT NativeFLACSourcePin::DeliverEndOfStream(void)
00071 {
00072 mDataQueue->EOS();
00073 return S_OK;
00074 }
00075
00076 HRESULT NativeFLACSourcePin::DeliverEndFlush(void)
00077 {
00078 mDataQueue->EndFlush();
00079 return S_OK;
00080 }
00081
00082 HRESULT NativeFLACSourcePin::DeliverBeginFlush(void)
00083 {
00084 mDataQueue->BeginFlush();
00085 return S_OK;
00086 }
00087
00088 HRESULT NativeFLACSourcePin::CompleteConnect (IPin *inReceivePin)
00089 {
00090 mFilterHR = S_OK;
00091
00092 mDataQueue = new COutputQueue (inReceivePin, &mFilterHR, FALSE, TRUE,1,TRUE, NUM_BUFFERS);
00093 if (FAILED(mFilterHR)) {
00094
00095 mFilterHR = mFilterHR;
00096 }
00097
00098 return CBaseOutputPin::CompleteConnect(inReceivePin);
00099 }
00100
00101 HRESULT NativeFLACSourcePin::BreakConnect(void) {
00102 delete mDataQueue;
00103 mDataQueue = NULL;
00104 return CBaseOutputPin::BreakConnect();
00105 }
00106
00107
00108 HRESULT NativeFLACSourcePin::GetMediaType(int inPosition, CMediaType* outMediaType) {
00109 if (inPosition == 0) {
00110 outMediaType->SetType(&MEDIATYPE_Audio);
00111 outMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
00112 outMediaType->SetFormatType(&FORMAT_WaveFormatEx);
00113 outMediaType->SetTemporalCompression(FALSE);
00114 outMediaType->SetSampleSize(0);
00115
00116 WAVEFORMATEX* locFormat = (WAVEFORMATEX*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
00117 locFormat->wFormatTag = WAVE_FORMAT_PCM;
00118
00119 locFormat->nChannels = (WORD)mParentFilter->mNumChannels;
00120 locFormat->nSamplesPerSec = mParentFilter->mSampleRate;
00121 locFormat->wBitsPerSample = (WORD)mParentFilter->mBitsPerSample;
00122 locFormat->nBlockAlign = (WORD)((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3));
00123 locFormat->nAvgBytesPerSec = ((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3)) * mParentFilter->mSampleRate;
00124 locFormat->cbSize = 0;
00125
00126 return S_OK;
00127 } else {
00128 return VFW_S_NO_MORE_ITEMS;
00129 }
00130 }
00131 HRESULT NativeFLACSourcePin::CheckMediaType(const CMediaType* inMediaType) {
00132 if ((inMediaType->majortype == MEDIATYPE_Audio) && (inMediaType->subtype == MEDIASUBTYPE_PCM) && (inMediaType->formattype == FORMAT_WaveFormatEx)) {
00133 return S_OK;
00134 } else {
00135 return E_FAIL;
00136 }
00137 }
00138 HRESULT NativeFLACSourcePin::DecideBufferSize(IMemAllocator* inoutAllocator, ALLOCATOR_PROPERTIES* inoutInputRequest) {
00139 HRESULT locHR = S_OK;
00140
00141 ALLOCATOR_PROPERTIES locReqAlloc;
00142 ALLOCATOR_PROPERTIES locActualAlloc;
00143
00144 locReqAlloc.cbAlign = 1;
00145 locReqAlloc.cbBuffer = BUFFER_SIZE;
00146 locReqAlloc.cbPrefix = 0;
00147 locReqAlloc.cBuffers = NUM_BUFFERS;
00148
00149 locHR = inoutAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00150
00151 if (locHR != S_OK) {
00152 return locHR;
00153 }
00154
00155 locHR = inoutAllocator->Commit();
00156
00157 return locHR;
00158 }
00159
00160
00161 HRESULT NativeFLACSourcePin::deliverData(unsigned char* inBuff, unsigned long inBuffSize, __int64 inStart, __int64 inEnd) {
00162
00163
00164 IMediaSample* locSample = NULL;
00165 REFERENCE_TIME locStart = inStart;
00166 REFERENCE_TIME locStop = inEnd;
00167
00168 HRESULT locHR = GetDeliveryBuffer(&locSample, &locStart, &locStop, NULL);
00169
00170
00171 if (locHR != S_OK) {
00172 delete[] inBuff;
00173 return locHR;
00174 }
00175
00176 locSample->SetTime(&locStart, &locStop);
00177
00178 locSample->SetSyncPoint(TRUE);
00179
00180
00181 BYTE* locBuffer = NULL;
00182 locSample->GetPointer(&locBuffer);
00183
00184
00185 if (locSample->GetSize() >= inBuffSize) {
00186 memcpy((void*)locBuffer, (const void*)inBuff, inBuffSize);
00187 locSample->SetActualDataLength(inBuffSize);
00188
00189 locHR = mDataQueue->Receive(locSample);
00190
00191 if (locHR != S_OK) {
00192 delete[] inBuff;
00193 return locHR;
00194
00195 } else {
00196 delete[] inBuff;
00197 return S_OK;
00198 }
00199 } else {
00200 delete[] inBuff;
00201 throw 0;
00202 }
00203 }