AbstractTransformOutputPin.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 
00032 #include "stdafx.h"
00033 #include "AbstractTransformOutputPin.h"
00034 
00035 
00036 AbstractTransformOutputPin::AbstractTransformOutputPin(AbstractTransformFilter* inParentFilter, CCritSec* inFilterLock, CHAR* inObjectName, LPCWSTR inPinDisplayName, int inBuffSize, int inNumBuffs, vector<CMediaType*> inAcceptableMediaTypes)
00037         :       CBaseOutputPin(inObjectName, inParentFilter, inFilterLock, &mHR, inPinDisplayName)
00038 
00039         ,       mParentFilter(inParentFilter)
00040         ,       mDataQueue(NULL)
00041         
00042         ,       mDesiredBufferSize(inBuffSize)
00043         ,       mDesiredBufferCount(inNumBuffs)
00044 
00045         ,       mActualBufferSize(0)
00046         ,       mActualBufferCount(0)
00047 
00048         ,       mAcceptableMediaTypes(inAcceptableMediaTypes)
00049 {
00050 
00051 }
00052 AbstractTransformOutputPin::~AbstractTransformOutputPin(void)
00053 {       
00054         ReleaseDelegate();
00055         delete mDataQueue;
00056         mDataQueue = NULL;
00057 
00058         for (size_t i = 0; i < mAcceptableMediaTypes.size(); i++) {
00059                 delete mAcceptableMediaTypes[i];
00060         }
00061 }
00062 
00063 STDMETHODIMP AbstractTransformOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) 
00064 {
00065         if (riid == IID_IMediaSeeking) {
00066                 *ppv = (IMediaSeeking*)this;
00067                 ((IUnknown*)*ppv)->AddRef();
00068                 return NOERROR;
00069         }
00070 
00071         return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv); 
00072 }
00073 
00074 HRESULT AbstractTransformOutputPin::DecideBufferSize(IMemAllocator* inAllocator, ALLOCATOR_PROPERTIES* inPropertyRequest) 
00075 {
00076         HRESULT locHR = S_OK;
00077 
00078         ALLOCATOR_PROPERTIES locReqAlloc;
00079         ALLOCATOR_PROPERTIES locActualAlloc;
00080         
00081         if (inPropertyRequest->cbAlign <= 0) {
00082                 locReqAlloc.cbAlign = 1;
00083         } else {
00084                 locReqAlloc.cbAlign = inPropertyRequest->cbAlign;
00085         }
00086 
00087         if (inPropertyRequest->cbBuffer < mDesiredBufferSize) {
00088                 locReqAlloc.cbBuffer = mDesiredBufferSize;
00089         } else {
00090                 locReqAlloc.cbBuffer = inPropertyRequest->cbBuffer;
00091         }
00092 
00093         if (inPropertyRequest->cbPrefix < 0) {
00094                         locReqAlloc.cbPrefix = 0;
00095         } else {
00096                 locReqAlloc.cbPrefix = inPropertyRequest->cbPrefix;
00097         }
00098         
00099         if (inPropertyRequest->cBuffers < mDesiredBufferCount) {
00100                 locReqAlloc.cBuffers = mDesiredBufferCount;
00101         } else {
00102                 locReqAlloc.cBuffers = inPropertyRequest->cBuffers;
00103         }
00104         
00105         locHR = inAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00106 
00107         if (locHR != S_OK) {
00108                 //TODO::: Handle a fail state here.
00109                 return locHR;
00110         } else {
00111                 //TODO::: Need to save this pointer to decommit in destructor ???
00112                 locHR = inAllocator->Commit();
00113 
00114                 if (locHR == S_OK) {
00115                         mActualBufferCount = locActualAlloc.cBuffers;
00116                         mActualBufferSize = locActualAlloc.cbBuffer;
00117                 } else {
00118                         //TODO::: Handle commit failure.
00119                 }
00120         
00121                 return locHR;
00122         }
00123 }
00124 HRESULT AbstractTransformOutputPin::CheckMediaType(const CMediaType *inMediaType) 
00125 {
00126         for (size_t i = 0;  i < mAcceptableMediaTypes.size(); i++) {
00127                 if      (               (inMediaType->majortype == mAcceptableMediaTypes[i]->majortype) 
00128                                 &&      (inMediaType->subtype == mAcceptableMediaTypes[i]->subtype) 
00129                                 &&      (inMediaType->formattype == mAcceptableMediaTypes[i]->formattype)
00130                         ) 
00131                 {
00132                         return S_OK;
00133                 
00134                 }
00135         }
00136 
00137         //If it was none of them return false.
00138         return S_FALSE;
00139 }
00140 
00141 void AbstractTransformOutputPin::FillMediaType(CMediaType* outMediaType, int inPosition) 
00142 {
00143         //We are gauranteed that inPosition is within the range of the vector (See GetMediaType)
00144         // If you override the mediaformat functions you must ensure this yourself before calling.
00145 
00146         outMediaType->SetType(&(mAcceptableMediaTypes[inPosition]->majortype));
00147         outMediaType->SetSubtype(&(mAcceptableMediaTypes[inPosition]->subtype));
00148         outMediaType->SetFormatType(&(mAcceptableMediaTypes[inPosition]->formattype));
00149 
00150         //If you want something different you need to override this yourself.
00151         // Sample size of 0 means variable size... so that is almost always acceptable.
00152         outMediaType->SetTemporalCompression(FALSE);
00153         outMediaType->SetSampleSize(0);
00154 }
00155 
00156 HRESULT AbstractTransformOutputPin::GetMediaType(int inPosition, CMediaType *outMediaType) 
00157 {
00158         if (inPosition < 0) {
00159                 return E_INVALIDARG;
00160         }
00161 
00162         if (((size_t)inPosition) < mAcceptableMediaTypes.size()) {
00163                 FillMediaType(outMediaType, inPosition);
00164                 CreateAndFillFormatBuffer(outMediaType, inPosition);
00165                 return S_OK;
00166         } else {
00167                 return VFW_S_NO_MORE_ITEMS;
00168         }
00169 }
00170 
00171 HRESULT AbstractTransformOutputPin::DeliverNewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate) 
00172 {
00173         mDataQueue->NewSegment(inStartTime, inStopTime, inRate);
00174         return S_OK;
00175 }
00176 HRESULT AbstractTransformOutputPin::DeliverEndOfStream(void) 
00177 {
00178         //Lock ?????
00179         mDataQueue->EOS();
00180     return S_OK;
00181 }
00182 
00183 HRESULT AbstractTransformOutputPin::DeliverEndFlush(void) 
00184 {
00185         CAutoLock locLock(m_pLock);
00186         
00187         mDataQueue->EndFlush();
00188     return S_OK;
00189 }
00190 
00191 HRESULT AbstractTransformOutputPin::DeliverBeginFlush(void) 
00192 {
00193         CAutoLock locLock(m_pLock);
00194         
00195         mDataQueue->BeginFlush();
00196     return S_OK;
00197 }
00198 
00199 HRESULT AbstractTransformOutputPin::CompleteConnect(IPin *inReceivePin) 
00200 {
00201         CAutoLock locLock(m_pLock);
00202         HRESULT locHR = S_OK;
00203 
00204         //Here when another pin connects to us, we internally connect the seek delegate
00205         // from this output pin onto the input pin... and we release it on breakconnect.
00206         //
00207         IMediaSeeking* locSeeker = NULL;
00208         mParentFilter->mInputPin->NonDelegatingQueryInterface(IID_IMediaSeeking, (void**)&locSeeker);
00209         SetDelegate(locSeeker);
00210         
00211         mDataQueue = new COutputQueue (inReceivePin, &locHR, FALSE, FALSE, 1, TRUE, mActualBufferCount);                        //Deleted in destructor
00212 
00213         if (FAILED(locHR)) {
00214                 //Handle data Q failure
00215                 
00216         }
00217         
00218         return CBaseOutputPin::CompleteConnect(inReceivePin);
00219 }
00220 
00221 HRESULT AbstractTransformOutputPin::BreakConnect(void) 
00222 {
00223         CAutoLock locLock(m_pLock);
00224 
00225         delete mDataQueue;
00226         mDataQueue = NULL;
00227 
00228         HRESULT locHR = CBaseOutputPin::BreakConnect();
00229         ReleaseDelegate();
00230 
00231         return locHR;
00232 }

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