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

📄 graph.cpp

📁 非常有用的VC视频音频开发所需要的东西 需要有用
💻 CPP
📖 第 1 页 / 共 3 页
字号:
CBDAFilterGraph::LoadFilter(
    REFCLSID clsid, 
    IBaseFilter** ppFilter,
    IBaseFilter* pConnectFilter, 
    BOOL fIsUpstream
    )
{
    HRESULT                 hr = S_OK;
    BOOL                    fFoundFilter = FALSE;
    CComPtr <IMoniker>      pIMoniker;
    CComPtr <IEnumMoniker>  pIEnumMoniker;

    if (!m_pICreateDevEnum)
    {
        hr = m_pICreateDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum);
        if (FAILED (hr))
        {
            ErrorMessageBox(TEXT("LoadFilter(): Cannot CoCreate ICreateDevEnum"));
            return hr;
        }
    }

    // obtain the enumerator
    hr = m_pICreateDevEnum->CreateClassEnumerator(clsid, &pIEnumMoniker, 0);
    // the call can return S_FALSE if no moniker exists, so explicitly check S_OK
    if (FAILED (hr))
    {
        ErrorMessageBox(TEXT("LoadFilter(): Cannot CreateClassEnumerator"));
        return hr;
    }
    if (S_OK != hr)  // Class not found
    {
        ErrorMessageBox(TEXT("LoadFilter(): Class not found, CreateClassEnumerator returned S_FALSE"));
        return E_UNEXPECTED;
    }

    // next filter
    while(pIEnumMoniker->Next(1, &pIMoniker, 0) == S_OK)
    {
        // obtain filter's friendly name
        CComPtr <IPropertyBag>  pBag;
        hr = pIMoniker->BindToStorage(
                                    NULL, 
                                    NULL, 
                                    IID_IPropertyBag,
                                    reinterpret_cast<void**>(&pBag)
                                    );

        if(FAILED(hr))
        {
            OutputDebugString (TEXT("LoadFilter(): Cannot BindToStorage"));
            return hr;
        }

        CComVariant varBSTR;
        hr = pBag->Read(L"FriendlyName", &varBSTR, NULL);
        if(FAILED(hr))
        {
            OutputDebugString (TEXT("LoadFilter(): IPropertyBag->Read method failed"));
            pIMoniker = NULL;
            continue;
        }

        // bind the filter
        CComPtr <IBaseFilter>   pFilter;
        hr = pIMoniker->BindToObject(
                                    NULL, 
                                    NULL, 
                                    IID_IBaseFilter,
                                    reinterpret_cast<void**>(&pFilter)
                                    );

        if (FAILED(hr))
        {
            pIMoniker = NULL;
            pFilter = NULL;
            continue;
        }


        hr = m_pFilterGraph->AddFilter (pFilter, varBSTR.bstrVal);

        if (FAILED(hr))
        {
            OutputDebugString (TEXT("Cannot add filter\n"));
            return hr;
        }

        //MessageBox (NULL, _T(""), _T(""), MB_OK);
        // test connections
        // to upstream filter
        if (pConnectFilter)
        {
            if(fIsUpstream)
            {
                hr = ConnectFilters (pConnectFilter, pFilter);
            }
            else
            {
                hr = ConnectFilters (pFilter, pConnectFilter);
            }

            if(SUCCEEDED(hr))
            {
                //that's the filter we want
                fFoundFilter = TRUE;
                pFilter.QueryInterface (ppFilter);
                break;
            }
            else
            {
                fFoundFilter = FALSE;
                // that wasn't the the filter we wanted
                // so unload and try the next one
                hr = m_pFilterGraph->RemoveFilter(pFilter);

                if(FAILED(hr))
                {
                    OutputDebugString(TEXT("Failed unloading Filter\n"));
                    return hr;
                }
            }
        }
        else
        {
            fFoundFilter = TRUE;
            pFilter.QueryInterface (ppFilter);
            break;
        }

        pIMoniker = NULL;
        pFilter = NULL;
    } // while
    return S_OK;
}


// loads the demux into the FilterGraph
HRESULT
CBDAFilterGraph::LoadDemux()
{
    HRESULT hr = S_OK;
    
    hr = CoCreateInstance(
                        CLSID_MPEG2Demultiplexer, 
                        NULL, 
                        CLSCTX_INPROC_SERVER,
                        IID_IBaseFilter, 
                        reinterpret_cast<void**>(&m_pDemux)
                        );
    if (FAILED (hr))
    {
        ErrorMessageBox(TEXT("Could not CoCreateInstance CLSID_MPEG2Demultiplexer\n"));
        return hr;
    }

    hr = m_pFilterGraph->AddFilter(m_pDemux, L"Demux");
    if(FAILED(hr))
    {
        ErrorMessageBox(TEXT("Unable to add demux filter to graph\n"));
        return hr;
    }

    return hr;
}


// renders demux output pins
HRESULT
CBDAFilterGraph::RenderDemux()
{
    HRESULT             hr = S_OK;
    CComPtr <IPin>      pIPin;
    CComPtr <IPin>      pDownstreamPin;
    CComPtr <IEnumPins> pIEnumPins;
    PIN_DIRECTION       direction;

    if (!m_pDemux)
    {
        return E_FAIL;
    }

    // connect the demux to the capture device
    hr = ConnectFilters (m_pCaptureDevice, m_pDemux);

    if (FAILED (hr))
    {
        ErrorMessageBox(TEXT("Cannot connect demux to capture filter\n"));
        return hr;
    }

    // load transform information filter and connect it to the demux
    hr = LoadFilter (
                    KSCATEGORY_BDA_TRANSPORT_INFORMATION, 
                    &m_pTIF, 
                    m_pDemux, 
                    TRUE
                    );
    if (FAILED (hr))
    {
        ErrorMessageBox(TEXT("Cannot load TIF\n"));
        return hr;
    }

    // load multi protocol encapsulator
    hr = LoadFilter (
                    KSCATEGORY_BDA_RECEIVER_COMPONENT, 
                    &m_pMPE, 
                    m_pDemux, 
                    TRUE
                    );
    if (FAILED (hr))
    {
        ErrorMessageBox(TEXT("Cannot load MPE\n"));
        return hr;
    }

    // load IP Sink
    hr = LoadFilter (
                    KSCATEGORY_IP_SINK, 
                    &m_pIPSink, 
                    m_pMPE, 
                    TRUE
                    );
    if (FAILED (hr))
    {
        ErrorMessageBox(TEXT("Cannot load IP Sink\n"));
        return hr;
    }

    // render/connect the rest of the demux pins
    hr = m_pDemux->EnumPins (&pIEnumPins);
    if (FAILED (hr))
    {
        ErrorMessageBox(TEXT("Cannot get the enumpins\n"));
        return hr;
    }

    while(pIEnumPins->Next(1, &pIPin, 0) == S_OK)
    {
        hr = pIPin->QueryDirection(&direction);

        if(direction == PINDIR_OUTPUT)
        {
            pIPin->ConnectedTo (&pDownstreamPin);

            if(pDownstreamPin == NULL)
            {
                m_pFilterGraph->Render (pIPin);
            }

            pDownstreamPin = NULL;
        }
        pIPin = NULL;
    }

    return hr;
}


// removes each filter from the graph
HRESULT
CBDAFilterGraph::TearDownGraph()
{
    HRESULT hr = S_OK;
    CComPtr <IBaseFilter> pFilter;
    CComPtr <IEnumFilters> pIFilterEnum;

    m_pITuningSpace = NULL;

    if(m_fGraphBuilt || m_fGraphFailure)
    {
        // unload manually added filters
        m_pFilterGraph->RemoveFilter(m_pIPSink);
        m_pFilterGraph->RemoveFilter(m_pMPE);
        m_pFilterGraph->RemoveFilter(m_pTIF);
        m_pFilterGraph->RemoveFilter(m_pDemux);
        m_pFilterGraph->RemoveFilter(m_pNetworkProvider);
        m_pFilterGraph->RemoveFilter(m_pTunerDevice);
        m_pFilterGraph->RemoveFilter(m_pCaptureDevice);

        m_pIPSink = NULL;
        m_pMPE = NULL;
        m_pTIF = NULL;
        m_pDemux = NULL;
        m_pNetworkProvider = NULL;
        m_pTunerDevice = NULL;
        m_pDemodulatorDevice = NULL;
        m_pCaptureDevice = NULL;

        // now go unload rendered filters
        hr = m_pFilterGraph->EnumFilters(&pIFilterEnum);

        if(FAILED(hr))
        {
            ErrorMessageBox(TEXT("TearDownGraph: cannot EnumFilters\n"));
            return E_FAIL;
        }

        pIFilterEnum->Reset();

        while(pIFilterEnum->Next(1, &pFilter, 0) == S_OK) // addrefs filter
        {
            hr = m_pFilterGraph->RemoveFilter(pFilter);

            if (FAILED (hr))
                return hr;

            pIFilterEnum->Reset();
            pFilter.Release ();
        }
    }

#ifdef REGISTER_FILTERGRAPH
    if (m_dwGraphRegister)
    {
        RemoveGraphFromRot(m_dwGraphRegister);
        m_dwGraphRegister = 0;
    }
#endif

    m_fGraphBuilt = FALSE;
    return S_OK;
}


// ConnectFilters is called from BuildGraph
// to enumerate and connect pins
HRESULT
CBDAFilterGraph::ConnectFilters(
    IBaseFilter* pFilterUpstream, 
    IBaseFilter* pFilterDownstream
    )
{
    HRESULT         hr = E_FAIL;

    CComPtr <IPin>  pIPinUpstream;


    PIN_INFO        PinInfoUpstream;
    PIN_INFO        PinInfoDownstream;

    // validate passed in filters
    ASSERT (pFilterUpstream);
    ASSERT (pFilterDownstream);

    // grab upstream filter's enumerator
    CComPtr <IEnumPins> pIEnumPinsUpstream;
    hr = pFilterUpstream->EnumPins(&pIEnumPinsUpstream);

    if(FAILED(hr))
    {
        ErrorMessageBox(TEXT("Cannot Enumerate Upstream Filter's Pins\n"));
        return hr;
    }

    // iterate through upstream filter's pins
    while (pIEnumPinsUpstream->Next (1, &pIPinUpstream, 0) == S_OK)
    {
        hr = pIPinUpstream->QueryPinInfo (&PinInfoUpstream);
        if(FAILED(hr))
        {
            ErrorMessageBox(TEXT("Cannot Obtain Upstream Filter's PIN_INFO\n"));
            return hr;
        }

        CComPtr <IPin>  pPinDown;
        pIPinUpstream->ConnectedTo (&pPinDown);

        // bail if pins are connected
        // otherwise check direction and connect
        if ((PINDIR_OUTPUT == PinInfoUpstream.dir) && (pPinDown == NULL))
        {
            // grab downstream filter's enumerator
            CComPtr <IEnumPins> pIEnumPinsDownstream;
            hr = pFilterDownstream->EnumPins (&pIEnumPinsDownstream);
            if(FAILED(hr))
            {
                ErrorMessageBox(TEXT("Cannot enumerate pins on downstream filter!\n"));
                return hr;
            }

            // iterate through downstream filter's pins
            CComPtr <IPin>  pIPinDownstream;
            while (pIEnumPinsDownstream->Next (1, &pIPinDownstream, 0) == S_OK)
            {
                // make sure it is an input pin
                hr = pIPinDownstream->QueryPinInfo(&PinInfoDownstream);
                if(SUCCEEDED(hr))
                {
                    CComPtr <IPin>  pPinUp;

                    // Determine if the pin is already connected.  Note that 
                    // VFW_E_NOT_CONNECTED is expected if the pin isn't yet connected.
                    hr = pIPinDownstream->ConnectedTo (&pPinUp);
                    if(FAILED(hr) && hr != VFW_E_NOT_CONNECTED)
                    {
                        ErrorMessageBox(TEXT("Failed in pIPinDownstream->ConnectedTo()!\n"));
                        continue;
                    }

                    if ((PINDIR_INPUT == PinInfoDownstream.dir) && (pPinUp == NULL))
                    {
                        if (SUCCEEDED (m_pFilterGraph->Connect(
                                        pIPinUpstream,
                                        pIPinDownstream))
                                        )
                        {
                            PinInfoDownstream.pFilter->Release();
                            PinInfoUpstream.pFilter->Release();
                            return S_OK;
                        }
                    }
                }

                PinInfoDownstream.pFilter->Release();

⌨️ 快捷键说明

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