// dynamic switch with Video Renderer (to change allocated buffer size as well // as format type HRESULT BridgeSourceOutput::SwitchTo(const CMediaType* pmt) { // must wait until queue is empty if (m_pQueue != NULL) { while (!m_pQueue->IsIdle()) { m_evQueue.Wait(); } } // now perform request HRESULT hr = GetConnected()->ReceiveConnection(this, pmt); LOG((TEXT("ReceiveConnection 0x%x"), hr)); if (SUCCEEDED(hr)) { SetMediaType(pmt); // for VMR, that's enough, but for old VR we need to re-commit the allocator m_pAllocator->Decommit(); m_bUpstreamTypeChanged = true; ALLOCATOR_PROPERTIES prop; hr = m_pAllocator->GetProperties(&prop); if (SUCCEEDED(hr)) { hr = DecideBufferSize(m_pAllocator, &prop); if (FAILED(hr)) { LOG((TEXT("Allocator failure on ReceiveConnection 0x%x"), hr)); } } if (SUCCEEDED(hr)) { m_pInputPin->NotifyAllocator(m_pAllocator, false); } m_pAllocator->Commit(); } return hr; }
HRESULT CAVIOutputPin::DecideAllocator(IMemInputPin* pPin, IMemAllocator ** pAlloc) { HRESULT hr = S_OK; *pAlloc = new CSampleBuffer(NULL, &hr); if (!(*pAlloc)) return E_OUTOFMEMORY; (*pAlloc)->AddRef(); if (SUCCEEDED(hr)) { ALLOCATOR_PROPERTIES propRequest; ZeroMemory(&propRequest, sizeof(propRequest)); hr = DecideBufferSize(*pAlloc, &propRequest); if (SUCCEEDED(hr)) { // tell downstream pins that modification // in-place is not permitted hr = pPin->NotifyAllocator(*pAlloc, TRUE); if (SUCCEEDED(hr)) { return NOERROR; } } } if (FAILED(hr)) { (*pAlloc)->Release(); *pAlloc = NULL; } return hr; }
HRESULT CLAVOutputPin::DecideAllocator(IMemInputPin * pPin, IMemAllocator **ppAlloc) { HRESULT hr = NOERROR; *ppAlloc = NULL; // get downstream prop request // the derived class may modify this in DecideBufferSize, but // we assume that he will consistently modify it the same way, // so we only get it once ALLOCATOR_PROPERTIES prop; ZeroMemory(&prop, sizeof(prop)); // whatever he returns, we assume prop is either all zeros // or he has filled it out. pPin->GetAllocatorRequirements(&prop); // if he doesn't care about alignment, then set it to 1 if (prop.cbAlign == 0) { prop.cbAlign = 1; } *ppAlloc = new CPacketAllocator(NAME("CPacketAllocator"), NULL, &hr); (*ppAlloc)->AddRef(); if (SUCCEEDED(hr)) { DbgLog((LOG_TRACE, 10, L"Trying to use our CPacketAllocator")); m_bPacketAllocator = TRUE; hr = DecideBufferSize(*ppAlloc, &prop); if (SUCCEEDED(hr)) { DbgLog((LOG_TRACE, 10, L"-> DecideBufferSize Success")); hr = pPin->NotifyAllocator(*ppAlloc, FALSE); if (SUCCEEDED(hr)) { DbgLog((LOG_TRACE, 10, L"-> NotifyAllocator Success")); return NOERROR; } } } if (*ppAlloc) { (*ppAlloc)->Release(); *ppAlloc = NULL; } m_bPacketAllocator = FALSE; /* Try the allocator provided by the input pin */ hr = pPin->GetAllocator(ppAlloc); if (SUCCEEDED(hr)) { hr = DecideBufferSize(*ppAlloc, &prop); if (SUCCEEDED(hr)) { hr = pPin->NotifyAllocator(*ppAlloc, FALSE); if (SUCCEEDED(hr)) { return NOERROR; } } } /* If the GetAllocator failed we may not have an interface */ if (*ppAlloc) { (*ppAlloc)->Release(); *ppAlloc = NULL; } return hr; }
HRESULT CBaseOutputPin::DecideAllocator(IMemInputPin *pPin, IMemAllocator **ppAlloc) { HRESULT hr = NOERROR; *ppAlloc = NULL; // get downstream prop request // the derived class may modify this in DecideBufferSize, but // we assume that he will consistently modify it the same way, // so we only get it once ALLOCATOR_PROPERTIES prop; ZeroMemory(&prop, sizeof(prop)); // whatever he returns, we assume prop is either all zeros // or he has filled it out. pPin->GetAllocatorRequirements(&prop); // if he doesn't care about alignment, then set it to 1 if (prop.cbAlign == 0) { prop.cbAlign = 1; } /* Try the allocator provided by the input pin */ hr = pPin->GetAllocator(ppAlloc); if (SUCCEEDED(hr)) { hr = DecideBufferSize(*ppAlloc, &prop); if (SUCCEEDED(hr)) { hr = pPin->NotifyAllocator(*ppAlloc, FALSE); if (SUCCEEDED(hr)) { return NOERROR; } } } /* If the GetAllocator failed we may not have an interface */ if (*ppAlloc) { (*ppAlloc)->Release(); *ppAlloc = NULL; } /* Try the output pin's allocator by the same method */ hr = InitAllocator(ppAlloc); if (SUCCEEDED(hr)) { // note - the properties passed here are in the same // structure as above and may have been modified by // the previous call to DecideBufferSize hr = DecideBufferSize(*ppAlloc, &prop); if (SUCCEEDED(hr)) { hr = pPin->NotifyAllocator(*ppAlloc, FALSE); if (SUCCEEDED(hr)) { return NOERROR; } } } /* Likewise we may not have an interface to release */ if (*ppAlloc) { (*ppAlloc)->Release(); *ppAlloc = NULL; } return hr; }