Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

362 lines
9.3 KiB

/******************************Module*Header*******************************\
* Module Name: VMRAllocator.cpp
*
*
*
*
* Created: Tue 02/15/2000
* Author: Stephen Estrop [StEstrop]
*
* Copyright (c) 2000 Microsoft Corporation
\**************************************************************************/
#include <streams.h>
#include <dvdmedia.h>
#include <windowsx.h>
#include "VMRenderer.h"
#if defined(CHECK_FOR_LEAKS)
#include "ifleak.h"
#endif
/******************************Public*Routine******************************\
* CVMRPinAllocator::CVMRPinAllocator
*
*
*
* History:
* Fri 02/25/2000 - StEstrop - Created
*
\**************************************************************************/
CVMRPinAllocator::CVMRPinAllocator(
CVMRInputPin* pPin,
CCritSec *pLock,
HRESULT *phr
) :
CBaseAllocator(NAME("Video Allocator"), NULL, phr, true, true),
m_pPin(pPin),
m_pInterfaceLock(pLock)
{
AMTRACE((TEXT("CVMRPinAllocator::CVMRPinAllocator")));
}
/******************************Public*Routine******************************\
* NonDelegatingAddRef
*
* Overriden to increment the owning object's reference count
*
* History:
* Fri 02/25/2000 - StEstrop - Created
*
\**************************************************************************/
STDMETHODIMP_(ULONG)
CVMRPinAllocator::NonDelegatingAddRef()
{
AMTRACE((TEXT("CVMRPinAllocator::NonDelegatingAddRef")));
return m_pPin->AddRef();
}
/******************************Public*Routine******************************\
* NonDelegatingQueryInterface
*
*
*
* History:
* Thu 12/14/2000 - StEstrop - Created
*
\**************************************************************************/
STDMETHODIMP
CVMRPinAllocator::NonDelegatingQueryInterface(REFIID riid,VOID **ppv)
{
HRESULT hr = E_NOINTERFACE;
*ppv = NULL;
hr = CBaseAllocator::NonDelegatingQueryInterface(riid,ppv);
#if defined(CHECK_FOR_LEAKS)
if (hr == S_OK) {
_pIFLeak->AddThunk((IUnknown **)ppv, "VMR Allocator Object", riid);
}
#endif
return hr;
}
/******************************Public*Routine******************************\
* NonDelegatingRelease
*
*
*
* History:
* Fri 02/25/2000 - StEstrop - Created
*
\**************************************************************************/
STDMETHODIMP_(ULONG)
CVMRPinAllocator::NonDelegatingRelease()
{
AMTRACE((TEXT("CVMRPinAllocator::NonDelegatingRelease")));
return m_pPin->Release();
}
/******************************Public*Routine******************************\
* SetProperties
*
*
*
* History:
* Fri 02/25/2000 - StEstrop - Created
*
\**************************************************************************/
STDMETHODIMP
CVMRPinAllocator::SetProperties(
ALLOCATOR_PROPERTIES* pRequest,
ALLOCATOR_PROPERTIES* pActual
)
{
AMTRACE((TEXT("CVMRPinAllocator::SetProperties")));
HRESULT hr = CBaseAllocator::SetProperties(pRequest, pActual);
if (SUCCEEDED(hr)) {
hr = m_pPin->OnSetProperties(pRequest, pActual);
}
else {
DbgLog((LOG_ERROR, 1,
TEXT("CBaseAllocator::SetProperties failed hr=%#X"), hr));
}
if (SUCCEEDED(hr)) {
hr = m_pPin->m_pRenderer->OnSetProperties(m_pPin);
}
return hr;
}
/******************************Public*Routine******************************\
* CVMRPinAllocator::GetBuffer
*
*
*
* History:
* Fri 02/25/2000 - StEstrop - Created
*
\**************************************************************************/
STDMETHODIMP
CVMRPinAllocator::GetBuffer(
IMediaSample **ppSample,
REFERENCE_TIME *pStartTime,
REFERENCE_TIME *pEndTime,
DWORD dwFlags
)
{
AMTRACE((TEXT("CVMRPinAllocator::GetBuffer")));
HRESULT hr = S_OK;
IMediaSample *pSample = NULL;
hr = CBaseAllocator::GetBuffer(&pSample, pStartTime, pEndTime, dwFlags);
DbgLog((LOG_TRACE, 2, TEXT("pSample= %#X"), pSample));
if (SUCCEEDED(hr)) {
hr = m_pPin->OnGetBuffer(pSample, pStartTime, pEndTime, dwFlags);
if (FAILED(hr)) {
DbgLog((LOG_ERROR, 1, TEXT("CVMRPin::OnGetBuffer failed hr= %#X"), hr));
}
}
else {
DbgLog((LOG_ERROR, 1, TEXT("CBaseAllocator::GetBuffer failed hr= %#X"), hr));
}
if (FAILED(hr) && pSample) {
pSample->Release();
pSample = NULL;
}
*ppSample = pSample;
return hr;
}
/******************************Public*Routine******************************\
* CVMRPinAllocator::ReleaseBuffer
*
*
*
* History:
* Fri 02/25/2000 - StEstrop - Created
*
\**************************************************************************/
STDMETHODIMP
CVMRPinAllocator::ReleaseBuffer(
IMediaSample *pMediaSample
)
{
AMTRACE((TEXT("CVMRPinAllocator::ReleaseBuffer")));
DbgLog((LOG_TRACE, 2, TEXT("pMediaSample= %#X"), pMediaSample));
CVMRMediaSample* pVMRSample = (CVMRMediaSample*)pMediaSample;
LPBYTE lpSample;
HRESULT hr = S_OK;
if (m_pPin->m_pVidSurfs) {
CAutoLock l(&m_pPin->m_DeinterlaceLock);
DWORD i = pVMRSample->GetIndex();
m_pPin->m_pVidSurfs[i].InUse = FALSE;
}
if (S_OK == pVMRSample->IsSurfaceLocked()) {
hr = pVMRSample->UnlockSurface();
if (hr == DDERR_SURFACELOST) {
hr = S_OK;
}
}
if (SUCCEEDED(hr)) {
// Copy of base class code - put at end of the list
CheckPointer(pMediaSample, E_POINTER);
ValidateReadPtr(pMediaSample, sizeof(IMediaSample));
BOOL bRelease = FALSE;
{
CAutoLock cal(this);
/* Put back on the free list */
CMediaSample **ppTail;
for (ppTail = &m_lFree.m_List; *ppTail;
ppTail = &((CVMRMediaSample *)(*ppTail))->Next()) {
}
*ppTail = (CMediaSample *)pMediaSample;
((CVMRMediaSample *)pMediaSample)->Next() = NULL;
m_lFree.m_nOnList++;
if (m_lWaiting != 0) {
NotifySample();
}
// if there is a pending Decommit, then we need to complete it by
// calling Free() when the last buffer is placed on the free list
LONG l1 = m_lFree.GetCount();
if (m_bDecommitInProgress && (l1 == m_lAllocated)) {
Free();
m_bDecommitInProgress = FALSE;
bRelease = TRUE;
}
}
if (m_pNotify) {
m_pNotify->NotifyRelease();
}
// For each buffer there is one AddRef, made in GetBuffer and released
// here. This may cause the allocator and all samples to be deleted
if (bRelease)
{
Release();
}
}
return hr;
}
/******************************Public*Routine******************************\
* CVMRPinAllocator::Alloc
*
*
*
* History:
* Fri 02/25/2000 - StEstrop - Created
*
\**************************************************************************/
HRESULT
CVMRPinAllocator::Alloc()
{
AMTRACE((TEXT("CVMRPinAllocator::Alloc")));
ASSERT(m_lAllocated == 0);
HRESULT hr = S_OK;
CVMRMediaSample** ppSampleList = NULL;
LONG lToAllocate;
lToAllocate = m_lCount;
if (m_pPin->m_dwBackBufferCount > 1) {
lToAllocate++;
}
ppSampleList = new CVMRMediaSample*[lToAllocate];
if (!ppSampleList) {
DbgLog((LOG_ERROR, 1, TEXT("new failed - trying to allocate %d bytes"), lToAllocate));
return E_OUTOFMEMORY;
}
for (LONG i = 0; i < lToAllocate; i++) {
ppSampleList[i] = new CVMRMediaSample(TEXT("VMRMediaSample"),
this, &hr, NULL, 0);
if (!ppSampleList[i]) {
DbgLog((LOG_ERROR, 1, TEXT("new failed - trying to allocate %d bytes"),
sizeof(CVMRMediaSample)));
DbgLog((LOG_ERROR, 1, TEXT("new failed")));
for (LONG j = 0; j < i; j++ )
delete ppSampleList[j];
delete [] ppSampleList;
return E_OUTOFMEMORY;
}
if (FAILED(hr)) {
delete ppSampleList[i];
DbgLog((LOG_ERROR, 1, TEXT("CVMRMediaSample constructor failed")));
break;
}
// Add the completed sample to the available list
m_lAllocated++;
m_lFree.Add(ppSampleList[i]);
}
if (SUCCEEDED(hr)) {
hr = m_pPin->OnAlloc(ppSampleList, lToAllocate);
if (FAILED(hr)) {
DbgLog((LOG_ERROR, 1, TEXT("m_pPin->OnAlloc(), hr = 0x%x"), hr));
Free();
}
}
delete [] ppSampleList;
return hr;
}
/******************************Public*Routine******************************\
* CVMRPinAllocator::Free()
*
*
*
* History:
* Fri 02/25/2000 - StEstrop - Created
*
\**************************************************************************/
void
CVMRPinAllocator::Free()
{
AMTRACE((TEXT("CVMRPinAllocator::Free")));
ASSERT(m_lAllocated == m_lFree.GetCount());
CVMRMediaSample *pSample;
while (m_lFree.GetCount() != 0) {
pSample = (CVMRMediaSample *) m_lFree.RemoveHead();
delete pSample;
}
m_lAllocated = 0;
DbgLog((LOG_TRACE,2,TEXT("All buffers free on pin#%d"), m_pPin->m_dwPinID));
}