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
}
Beispiel #4
0
HRESULT
CBaseOutputPin::InitAllocator(IMemAllocator **ppAlloc)
{
	return CreateMemoryAllocator(ppAlloc);
}