windows-nt/Source/XPSP1/NT/multimedia/dshow/vidctl/tunerimpl.h
2020-09-26 16:20:57 +08:00

179 lines
6.1 KiB
C++

//==========================================================================;
//
// tunerimpl.h : additional infrastructure to support implementing IMSVidTuner
// nicely from c++
// Copyright (c) Microsoft Corporation 1999.
//
/////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef TUNERIMPL_H
#define TUNERIMPL_H
#include "videoinputimpl.h"
#include "tune.h"
#include <deviceeventimpl.h>
namespace MSVideoControl {
template<class T, LPCGUID LibID, LPCGUID KSCategory, class MostDerivedInterface = IMSVidTuner>
class DECLSPEC_NOVTABLE IMSVidTunerImpl :
public IMSVidVideoInputImpl<T, LibID, KSCategory, MostDerivedInterface> {
public:
TNTuningSpace m_TS;
TNTuneRequest m_pCurrentTR;
IMSVidTunerImpl() : m_TS(), m_pCurrentTR() {}
virtual ~IMSVidTunerImpl() {}
virtual HRESULT DoTune(TNTuneRequest& pTR) = 0;
virtual HRESULT UpdateTR(TNTuneRequest& pTR) = 0;
// IMSVidInputDevice
STDMETHOD(IsViewable)(VARIANT* pv, VARIANT_BOOL *pfViewable)
{
if (!m_fInit) {
return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED);
}
if (!pv) {
return E_POINTER;
}
return E_NOTIMPL;
}
STDMETHOD(View)(VARIANT* pv) {
if (!m_fInit) {
return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED);
}
if (!pv) {
return E_POINTER;
}
try {
if (pv->vt != VT_DISPATCH && pv->vt != VT_UNKNOWN) {
return ImplReportError(__uuidof(T), IDS_INVALID_CONTENT, __uuidof(IMSVidTuner), E_INVALIDARG);
}
PQTuneRequest tr((pv->vt == VT_UNKNOWN) ? pv->punkVal : pv->pdispVal);
if (!tr) {
return ImplReportError(__uuidof(T), IDS_INVALID_CONTENT, __uuidof(IMSVidTuner), E_INVALIDARG);
}
return put_Tune(tr);
} catch(...) {
return E_UNEXPECTED;
}
}
// IMSVidTuner
STDMETHOD(put_Tune)(ITuneRequest *pTR) {
TRACELM(TRACE_DETAIL, "IMSVidTunerImpl<>::put_Tune()");
if (!m_fInit) {
return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED);
}
if (!pTR) {
return E_POINTER;
}
try {
TNTuneRequest req(pTR);
ASSERT(req);
if (m_TS) {
// if this tuner has been initialized propertly it will have a tuning space
// that it handles already specified. in that case, we should only
// handle tune requests for our ts
TNTuningSpace ts(req.TuningSpace());
if (ts != m_TS) {
return ImplReportError(__uuidof(T), IDS_INVALID_TS, __uuidof(IMSVidTuner), E_INVALIDARG);
}
} else {
// undone: if dev init is correct this case should never occur
// return E_UNEXPECTED;
}
HRESULT hr = DoTune(req);
if (SUCCEEDED(hr)) {
m_pCurrentTR = req;
m_pCurrentTR.Clone();
if (!m_TS) {
// undone: this is bad. temporary hack until dev init is correct.
m_TS = req.TuningSpace();
m_TS.Clone();
}
}
return hr;
} catch(...) {
return E_INVALIDARG;
}
}
STDMETHOD(get_Tune)(ITuneRequest **ppTR) {
if (!m_fInit) {
return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED);
}
if (!ppTR) {
return E_POINTER;
}
try {
HRESULT hr = UpdateTR(m_pCurrentTR);
if (FAILED(hr)) {
return hr;
}
return m_pCurrentTR.CopyTo(ppTR);
} catch(...) {
return E_INVALIDARG;
}
}
STDMETHOD(get_TuningSpace)(ITuningSpace **ppTS) {
if (!m_fInit) {
return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidTuner), CO_E_NOTINITIALIZED);
}
if (ppTS == NULL)
return E_POINTER;
try {
m_TS.CopyTo(ppTS);
return NOERROR;
} catch(...) {
return E_UNEXPECTED;
}
}
STDMETHOD(put_TuningSpace)(ITuningSpace* pTS) {
return E_NOTIMPL;
}
};
template <class T, const IID* piid = &IID_IMSVidTunerEvent, class CDV = CComDynamicUnkArray>
class CProxy_Tuner : public CProxy_DeviceEvent<T, piid, CDV>
{
//Warning this class may be recreated by the wizard.
public:
VOID Fire_OnTuneChanged(IMSVidTuner *pTunerDev)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = pTunerDev;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(eventidOnTuneChanged, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}
};
}; // namespace
#endif
// end of file - tunerimpl.h