|
|
//==========================================================================;
//
// Copyright (c) Microsoft Corporation 1999-2000.
//
//--------------------------------------------------------------------------;
//
// MSVidAudioRenderer.cpp : Implementation of CMSVidAudioRenderer
//
#include "stdafx.h"
#ifndef TUNING_MODEL_ONLY
#include "MSVidCtl.h"
#include "MSVidAudioRenderer.h"
#include "MSVidVideoRenderer.h"
#include "dvdmedia.h"
#include "sbe.h"
DEFINE_EXTERN_OBJECT_ENTRY(CLSID_MSVidAudioRenderer, CMSVidAudioRenderer)
/////////////////////////////////////////////////////////////////////////////
// CMSVidAudioRenderer
STDMETHODIMP CMSVidAudioRenderer::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_IMSVidAudioRenderer }; for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (InlineIsEqualGUID(*arr[i],riid)) return S_OK; } return S_FALSE; }
STDMETHODIMP CMSVidAudioRenderer::PreRun() { if (m_fUseKSRenderer) { return NOERROR; } // until sysaudio works correctly with ksproxy so that we only have 1 audio renderer
// filter for both digital and analog we have to have two different rendering filters and
// we don't which we're going to need. in the analog case, after we're done building
// we're left with the dsound renderer hooked up to the analog filter which creates a 1/2 second(or so)
// delayed echo. find this scenario if it exists and disconnect the dsound renderer from the wavein filter
TRACELM(TRACE_DEBUG, "CMSVidAudioRenderer::PreRun()"); if (m_iAudioRenderer == -1) { TRACELM(TRACE_ERROR, "CMSVidAudioRenderer::PreRun() no dsr"); return VFW_E_NO_AUDIO_HARDWARE; } DSFilter dsr(m_Filters[m_iAudioRenderer]); DSPin dsrin(*dsr.begin()); if (dsrin.GetDirection() != PINDIR_INPUT) { TRACELM(TRACE_ERROR, "CMSVidAudioRenderer::PreRun() first dsound renderer pin not an input"); return E_UNEXPECTED; } DSPin upstreampin; HRESULT hr = dsrin->ConnectedTo(&upstreampin); if (FAILED(hr) || !upstreampin) { // dsound renderer not connected to anything
TRACELM(TRACE_DEBUG, "CMSVidAudioRenderer::PreRun() dsr not connected"); return NOERROR; } DSFilter upstreamfilter(upstreampin.GetFilter()); if (!upstreamfilter) { TRACELM(TRACE_ERROR, "CMSVidAudioRenderer::PreRun() upstream pin has no filter"); return E_UNEXPECTED; } PQAudioInputMixer p(upstreamfilter); if (!p) { TRACELM(TRACE_ERROR, "CMSVidAudioRenderer::PreRun() upstream filter not wavein"); #if 0
PQVidCtl pqCtl; hr = m_pContainer->QueryInterface(IID_IMSVidCtl, reinterpret_cast<void**>(&pqCtl)); if(FAILED(hr)){ return hr; } CComQIPtr<IMSVidVideoRenderer> pq_VidVid; hr = pqCtl->get_VideoRendererActive(&pq_VidVid); if(FAILED(hr)){ return hr; }
CComQIPtr<IMSVidStreamBufferSource> pq_SBESource; CComQIPtr<IMSVidInputDevice> pq_Dev; hr = pqCtl->get_InputActive(&pq_Dev); if(FAILED(hr)){ return hr; } pq_SBESource = pq_Dev;
if(!pq_VidVid || !pq_SBESource){ return NOERROR; } VWGraphSegment vVid(pq_VidVid); if(!vVid){ return E_NOINTERFACE; } VWGraphSegment::iterator iV; for (iV = vVid.begin(); iV != vVid.end(); ++iV) { if (IsVideoRenderer(*iV)) { break; } } if (iV == vVid.end()) { TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() segment has no video mixer filter"); return E_FAIL; } CComQIPtr<IMediaFilter> pq_MFVid(*iV); if(!pq_MFVid){ return E_NOINTERFACE; }
CComQIPtr<IMediaFilter> pq_MFAud(dsr); if(!pq_MFAud){ return E_NOINTERFACE; }
CComQIPtr<IMediaFilter> pq_MFGph(m_pGraph); if(!pq_MFGph){ return E_NOINTERFACE; }
VWGraphSegment vSbe(pq_SBESource); if(!vSbe){ return E_NOINTERFACE; } CComQIPtr<IStreamBufferSource> pq_SBE; VWGraphSegment::iterator iS; for (iS = vSbe.begin(); iS != vSbe.end(); ++iS) { pq_SBE = (*iS); if (!!pq_SBE) { break; } } if (iS == vSbe.end()) { TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() segment has no video mixer filter"); return E_FAIL; } CComQIPtr<IReferenceClock> pq_IClock; hr = dsr->QueryInterface(&pq_IClock); if(FAILED(hr)){ return hr; } if(!pq_IClock || !pq_MFVid || !pq_MFAud || !pq_MFGph){ return E_NOINTERFACE; }
hr = pq_MFGph->SetSyncSource(pq_IClock); if(FAILED(hr)){ return hr; } #if 0
hr = pq_MFilter2->SetSyncSource(pq_IClock); if(FAILED(hr)){ return hr; }
#endif
hr = pq_MFVid->SetSyncSource(pq_IClock); if(FAILED(hr)){ return hr; } #endif
return NOERROR; } bool rc = m_pGraph.DisconnectFilter(dsr, false, false); if (!rc) { TRACELM(TRACE_ERROR, "CMSVidAudioRenderer::PreRun() disconnect filter failed"); return E_UNEXPECTED; }
return NOERROR; }
STDMETHODIMP CMSVidAudioRenderer::Build() { if (!m_fInit || !m_pGraph) { return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidAudioRenderer), CO_E_NOTINITIALIZED); } try { CString csName; DSFilter ar; PQCreateDevEnum SysEnum(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER); if(m_iAudioRenderer==-1){ if (m_fUseKSRenderer) { csName = _T("KS System Renderer"); // undone: use ks system renderer
} else if (m_fAnalogOnly) { csName = _T("Analog Audio Renderer"); DSDevices ARList(SysEnum, CLSID_AudioInputDeviceCategory); if (ARList.begin() != ARList.end()) { ar = m_pGraph.LoadFilter(*ARList.begin(), csName); m_pAR = ar; } } else if (m_fDigitalOnly) { csName = _T("Default DSound Renderer"); ar = DSFilter(CLSID_DSoundRender); m_pAR = ar; } else { // NOTE: its important that digital audio be first so that we short circuit
// loading 8 billion audio codecs trying to connect a digital source
// to the analog renderer. there aren't any analog codecs(a physical impossiblity),
// so we don't have to worry about the reverse case.
csName = _T("Default DSound Renderer"); ar = DSFilter(CLSID_DSoundRender); if (ar) { m_pGraph.AddFilter(ar, csName); m_Filters.push_back(ar); } csName = _T("Analog Audio Renderer"); DSDevices ARList(SysEnum, CLSID_AudioInputDeviceCategory); if (ARList.begin() != ARList.end()) { ar = m_pGraph.LoadFilter(*ARList.begin(), csName); } } } if (ar) { m_pGraph.AddFilter(ar, csName); m_Filters.push_back(ar); m_iAudioRenderer = 0; } if(m_iAudioRenderer == -1){ return VFW_E_NO_AUDIO_HARDWARE; } else{ return NOERROR; } } catch (ComException &e) { return e; } catch (...) { return E_UNEXPECTED; } }
#endif //TUNING_MODEL_ONLY
// end of file - msvidaudiorenderer.cpp
|