HRESULT CGraphConnector::IncreaseBufferSizeRuntime( int RequestedSize ) { //need to wait until all output is flushed bool NeedWait = false; int RetrysRemaining = 1000; //wait aprox 1 second then give up do{ if( NeedWait ) { Sleep( 1 ); RetrysRemaining--; } NeedWait = (IsOuputQueueEmpty() == S_OK) ? false : true; }while( NeedWait == true && RetrysRemaining > 0 ); if( NeedWait == false ) { IMemAllocator* pNewAllocator = NULL; if (FAILED(CreateMemoryAllocator( &pNewAllocator ))) { return S_FALSE; } m_pAllocator->Release(); m_pAllocator = pNewAllocator; m_bBufferDecided = false; SetAllocatorProperties( RequestedSize ); return S_OK; } return S_FALSE; }
STDMETHODIMP CTransInPlaceInputPin::NotifyAllocator( IMemAllocator * pAllocator, BOOL bReadOnly) { HRESULT hr = S_OK; CheckPointer(pAllocator,E_POINTER); ValidateReadPtr(pAllocator,sizeof(IMemAllocator)); CAutoLock cObjectLock(m_pLock); m_bReadOnly = bReadOnly; // If we modify data then don't accept the allocator if it's // the same as the output pin's allocator // If our output is not connected just accept the allocator // We're never going to use this allocator because when our // output pin is connected we'll reconnect this pin if (!m_pTIPFilter->OutputPin()->IsConnected()) { return CTransformInputPin::NotifyAllocator(pAllocator, bReadOnly); } // If the allocator is read-only and we're modifying data // and the allocator is the same as the output pin's // then reject if (bReadOnly && m_pTIPFilter->m_bModifiesData) { IMemAllocator *pOutputAllocator = m_pTIPFilter->OutputPin()->PeekAllocator(); // Make sure we have an output allocator if (pOutputAllocator == NULL) { hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()-> GetAllocator(&pOutputAllocator); if(FAILED(hr)) { hr = CreateMemoryAllocator(&pOutputAllocator); } if (SUCCEEDED(hr)) { m_pTIPFilter->OutputPin()->SetAllocator(pOutputAllocator); pOutputAllocator->Release(); } } if (pAllocator == pOutputAllocator) { hr = E_FAIL; } else if(SUCCEEDED(hr)) { // Must copy so set the allocator properties on the output ALLOCATOR_PROPERTIES Props, Actual; hr = pAllocator->GetProperties(&Props); if (SUCCEEDED(hr)) { hr = pOutputAllocator->SetProperties(&Props, &Actual); } if (SUCCEEDED(hr)) { if ( (Props.cBuffers > Actual.cBuffers) || (Props.cbBuffer > Actual.cbBuffer) || (Props.cbAlign > Actual.cbAlign) ) { hr = E_FAIL; } } // Set the allocator on the output pin if (SUCCEEDED(hr)) { hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin() ->NotifyAllocator( pOutputAllocator, FALSE ); } } } else { hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin() ->NotifyAllocator( pAllocator, bReadOnly ); if (SUCCEEDED(hr)) { m_pTIPFilter->OutputPin()->SetAllocator( pAllocator ); } } if (SUCCEEDED(hr)) { // It's possible that the old and the new are the same thing. // AddRef before release ensures that we don't unload it. pAllocator->AddRef(); if( m_pAllocator != NULL ) m_pAllocator->Release(); m_pAllocator = pAllocator; // We have an allocator for the input pin } return hr; } // NotifyAllocator
CGraphConnector::CGraphConnector(LPUNKNOWN pUnk, HRESULT *phr) : CUnknown(NAME("CGraphConnector"), pUnk), m_pInputFilter(NULL), m_pInputPin(NULL), m_nNumOutputs(0) { m_pInputPinForPush = NULL; m_pInputPin = NULL; for( int i=0;i<CONNECTOR_MAX_OUTPUT_COUNT;i++) { m_pOutputFilter[i] = NULL; m_pOutputPin[i] = NULL; m_pOutputPinForPush[i] = NULL; m_pOutputPinForPull[i] = NULL; } m_Type = GCB_THROW_PACKET_UNLESS_OUTPUT_CONNECTED; m_nAllocatorType = GCAT_USE_INTERNAL; // m_nAllocatorType = GCAT_USE_FROM_INPUT; //passthrough mode, when you want to make sure input is the same as output ASSERT(phr); HRESULT hr = CreateMemoryAllocator( &m_pAllocator ); if ( FAILED(hr) ) { return; } m_bBufferDecided = FALSE; IBaseFilter* pFilter = NULL; hr = CoCreateInstance(CLSID_GraphConnectorInput, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&pFilter); if (pFilter == NULL) { if (phr) *phr = E_OUTOFMEMORY; return; } m_pInputFilter = (CGraphConnectorInputFilter*)pFilter; //new CGraphConnectorInputFilter(this, GetOwner(), &m_Lock, phr); m_pInputFilter->m_pConnector = this; m_pInputFilter->m_pPosition = NULL; m_pInputPinForPush = new CGraphConnectorInputPin(this,GetOwner(), m_pInputFilter, &m_Lock, &m_QueueLock, phr); m_pInputPin = m_pInputPinForPush; if ( m_pInputPin == NULL ) { if (phr) *phr = E_OUTOFMEMORY; return; } m_pInputPinForPull = NULL; m_bUseAsyncReaderOutput = FALSE; //add one default output // AddOutput(); // memset( &m_mMediaType, 0, sizeof( m_mMediaType )); //constructor already solves the initialization #ifdef DEBUGGING_IN_TESTBENCH PacketCounterOut = 0; PacketCounterIn = 0; m_fdLogs = NULL; char FileName[100]; //it's all because of Danilo and he's special PC if( m_fdLogs == NULL ) { sprintf( FileName,"./Log/GC_PIN_%d_%p_%d.txt", (char)(m_mMediaType.majortype==MEDIATYPE_Video), (int)this, GetTickCount() ); m_fdLogs = fopen( FileName, "wt" ); } if( m_fdLogs == NULL ) { sprintf( FileName,"./Logs/GC_PIN_%d_%p_%d.txt", (char)(m_mMediaType.majortype==MEDIATYPE_Video), (int)this, GetTickCount() ); m_fdLogs = fopen( FileName, "wt" ); } if( m_fdLogs == NULL ) { sprintf( FileName,"C:/temp/GC_PIN_%d_%p_%d.txt", (char)(m_mMediaType.majortype==MEDIATYPE_Video), (int)this, GetTickCount() ); m_fdLogs = fopen( FileName, "wt" ); } if( m_fdLogs == NULL ) { sprintf( FileName,"C:/GC_PIN_%d_%p_%d.txt", (char)(m_mMediaType.majortype==MEDIATYPE_Video), (int)this, GetTickCount() ); m_fdLogs = fopen( FileName, "wt" ); } #endif }
HRESULT CBaseOutputPin::InitAllocator(IMemAllocator **ppAlloc) { return CreateMemoryAllocator(ppAlloc); }