|
|
// Copyright (c) 1997 - 1998 Microsoft Corporation. All Rights Reserved.
// mss.cpp : Implementation of CAMMediaTypeStream
#include "stdafx.h"
#include "project.h"
/////////////////////////////////////////////////////////////////////////////
// CAMMediaTypeStream
CAMMediaTypeStream::CAMMediaTypeStream() { InitMediaType(&m_MediaType); m_AllocatorProperties.cBuffers = 1; m_AllocatorProperties.cbBuffer = 0x1000; m_AllocatorProperties.cbAlign = 1;
// We don't require any prefix. If there is a prefix we don't
// need to add it in GetPointer - it's hidden unless we want to
// access it.
m_AllocatorProperties.cbPrefix = 0; }
STDMETHODIMP CAMMediaTypeStream::AllocateSample(DWORD dwFlags, IStreamSample **ppSample) { TRACEINTERFACE(_T("IDirectDrawStream::AllocateSample(0x%8.8X, 0x%8.8X)\n"), dwFlags, ppSample); HRESULT hr; if (!ppSample) { hr = E_POINTER; } else { *ppSample = NULL; if (dwFlags) { hr = E_INVALIDARG; } else { hr = CreateSample(m_AllocatorProperties.cbBuffer, NULL, 0, NULL, (IAMMediaTypeSample **)ppSample); } } return hr; }
STDMETHODIMP CAMMediaTypeStream::CreateSharedSample(IStreamSample *pExistingSample, DWORD dwFlags, IStreamSample **ppNewSample) { return E_NOTIMPL; // There really is no way to share data since the actual
// size of the data can not be transfered.
}
STDMETHODIMP CAMMediaTypeStream::SetSameFormat(IMediaStream *pStream, DWORD dwFlags) { TRACEINTERFACE(_T("IAMMediaSampleStream::SetSameFormat(0x%8.8X, 0x%8.8X)\n"), pStream, dwFlags); CComQIPtr<IAMMediaTypeStream, &IID_IAMMediaTypeStream> pSource(pStream); HRESULT hr; if (!pSource) { hr = MS_E_INCOMPATIBLE; } else { AM_MEDIA_TYPE MediaType; hr = pSource->GetFormat(&MediaType, 0); if (SUCCEEDED(hr)) { hr = SetFormat(&MediaType, 0); FreeMediaType(MediaType); } } return hr; }
////////////////////////////////////
STDMETHODIMP CAMMediaTypeStream::GetFormat(AM_MEDIA_TYPE *pMediaType, DWORD dwFlags) { AUTO_CRIT_LOCK; HRESULT hr = S_OK;
if (m_pConnectedPin) { CopyMediaType(pMediaType, &m_MediaType); } else { hr = MS_E_NOSTREAM; }
return hr; }
STDMETHODIMP CAMMediaTypeStream::SetFormat(AM_MEDIA_TYPE *pMediaType, DWORD dwFlags) { AUTO_CRIT_LOCK; HRESULT hr = S_OK; if (m_cAllocated) { if (!IsEqualMediaType(*pMediaType, m_MediaType)) { hr = MS_E_SAMPLEALLOC; } } else { FreeMediaType(m_MediaType); CopyMediaType(&m_MediaType, pMediaType); } return hr; }
STDMETHODIMP CAMMediaTypeStream::CreateSample(long lSampleSize, BYTE * pbBuffer, DWORD dwFlags, IUnknown * pUnkOuter, IAMMediaTypeSample **ppSample) { AUTO_CRIT_LOCK; HRESULT hr; if (!ppSample) { hr = E_POINTER; } else { *ppSample = NULL; CComPolyObject<CAMMediaTypeSample> * pATLSampleObject = new CComPolyObject<CAMMediaTypeSample>(pUnkOuter); if (!pATLSampleObject) { hr = E_OUTOFMEMORY; } else { CAMMediaTypeSample *pNewSample = &pATLSampleObject->m_contained; hr = pNewSample->Initialize(this, lSampleSize, pbBuffer); if (SUCCEEDED(hr)) { pNewSample->GetControllingUnknown()->QueryInterface(IID_IAMMediaTypeSample, (void **)ppSample); } else { delete pATLSampleObject; } } } return hr; }
STDMETHODIMP CAMMediaTypeStream::GetStreamAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) { return E_FAIL; }
STDMETHODIMP CAMMediaTypeStream::SetStreamAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) { return E_FAIL; }
//
// IPin implementation
//
STDMETHODIMP CAMMediaTypeStream::ReceiveConnection(IPin * pConnector, const AM_MEDIA_TYPE *pmt) { // Check the type is accepted and then save the connected pin
HRESULT hr = QueryAccept(pmt); if (FAILED(hr)) { return hr; } AUTO_CRIT_LOCK; m_pConnectedPin = pConnector; return hr; }
STDMETHODIMP CAMMediaTypeStream::QueryAccept(const AM_MEDIA_TYPE *pmt) { AUTO_CRIT_LOCK; return (IsEqualMediaType(*pmt, m_MediaType) ? S_OK : VFW_E_TYPE_NOT_ACCEPTED); }
STDMETHODIMP CAMMediaTypeStream::Receive(IMediaSample *pMediaSample) { if (m_bFlushing || m_bStopIfNoSamples && m_cAllocated == 0) { EndOfStream(); return S_FALSE; }
HRESULT hr = S_OK; // Send quality message if clocked
REFERENCE_TIME CurTime; if (S_OK == m_pFilter->GetCurrentStreamTime(&CurTime)) { REFERENCE_TIME rtStart, rtStop; if (m_pQC && SUCCEEDED(pMediaSample->GetTime(&rtStart, &rtStop))) { Quality msg; msg.Proportion = 1000; msg.Type = Famine; msg.Late = CurTime - rtStart; msg.TimeStamp = rtStart;
// Call Notify on our connected pin
m_pQC->Notify(m_pBaseFilter, msg); } } #ifdef DEBUG
if (bDbgTraceTimes) { REFERENCE_TIME rtStart, rtStop; if (SUCCEEDED(pMediaSample->GetTime(&rtStart, &rtStop))) { ATLTRACE(_T("AMSTREAM.DLL : Video sample received - start %dms, end %dms\n"), (LONG)(rtStart / 10000), (LONG)(rtStop / 10000)); } } #endif
if (m_bUsingMyAllocator) { CAMMediaTypeSample *pSrcSample = (CAMMediaTypeSample *)((CMediaSample *)pMediaSample)->m_pSample; pSrcSample->m_bReceived = true; } else { CAMMediaTypeSample *pDestSample; REFERENCE_TIME rtStart, rtEnd; pMediaSample->GetTime(&rtStart, &rtEnd); hr = AllocMTSampleFromPool(&rtStart, &pDestSample); Lock(); // This is a media sample coming from a different allocator.
// Because QueryAccept only accepts our type the format should
// be compatible
if (SUCCEEDED(hr)) { hr = pDestSample->SetCompletionStatus(pDestSample->CopyFrom(pMediaSample)); // Warning! The SetCompletionStatus may delete pDestSample. Don't touch it after this point!
} Unlock(); }
#ifdef DEBUG
if (bDbgTraceTimes) { REFERENCE_TIME CurTime; m_pFilter->GetCurrentStreamTime(&CurTime); ATLTRACE(_T("AMSTREAM.DLL : Got sample at %dms\n"), (LONG)(CurTime / 10000)); } #endif
return hr; }
//
// IMemAllocator implementation
//
//
// IMemAllocator
//
STDMETHODIMP CAMMediaTypeStream::SetProperties(ALLOCATOR_PROPERTIES* pRequest, ALLOCATOR_PROPERTIES* pActual) { HRESULT hr;
AUTO_CRIT_LOCK; ZeroMemory(pActual, sizeof(*pActual)); if (pRequest->cbAlign == 0) { hr = VFW_E_BADALIGN; } else { if (m_bCommitted == TRUE) { hr = VFW_E_ALREADY_COMMITTED; } else {
m_AllocatorProperties = *pRequest; hr = GetProperties(pActual); } } return hr; }
STDMETHODIMP CAMMediaTypeStream::GetProperties(ALLOCATOR_PROPERTIES* pProps) { AUTO_CRIT_LOCK; CopyMemory(pProps, &m_AllocatorProperties, sizeof(*pProps)); return S_OK; }
STDMETHODIMP CAMMediaTypeStream::GetBuffer(IMediaSample **ppBuffer, REFERENCE_TIME * pStartTime, REFERENCE_TIME * pEndTime, DWORD dwFlags) { *ppBuffer = NULL; CAMMediaTypeSample *pSample; if (m_bStopIfNoSamples && m_cAllocated == 0) { return E_FAIL; } #ifdef DEBUG
if (bDbgTraceTimes) { ATLTRACE(_T("AMSTREAM.DLL : GetBuffer for %dms\n"), pStartTime ? (LONG)(*pStartTime / 10000) : 0); } #endif
HRESULT hr = AllocMTSampleFromPool(pStartTime, &pSample); if (SUCCEEDED(hr)) { pSample->m_bReceived = false; pSample->m_bModified = true; *ppBuffer = (IMediaSample *)(pSample->m_pMediaSample); (*ppBuffer)->AddRef(); } return hr; }
//
// Special CStream methods
//
HRESULT CAMMediaTypeStream::GetMediaType(ULONG Index, AM_MEDIA_TYPE **ppMediaType) { if (Index != 0) { return S_FALSE; }
*ppMediaType = CreateMediaType(&m_MediaType); return (*ppMediaType) ? S_OK : E_OUTOFMEMORY; }
|