HRESULT CCINVideoDecompressor::DecideBufferSize(
	IMemAllocator *pAlloc,
	ALLOCATOR_PROPERTIES *pProperties
)
{
	CAutoLock lock(m_pLock);

	ASSERT(pAlloc);
	ASSERT(pProperties);

	// Check if we have the input pin and it's connected.
	// Otherwise there's no way to proceed any further
	if (
		(m_pInput == NULL) ||
		(!m_pInput->IsConnected())
	)
		return E_UNEXPECTED;

	// At this time we should have the format block
	if (!m_pFormat)
		return E_UNEXPECTED;

	// Get the input pin's allocator
	IMemAllocator *pInputAlloc = NULL;
	HRESULT hr = m_pInput->GetAllocator(&pInputAlloc);
	if (FAILED(hr))
		return hr;

	// Get the input pin's allocator properties
	ALLOCATOR_PROPERTIES apInput;
	hr = pInputAlloc->GetProperties(&apInput);
	if (FAILED(hr)) {
		pInputAlloc->Release();
		return hr;
	}

	// Release the input pin's allocator
	pInputAlloc->Release();

	// Set the properties: output buffer's size is frame size, 
	// the buffers amount is the same as for the input pin and 
	// we don't care about alignment and prefix
	LONG cbFrame = m_pFormat->dwVideoWidth * m_pFormat->dwVideoHeight;
	pProperties->cbBuffer = max(pProperties->cbBuffer, cbFrame);
	pProperties->cBuffers = max(pProperties->cBuffers, apInput.cBuffers);
	ALLOCATOR_PROPERTIES apActual;
	hr = pAlloc->SetProperties(pProperties, &apActual);
	if (FAILED(hr))
		return hr;

	// Check if the allocator is suitable
	return (
		(apActual.cBuffers < pProperties->cBuffers) ||
		(apActual.cbBuffer < pProperties->cbBuffer)
	) ? E_FAIL : NOERROR;
}
示例#2
0
HRESULT CCorePNGSubtitlerFilter::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) {
	HRESULT hr = NOERROR;

	// Is the input pin connected
	if(m_pInput->IsConnected() == FALSE) {
		return E_UNEXPECTED;
	}

	CheckPointer(pAlloc, E_POINTER);
	CheckPointer(ppropInputRequest, E_POINTER);

	ppropInputRequest->cBuffers = 1;
	ppropInputRequest->cbAlign  = 1;

	// Get input pin's allocator size and use that
	ALLOCATOR_PROPERTIES InProps;
	IMemAllocator *pInAlloc = NULL;

	hr = m_pInput->GetAllocator(&pInAlloc);
	if(SUCCEEDED(hr)) {
		hr = pInAlloc->GetProperties(&InProps);
		if(SUCCEEDED(hr)) {
			ppropInputRequest->cbBuffer = InProps.cbBuffer * InProps.cBuffers;
			m_BufferSize = ppropInputRequest->cbBuffer;
		}
		pInAlloc->Release();
	}

	if(FAILED(hr))
		return hr;

	ASSERT(ppropInputRequest->cbBuffer);

	// Ask the allocator to reserve us some sample memory, NOTE the function
	// can succeed (that is return NOERROR) but still not have allocated the
	// memory that we requested, so we must check we got whatever we wanted

	ALLOCATOR_PROPERTIES Actual;
	hr = pAlloc->SetProperties(ppropInputRequest, &Actual);
	if(FAILED(hr)) {
		return hr;
	}

	ASSERT(Actual.cBuffers == 1);

	if(ppropInputRequest->cBuffers > Actual.cBuffers ||
		ppropInputRequest->cbBuffer > Actual.cbBuffer)
	{
		return E_FAIL;
	}

	return NOERROR;

};
///////////////////////////////////////////////////////////////////////
// DecideBufferSize: Tell the output pin's allocator what size buffers
// we require. Can only do this when the input is connected
///////////////////////////////////////////////////////////////////////
HRESULT CAACSBREnhanced::DecideBufferSize(IMemAllocator *pAlloc,
        ALLOCATOR_PROPERTIES *pProperties)
{
    // Is the input pin connected
    if (m_pInput->IsConnected() == FALSE) {
        return E_UNEXPECTED;
    }

    ASSERT(pAlloc);
    ASSERT(pProperties);
    HRESULT hr = NOERROR;


    pProperties->cBuffers = 1;

    // Get input pin's allocator size and use that
    ALLOCATOR_PROPERTIES InProps;
    IMemAllocator * pInAlloc = NULL;
    hr = m_pInput->GetAllocator(&pInAlloc);
    if (SUCCEEDED (hr))
    {
        hr = pInAlloc->GetProperties (&InProps);
        if (SUCCEEDED (hr))
        {
            pProperties->cbBuffer = 8*1024;
        }
        pInAlloc->Release();
    }

    if (FAILED(hr))
        return hr;

    ASSERT(pProperties->cbBuffer);

    // Ask the allocator to reserve us some sample memory, NOTE the function
    // can succeed (that is return NOERROR) but still not have allocated the
    // memory that we requested, so we must check we got whatever we wanted

    ALLOCATOR_PROPERTIES Actual;
    hr = pAlloc->SetProperties(pProperties,&Actual);
    if (FAILED(hr)) {
        return hr;
    }

    ASSERT( Actual.cBuffers == 1 );

    if ( pProperties->cBuffers > Actual.cBuffers ||
            pProperties->cbBuffer > Actual.cbBuffer) {
        return E_FAIL;
    }

    return NOERROR;
}
// we need to return an addref'ed allocator, even if it is the preferred
// one, since he doesn't know whether it is the preferred one or not.
STDMETHODIMP
CAsyncOutputPin::RequestAllocator(
	IMemAllocator* pPreferred,
	ALLOCATOR_PROPERTIES* pProps,
	IMemAllocator ** ppActual)
{
	CheckPointer(pProps, E_POINTER);
	ASSERT(m_pIo);

	// we care about alignment but nothing else
	if (!pProps->cbAlign || !m_pIo->IsAligned(pProps->cbAlign))
		m_pIo->Alignment(&pProps->cbAlign);

	ALLOCATOR_PROPERTIES Actual;
	HRESULT hr;

	if (pPreferred)
	{
		hr = pPreferred->SetProperties(pProps, &Actual);

		if (SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign))
		{
			pPreferred->AddRef();
			*ppActual = pPreferred;
			return S_OK;
		}
	}

	// create our own allocator
	IMemAllocator* pAlloc;
	hr = InitAllocator(&pAlloc);
	if (FAILED(hr))
		return hr;

	//...and see if we can make it suitable
	hr = pAlloc->SetProperties(pProps, &Actual);
	if (SUCCEEDED(hr) && m_pIo->IsAligned(Actual.cbAlign))
	{
		// we need to release our refcount on pAlloc, and addref
		// it to pass a refcount to the caller - this is a net nothing.
		*ppActual = pAlloc;
		return S_OK;
	}

	// failed to find a suitable allocator
	pAlloc->Release();

	// if we failed because of the IsAligned test, the error code will
	// not be failure
	if (SUCCEEDED(hr))
		hr = VFW_E_BADALIGN;
	return hr;
}
HRESULT CMVEADPCMDecompressor::DecideBufferSize(
	IMemAllocator *pAlloc,
	ALLOCATOR_PROPERTIES *pProperties
)
{
	CAutoLock lock(m_pLock);

	ASSERT(pAlloc);
	ASSERT(pProperties);

	// Check if we have the input pin and it's connected.
	// Otherwise there's no way to proceed any further
	if (
		(m_pInput == NULL) ||
		(!m_pInput->IsConnected())
	)
		return E_UNEXPECTED;

	// Get the input pin's allocator
	IMemAllocator *pInputAlloc = NULL;
	HRESULT hr = m_pInput->GetAllocator(&pInputAlloc);
	if (FAILED(hr))
		return hr;

	// Get the input pin's allocator properties
	ALLOCATOR_PROPERTIES apInput;
	hr = pInputAlloc->GetProperties(&apInput);
	if (FAILED(hr)) {
		pInputAlloc->Release();
		return hr;
	}

	// Release the input pin's allocator
	pInputAlloc->Release();

	// Set the properties: output buffer is two times larger 
	// then the input one, the buffers amount is the same and 
	// we don't care about alignment and prefix
	pProperties->cbBuffer = max(pProperties->cbBuffer, apInput.cbBuffer * 2);
	pProperties->cBuffers = max(pProperties->cBuffers, apInput.cBuffers);
	ALLOCATOR_PROPERTIES apActual;
	hr = pAlloc->SetProperties(pProperties, &apActual);
	if (FAILED(hr))
		return hr;

	// Check if the allocator is suitable
	return (
		(apActual.cBuffers < pProperties->cBuffers) ||
		(apActual.cbBuffer < pProperties->cbBuffer)
	) ? E_FAIL : NOERROR;
}
示例#6
0
HRESULT CG729EncoderFilter::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties)
{
	HRESULT hr = NOERROR;
	if ( ! m_pInput->IsConnected() ) return E_UNEXPECTED;
	
	CheckPointer( pAlloc, E_POINTER );
	CheckPointer( pProperties, E_POINTER );
	
	pProperties->cBuffers = 1;
//	pProperties->cbAlign  = 1;
    pProperties->cbBuffer = m_pInput->CurrentMediaType().GetSampleSize();
	
	ALLOCATOR_PROPERTIES InProps;
	IMemAllocator * pInAlloc = NULL;
	
	hr = m_pInput->GetAllocator(&pInAlloc);
	if(SUCCEEDED(hr))
	{
		hr = pInAlloc->GetProperties(&InProps);
		if ( SUCCEEDED(hr) )
		{
			pProperties->cbBuffer = InProps.cbBuffer;
		}
		pInAlloc->Release();
    }
	
	if ( FAILED(hr) ) return hr;
	
	ASSERT( pProperties->cbBuffer );
	
	ALLOCATOR_PROPERTIES Actual;
	hr = pAlloc->SetProperties(pProperties,&Actual);
	if ( FAILED(hr) ) return hr;
	
	ASSERT( Actual.cBuffers == 1 );
	
	if (pProperties->cBuffers > Actual.cBuffers ||
		pProperties->cbBuffer > Actual.cbBuffer)
	{
		return E_FAIL;
	}
	
	return NOERROR;
}
HRESULT CGraphConnector::SetAllocatorProperties( int RequestedSize )
{
	if( m_pInputPin->IsConnected() )
	{
		ALLOCATOR_PROPERTIES props;
		ALLOCATOR_PROPERTIES propsActual;
		HRESULT hr;
		IMemAllocator	*InputAllocator;
		hr = m_pInputPin->GetAllocator( &InputAllocator );
		if( hr != S_OK || InputAllocator == NULL )
		{
			Dlog("Could not set allocator properties 1\n");
			return S_FALSE;
		}
		hr = InputAllocator->GetProperties( &props );
		if( hr != S_OK || props.cBuffers == 0 || props.cbBuffer == 0 )
		{
			Dlog("Could not set allocator properties 2\n");
			return S_FALSE;
		}

		//more like a hack. I found some http input stream that was sending larger then agreed media buffers
		//If we reject the too large packet then input will DC. If we pass on the large packet then probably the next PIN will DC. Hope for the best
		//video stream packet can be for VBR anything. For CBR the rule is to be 3xbitrate
		if( ( m_mMediaType.majortype == MEDIATYPE_Video || m_mMediaType.majortype == MEDIATYPE_Stream ) && props.cbBuffer < 1024 * 8 ) //less then 8k ? probably size is not set. We need to know the size
			props.cbBuffer = 1024 * 8 * 1024; //8 Mbit ? I really hope this will be enough

		props.cbBuffer = max( props.cbBuffer * 2, RequestedSize ); 

		if( CONNECTOR_BUFFERS_UNTIL_LOCK > props.cBuffers )
			props.cBuffers = CONNECTOR_BUFFERS_UNTIL_LOCK;
		hr = m_pAllocator->SetProperties( &props, &propsActual );
		if( hr != S_OK )
		{
			Dlog1("Could not set allocator properties 4 %p\n",this);
			return S_FALSE;
		}
		hr = m_pAllocator->Commit();
		m_bBufferDecided = TRUE;
	}
}
HRESULT CGraphConnector::GetAllocatorProperties( ALLOCATOR_PROPERTIES* pProperties )
{
	pProperties->cbAlign = 1;
	pProperties->cBuffers = 1;
	pProperties->cbBuffer = 1;
	//try to fetch latest still connected input PIN properties
	if( m_pInputPin->IsConnected() == true )
	{
		HRESULT hr;
		IMemAllocator	*InputAllocator;
		hr = m_pInputPin->GetAllocator( &InputAllocator );
		if( hr != S_OK || InputAllocator == NULL )
		{
			Dlog("Could not set allocator properties 1\n");
			return S_FALSE;
		}
		hr = InputAllocator->GetProperties( pProperties );
		if( hr != S_OK )
		{
			Dlog("Could not set allocator properties 2\n");
			return S_FALSE;
		}
		//try to fetch buffer properties from input. Update it, even if we already had a previous connection
		// GetAllocatorProperties function is called when the filters are getting connected
		//SetAllocatorProperties();
	}
	//if right now input PIN is not connected then try to fetch our memorized properties
	else if( m_bBufferDecided == TRUE )
	{
		m_pAllocator->GetProperties( pProperties );
	}
	else
	{
		return S_FALSE;
	}
	return S_OK;
}
示例#9
0
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
示例#10
0
STDMETHODIMP CRFSOutputPin::RequestAllocator (IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual)
{
    if (!(pPreferred && pProps && ppActual))
        return E_POINTER;

    ALLOCATOR_PROPERTIES actual;
    HRESULT hr;

    DbgLog((LOG_TRACE, 2, L"Requested alignment = %ld", pProps->cbAlign));
    if (pProps->cbAlign)
        m_align = pProps->cbAlign;
    else
        pProps->cbAlign = m_align;

    if (pPreferred)
    {
        hr = pPreferred->SetProperties (pProps, &actual);

        if (SUCCEEDED (hr) && IsAligned (actual.cbAlign))
        {
            DbgLog((LOG_TRACE, 2, L"Using preferred allocator."));
            pPreferred->AddRef ();
            *ppActual = pPreferred;
            return S_OK;
        }
    }

    CMemAllocator *pMemObject = new CMemAllocator (L"RFS memory allocator", NULL, &hr);

    if (!pMemObject)
        return E_OUTOFMEMORY;

    if (FAILED (hr))
    {
        delete pMemObject;
        return hr;
    }

    IMemAllocator* pAlloc;

    hr = pMemObject->QueryInterface (IID_IMemAllocator, (void **) &pAlloc);

    if (FAILED (hr))
    {
        delete pMemObject;
        return E_NOINTERFACE;
    }

    hr = pAlloc->SetProperties (pProps, &actual);

    if (SUCCEEDED (hr) && IsAligned (actual.cbAlign))
    {
        DbgLog((LOG_TRACE, 2, L"Using our allocator."));
        *ppActual = pAlloc;
        return S_OK;
    }

    pAlloc->Release ();

    if (SUCCEEDED (hr))
        hr = VFW_E_BADALIGN;

    DbgLog((LOG_TRACE, 2, L"RequestAllocator failed."));
    return hr;
}
示例#11
0
HRESULT CAudioDecFilter::ReconnectOutput(long BufferSize, const CMediaType &mt)
{
	HRESULT hr;

	IPin *pPin = m_pOutput->GetConnected();
	if (pPin == NULL)
		return E_POINTER;

	IMemInputPin *pMemInputPin = NULL;
	hr = pPin->QueryInterface(IID_IMemInputPin, pointer_cast<void**>(&pMemInputPin));
	if (FAILED(hr)) {
		OutputLog(TEXT("IMemInputPinインターフェースが取得できません。(%08x)\r\n"), hr);
	} else {
		IMemAllocator *pAllocator = NULL;
		hr = pMemInputPin->GetAllocator(&pAllocator);
		if (FAILED(hr)) {
			OutputLog(TEXT("IMemAllocatorインターフェースが取得できません。(%08x)\r\n"), hr);
		} else {
			ALLOCATOR_PROPERTIES Props;
			hr = pAllocator->GetProperties(&Props);
			if (FAILED(hr)) {
				OutputLog(TEXT("IMemAllocatorのプロパティが取得できません。(%08x)\r\n"), hr);
			} else {
				if (mt != m_pOutput->CurrentMediaType()
						|| Props.cBuffers < NUM_SAMPLE_BUFFERS
						|| Props.cbBuffer < BufferSize) {
					hr = S_OK;
					if (Props.cBuffers < NUM_SAMPLE_BUFFERS
							|| Props.cbBuffer < BufferSize) {
						ALLOCATOR_PROPERTIES ActualProps;

						Props.cBuffers = NUM_SAMPLE_BUFFERS;
						Props.cbBuffer = BufferSize * 3 / 2;
						OutputLog(TEXT("バッファサイズを設定します。(%ld bytes)\r\n"), Props.cbBuffer);
						if (SUCCEEDED(hr = m_pOutput->DeliverBeginFlush())
								&& SUCCEEDED(hr = m_pOutput->DeliverEndFlush())
								&& SUCCEEDED(hr = pAllocator->Decommit())
								&& SUCCEEDED(hr = pAllocator->SetProperties(&Props, &ActualProps))
								&& SUCCEEDED(hr = pAllocator->Commit())) {
							if (ActualProps.cBuffers < Props.cBuffers
									|| ActualProps.cbBuffer < BufferSize) {
								OutputLog(TEXT("バッファサイズの要求が受け付けられません。(%ld / %ld)\r\n"),
										  ActualProps.cbBuffer, Props.cbBuffer);
								hr = E_FAIL;
								NotifyEvent(EC_ERRORABORT, hr, 0);
							} else {
								OutputLog(TEXT("ピンの再接続成功\r\n"));
								hr = S_OK;
							}
						} else {
							OutputLog(TEXT("ピンの再接続ができません。(%08x)\r\n"), hr);
						}
					}
				} else {
					hr = S_FALSE;
				}
			}

			pAllocator->Release();
		}

		pMemInputPin->Release();
	}

	return hr;
}