windows-nt/Source/XPSP1/NT/net/tapi/skywalker/mspbase/msptrmvc.cpp
2020-09-26 16:20:57 +08:00

342 lines
8.2 KiB
C++

/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
msptrmvc.cpp
Abstract:
MSP base classes: implementation of video capture terminal.
--*/
#include "precomp.h"
#pragma hdrstop
#include <amvideo.h>
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CVideoCaptureTerminal::~CVideoCaptureTerminal()
{
LOG((MSP_TRACE, "CVideoCaptureTerminal::~CVideoCaptureTerminal() finished"));
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT CVideoCaptureTerminal::CreateTerminal(
IN CComPtr<IMoniker> pMoniker,
IN MSP_HANDLE htAddress,
OUT ITTerminal **ppTerm
)
{
USES_CONVERSION;
LOG((MSP_TRACE, "CVideoCaptureTerminal::CreateTerminal - enter"));
//
// Validate the parameters
//
if ( MSPB_IsBadWritePtr(ppTerm, sizeof(ITTerminal *) ) )
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::CreateTerminal : "
"bad terminal pointer; returning E_POINTER"));
return E_POINTER;
}
if ( IsBadReadPtr(pMoniker, sizeof(IMoniker) ) )
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::CreateTerminal : "
"bad moniker pointer; returning E_POINTER"));
return E_POINTER;
}
*ppTerm = NULL;
HRESULT hr;
//
// Get the name for this filter out of the property bag.
//
CComPtr<IPropertyBag> pBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if (FAILED(hr))
{
LOG((MSP_ERROR,
"CVideoCaptureTerminal::CreateTerminal (BindToStorage) - returning %8x", hr));
return hr;
}
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, 0);
if (FAILED(hr))
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::CreateTerminal (IPropertyBag::Read) - returning %8x", hr));
return hr;
}
//
// Create the actual terminal object
//
CMSPComObject<CVideoCaptureTerminal> *pLclTerm = new CMSPComObject<CVideoCaptureTerminal>;
if (pLclTerm == NULL)
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::CreateTerminal returning E_OUTOFMEMORY"));
return E_OUTOFMEMORY;
}
//
// Save some stuff we'll need later
//
pLclTerm->m_pMoniker = pMoniker;
lstrcpyn(pLclTerm->m_szName, OLE2T(var.bstrVal), MAX_PATH);
SysFreeString(var.bstrVal);
//
// Finally get the ITTerminal interface that we were asked for.
//
hr = pLclTerm->_InternalQueryInterface(IID_ITTerminal, (void**)ppTerm);
if ( FAILED(hr) )
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::CreateTerminal - "
"Internal QI failed; returning 0x%08x", hr));
delete pLclTerm;
return hr;
}
//
// Finish initializing the terminal.
//
hr = pLclTerm->Initialize(CLSID_VideoInputTerminal,
TAPIMEDIATYPE_VIDEO,
TD_CAPTURE,
htAddress
);
if ( FAILED(hr) )
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::CreateTerminal - "
"Initialize failed; returning 0x%08x", hr));
(*ppTerm)->Release();
return hr;
}
LOG((MSP_TRACE, "CVideoCaptureTerminal::CreateTerminal - exit S_OK"));
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Create the filters used by this terminal
HRESULT CVideoCaptureTerminal::CreateFilters()
{
LOG((MSP_TRACE, "CVideoCaptureTerminal::CreateFilters() - enter"));
//
// If we already have the filter, just return S_OK.
//
if ( m_pIFilter != NULL )
{
LOG((MSP_TRACE, "CVideoCaptureTerminal::CreateFilters() - "
"already have a filter - exit S_OK"));
return S_OK;
}
//
// Now make the filter.
//
HRESULT hr = m_pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pIFilter);
if ( FAILED(hr) )
{
// reset the filer interface - it's a CComPointer so this releases it
m_pIFilter = NULL;
LOG((MSP_ERROR, "CVideoCaptureTerminal::CreateFilters() - "
"BindToObject failed - exit 0x%08x", hr));
return hr;
}
LOG((MSP_TRACE, "CVideoCaptureTerminal::CreateFilters() - exit S_OK"));
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT
CVideoCaptureTerminal::FindCapturePin(
)
{
LOG((MSP_TRACE, "CVideoCaptureTerminal::FindCapturePin() - enter"));
if ( m_pIPin != NULL )
{
LOG((MSP_INFO, "CVideoCaptureTerminal::FindCapturePin() - "
"already called, so we already have a pin - exit S_OK"));
return S_OK;
}
HRESULT hr;
CComPtr<IEnumPins> pIEnumPins;
ULONG cFetched;
//
// Find the capture pin for the filter.
//
if (FAILED(hr = m_pIFilter->EnumPins(&pIEnumPins)))
{
LOG((MSP_ERROR,
"CVideoCaptureTerminal::FindCapturePin - can't enum pins %8x",
hr));
return hr;
}
IPin * pIPin;
// Enumerate all the pins and break on the
// first pin that meets requirement.
for (;;)
{
if (pIEnumPins->Next(1, &pIPin, &cFetched) != S_OK)
{
LOG((MSP_ERROR,
"CVideoCaptureTerminal::FindCapturePin - can't get a pin %8x",
hr));
return (hr == S_FALSE) ? E_FAIL : hr;
}
if (0 == cFetched)
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::FindCapturePin - got zero pins"));
return E_FAIL;
}
PIN_DIRECTION dir;
if (FAILED(hr = pIPin->QueryDirection(&dir)))
{
LOG((MSP_ERROR,
"CVideoCaptureTerminal::FindCapturePin - can't query pin direction %8x",
hr));
pIPin->Release();
return hr;
}
if (PINDIR_OUTPUT == dir)
{
break;
}
pIPin->Release();
}
m_pIPin = pIPin;
LOG((MSP_TRACE, "CVideoCaptureTerminal::FindCapturePin - exit S_OK"));
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT
CVideoCaptureTerminal::AddFiltersToGraph(
)
{
LOG((MSP_TRACE, "CVideoCaptureTerminal::AddFiltersToGraph called"));
if (m_pGraph == NULL)
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::AddFiltersToGraph - "
"no graph - exit E_UNEXPECTED"));
return E_UNEXPECTED;
}
HRESULT hr;
hr = CreateFilters();
if ( FAILED(hr) )
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::AddFiltersToGraph - "
"CreateFilters failed - exit 0x%08x", hr));
return hr;
}
//
// Add the filter to the graph.
//
// A word about names:
// If a filter has already been added with the same name (which will
// happen if we have more than one video capture terminal in the same
// graph) then that will return VFW_S_DUPLICATE_NAME, which is not
// a failure.
//
try
{
USES_CONVERSION;
hr = m_pGraph->AddFilter(m_pIFilter, T2CW(m_szName));
}
catch (...)
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::AddFiltersToGraph - T2CW threw an exception - "
"return E_OUTOFMEMORY"));
return E_OUTOFMEMORY;
}
if ( FAILED(hr) )
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::AddFiltersToGraph - "
"AddFilter failed - exit 0x%08x", hr));
return hr;
}
//
// set the terminal's capture pin (output pin)
//
hr = FindCapturePin();
if ( FAILED(hr) )
{
LOG((MSP_ERROR, "CVideoCaptureTerminal::AddFiltersToGraph - "
"FindCapturePin failed - exit 0x%08x", hr));
return hr;
}
LOG((MSP_TRACE, "CVideoCaptureTerminal::AddFiltersToGraph succeeded"));
return S_OK;
}
// eof