|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
我DirectShow开发DVBT的应用程序。
DVBT接收卡代号:USB 2870 Devie
信号源是用模拟的信号源来代替。
用NewSoft 的PVR软件可以收到音视频信号,至少也可以扫描到频道,但用自己写的代码,却扫描不到信号,不知道为什么。现把代码帖出来,请高手指点迷津。
//这是构建Filter Graph的函数,有些支节的代码删去
HRESULT VVPreviewBuilderDVBT()
{
HRESULT hr = S_OK;
if (m_pGraph == NULL)
{
return E_FAIL;
}
hr = m_pBuild.CoCreateInstance(CLSID_CaptureGraphBuilder2, 0, CLSCTX_INPROC_SERVER);
hr = m_pBuild->SetFiltergraph(m_pGraph);
// STEP 1: load network provider first so that it can configure other
// filters, such as configuring the demux to sprout output pins.
// We also need to submit a tune request to the Network Provider so it will
// tune to a channel
if(FAILED (hr = LoadNetworkProvider("DVB-T")))
{
TearDownGraph();
return hr;
}
hr = m_pNetworkProvider->QueryInterface(__uuidof (ITuner), reinterpret_cast <void**> (&m_pITuner));
if(FAILED (hr))
{
TearDownGraph();
return hr;
}
// create a tune request to initialize the network provider
// before connecting other filters
CComPtr <IDVBTuneRequest> pDVBTTuneRequest;
if(FAILED (hr = CreateDVBTTuneRequest(&pDVBTTuneRequest)))
{
TearDownGraph();
return hr;
}
//submit the tune request to the network provider
hr = m_pITuner->put_TuneRequest(pDVBTTuneRequest);
if(FAILED(hr))
{
TearDownGraph();
return hr;
}
// STEP2: Load tuner device and connect to network provide
if(FAILED (hr = LoadFilter (KSCATEGORY_BDA_NETWORK_TUNER,
&m_pTunerDemodDevice,
m_pNetworkProvider,
TRUE)))
{
TearDownGraph();
return hr;
}
// Step3: Load capture device and connect to tuner/demod device
if(FAILED (hr = LoadFilter (KSCATEGORY_BDA_RECEIVER_COMPONENT,
&m_pVideoDevice,
m_pTunerDemodDevice,
TRUE)))
{
TearDownGraph();
return hr;
}
//
// this next call loads and connects filters associated with
// the demultiplexor. if you want to manually load individual
// filters such as audio and video decoders, use the code at
// the bottom of this file
// Step4: Load demux
hr = AddFilterByCLSID2(m_pGraph, CLSID_MPEG2Demultiplexer, L"Mpeg2 Demux",
&m_pDemux);
if(FAILED (hr))
{
TearDownGraph();
return hr;
}
// Step5: Render demux pins
//if (FAILED (hr = BuildAVSegment()))
if(FAILED (hr = RenderDemux()))
{
TearDownGraph();
return hr;
}
// Step6: get pointer to Tuner and Demod pins on Tuner/Demod filter
// for setting the tuner and demod. property sets
if (GetTunerDemodPropertySetInterfaces() == FALSE )
{
TearDownGraph();
}
return S_OK;
}
//
HRESULT LoadNetworkProvider( CComBSTR pNetworkType)
{
HRESULT hr = S_OK;
CComBSTR bstrNetworkType;
CLSID CLSIDNetworkType;
OutputDebugString(TEXT("BDASample: CBDAFilterGraph:oadNetworkProvider\n"));
// obtain tuning space then load network provider
if(m_pITuningSpace == NULL)
{
hr = LoadTuningSpace(pNetworkType);
if(FAILED(hr))
{
OutputDebugString(TEXT("BDASample: Cannot find MYDVBT TuningSpace\n"));
// so we create one.
hr = CreateTuningSpace(pNetworkType);
if (FAILED(hr))
{
TearDownGraph();
return E_FAIL;
}
}
}
if (!m_pITuningSpace)
{
TearDownGraph();
return E_FAIL;
}
// Get the current Network Type clsid
hr = m_pITuningSpace->get_NetworkType(&bstrNetworkType);
if (FAILED (hr))
{
TearDownGraph();
return hr;
}
hr = CLSIDFromString(bstrNetworkType, &CLSIDNetworkType);
if (FAILED (hr))
{
TearDownGraph();
return hr;
}
// create the network provider based on the clsid obtained from the tuning space
hr = CoCreateInstance(CLSIDNetworkType, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
reinterpret_cast<void**>(&m_pNetworkProvider));
if (FAILED (hr))
{
TearDownGraph();
return hr;
}
//add the Network Provider filter to the graph
hr = m_pGraph->AddFilter(m_pNetworkProvider, L"Network Provider");
return hr;
}
//LoadFilter (....) 该函数将两个Filter 连接起来,具体代码比较简单,就不把代码巾出来了。
HRESULT CreateTuningSpace(CComBSTR pNetworkType)
{
HRESULT hr = S_OK;
OutputDebugString(TEXT("BDASample: CBDAFilterGraph::CreateTuningSpace\n"));
CComPtr <IDVBTuningSpace> pIDVBTuningSpace;
hr = pIDVBTuningSpace.CoCreateInstance(CLSID_DVBTuningSpace);
if (FAILED(hr) || !pIDVBTuningSpace)
{
//ErrorMessageBox(TEXT("Failed to create system tuning space."));
return FALSE;
}
// set the Frequency mapping
WCHAR szFreqMapping[ 3 ]=L"-1";
BSTR bstrFreqMapping = SysAllocString(szFreqMapping);
if (bstrFreqMapping)
{
hr = pIDVBTuningSpace->put_FrequencyMapping(bstrFreqMapping); // not used
SysFreeString(bstrFreqMapping);
}
// set the Friendly Name of the network type, shown as Name in the registry
hr = pIDVBTuningSpace->put_UniqueName(pNetworkType);
if (FAILED(hr))
{
OutputDebugString(TEXT("BDASample: put_FriendlyName failed\n"));
return hr;
}
// set the System type to terrestrial
hr = pIDVBTuningSpace->put_SystemType(DVB_Terrestrial);
if (FAILED(hr))
{
OutputDebugString(TEXT("BDASample: put_SystemType failed\n"));
return hr;
}
// set the Network Type to DVBT
CComBSTR clsid_dvbt = ("{216C62DF-6D7F-4e9a-8571-05F14EDB766A}");
hr = pIDVBTuningSpace->put_NetworkType(clsid_dvbt);
if (FAILED(hr))
{
OutputDebugString(TEXT("BDASample: put_NetworkType failed\n"));
return hr;
}
// set the Friendly Name, shown as Description in the registry
WCHAR szFriendlyName[ 8 ]=L"UK DVBT";
BSTR bstrFriendlyName = SysAllocString(szFriendlyName);
if (bstrFriendlyName)
{
hr = pIDVBTuningSpace->put_FriendlyName(bstrFriendlyName);
SysFreeString(bstrFriendlyName);
}
// create DVBT Locator
CComPtr <IDVBTLocator> pIDVBTLocator;
hr = CoCreateInstance(CLSID_DVBTLocator,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDVBTLocator,
reinterpret_cast<void**>(&pIDVBTLocator));
if (FAILED(hr) || !pIDVBTLocator)
{
// ErrorMessageBox(TEXT("BDASample: Failed to create system locator."));
return hr;
}
// NOTE: The below parameter with the exception of
// setting the carrier frequency don't need to set.
// Thus they are set to -1. The demodulator can
// handle these parameters without having to specifically
// set them in the hardware.
// set the Carrier Frequency
hr = pIDVBTLocator->put_CarrierFrequency(m_ulCarrierFrequency);
// set the Bandwidth
hr = pIDVBTLocator->put_Bandwidth(-1); // not used
// set the Low Priority FEC type
hr = pIDVBTLocator->put_LPInnerFEC(BDA_FEC_METHOD_NOT_SET); // not used
// set the Low Priority code rate
hr = pIDVBTLocator->put_LPInnerFECRate(BDA_BCC_RATE_NOT_SET); // not used
// set the hieriarcy alpha
hr = pIDVBTLocator->put_HAlpha(BDA_HALPHA_NOT_SET); // not used
// set the guard interval
hr = pIDVBTLocator->put_Guard(BDA_GUARD_NOT_SET); // not used
// set the transmission mode/FFT
hr = pIDVBTLocator->put_Mode(BDA_XMIT_MODE_NOT_SET); // not used
// set whether the frequency is being used by another DVB-T broadcaster
hr = pIDVBTLocator->put_OtherFrequencyInUse(VARIANT_BOOL(FALSE)); // not used
// set the inner FEC type
hr = pIDVBTLocator->put_InnerFEC(BDA_FEC_METHOD_NOT_SET); // not used
// set the inner code rate
hr = pIDVBTLocator->put_InnerFECRate(BDA_BCC_RATE_NOT_SET); // not used
// set the outer FEC type
hr = pIDVBTLocator->put_OuterFEC(BDA_FEC_METHOD_NOT_SET); // not used
// set the outer code rate
hr = pIDVBTLocator->put_OuterFECRate(BDA_BCC_RATE_NOT_SET); // not used
// set the modulation type
hr = pIDVBTLocator->put_Modulation(BDA_MOD_NOT_SET); // not used
// set the symbol rate
hr = pIDVBTLocator->put_SymbolRate(-1); // not used
// set this a default locator
hr = pIDVBTuningSpace->put_DefaultLocator(pIDVBTLocator);
// create a tuning space container for the values we just set
// so we can create in the registry.
CComPtr <ITuningSpaceContainer> pTunerSpaceContainer;
hr = CoCreateInstance(CLSID_SystemTuningSpaces,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITuningSpaceContainer,
reinterpret_cast<void**>(&pTunerSpaceContainer));
if (FAILED(hr) || !pTunerSpaceContainer)
{
// ErrorMessageBox(TEXT("BDASample: Failed to create tuning space container"));
return hr;
}
// get the number of tuning spaces that have been created
LONG lCount;
hr = pTunerSpaceContainer->get_Count(&lCount);
if (FAILED(hr))
{
//ErrorMessageBox(TEXT("BDASample: get_Count failed"));
return hr;
}
// add the tuning spacing container values to the registry
CComVariant varIndex(lCount+1);
hr = pTunerSpaceContainer->Add(pIDVBTuningSpace, &varIndex);
if (FAILED(hr))
{
//ErrorMessageBox(TEXT("BDASample: Failed to add new tuning space to registry"));
return hr;
}
// create a copy of this tuning space for the
// class member variable.
hr = pIDVBTuningSpace->Clone(&m_pITuningSpace);
if (FAILED(hr))
{
//ErrorMessageBox(TEXT("BDASample: Clone failed"));
m_pITuningSpace = NULL;
return hr;
}
pIDVBTuningSpace = NULL;
pIDVBTLocator = NULL;
pTunerSpaceContainer = NULL;
return hr;
}
HRESULT LoadTuningSpace(CComBSTR pNetworkType)
{
HRESULT hr;
ITuningSpace* pTuningSpace = NULL;
IEnumTuningSpaces* pEnumTuningSpaces = NULL;
ITuningSpace** pTuningSpaceArray = NULL;
long lCount = 0;
ULONG ulNumFetched = 0, i = 0;
CComBSTR bstrTemp;
OutputDebugString(TEXT("BDASample: CBDAFilterGraph:oadTuningSpace\n"));
// Get the tuning space collection
hr = CoCreateInstance(CLSID_SystemTuningSpaces, NULL,
CLSCTX_INPROC_SERVER, IID_ITuningSpaceContainer,
reinterpret_cast<void**>(&m_pTuningSpaceContainer));
if (FAILED(hr))
{
//ErrorMessageBox(TEXT("Failed to create system tuning space."));
return hr;
}
// Find the tuning space in the collection
hr = m_pTuningSpaceContainer->get_EnumTuningSpaces(&pEnumTuningSpaces);
if (FAILED(hr))
{
//ErrorMessageBox(TEXT("Failed to get tuning space enumerator."));
return hr;
}
hr = m_pTuningSpaceContainer->get_Count(&lCount);
if (FAILED(hr))
{
//ErrorMessageBox(TEXT("Failed to enumerate tuning spaces."));
return hr;
}
// Read tuning space info into allocated array
pTuningSpaceArray = new ITuningSpace*[lCount];
hr = pEnumTuningSpaces->Next(lCount, pTuningSpaceArray, &ulNumFetched);
if (FAILED(hr))
{
//ErrorMessageBox(TEXT("Failed to read tuning spaces."));
return hr;
}
pEnumTuningSpaces = NULL;
// Find the tuning space
for (i = 0; i < ulNumFetched; i++)
{
hr = pTuningSpaceArray->get_UniqueName(&bstrTemp);
if (FAILED(hr))
{
return hr;
}
// Is this the correct tuning space?
if (bstrTemp == pNetworkType)
{
hr = pTuningSpaceArray->Clone(&pTuningSpace);
break;
}
}
pTuningSpaceArray = NULL;
if (pTuningSpace == NULL)
{
return E_FAIL;
}
// QI for IDVBTuningSpace
hr = pTuningSpace->QueryInterface(IID_IDVBTuningSpace, reinterpret_cast<void**>(&m_pITuningSpace));
if (FAILED(hr))
{
return hr;
}
pTuningSpace = NULL;
delete pTuningSpaceArray;
return hr;
}
//判断是否有信号的函数
BOOL GetDemodLocked(BOOL* pDemodLocked)
{
if ( !m_KsDemodPropSet )
{
return FALSE;
}
HRESULT hr;
ULONG ulBytesReturned;
BOOL bDemodLocked;
DWORD type_support = 0;
// See if a demod. property set is supported
hr = m_KsDemodPropSet->QuerySupported(KSPROPSETID_BdaSignalStats,
KSPROPERTY_BDA_SIGNAL_LOCKED,
&type_support);
if (FAILED(hr))
{
return FALSE;
}
if (type_support & KSPROPERTY_SUPPORT_GET)
{
KSPROPERTY instance_data;
instance_data.Id = KSPROPERTY_BDA_SIGNAL_LOCKED;
// make call into driver
hr = m_KsDemodPropSet->Get(KSPROPSETID_BdaSignalStats,
KSPROPERTY_BDA_SIGNAL_LOCKED,
&instance_data, sizeof(instance_data),
&bDemodLocked, sizeof(bDemodLocked),
&ulBytesReturned);
if (FAILED(hr))
{
return FALSE;
}
}
else
{
return FALSE;
}
*pDemodLocked = bDemodLocked;
return TRUE;
}
这是比较完整的代码,构建Filter Graph成功,Run也成功,就是接收不到频道信息以及节目数据??????? |
|