Esempio n. 1
0
/*****************************************************************************
 * FindCrossbarRoutes
 *****************************************************************************/
HRESULT FindCrossbarRoutes( vlc_object_t *p_this, access_sys_t *p_sys,
                            IPin *p_input_pin, LONG physicalType, int depth )
{
    HRESULT result = S_FALSE;

    IPin *p_output_pin;
    if( FAILED(p_input_pin->ConnectedTo(&p_output_pin)) ) return S_FALSE;

    // It is connected, so now find out if the filter supports IAMCrossbar
    PIN_INFO pinInfo;
    if( FAILED(p_output_pin->QueryPinInfo(&pinInfo)) ||
        PINDIR_OUTPUT != pinInfo.dir )
    {
        p_output_pin->Release ();
        return S_FALSE;
    }

    IAMCrossbar *pXbar = NULL;
    if( FAILED(pinInfo.pFilter->QueryInterface(IID_IAMCrossbar,
                                               (void **)&pXbar)) )
    {
        pinInfo.pFilter->Release();
        p_output_pin->Release ();
        return S_FALSE;
    }

    LONG inputPinCount, outputPinCount;
    if( FAILED(pXbar->get_PinCounts(&outputPinCount, &inputPinCount)) )
    {
        pXbar->Release();
        pinInfo.pFilter->Release();
        p_output_pin->Release ();
        return S_FALSE;
    }

    LONG inputPinIndexRelated, outputPinIndexRelated;
    LONG inputPinPhysicalType = 0, outputPinPhysicalType;
    LONG inputPinIndex = 0, outputPinIndex;
    if( FAILED(GetCrossbarIndexFromIPin( pXbar, &outputPinIndex,
                                         FALSE, p_output_pin )) ||
        FAILED(pXbar->get_CrossbarPinInfo( FALSE, outputPinIndex,
                                           &outputPinIndexRelated,
                                           &outputPinPhysicalType )) )
    {
        pXbar->Release();
        pinInfo.pFilter->Release();
        p_output_pin->Release ();
        return S_FALSE;
    }

    /*
    ** if physical type is 0, then use default/existing route to physical connector
    */
    if( physicalType == 0 )
    {
        /* use following as default connector type if we fail to find an existing route */
        physicalType = PhysConn_Video_Tuner;
        if( SUCCEEDED(pXbar->get_IsRoutedTo(outputPinIndex, &inputPinIndex)) )
        {

            if( SUCCEEDED( pXbar->get_CrossbarPinInfo( TRUE,  inputPinIndex,
                           &inputPinIndexRelated, &inputPinPhysicalType )) )
            {
                // remember connector type
                physicalType = inputPinPhysicalType;
 
                msg_Dbg( p_this, "found existing route for output %ld (type %s) to input %ld (type %s)",
                         outputPinIndex, GetPhysicalPinName( outputPinPhysicalType ),
                         inputPinIndex, GetPhysicalPinName( inputPinPhysicalType ) );
 
                // fall through to for loop, note 'inputPinIndex' is set to the pin we are looking for
                // hence, loop iteration should not wind back

            }
        }
        else {
            // reset to first pin for complete loop iteration
            inputPinIndex = 0;
        }
    }
 
    //
    // for all input pins
    //
    for( /* inputPinIndex has been set */ ; (S_OK != result) && (inputPinIndex < inputPinCount); ++inputPinIndex )
    {
        if( FAILED(pXbar->get_CrossbarPinInfo( TRUE,  inputPinIndex,
            &inputPinIndexRelated, &inputPinPhysicalType )) ) continue;

        // Is this pin matching required connector physical type?
        if( inputPinPhysicalType != physicalType ) continue;

        // Can we route it?
        if( FAILED(pXbar->CanRoute(outputPinIndex, inputPinIndex)) ) continue;
 
 
        IPin *pPin;
        if( FAILED(GetCrossbarIPinAtIndex( pXbar, inputPinIndex,
                                           TRUE, &pPin)) ) continue;

        result = FindCrossbarRoutes( p_this, p_sys, pPin,
                                     physicalType, depth+1 );

        if( S_OK == result || (S_FALSE == result &&
            physicalType == inputPinPhysicalType &&
            (p_sys->i_crossbar_route_depth = depth+1) < MAX_CROSSBAR_DEPTH) )
        {
            // hold on crossbar, will be released when graph is destroyed
            pXbar->AddRef();

            // remember crossbar route
            p_sys->crossbar_routes[depth].pXbar = pXbar;
            p_sys->crossbar_routes[depth].VideoInputIndex = inputPinIndex;
            p_sys->crossbar_routes[depth].VideoOutputIndex = outputPinIndex;
            p_sys->crossbar_routes[depth].AudioInputIndex = inputPinIndexRelated;
            p_sys->crossbar_routes[depth].AudioOutputIndex = outputPinIndexRelated;

            msg_Dbg( p_this, "crossbar at depth %d, found route for "
                     "output %ld (type %s) to input %ld (type %s)", depth,
                     outputPinIndex, GetPhysicalPinName( outputPinPhysicalType ),
                     inputPinIndex, GetPhysicalPinName( inputPinPhysicalType ) );

            result = S_OK;
        }
    }

    pXbar->Release();
    pinInfo.pFilter->Release();
    p_output_pin->Release ();

    return result;
}
Esempio n. 2
0
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;
}