【问题标题】:How to access to BDA device such as usb tv tuner card如何访问 USB 电视调谐器卡等 BDA 设备
【发布时间】:2016-09-01 08:17:23
【问题描述】:

我正在使用 Windows 10 并希望从我的电视调谐器 USB 设备访问视频流。

首先,我尝试使用媒体基础 api,经过多次搜索后才知道该 API 不支持电视调谐器卡。

然后我切换到 directshow 但枚举视频设备并没有列出我的电视调谐器设备。仅列出了我的网络摄像头。我发现我应该使用过滤器和引脚,但没有此类操作的指南。

任何帮助、建议或示例都会有所帮助。

谢谢。

K

【问题讨论】:

    标签: c++ directshow


    【解决方案1】:

    这个周末我正在解决同样的问题 :-)。我想做一个简单的电视调谐器/播放器。直接展示似乎是开发的最后一部分,因为您必须从 USB 加密狗获取数据。

    我搜索了很多,但正如您所写,不幸的是几乎没有指南。但是,我认为,您可以从 MS 页面开始 - Microsoft TV Technologies: https://msdn.microsoft.com/en-us/library/windows/desktop/dd695086%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 并专注于统一调优模型,这导致了微软统一调优模型,其中有一些提示,如何操作。然而,关于代码和细节的例子,我闭口不谈……这是基于带有 OLE 的 MFC(我对这项技术很陌生)。

    目前,我正在研究部分 Tuning Spaces,不幸的是,有一些陷阱,如注册表权限(我还没有解决这个问题)。 稍后,您应该在编写时了解有关过滤器和引脚的知识。见https://msdn.microsoft.com/en-us/library/dd377601(v=vs.85).aspx。 不幸的是,我不知道如何为 DVB-T 创建图表。无论如何,在我的开发中。使用 Win 10 的桌面,当我打开 Direct Show Filters 时,GraphEdit 崩溃(可能与 DVB-T HW 的当前 SW 崩溃的原因相同)。我发现了一个有趣的博客,带有替代图形编辑器: https://en.wikipedia.org/wiki/GraphStudio - 检查外部链接。较新的 GraphStudioNext 看起来也很有希望(我还没有尝试过)。

    这是我刚开始的方式,如果您仍然感兴趣,希望对您有所帮助。如果您有更多经验,欢迎提出任何建议! :-)

    我的测试代码(还不能正常工作!)如下。灵感来自ITuner::put_TuneRequest() call ignored

    hCo = CoInitializeEx(nullptr, COINIT::COINIT_APARTMENTTHREADED);
    
    if (hCo == S_OK)
    {
        IErrorInfo* pIErrorInfo = nullptr;
        HRESULT hr = S_FALSE;
    
        // Create the SystemTuningSpaces container.
        PQTuningSpaceContainer pTuningSpaceContainer; // PQTuningSpaceContaineris typedef of CComQIPtr<ITuningSpace
        hr = pTuningSpaceContainer.CoCreateInstance(__uuidof(SystemTuningSpaces));
        if (SUCCEEDED(hr))
        {
            // Get the enumerator for the collection.
            CComPtr<IEnumTuningSpaces> pTuningSpaceEnum;
            hr = pTuningSpaceContainer->get_EnumTuningSpaces(&pTuningSpaceEnum);
            if (SUCCEEDED(hr))
            {
                // Loop through the collection.
                PQTuningSpace pTuningSpace;
                while (S_OK == pTuningSpaceEnum->Next(1, &pTuningSpace, nullptr))
                {
                    BSTR bstrDVBValue;
                    pTuningSpace->get_UniqueName(&bstrDVBValue);
                    printf("%S\n", bstrDVBValue);
                    pTuningSpace->get_FriendlyName(&bstrDVBValue);
                    printf("%S\n", bstrDVBValue);
                    pTuningSpace->get_NetworkType(&bstrDVBValue);
                    printf("%S\n\n", bstrDVBValue);
                    // pTuningSpace points to the next tuning space.
                    // You can query this pointer for derived interfaces.
                    pTuningSpace.Release();
                }
            }
        }
    
        PQDVBTuningSpace pDVBTuningSpace;
        WCHAR szDVBNameU[64] = L"DVB-T";
        WCHAR szDVBNameF[64] = L"Local DVB-T Digital Antenna";
        // WCHAR szDVBNetworkType[64] = L"{B2F3A67C-29DA-4C78-8831-091ED509A475}";
        WCHAR szDVBNetworkType[64] = L"{216C62DF-6D7F-4e9a-8571-05F14EDB766A}"; // DVB-T Network type
    
        hr = pDVBTuningSpace.CoCreateInstance(__uuidof(DVBTuningSpace));
        if (FAILED(hr))
        {
            printf("Failed to create system tuning spaces object.");
            return;
        }
    
        hr = pDVBTuningSpace->put_SystemType(DVBSystemType::DVB_Terrestrial);
        if (FAILED(hr))
        {
            printf("Failed to put system type of tuning space.");
            return;
        }
    
        hr = pDVBTuningSpace->put_NetworkType(szDVBNetworkType);
        if (FAILED(hr))
        {
            printf("Failed to put network type of tuning space.");
            return;
        }
    
        BSTR bstrDVBNetworkType = SysAllocString(szDVBNetworkType);
        hr = pDVBTuningSpace->put_NetworkType(bstrDVBNetworkType);
        SysFreeString(bstrDVBNetworkType);
        if (FAILED(hr))
        {
            printf("Failed to put network type of tuning space.");
            return;
        }
    
        BSTR bstrDVBName = nullptr;
        bstrDVBName = SysAllocString(szDVBNameU);
        hr = pDVBTuningSpace->put_UniqueName(bstrDVBName);
        SysFreeString(bstrDVBName);
    
        bstrDVBName = SysAllocString(szDVBNameF);
        hr = pDVBTuningSpace->put_FriendlyName(bstrDVBName);
        SysFreeString(bstrDVBName);
    
        if (FAILED(hr))
        {
            printf("Failed to put name of tuning space.");
            return;
        }
    
        PQDVBTLocator pDVBTLocator;
        hr = pDVBTLocator.CoCreateInstance(__uuidof(DVBTLocator));
        hr = pDVBTLocator->put_CarrierFrequency(538000);
        hr = pDVBTLocator->put_Bandwidth(8);
        hr = pDVBTuningSpace->put_DefaultLocator(pDVBTLocator);
        if (FAILED(hr))
        {
            printf("Failed to put locator of tuning space.");
            return;
        }
    
        VARIANT tiIndex = {};
        //PQTuningSpaceContainer pTuningSpaceContainer;
        //hr = pTuningSpaceContainer.CoCreateInstance(__uuidof(SystemTuningSpaces));
        hr = pTuningSpaceContainer->Add(pDVBTuningSpace, &tiIndex); // #fix needed: registry permissions
        if (hr == HRESULT_FROM_WIN32(ERROR_DUP_NAME))
        {
            CComPtr<IEnumTuningSpaces> pTuningSpaceEnum;
            hr = pTuningSpaceContainer->get_EnumTuningSpaces(&pTuningSpaceEnum);
            if (SUCCEEDED(hr))
            {
                // Loop through the collection.
                PQTuningSpace pTuningSpace;
                tiIndex.intVal = 0;
                while (S_OK == pTuningSpaceEnum->Next(1, &pTuningSpace, nullptr))
                {
                    CComBSTR name;
                    hr = pTuningSpace->get_UniqueName(&name);
                    if (SUCCEEDED(hr))
                    {
                        if (name == szDVBNameU)
                        {
                            hr = pTuningSpaceContainer->put_Item(tiIndex, pDVBTuningSpace); // #fix needed: E_INVALIDARG One or more arguments are invalid.
                            break;
                        }
                    }
    
                    tiIndex.intVal++;
                    pTuningSpace.Release();
                }
            }
        }
    
        PQTuneRequest pTuneRequest;
        hr = pDVBTuningSpace->CreateTuneRequest(&pTuneRequest);
        if (FAILED(hr))
        {
            printf("Failed to create tune request.");
            return;
        }
    
        PQDVBTuneRequest pDVBTuneRequest(pTuneRequest);
        if (pDVBTuneRequest) 
        {
            hr = pDVBTuneRequest->put_SID(-1);
            hr = pDVBTuneRequest->put_TSID(-1);
            hr = pDVBTuneRequest->put_ONID(-1);
        }
    
        CComPtr<IGraphBuilder> pGraph;
        hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX::CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
    
        CComPtr<IBaseFilter> pNetworkProvider;
        GUID CLSIDNetworkType;
        hr = pDVBTuningSpace->get__NetworkType(&CLSIDNetworkType);
        hr = CoCreateInstance(CLSIDNetworkType, NULL, CLSCTX::CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pNetworkProvider);
        hr = pGraph->AddFilter(pNetworkProvider, L"Network Provider");
    
        //// Query for ITuner.
        CComQIPtr<ITuner> pTuner(pNetworkProvider);
        if (pTuner) 
        {
            // Submit the tune request to the network provider.
            hr = pTuner->put_TuneRequest(pTuneRequest);
        }
    
        // TODO: What next???
    
        CoUninitialize();
    

    编辑:

    这会很有帮助: https://github.com/dgis/CodeTV (检查并为我工作)

    【讨论】:

    • 感谢您提供所有这些信息。我会试试看的。
    猜你喜欢
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2014-04-18
    相关资源
    最近更新 更多