www.pudn.com > VOBSUB.rar > MyCustomAllocator.cpp
#include "stdafx.h" #include#include #include "MyCustomAllocator.h" #include "misc.h" CMyCustomAllocator::CMyCustomAllocator(CBaseFilter* pFilter, HRESULT* phr) : CMemAllocator(NAME("CMyCustomAllocator"), NULL, phr), m_pFilter(pFilter), m_fMediaTypeChanged(false), m_pMediaType(NULL) { ASSERT(phr); ASSERT(pFilter); } #ifdef DEBUG CMyCustomAllocator::~CMyCustomAllocator() { ASSERT(m_bCommitted == FALSE); } #endif STDMETHODIMP CMyCustomAllocator::GetBuffer(IMediaSample** ppBuffer, REFERENCE_TIME* pStartTime, REFERENCE_TIME* pEndTime, DWORD dwFlags) { if(!m_bCommitted) return VFW_E_NOT_COMMITTED; if(m_fMediaTypeChanged) { BITMAPINFOHEADER bih; ExtractBIH(m_pMediaType, &bih); ALLOCATOR_PROPERTIES Properties, Actual; if(FAILED(GetProperties(&Properties))) return E_FAIL; int biSizeImage = (bih.biWidth*abs(bih.biHeight)*bih.biBitCount)>>3; if(bih.biSizeImage < biSizeImage) { // bugus intervideo mpeg2 decoder doesn't seem to adjust biSizeImage to the really needed buffer size bih.biSizeImage = biSizeImage; } if(Properties.cbBuffer < bih.biSizeImage || !m_bCommitted) { Properties.cbBuffer = bih.biSizeImage; if(FAILED(Decommit())) return E_FAIL; if(FAILED(SetProperties(&Properties, &Actual))) return E_FAIL; if(FAILED(Commit())) return E_FAIL; ASSERT(Actual.cbBuffer >= Properties.cbBuffer); if(Actual.cbBuffer < Properties.cbBuffer) return E_FAIL; } } HRESULT hr = CMemAllocator::GetBuffer(ppBuffer, pStartTime, pEndTime, dwFlags); if(m_fMediaTypeChanged && SUCCEEDED(hr)) { (*ppBuffer)->SetMediaType(m_pMediaType); m_fMediaTypeChanged = false; } return hr; } void CMyCustomAllocator::NotifyMediaType(CMediaType* pMediaType) { m_pMediaType = pMediaType; m_fMediaTypeChanged = true; }