NativeFLACSourcePin.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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         //Subvert COM and do this directly... this way, the source filter won't expose the interface to the
00041         // graph but we can still delegate to it.
00042         IMediaSeeking* locSeeker = NULL;
00043         locSeeker = (IMediaSeeking*)mParentFilter;
00044         SetDelegate(locSeeker);
00045 }
00046 
00047 NativeFLACSourcePin::~NativeFLACSourcePin(void)
00048 {
00049         SetDelegate(NULL);              //Avoid infinite destructor loop.
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         //Deleted in destructor
00092         mDataQueue = new COutputQueue (inReceivePin, &mFilterHR, FALSE, TRUE,1,TRUE, NUM_BUFFERS);
00093         if (FAILED(mFilterHR)) {
00094                 //TODO::: Probably should handle this !
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         //CSourceStream virtuals
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 //This method is responsible for deleting the incoming buffer.
00161 HRESULT NativeFLACSourcePin::deliverData(unsigned char* inBuff, unsigned long inBuffSize, __int64 inStart, __int64 inEnd) {
00162         //Locks !!
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         //Error checks
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         // Create a pointer for the samples buffer
00181         BYTE* locBuffer = NULL;
00182         locSample->GetPointer(&locBuffer);
00183 
00184         //*** WARNING 4018 ::: leave this.
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 }

Generated on Tue Feb 15 14:54:15 2005 for oggdsf by  doxygen 1.3.9