⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bdagraph.cpp

📁 VLC Player Source Code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                return hr;            }            hr = p_tuning_space->CreateTuneRequest( &p_tune_request );            if( FAILED( hr ) )            {                msg_Warn( p_access, "CreateTuneRequest: "\                    "Cannot Create Tune Request: hr=0x%8lx", hr );                return hr;            }            return hr;        }    }    hr = E_FAIL;    if( FAILED( hr ) )    {        msg_Warn( p_access, "CreateTuneRequest: "\            "Cannot find a suitable System Tuning Space: hr=0x%8lx", hr );        return hr;    }    return hr;}/******************************************************************************* Build* Step 4: Build the Filter Graph* Build sets up devices, adds and connects filters******************************************************************************/HRESULT BDAGraph::Build(){    HRESULT hr = S_OK;    long l_capture_used, l_tif_used;    AM_MEDIA_TYPE grabber_media_type;    /* If we have already have a filter graph, rebuild it*/    Destroy();    hr = ::CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC,        IID_IGraphBuilder, (void**)&p_filter_graph );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot CoCreate IFilterGraph: hr=0x%8lx", hr );        return hr;    }    /* First filter in the graph is the Network Provider and     * its Scanning Tuner which takes the Tune Request*/    hr = ::CoCreateInstance( guid_network_type, NULL, CLSCTX_INPROC_SERVER,        IID_IBaseFilter, (void**)&p_network_provider);    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot CoCreate Network Provider: hr=0x%8lx", hr );        return hr;    }    hr = p_filter_graph->AddFilter( p_network_provider, L"Network Provider" );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot load network provider: hr=0x%8lx", hr );        return hr;    }    hr = p_network_provider->QueryInterface( IID_IScanningTuner,        (void**)&p_scanning_tuner );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot QI Network Provider for Scanning Tuner: hr=0x%8lx", hr );        return hr;    }    hr = p_scanning_tuner->Validate( p_tune_request );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Tune Request is invalid: hr=0x%8lx", hr );        return hr;    }    hr = p_scanning_tuner->put_TuneRequest( p_tune_request );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot submit the tune request: hr=0x%8lx", hr );        return hr;    }    /* Add the Network Tuner to the Network Provider. On subsequent calls,     * l_tuner_used will cause a different tuner to be selected */    hr = FindFilter( KSCATEGORY_BDA_NETWORK_TUNER, &l_tuner_used,        p_network_provider, &p_tuner_device );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot load tuner device and connect network provider: "\            "hr=0x%8lx", hr );        return hr;    }    /* Always look for all capture devices to match the Network Tuner */    l_capture_used = -1;    hr = FindFilter( KSCATEGORY_BDA_RECEIVER_COMPONENT, &l_capture_used,        p_tuner_device, &p_capture_device );    if( FAILED( hr ) )    {        /* Some BDA drivers do not provide a Capture Device Filter so force         * the Sample Grabber to connect directly to the Tuner Device */        p_capture_device = p_tuner_device;        p_tuner_device = NULL;        msg_Warn( p_access, "Build: "\            "Cannot find Capture device. Connecting to tuner: hr=0x%8lx", hr );    }    /* Insert the Sample Grabber to tap into the Transport Stream. */    hr = ::CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,        IID_IBaseFilter, (void**)&p_sample_grabber );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot load Sample Grabber Filter: hr=0x%8lx", hr );        return hr;    }    hr = p_filter_graph->AddFilter( p_sample_grabber, L"Sample Grabber" );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot add Sample Grabber Filter to graph: hr=0x%8lx", hr );        return hr;    }    hr = p_sample_grabber->QueryInterface( IID_ISampleGrabber,        (void**)&p_grabber );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot QI Sample Grabber Filter: hr=0x%8lx", hr );        return hr;    }    ZeroMemory( &grabber_media_type, sizeof( AM_MEDIA_TYPE ) );    grabber_media_type.majortype == MEDIATYPE_Stream;    grabber_media_type.subtype == MEDIASUBTYPE_MPEG2_TRANSPORT;    hr = p_grabber->SetMediaType( &grabber_media_type );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot set media type on grabber filter: hr=0x%8lx", hr );        return hr;    }    hr = Connect( p_capture_device, p_sample_grabber );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot connect Sample Grabber to Capture device: hr=0x%8lx", hr );        return hr;    }    /* We need the MPEG2 Demultiplexer even though we are going to use the VLC     * TS demuxer. The TIF filter connects to the MPEG2 demux and works with     * the Network Provider filter to set up the stream */    hr = ::CoCreateInstance( CLSID_MPEG2Demultiplexer, NULL,        CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&p_mpeg_demux );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot CoCreateInstance MPEG2 Demultiplexer: hr=0x%8lx", hr );        return hr;    }    hr = p_filter_graph->AddFilter( p_mpeg_demux, L"Demux" );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot add demux filter to graph: hr=0x%8lx", hr );        return hr;    }    hr = Connect( p_sample_grabber, p_mpeg_demux );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot connect demux to grabber: hr=0x%8lx", hr );        return hr;    }    /* Always look for the Transform Information Filter from the start     * of the collection*/    l_tif_used = -1;    hr = FindFilter( KSCATEGORY_BDA_TRANSPORT_INFORMATION, &l_tif_used,        p_mpeg_demux, &p_transport_info );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot load TIF onto demux: hr=0x%8lx", hr );        return hr;    }    /* Configure the Sample Grabber to buffer the samples continuously */    hr = p_grabber->SetBufferSamples( TRUE );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot set Sample Grabber to buffering: hr=0x%8lx", hr );        return hr;    }    hr = p_grabber->SetOneShot( FALSE );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot set Sample Grabber to multi shot: hr=0x%8lx", hr );        return hr;    }    hr = p_grabber->SetCallback( this, 0 );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot set SampleGrabber Callback: hr=0x%8lx", hr );        return hr;    }    hr = Register();    if( FAILED( hr ) )    {        d_graph_register = 0;    }    /* The Media Control is used to Run and Stop the Graph */    hr = p_filter_graph->QueryInterface( IID_IMediaControl,        (void**)&p_media_control );    if( FAILED( hr ) )    {        msg_Warn( p_access, "Build: "\            "Cannot QI Media Control: hr=0x%8lx", hr );        return hr;    }    return hr;}/******************************************************************************* FindFilter* Looks up all filters in a category and connects to the upstream filter until* a successful match is found. The index of the connected filter is returned.* On subsequent calls, this can be used to start from that point to find* another match.* This is used when the graph does not run because a tuner device is in use so* another one needs to be slected.******************************************************************************/HRESULT BDAGraph::FindFilter( REFCLSID clsid, long* i_moniker_used,    IBaseFilter* p_upstream, IBaseFilter** p_p_downstream ){    HRESULT                 hr = S_OK;    int                     i_moniker_index = -1;    class localComPtr    {        public:        IMoniker*      p_moniker;        IEnumMoniker*  p_moniker_enum;        IBaseFilter*   p_filter;        IPropertyBag*  p_property_bag;        VARIANT        var_bstr;        localComPtr():            p_moniker(NULL),            p_moniker_enum(NULL),            p_filter(NULL),            p_property_bag(NULL)            { ::VariantInit(&var_bstr); };        ~localComPtr()        {            if( p_moniker )                p_moniker->Release();            if( p_moniker_enum )                p_moniker_enum->Release();            if( p_filter )                p_filter->Release();            if( p_property_bag )                p_property_bag->Release();            ::VariantClear(&var_bstr);        }    } l;    if( !p_system_dev_enum )    {        hr = ::CoCreateInstance( CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC,            IID_ICreateDevEnum, (void**)&p_system_dev_enum );        if( FAILED( hr ) )        {            msg_Warn( p_access, "FindFilter: "\                "Cannot CoCreate SystemDeviceEnum: hr=0x%8lx", hr );            return hr;        }    }    hr = p_system_dev_enum->CreateClassEnumerator( clsid,        &l.p_moniker_enum, 0 );    if( hr != S_OK )    {        msg_Warn( p_access, "FindFilter: "\            "Cannot CreateClassEnumerator: hr=0x%8lx", hr );        return E_FAIL;    }    while( l.p_moniker_enum->Next( 1, &l.p_moniker, 0 ) == S_OK )    {        i_moniker_index++;        /* Skip over devices already found on previous calls */        if( i_moniker_index <= *i_moniker_used ) continue;        *i_moniker_used = i_moniker_index;        hr = l.p_moniker->BindToObject( NULL, NULL, IID_IBaseFilter,            (void**)&l.p_filter );        if( FAILED( hr ) )        {            if( l.p_moniker )                l.p_moniker->Release();            l.p_moniker = NULL;            if( l.p_filter)                 l.p_filter->Release();            l.p_filter = NULL;            continue;        }        hr = l.p_moniker->BindToStorage( NULL, NULL, IID_IPropertyBag,            (void**)&l.p_property_bag );        if( FAILED( hr ) )        {            msg_Warn( p_access, "FindFilter: "\                "Cannot Bind to Property Bag: hr=0x%8lx", hr );            return hr;        }        hr = l.p_property_bag->Read( L"FriendlyName", &l.var_bstr, NULL );        if( FAILED( hr ) )        {            msg_Warn( p_access, "FindFilter: "\                "Cannot read filter friendly name: hr=0x%8lx", hr );            return hr;        }        hr = p_filter_graph->AddFilter( l.p_filter, l.var_bstr.bstrVal );        if( FAILED( hr ) )        {            msg_Warn( p_access, "FindFilter: "\                "Cannot add filter: hr=0x%8lx", hr );            return hr;        }        hr = Connect( p_upstream, l.p_filter );        if( SUCCEEDED( hr ) )        {            msg_Dbg( p_access, "FindFilter: Connected %S", l.var_bstr.bstrVal );            l.p_filter->QueryInterface( IID_IBaseFilter,                (void**)p_p_downstream );            return S_OK;        }        /* Not the filter we want so unload and try the next one */        hr = p_filter_graph->RemoveFilter( l.p_filter );        if( FAILED( hr ) )        {            msg_Warn( p_access, "FindFilter: "\                "Failed unloading Filter: hr=0x%8lx", hr );            return hr;        }        if( l.p_moniker )            l.p_moniker->Release();        l.p_moniker = NULL;        if( l.p_filter)            l.p_filter->Release();        l.p_filter = NULL;    }    hr = E_FAIL;    msg_Warn( p_access, "FindFilter: No filter connected: hr=0x%8lx", hr );    return hr;}/*****************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -