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

178 lines
5.3 KiB
C++

//==========================================================================;
// MSVidXDS.cpp : Declaration of the CMSVidXDS
// copyright (c) Microsoft Corp. 1998-1999.
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#ifndef TUNING_MODEL_ONLY
#include "msvidXDS.h"
#include <winerror.h>
#include <algorithm>
#include "segimpl.h"
#include "devices.h"
#include <compimpl.h>
#include <seg.h>
#include <objectwithsiteimplsec.h>
#include "resource.h" // main symbols
DEFINE_EXTERN_OBJECT_ENTRY(CLSID_MSVidXDS, CXDS)
HRESULT CXDS::Unload(void) {
IMSVidGraphSegmentImpl<CXDS, MSVidSEG_XFORM, &GUID_NULL>::Unload();
m_iIPSink = -1;
return NOERROR;
}
// IMSVidGraphSegment
STDMETHODIMP CXDS::Build() {
return NOERROR;
}
STDMETHODIMP CXDS::PreRun() {
return NOERROR;
}
STDMETHODIMP CXDS::put_Container(IMSVidGraphSegmentContainer *pCtl){
if (!m_fInit) {
return CO_E_NOTINITIALIZED;
}
try {
if (!pCtl) {
return Unload();
}
if (m_pContainer) {
if (!m_pContainer.IsEqualObject(VWSegmentContainer(pCtl))) {
return Error(IDS_OBJ_ALREADY_INIT, __uuidof(IMSVidXDS), CO_E_ALREADYINITIALIZED);
} else {
return NO_ERROR;
}
}
// DON'T addref the container. we're guaranteed nested lifetimes
// and an addref creates circular refcounts so we never unload.
m_pContainer.p = pCtl;
m_pGraph = m_pContainer.GetGraph();
if (!m_pSystemEnum) {
HRESULT hr = m_pSystemEnum.CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER);
if (FAILED(hr)) {
return E_UNEXPECTED;
}
}
PQVidCtl pqCtl;
HRESULT hr = m_pContainer->QueryInterface(IID_IMSVidCtl, reinterpret_cast<void**>(&pqCtl));
if(FAILED(hr)){
return hr;
}
PQFeatures activeFeat;
hr = pqCtl->get_FeaturesActive(&activeFeat);
if(FAILED(hr)){
return hr;
}
CFeatures* pC = static_cast<CFeatures *>(activeFeat.p);
DeviceCollection::iterator i;
// Check to see if data services is active, if it is not find and load the cc codec
for(i = pC->m_Devices.begin(); i != pC->m_Devices.end(); ++i){
if(VWGraphSegment(*i).ClassID() == CLSID_MSVidDataServices){
break;
}
}
DSFilter ccDec;
DSPin ccDecPin;
if(i == pC->m_Devices.end()){
DSDevices codeclist(m_pSystemEnum, KSCATEGORY_VBICODEC);
DSMediaType mtL21(MEDIATYPE_AUXLine21Data, MEDIASUBTYPE_Line21_BytePair);
for(DSDevices::iterator n = codeclist.begin(); n != codeclist.end() && !ccDec; ++n){
DSFilter codecFilter = m_pGraph.AddMoniker((*n));
for(DSFilter::iterator codecPin = codecFilter.begin(); codecPin != codecFilter.end(); ++codecPin){
if((*codecPin).GetDirection() == PINDIR_OUTPUT){
for(DSPin::iterator codecMediaType = (*codecPin).begin(); codecMediaType != (*codecPin).end(); ++codecMediaType){
if((*codecMediaType) == mtL21){
ccDec = codecFilter;
m_Filters.push_back(ccDec);
ccDecPin = *codecPin;
}
}
}
}
if(!ccDec){
m_pGraph.RemoveFilter(codecFilter);
}
}
}
if(!ccDec){
return E_UNEXPECTED;
}
CComBSTR xdsString(L"{C4C4C4F3-0049-4E2B-98FB-9537F6CE516D}");
GUID2 xdsGuid(xdsString);
// bring in xds filter
CComPtr<IUnknown> fXDS(xdsGuid, NULL, CLSCTX_INPROC_SERVER);
if (!fXDS) {
TRACELM(TRACE_ERROR, "CMSVidClosedCaptioning::put_Container() can't load line 21 decoder");
return E_FAIL;
}
DSFilter xdsFilter(fXDS);
if (!xdsFilter) {
return E_UNEXPECTED;
}
CString csName(_T("XDS Decoder"));
hr = m_pGraph.AddFilter(xdsFilter, csName);
if (FAILED(hr)) {
return hr;
}
m_Filters.push_back(xdsFilter);
DSFilterList intermediates;
hr = m_pGraph.Connect(ccDec, xdsFilter, intermediates);
if(FAILED(hr)){
return hr;
}
m_Filters.insert(m_Filters.end(), intermediates.begin(), intermediates.end());
return NOERROR;
} catch (ComException &e) {
return e;
} catch(...) {
return E_UNEXPECTED;
}
return NOERROR;
}
// IMSVidDevice
STDMETHODIMP CXDS::get_Name(BSTR * Name){
if (!m_fInit) {
return CO_E_NOTINITIALIZED;
}
try {
return CComBSTR("XDS Segment").CopyTo(Name);
} catch(...) {
return E_POINTER;
}
}
STDMETHODIMP CXDS::InterfaceSupportsErrorInfo(REFIID riid){
static const IID* arr[] =
{
&IID_IMSVidXDS
};
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++){
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
#endif // TUNING_MODEL_ONLY