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