Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

482 lines
11 KiB

//
// FPPin.cpp
//
#include "stdafx.h"
#include "FPPin.h"
//////////////////////////////////////////////////////////////////////
//
// Constructor / Destructor - Methods implementation
//
//////////////////////////////////////////////////////////////////////
CFPPin::CFPPin(
CFPFilter* pFilter,
HRESULT* phr,
LPCWSTR pPinName
) :
CSourceStream(NAME("Output"), phr, pFilter, pPinName),
m_pFPFilter(pFilter),
m_bFinished(FALSE)
{
LOG((MSP_TRACE, "CFPPin::CFPPin - enter"));
LOG((MSP_TRACE, "CFPPin::CFPPin - exit"));
}
CFPPin::~CFPPin()
{
LOG((MSP_TRACE, "CFPPin::~CFPPin - enter"));
LOG((MSP_TRACE, "CFPPin::~CFPPin - exit"));
}
//////////////////////////////////////////////////////////////////////
//
// IUnknown - Methods implementation
//
//////////////////////////////////////////////////////////////////////
/*++
NonDelegatingQueryInterface
Description;
What interfaces support
--*/
STDMETHODIMP CFPPin::NonDelegatingQueryInterface(
REFIID riid,
void** ppv
)
{
LOG((MSP_TRACE, "CFPPin::NonDelegatingQueryInterface - enter"));
if (riid == IID_IAMStreamControl)
{
LOG((MSP_TRACE, "CFPPin::NQI IAMStreamControl - exit"));
return GetInterface((LPUNKNOWN)(IAMStreamControl *)this, ppv);
}
else if (riid == IID_IAMStreamConfig)
{
LOG((MSP_TRACE, "CFPPin::NQI IAMStreamconfig - exit"));
return GetInterface((LPUNKNOWN)(IAMStreamConfig *)this, ppv);
}
else if (riid == IID_IAMBufferNegotiation)
{
LOG((MSP_TRACE, "CFPPin::NQI IAMBufferNegotiation - exit"));
return GetInterface((LPUNKNOWN)(IAMBufferNegotiation *)this, ppv);
}
LOG((MSP_TRACE, "CFPPin::NQI call base NQI - exit"));
return CSourceStream::NonDelegatingQueryInterface(riid, ppv);
}
//////////////////////////////////////////////////////////////////////
//
// CSourceStream - Methods implementation
//
//////////////////////////////////////////////////////////////////////
// stuff an audio buffer with the current format
HRESULT CFPPin::FillBuffer(
IN IMediaSample *pms
)
{
LOG((MSP_TRACE, "CFPPin::FillBuffer - enter"));
//
// Critical section
//
CLock lock(m_Lock);
if( m_pFPFilter == NULL)
{
LOG((MSP_ERROR, "CFPPin::FillBuffer - exit "
" pointer to the filter is NULL. Returns E_UNEXPECTED"));
return E_UNEXPECTED;
}
HRESULT hr = m_pFPFilter->PinFillBuffer( pms );
if( FAILED(hr) )
{
LOG((MSP_ERROR, "CFPPin::FillBuffer - exit "
" PinFillBuffer failed. Returns 0x%08x", hr));
return hr;
}
LOG((MSP_TRACE, "CFPPin::FillBuffer - exit S_OK"));
return S_OK;
}
// ask for buffers of the size appropriate to the agreed media type.
HRESULT CFPPin::DecideBufferSize(
IN IMemAllocator *pAlloc,
OUT ALLOCATOR_PROPERTIES *pProperties
)
{
LOG((MSP_TRACE, "CFPPin::DecideBufferSize - enter"));
//
// Validates arguments
//
if( NULL == pAlloc)
{
LOG((MSP_ERROR, "CFPPin::DecideBufferSize - "
"inavlid IMemAllocator pointer - returns E_INVALIDARG"));
return E_INVALIDARG;
}
if( IsBadWritePtr( pProperties, sizeof(ALLOCATOR_PROPERTIES)) )
{
LOG((MSP_ERROR, "CFPPin::DecideBufferSize - "
"inavlid ALLOCATOR_PROPERTIES pointer - returns E_INVALIDARG"));
return E_INVALIDARG;
}
//
// Critical section
//
CLock lock(m_Lock);
//
// Validates filter
//
if( NULL == m_pFPFilter )
{
LOG((MSP_ERROR, "CFPPin::DecideBufferSize - "
"inavlid pointer to filter. Returns E_UNEXPECTED"));
return E_UNEXPECTED;
}
HRESULT hr = m_pFPFilter->PinGetBufferSize(
pAlloc,
pProperties
);
if( FAILED(hr) )
{
LOG((MSP_ERROR, "CFPPin::DecideBufferSize - "
"PinGetBufferSize failed. Returns 0x%08x", hr));
return hr;
}
LOG((MSP_TRACE, "CFPPin::DecideBufferSize - exit"));
return S_OK;
}
HRESULT CFPPin::GetMediaType(
OUT CMediaType *pmt
)
{
//
// Critical section
//
CLock lock(m_Lock);
LOG((MSP_TRACE, "CFPPin::GetMediaType - enter"));
//
// Validates argument
//
if( IsBadWritePtr( pmt, sizeof( CMediaType)) )
{
LOG((MSP_ERROR, "CFPPin::GetMediaType - "
"invalid CmediaType pointer - returns E_POINTER"));
return E_POINTER;
}
//
// Validates filter
//
if( NULL == m_pFPFilter )
{
LOG((MSP_ERROR, "CFPPin::GetMediaType - "
"inavlid pointer to filter. Returns E_UNEXPECTED"));
return E_UNEXPECTED;
}
//
// Get media type from the filter
//
HRESULT hr = m_pFPFilter->PinGetMediaType( pmt );
if( FAILED(hr) )
{
LOG((MSP_ERROR, "CFPPin::GetMediaType - "
"inavlid pointer to filter. Returns 0x%08x", hr));
return hr;
}
LOG((MSP_TRACE, "CFPPin::GetMediaType - exit S_OK"));
return S_OK;
}
// verify we can handle this format
HRESULT CFPPin::CheckMediaType(
IN const CMediaType *pMediaType
)
{
LOG((MSP_TRACE, "CFPPin::CheckMediaType - enter"));
//
// Validates argument
//
if( IsBadReadPtr( pMediaType, sizeof(CMediaType)) )
{
LOG((MSP_ERROR, "CFPPin::CheckMediaType - "
"inavlid pointer - returns E_POINTER"));
return E_POINTER;
}
//
// Validates filter
//
if( NULL == m_pFPFilter )
{
LOG((MSP_ERROR, "CFPPin::CheckMediaType - "
"inavlid pointer to filter. Returns E_UNEXPECTED"));
return E_UNEXPECTED;
}
HRESULT hr = m_pFPFilter->PinCheckMediaType( pMediaType );
if( FAILED(hr) )
{
LOG((MSP_ERROR, "CFPPin::CheckMediaType - "
"inavlid pointer to stream. Returns 0x%08x", hr));
return hr;
}
LOG((MSP_TRACE, "CFPPin::CheckMediaType - exit"));
return S_OK;
}
HRESULT CFPPin::SetMediaType(
IN const CMediaType *pMediaType
)
{
LOG((MSP_TRACE, "CFPPin::SetMediaType - enter"));
HRESULT hr;
// Pass the call up to my base class
hr = CSourceStream::SetMediaType(pMediaType);
LOG((MSP_TRACE, "CFPPin::SetMediaType - exit (0x%08x)", hr));
return hr;
}
//////////////////////////////////////////////////////////////////////
//
// IAMStreamConfig - Methods implementation
//
//////////////////////////////////////////////////////////////////////
STDMETHODIMP CFPPin::SetFormat(
AM_MEDIA_TYPE* pmt
)
{
//
// Critical section
//
CLock lock(m_Lock);
LOG((MSP_TRACE, "CFPPin::SetFormat - enter"));
//
// Validates argument
//
if( IsBadReadPtr( pmt, sizeof(AM_MEDIA_TYPE)) )
{
LOG((MSP_ERROR, "CFPPin::SetFormat - "
"inavlid pointer. Returns E_POINTER"));
return E_POINTER;
}
//
// Validates filter
//
if( NULL == m_pFPFilter )
{
LOG((MSP_ERROR, "CFPPin::SetFormat - "
"inavlid pointer to filter. Returns E_UNEXPECTED"));
return E_UNEXPECTED;
}
HRESULT hr = m_pFPFilter->PinSetFormat( pmt );
if( FAILED(hr) )
{
LOG((MSP_ERROR, "CFPPin::SetFormat - "
"PinSetFormat failed. Returns 0x%08x", hr));
return hr;
}
LOG((MSP_TRACE, "CFPPin::SetFormat - exit"));
return S_OK;
}
STDMETHODIMP CFPPin::GetFormat(
AM_MEDIA_TYPE** ppmt
)
{
LOG((MSP_TRACE, "CFPPin::GetFormat - enter"));
LOG((MSP_TRACE, "CFPPin::GetFormat - exit E_NOTIMPL"));
return E_NOTIMPL;
}
STDMETHODIMP CFPPin::GetNumberOfCapabilities(
int* piCount,
int* piSize
)
{
LOG((MSP_TRACE, "CFPPin::GetNumberOfCapabilities - enter"));
LOG((MSP_TRACE, "CFPPin::GetNumberOfCapabilities - exit E_NOTIMPL"));
return E_NOTIMPL;
}
STDMETHODIMP CFPPin::GetStreamCaps(
int i,
AM_MEDIA_TYPE** ppmt,
LPBYTE pSCC
)
{
LOG((MSP_TRACE, "CFPPin::GetStreamCaps - enter"));
LOG((MSP_TRACE, "CFPPin::GetStreamCaps - exit E_NOTIMPL"));
return E_NOTIMPL;
}
//////////////////////////////////////////////////////////////////////
//
// IAMBufferNegotiation - Methods implementation
//
//////////////////////////////////////////////////////////////////////
STDMETHODIMP CFPPin::SuggestAllocatorProperties(
const ALLOCATOR_PROPERTIES* pprop
)
{
LOG((MSP_TRACE, "CFPPin::SuggestAllocatorProperties - enter"));
//
// Validates argument
//
if( IsBadReadPtr( pprop, sizeof(ALLOCATOR_PROPERTIES)) )
{
LOG((MSP_ERROR, "CFPPin::SuggestAllocatorProperties - "
"inavlid pointer - returns E_POINTER"));
return E_POINTER;
}
//
// Validates filter
//
if( NULL == m_pFPFilter )
{
LOG((MSP_ERROR, "CFPPin::SuggestAllocatorProperties - "
"inavlid pointer to filter. Returns E_UNEXPECTED"));
return E_UNEXPECTED;
}
//
// Set the allocator properties
//
LOG((MSP_TRACE, "CFPPin::SuggestAllocatorProperties - "
"Size=%ld, Count=%ld",
pprop->cbBuffer,
pprop->cBuffers));
HRESULT hr = m_pFPFilter->PinSetAllocatorProperties( pprop );
if( FAILED(hr) )
{
LOG((MSP_ERROR, "CFPPin::SuggestAllocatorProperties - "
"PinSetAllocatorProperties failed. Returns 0x%08x", hr));
return hr;
}
LOG((MSP_TRACE, "CFPPin::SuggestAllocatorProperties - exit"));
return S_OK;
}
STDMETHODIMP CFPPin::GetAllocatorProperties(
ALLOCATOR_PROPERTIES* pprop
)
{
LOG((MSP_TRACE, "CFPPin::GetAllocatorProperties - enter"));
LOG((MSP_TRACE, "CFPPin::GetAllocatorProperties - exit E_NOTIMPL"));
return E_NOTIMPL;
}
HRESULT CFPPin::OnThreadStartPlay()
{
LOG((MSP_TRACE, "CFPPin::OnThreadStartPlay - enter"));
//
// Critical section
//
CLock lock(m_Lock);
//
// Validates filter
//
if( NULL == m_pFPFilter )
{
LOG((MSP_ERROR, "CFPPin::OnThreadStartPlay - "
"inavlid pointer to filter. Returns E_UNEXPECTED"));
return E_UNEXPECTED;
}
HRESULT hr = m_pFPFilter->PinThreadStart( );
LOG((MSP_TRACE, "CFPPin::OnThreadStartPlay - exit 0x%08x", hr));
return hr;
}
/*++
Deliver
We overite CSourceStream::Deliver() method
and right now we don't deliver 0 length samples
It's just an optimization.
--*/
HRESULT CFPPin::Deliver(
IN IMediaSample* pSample
)
{
if (m_pInputPin == NULL)
{
return VFW_E_NOT_CONNECTED;
}
if( pSample == NULL )
{
return E_UNEXPECTED;
}
long nLength = pSample->GetActualDataLength();
if( nLength == 0 )
{
return S_OK;
}
return CSourceStream::Deliver( pSample );
}
// eof