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; }
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; }
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; }
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; }
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; }