/***************************************************************************** * 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; }
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; }