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

📄 crossbar.cpp

📁 通用摄像头驱动的应用程序部分
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
// File: Crossbar.cpp
//
// Desc: A class for controlling video crossbars. 
//
//       This class creates a single object which encapsulates all connected
//       crossbars, enumerates all unique inputs which can be reached from
//       a given starting pin, and automatically routes audio when a video
//       source is selected.
//
//       The class supports an arbitrarily complex graph of crossbars, 
//       which can be cascaded and disjoint, that is not all inputs need 
//       to traverse the same set of crossbars.
//
//       Given a starting input pin (typically the analog video input to
//       the capture filter), the class recursively traces upstream 
//       searching for all viable inputs.  An input is considered viable if
//       it is a video pin and is either:
//
//           - unconnected 
//           - connects to a filter which does not support IAMCrossbar 
//
//       Methods:
//
//       CCrossbar (IPin *pPin);             
//       ~CCrossbar();
//
//       HRESULT GetInputCount (LONG *pCount);
//       HRESULT GetInputType  (LONG Index, LONG * PhysicalType);
//       HRESULT GetInputName  (LONG Index, TCHAR * pName, LONG NameSize);
//       HRESULT SetInputIndex (LONG Index);
//       HRESULT GetInputIndex (LONG *Index);
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------

#include <streams.h>

#include "crossbar.h"


//------------------------------------------------------------------------------
// Name: CCrossbar::CCrossbar()
// Desc: Constructor for the CCrossbar class
//------------------------------------------------------------------------------
CCrossbar::CCrossbar(
        IPin *pStartingInputPin,
        HRESULT *phr
    ) 
    : m_pStartingPin (pStartingInputPin)
    , m_CurrentRoutingIndex (0)
    , m_RoutingList (NULL)

{
    HRESULT hr;
    ASSERT(phr);

    DbgLog((LOG_TRACE,3,TEXT("CCrossbar Constructor")));

    ASSERT (pStartingInputPin != NULL);

    // Init everything to zero
    ZeroMemory (&m_RoutingRoot, sizeof (m_RoutingRoot));

    m_RoutingList = new CRoutingList (TEXT("RoutingList"), 5);

    if (m_RoutingList)
        hr = BuildRoutingList(pStartingInputPin, &m_RoutingRoot, 0 /* Depth */);
    else
        hr = E_OUTOFMEMORY;

    // Return an error/success code from the constructor        
    if (phr)
        *phr = hr;
}


//------------------------------------------------------------------------------
// Name: CCrossbar::CCrossbar()
// Desc: Destructor for the CCrossbar class
//------------------------------------------------------------------------------
CCrossbar::~CCrossbar()
{
    DbgLog((LOG_TRACE,3,TEXT("CCrossbar Destructor")));

    HRESULT hr = DestroyRoutingList ();

    delete m_RoutingList;
}


//
// This function is called recursively, every time a new crossbar is
// entered as we search upstream.
//
// Return values:
//
//  S_OK -    Returned on final exit after recursive search if at least
//            one routing is possible
//  S_FALSE - Normal return indicating we've reached the end of a 
//            recursive search, so save the current path
//  E_FAIL -  Unable to route anything

HRESULT CCrossbar::BuildRoutingList (
   IPin     *pStartingInputPin,
   CRouting *pRouting,
   int       Depth
   )
{
    HRESULT  hr;
    LONG     InputIndexRelated, OutputIndexRelated;
    LONG     InputPhysicalType, OutputPhysicalType;
    LONG     Inputs, Outputs, InputIndex, OutputIndex;

    IPin    *pPin=0;
    IPin    *pStartingOutputPin=0;
    PIN_INFO pinInfo;
    CRouting RoutingNext;
    IAMCrossbar *pXbar=0;


    ASSERT (pStartingInputPin != NULL);
    ASSERT (pRouting != NULL);

    if (!pStartingInputPin || !pRouting)
        return E_POINTER;

    //
    // If the pin isn't connected, then it's a terminal pin
    //

    hr = pStartingInputPin->ConnectedTo (&pStartingOutputPin);
    if (hr != S_OK)
        return (Depth == 0) ? E_FAIL : S_FALSE;

    //
    // It is connected, so now find out if the filter supports 
    // IAMCrossbar
    //

    if (S_OK == pStartingOutputPin->QueryPinInfo(&pinInfo)) 
    {
        ASSERT (pinInfo.dir == PINDIR_OUTPUT);

        hr = pinInfo.pFilter->QueryInterface(IID_IAMCrossbar, (void **)&pXbar);
        if (hr == S_OK) 
        {
            EXECUTE_ASSERT (S_OK == pXbar->get_PinCounts(&Outputs, &Inputs));

            EXECUTE_ASSERT (S_OK == GetCrossbarIndexFromIPin (
                                    pXbar,
                                    &OutputIndex,
                                    FALSE,   // Input ?
                                    pStartingOutputPin));

            EXECUTE_ASSERT (S_OK == pXbar->get_CrossbarPinInfo(
                                    FALSE, // Input ?
                                    OutputIndex,
                                    &OutputIndexRelated,
                                    &OutputPhysicalType));

            //
            // for all input pins
            //

            for (InputIndex = 0; InputIndex < Inputs; InputIndex++) 
            {
                EXECUTE_ASSERT (S_OK == pXbar->get_CrossbarPinInfo(
                                        TRUE, // Input?
                                        InputIndex,
                                        &InputIndexRelated,
                                        &InputPhysicalType));

                //
                // Is the pin a video pin?
                //
                if (InputPhysicalType < PhysConn_Audio_Tuner) 
                {
                    //
                    // Can we route it?
                    //
                    if (S_OK == pXbar->CanRoute(OutputIndex, InputIndex)) 
                    {

                        EXECUTE_ASSERT (S_OK == GetCrossbarIPinAtIndex (
                                        pXbar,
                                        InputIndex,
                                        TRUE,   // Input
                                        &pPin));

                        //
                        // We've found a route through this crossbar
                        // so save our state before recusively searching
                        // again.
                        //
                        ZeroMemory (&RoutingNext, sizeof (RoutingNext));

                        // doubly linked list
                        RoutingNext.pRightRouting = pRouting;
                        pRouting->pLeftRouting = &RoutingNext;

                        pRouting->pXbar = pXbar;
                        pRouting->VideoInputIndex = InputIndex;
                        pRouting->VideoOutputIndex = OutputIndex;
                        pRouting->AudioInputIndex = InputIndexRelated;
                        pRouting->AudioOutputIndex = OutputIndexRelated;
                        pRouting->InputPhysicalType = InputPhysicalType;
                        pRouting->OutputPhysicalType = OutputPhysicalType;
                        pRouting->Depth = Depth;

                        hr = BuildRoutingList (pPin, &RoutingNext, Depth + 1);
                        
                        if (hr == S_FALSE) 
                        {
                            pRouting->pLeftRouting = NULL;
                            SaveRouting (pRouting);
                        }
                    } // if we can route

                } // if its a video pin

            } // for all input pins

            pXbar->Release();
        }
        else 
        {
            // The filter doesn't support IAMCrossbar, so this
            // is a terminal pin
            pinInfo.pFilter->Release();
            pStartingOutputPin->Release ();

            return (Depth == 0) ? E_FAIL : S_FALSE;
        }

        pinInfo.pFilter->Release();
    }

    pStartingOutputPin->Release ();

    return S_OK;
}

//
// Make a copy of the current routing, and AddRef the IAMCrossbar
// interfaces.
//

HRESULT CCrossbar::SaveRouting (CRouting *pRoutingNew)
{
    int Depth = pRoutingNew->Depth + 1;
    CRouting *pr=0;
    CRouting *pCurrent = pRoutingNew;

    if (!pRoutingNew || !m_RoutingList)
        return E_POINTER;

    DbgLog((LOG_TRACE,3,TEXT("CCrossbar::SaveRouting, Depth=%d, NumberOfRoutings=%d"), 
            Depth, m_RoutingList->GetCount() + 1));

    pr = new CRouting[Depth];
    if (pr == NULL)
        return E_FAIL;

    m_RoutingList->AddTail (pr);

    for (int j = 0; j < Depth; j++, pr++) 
    {
        *pr = *pCurrent;
        ASSERT (pCurrent->pXbar != NULL);

        //
        // We're holding onto this interface, so AddRef
        //
        pCurrent->pXbar->AddRef();
        pCurrent = pCurrent->pRightRouting;

        //
        // Pointers were stack based during recursive search, so update them
        // in the allocated array
        //
        pr->pLeftRouting  = pr - 1;
        pr->pRightRouting = pr + 1;

        if (j == 0) {                   // first element
            pr->pLeftRouting = NULL;
        } 
        if (j == (Depth - 1)) {  // last element
            pr->pRightRouting = NULL;
        }
    }

    return S_OK;
}


HRESULT CCrossbar::DestroyRoutingList()
{
    int k, Depth;
    CRouting *pCurrent=0, *pFirst=0;

    if (!m_RoutingList)
        return E_POINTER;

    DbgLog((LOG_TRACE,3,TEXT("DestroyRoutingList")));

    while (m_RoutingList->GetCount()) 
    {
        pCurrent = pFirst = m_RoutingList->RemoveHead();

        if (pCurrent)
        {
            Depth = pCurrent->Depth + 1;

⌨️ 快捷键说明

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