void DirectShowGrabber::routeCrossbar() { HRESULT hr; long output = -1; long input = -1; int compositePort = -1; int videoDecoderPort = -1; long related; long pinType; IAMCrossbar *xb; if( crossbar == NULL ) return; xb = crossbar->getXBar(); xb->get_IsRoutedTo(0, &input); debug_msg("DirectShowGrabber::routeCrossbar(): pin %d is routed to output pin 0\n", input); hr = xb->get_PinCounts(&output, &input); for( int i = 0; i < input; ++i ) { xb->get_CrossbarPinInfo(TRUE, i, &related, &pinType); if( pinType == PhysConn_Video_Composite ) { compositePort = i; break; } } for( int i = 0; i < output; ++i ) { xb->get_CrossbarPinInfo(FALSE, i, &related, &pinType); if( pinType == PhysConn_Video_VideoDecoder ) { videoDecoderPort = i; break; } } if( xb->CanRoute(videoDecoderPort, compositePort) == S_FALSE ) debug_msg("DirectShowGrabber::routeCrossbar(): cannot route input pin %d to output pin %d\n", compositePort, videoDecoderPort); else { debug_msg("DirectShowGrabber::routeCrossbar() routing pin %d to pin %d\n", compositePort, videoDecoderPort); hr = xb->Route(videoDecoderPort, compositePort); //showErrorMessage(hr); } xb->get_IsRoutedTo(0, &input); debug_msg("DirectShowGrabber::routeCrossbar(): pin %d is now routed to output pin 0\n", input); }
/***************************************************************************** * 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; }