|
|
//==========================================================================;
//
// Composition.h : Declaration of the custom composition class for gluing analog capture to ovmixer
// Copyright (c) Microsoft Corporation 1999.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef ANACAP_H
#define ANACAP_H
#pragma once
#include <uuids.h>
#include "bdamedia.h"
#include "MSVidTVTuner.h"
#include "resource.h" // main symbols
#include <winerror.h>
#include <algorithm>
#include <compimpl.h>
#include <seg.h>
#include <objectwithsiteimplsec.h>
#include "devices.h"
/////////////////////////////////////////////////////////////////////////////
// CAnaCapComp
class ATL_NO_VTABLE __declspec(uuid("E18AF75A-08AF-11d3-B64A-00C04F79498E")) CAnaCapComp : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CAnaCapComp, &__uuidof(CAnaCapComp)>, public IObjectWithSiteImplSec<CAnaCapComp>, public IMSVidCompositionSegmentImpl<CAnaCapComp> { public: CAnaCapComp() {} virtual ~CAnaCapComp() {}
REGISTER_NONAUTOMATION_OBJECT(IDS_PROJNAME, IDS_REG_ANACAPCOMP_DESC, LIBID_MSVidCtlLib, __uuidof(CAnaCapComp));
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CAnaCapComp) COM_INTERFACE_ENTRY(IMSVidCompositionSegment) COM_INTERFACE_ENTRY(IMSVidGraphSegment) COM_INTERFACE_ENTRY(IObjectWithSite) COM_INTERFACE_ENTRY(IPersist) END_COM_MAP()
// IMSVidComposition
public: // IMSVidGraphSegment
// IMSVidCompositionSegment
STDMETHOD(Compose)(IMSVidGraphSegment * upstream, IMSVidGraphSegment * downstream) { if (m_fComposed) { return NOERROR; } ASSERT(m_pGraph); try { TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose()"); VWGraphSegment up(upstream); ASSERT(up.Graph() == m_pGraph); VWGraphSegment down(downstream); ASSERT(down.Graph() == m_pGraph); if (up.begin() == up.end()) { TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() can't compose empty up segment"); return E_INVALIDARG; } if (down.begin() == down.end()) { TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() can't compose empty down segment"); return E_INVALIDARG; }
VWGraphSegment::iterator iOv; for (iOv = down.begin(); iOv != down.end(); ++iOv) { if (IsVideoRenderer(*iOv)) { break; } }
if (iOv == down.end()) { TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() downstream segment has no ov mixer filter"); return E_FAIL; }
TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() found vr");
ASSERT((*iOv).GetGraph() == m_pGraph); DSFilter pOv(*iOv);
CComQIPtr<IMSVidAnalogTuner> qiITV(upstream); CMSVidTVTuner* qiTV; qiTV = static_cast<CMSVidTVTuner*>(qiITV.p); DSPin pVidPin; VWGraphSegment::iterator iCap; for (iCap = up.begin(); iCap != up.end(); ++iCap) { if (IsAnalogVideoCapture(*iCap)) { break; } } if (iCap == up.end()) { TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() upstream segment has no capture filter"); return E_FAIL; } ASSERT((*iCap).GetGraph() == m_pGraph); TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() found capture filter");
DSFilter pCap(*iCap);
DSFilter::iterator iCapPin; DSFilter::iterator iPrePin; for (iCapPin = pCap.begin(); iCapPin != pCap.end(); ++iCapPin) { if (IsAnalogVideoCaptureViewingPin(*iCapPin)) { break; } } for (iPrePin = pCap.begin(); iPrePin != pCap.end(); ++iPrePin) { if (IsAnalogVideoCapturePreviewPin(*iPrePin)) { break; } } if (iCapPin == pCap.end() && iPrePin == pCap.end()) {
TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() no video pin on capture"); bool fDeMux = false;
// See if this is an error or not
PQVidCtl pqCtl; if(!!m_pContainer){ HRESULT hr = m_pContainer->QueryInterface(IID_IMSVidCtl, reinterpret_cast<void**>(&pqCtl)); if(FAILED(hr)){ return hr; }
PQFeatures fa; hr = pqCtl->get_FeaturesActive(&fa); if(FAILED(hr)){ return hr; }
CFeatures* pC = static_cast<CFeatures *>(fa.p); DeviceCollection::iterator i; for(i = pC->m_Devices.begin(); i != pC->m_Devices.end(); ++i){ if(VWGraphSegment(*i).ClassID() == CLSID_MSVidEncoder){ break; } }
if(i != pC->m_Devices.end()){ fDeMux = true; } } if (fDeMux){ TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() no viewing or previewing pin found but encoder active"); return NOERROR; } else{ TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() no viewing or previewing pin found"); return E_FAIL; } }
TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() found viewing or previewing pin");
// this is an intelligent connect so that we can bring in xforms
// for example certain usb tuners want to have media type jpg not yuv which
// means we need a jpg/yuv xform between capture and render
// this will also bring in the vpm if necessary
DSPin pCapPin(*iCapPin); DSPin pPrePin(*iPrePin); if(iCapPin != pCap.end()){ if (pCapPin.HasCategory(PIN_CATEGORY_VIDEOPORT)) {
DSFilter vpm; bool fVPMalreadyloaded = false;
for (DSGraph::iterator i = m_pGraph.begin(); i != m_pGraph.end(); ++i) { DSFilter f(*i); if (IsVPM(f)) { vpm = f; fVPMalreadyloaded = true; break; } }
if (!fVPMalreadyloaded) { HRESULT hr = vpm.CoCreateInstance(CLSID_VideoPortManager); if (FAILED(hr)) { TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() can't create vpm"); return E_UNEXPECTED; } CString csName; hr = m_pGraph.AddFilter(vpm, csName); if (FAILED(hr)) { TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() can't insert vpm in graph"); return E_UNEXPECTED; } }
if (vpm && !fVPMalreadyloaded) { m_Filters.push_back(vpm); } DSFilter::iterator iVPVBI; for (iVPVBI = pCap.begin(); iVPVBI != pCap.end(); ++iVPVBI) { DSPin pVPVBI(*iVPVBI); if (pVPVBI.HasCategory(PIN_CATEGORY_VIDEOPORT_VBI)) { HRESULT hr = pVPVBI.IntelligentConnect(vpm, m_Filters); if (SUCCEEDED(hr)) { break; } } }
} } HRESULT hr = E_FAIL; DSFilterList intermediates; if(iCapPin != pCap.end()){ hr = pCapPin.IntelligentConnect(pOv, intermediates); }
if(FAILED(hr)){ if(iPrePin != pCap.end()){ pPrePin = *iPrePin; hr = pPrePin.IntelligentConnect(pOv, intermediates); } }
if (FAILED(hr)) { return Error(IDS_CANT_CONNECT_CAP_VR, __uuidof(IMSVidCtl), E_UNEXPECTED); } m_Filters.insert(m_Filters.end(), intermediates.begin(), intermediates.end());
TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() SUCCEEDED"); m_fComposed = true; return NOERROR; } catch (ComException &e) { HRESULT hr = e; TRACELSM(TRACE_ERROR, (dbgDump << "CAnaCapComp::Compose() exception = " << hexdump(hr)), ""); return e; } catch (...) { TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() exception ... "); return E_UNEXPECTED; } } };
#endif // ANACAP_H
// end of file - anacap.h
|