278 lines
11 KiB
C++
278 lines
11 KiB
C++
//==========================================================================;
|
|
//
|
|
// Composition.h : Declaration of the custom composition class for gluing ANAlog capture to sbe SINk
|
|
// Copyright (c) Microsoft Corporation 1999.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#ifndef ANASIN_H
|
|
#define ANASIN_H
|
|
|
|
#pragma once
|
|
#include "stdafx.h"
|
|
#include <uuids.h>
|
|
#include "bdamedia.h"
|
|
#include "MSVidTVTuner.h"
|
|
#include "MSVidSBESink.h"
|
|
#include "encdec.h"
|
|
#include "resource.h" // main symbols
|
|
#include <objectwithsiteimplsec.h>
|
|
#include <winerror.h>
|
|
#include <algorithm>
|
|
#include <compimpl.h>
|
|
#include <seg.h>
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CAnaSinComp
|
|
class ATL_NO_VTABLE __declspec(uuid("9F50E8B1-9530-4ddc-825E-1AF81D47AED6")) CAnaSinComp :
|
|
public CComObjectRootEx<CComSingleThreadModel>,
|
|
public CComCoClass<CAnaSinComp, &__uuidof(CAnaSinComp)>,
|
|
public IObjectWithSiteImplSec<CAnaSinComp>,
|
|
public IMSVidCompositionSegmentImpl<CAnaSinComp>
|
|
{
|
|
public:
|
|
CAnaSinComp() {}
|
|
virtual ~CAnaSinComp() {}
|
|
|
|
REGISTER_NONAUTOMATION_OBJECT(IDS_PROJNAME,
|
|
IDS_REG_ANASINCOMP_DESC,
|
|
LIBID_MSVidCtlLib,
|
|
__uuidof(CAnaSinComp));
|
|
|
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
|
|
|
BEGIN_COM_MAP(CAnaSinComp)
|
|
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, "CAnaSinComp::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, "CAnaSinComp::Compose() can't compose empty up segment");
|
|
return E_INVALIDARG;
|
|
}
|
|
if (down.begin() == down.end()) {
|
|
TRACELM(TRACE_ERROR, "CAnaSinComp::Compose() can't compose empty down segment");
|
|
return E_INVALIDARG;
|
|
}
|
|
#if 0
|
|
VWGraphSegment::iterator iOv = std::find_if(down.begin(),
|
|
down.end(),
|
|
arity1_pointer(&IsVideoRenderer));
|
|
#endif
|
|
CMSVidStreamBufferSink* ds = (CMSVidStreamBufferSink*)downstream;
|
|
DSFilter pSink(ds->m_Filters[0]);
|
|
|
|
CComQIPtr<IMSVidAnalogTuner> qiITV(upstream);
|
|
CMSVidTVTuner* qiTV;
|
|
qiTV = static_cast<CMSVidTVTuner*>(qiITV.p);
|
|
DSPin pVidPin;
|
|
DSPin pAudPin;
|
|
#if 0
|
|
if(!!qiTV && qiTV->m_iDeMux > 0){
|
|
CString csName;
|
|
// render demux out to vr
|
|
DSFilter pDeMux = qiTV->m_Filters[qiTV->m_iDeMux];
|
|
DSFilter::iterator iVidPin;
|
|
DSMediaType mtVideo(MEDIATYPE_Video, MEDIASUBTYPE_MPEG2_VIDEO, FORMAT_MPEG2Video);
|
|
DSMediaType mtAudio(MEDIATYPE_Audio, MEDIASUBTYPE_MPEG1Payload, FORMAT_WaveFormatEx);
|
|
for (iVidPin = pDeMux.begin(); iVidPin != pDeMux.end(); ++iVidPin) {
|
|
DSPin::iterator j;
|
|
for(j = (*iVidPin).begin(); j != (*iVidPin).end(); ++j){
|
|
DSMediaType pinType(*j);
|
|
if (pinType == mtVideo){
|
|
CComPtr<IUnknown> spMpeg2Analyze(CLSID_Mpeg2VideoStreamAnalyzer, NULL, CLSCTX_INPROC_SERVER);
|
|
if (!spMpeg2Analyze) {
|
|
//TRACELSM(TRACE_ERROR, (dbgDump << "CMSVidStreamBufferSink::Build() can't load Stream Buffer Sink");
|
|
return ImplReportError(__uuidof(IMSVidStreamBufferSink), IDS_CANT_CREATE_FILTER, __uuidof(IStreamBufferSink), E_UNEXPECTED);
|
|
}
|
|
DSFilter vr(spMpeg2Analyze);
|
|
if (!vr) {
|
|
ASSERT(false);
|
|
return ImplReportError(__uuidof(IMSVidStreamBufferSink), IDS_CANT_CREATE_FILTER, __uuidof(IBaseFilter), E_UNEXPECTED);
|
|
}
|
|
m_Filters.push_back(vr);
|
|
csName = _T("Mpeg2 Analysis");
|
|
m_pGraph.AddFilter(vr, csName);
|
|
DSFilter::iterator a;
|
|
for(a = vr.begin(); a != vr.end(); ++a){
|
|
HRESULT hr = (*a).Connect(*iVidPin);
|
|
if(FAILED(hr)){
|
|
continue;
|
|
}
|
|
else{
|
|
break;
|
|
}
|
|
}
|
|
if(a == vr.end()){
|
|
return E_FAIL;
|
|
}
|
|
for(a = vr.begin(); a != vr.end(); ++a){
|
|
if((*a).GetDirection() == PINDIR_OUTPUT){
|
|
pVidPin = (*a);
|
|
}
|
|
}
|
|
if(!pVidPin){
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
if(pinType == mtAudio){
|
|
pAudPin = (*iVidPin);
|
|
}
|
|
}
|
|
if(!!pVidPin && !!pAudPin){
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!pVidPin || !pAudPin){
|
|
TRACELM(TRACE_DETAIL, "CAnaSinComp::Compose() can't find video and/or audio pin on demux");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
DSFilterList intermediates;
|
|
CComBSTR encString(L"{C4C4C4F1-0049-4E2B-98FB-9537F6CE516D}");
|
|
GUID2 encdecGuid (encString);
|
|
HRESULT hr = S_OK;
|
|
|
|
// Create and add to graph the Video Tagger Filter
|
|
CComPtr<IUnknown> spEncTagV(encdecGuid, NULL, CLSCTX_INPROC_SERVER);
|
|
if (!spEncTagV) {
|
|
TRACELM(TRACE_ERROR, "CMSVidStreamBufferSink::Build() can't load Tagger filter");
|
|
return ImplReportError(__uuidof(IMSVidStreamBufferSink), IDS_CANT_CREATE_FILTER, __uuidof(IStreamBufferSink), E_UNEXPECTED);
|
|
}
|
|
|
|
DSFilter vrV(spEncTagV);
|
|
if (!vrV) {
|
|
ASSERT(false);
|
|
return ImplReportError(__uuidof(IMSVidStreamBufferSink), IDS_CANT_CREATE_FILTER, __uuidof(IBaseFilter), E_UNEXPECTED);
|
|
}
|
|
|
|
m_Filters.push_back(vrV);
|
|
csName = _T("Video Encoder Tagger Filter");
|
|
m_pGraph.AddFilter(vrV, csName);
|
|
|
|
// Connect video pin to Tagger
|
|
hr = pVidPin.IntelligentConnect(vrV, intermediates);
|
|
if(FAILED(hr)){
|
|
TRACELM(TRACE_DETAIL, "CAnaSinComp::Compose() can't connect audio pin to Audio Tagger");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
// Connect Tagger to Sink
|
|
DSFilter::iterator fil, vP;
|
|
hr = E_FAIL;
|
|
for(vP = vrV.begin(); vP != vrV.end(); ++ vP){
|
|
if((*vP).GetDirection() == PINDIR_OUTPUT){
|
|
break;
|
|
}
|
|
}
|
|
if(vP == vrV.end()){
|
|
return E_UNEXPECTED;
|
|
}
|
|
for(fil = pSink.begin(); fil != pSink.end() && FAILED(hr); ++fil){
|
|
hr = (*vP).Connect((*fil));
|
|
}
|
|
if(FAILED(hr)){
|
|
|
|
TRACELM(TRACE_DETAIL, "CAnaSinComp::Compose() can't connect Video Tagger to Sink");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
// Create and add to graph the Audio Tagger Filter
|
|
CComPtr<IUnknown> spEncTagA(encdecGuid, NULL, CLSCTX_INPROC_SERVER);
|
|
if (!spEncTagA) {
|
|
TRACELM(TRACE_ERROR, "CMSVidStreamBufferSink::Build() can't load Tagger filter");
|
|
return ImplReportError(__uuidof(IMSVidStreamBufferSink), IDS_CANT_CREATE_FILTER, __uuidof(IStreamBufferSink), E_UNEXPECTED);
|
|
}
|
|
|
|
DSFilter vrA(spEncTagA);
|
|
if (!vrA) {
|
|
ASSERT(false);
|
|
return ImplReportError(__uuidof(IMSVidStreamBufferSink), IDS_CANT_CREATE_FILTER, __uuidof(IBaseFilter), E_UNEXPECTED);
|
|
}
|
|
|
|
m_Filters.push_back(vrA);
|
|
csName = _T("Audio Encoder Tagger Filter");
|
|
m_pGraph.AddFilter(vrA, csName);
|
|
|
|
// Connect audio pin to the Tagger
|
|
hr = pAudPin.IntelligentConnect(vrA, intermediates);
|
|
if(FAILED(hr)){
|
|
TRACELM(TRACE_DETAIL, "CAnaSinComp::Compose() can't connect audio pin to Audio Tagger");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
// Connect Tagger to Sink
|
|
hr = E_FAIL;
|
|
for(vP = vrA.begin(); vP != vrA.end(); ++ vP){
|
|
if((*vP).GetDirection() == PINDIR_OUTPUT){
|
|
break;
|
|
}
|
|
}
|
|
if(vP == vrA.end()){
|
|
return E_UNEXPECTED;
|
|
}
|
|
for(fil = pSink.begin(); fil != pSink.end() && FAILED(hr); ++fil){
|
|
hr = (*vP).Connect((*fil));
|
|
}
|
|
if(FAILED(hr)){
|
|
|
|
TRACELM(TRACE_DETAIL, "CAnaSinComp::Compose() can't connect Video Tagger to Sink");
|
|
return E_UNEXPECTED;
|
|
}
|
|
/*
|
|
hr = m_pGraph.Connect(vrA, pSink, intermediates);
|
|
if(FAILED(hr)){
|
|
TRACELM(TRACE_DETAIL, "CAnaSinComp::Compose() can't connect Audio Tagger to Sink");
|
|
return E_UNEXPECTED;
|
|
}
|
|
*/
|
|
|
|
ASSERT(intermediates.begin() == intermediates.end());
|
|
m_Filters.insert(m_Filters.end(), intermediates.begin(), intermediates.end());
|
|
|
|
}
|
|
else{
|
|
#endif
|
|
return S_OK;
|
|
#if 0
|
|
}
|
|
#endif
|
|
TRACELM(TRACE_DETAIL, "CAnaSinComp::Compose() SUCCEEDED");
|
|
m_fComposed = true;
|
|
return NOERROR;
|
|
} catch (ComException &e) {
|
|
HRESULT hr = e;
|
|
TRACELSM(TRACE_ERROR, (dbgDump << "CAnaSinComp::Compose() exception = " << hexdump(hr)), "");
|
|
return e;
|
|
} catch (...) {
|
|
TRACELM(TRACE_ERROR, "CAnaSinComp::Compose() exception ... ");
|
|
return E_UNEXPECTED;
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif // AnaSin_H
|
|
// end of file - AnaSin.h
|