00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <string.h>
00030
00031 #include <vlc/vlc.h>
00032 #include <vlc/input.h>
00033 #include <vlc/vout.h>
00034
00035 #ifndef _MSC_VER
00036
00037 # define QACONTAINERFLAGS QACONTAINERFLAGS_ANOTHERSOMETHINGELSE
00038 #endif
00039
00040 #include "common.h"
00041
00042
00043
00044
00045 void DeleteCrossbarRoutes( access_sys_t *p_sys )
00046 {
00047
00048 for( int i = 0; i < p_sys->i_crossbar_route_depth; i++ )
00049 {
00050 p_sys->crossbar_routes[i].pXbar->Release();
00051 }
00052 p_sys->i_crossbar_route_depth = 0;
00053 }
00054
00055
00056
00057
00058 static HRESULT GetCrossbarIPinAtIndex( IAMCrossbar *pXbar, LONG PinIndex,
00059 BOOL IsInputPin, IPin ** ppPin )
00060 {
00061 LONG cntInPins, cntOutPins;
00062 IPin *pP = 0;
00063 IBaseFilter *pFilter = NULL;
00064 IEnumPins *pins=0;
00065 ULONG n;
00066
00067 if( !pXbar || !ppPin ) return E_POINTER;
00068
00069 *ppPin = 0;
00070
00071 if( S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins) ) return E_FAIL;
00072
00073 LONG TrueIndex = IsInputPin ? PinIndex : PinIndex + cntInPins;
00074
00075 if( pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter) == S_OK )
00076 {
00077 if( SUCCEEDED(pFilter->EnumPins(&pins)) )
00078 {
00079 LONG i = 0;
00080 while( pins->Next(1, &pP, &n) == S_OK )
00081 {
00082 pP->Release();
00083 if( i == TrueIndex )
00084 {
00085 *ppPin = pP;
00086 break;
00087 }
00088 i++;
00089 }
00090 pins->Release();
00091 }
00092 pFilter->Release();
00093 }
00094
00095 return *ppPin ? S_OK : E_FAIL;
00096 }
00097
00098
00099
00100
00101 static HRESULT GetCrossbarIndexFromIPin( IAMCrossbar * pXbar, LONG * PinIndex,
00102 BOOL IsInputPin, IPin * pPin )
00103 {
00104 LONG cntInPins, cntOutPins;
00105 IPin *pP = 0;
00106 IBaseFilter *pFilter = NULL;
00107 IEnumPins *pins = 0;
00108 ULONG n;
00109 BOOL fOK = FALSE;
00110
00111 if(!pXbar || !PinIndex || !pPin )
00112 return E_POINTER;
00113
00114 if( S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins) )
00115 return E_FAIL;
00116
00117 if( pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter) == S_OK )
00118 {
00119 if( SUCCEEDED(pFilter->EnumPins(&pins)) )
00120 {
00121 LONG i=0;
00122
00123 while( pins->Next(1, &pP, &n) == S_OK )
00124 {
00125 pP->Release();
00126 if( pPin == pP )
00127 {
00128 *PinIndex = IsInputPin ? i : i - cntInPins;
00129 fOK = TRUE;
00130 break;
00131 }
00132 i++;
00133 }
00134 pins->Release();
00135 }
00136 pFilter->Release();
00137 }
00138
00139 return fOK ? S_OK : E_FAIL;
00140 }
00141
00142
00143
00144
00145 HRESULT FindCrossbarRoutes( vlc_object_t *p_this, access_sys_t *p_sys,
00146 IPin *p_input_pin, LONG physicalType, int depth )
00147 {
00148 HRESULT result = S_FALSE;
00149
00150 IPin *p_output_pin;
00151 if( FAILED(p_input_pin->ConnectedTo(&p_output_pin)) ) return S_FALSE;
00152
00153
00154 PIN_INFO pinInfo;
00155 if( FAILED(p_output_pin->QueryPinInfo(&pinInfo)) ||
00156 PINDIR_OUTPUT != pinInfo.dir )
00157 {
00158 p_output_pin->Release ();
00159 return S_FALSE;
00160 }
00161
00162 IAMCrossbar *pXbar=0;
00163 if( FAILED(pinInfo.pFilter->QueryInterface(IID_IAMCrossbar,
00164 (void **)&pXbar)) )
00165 {
00166 pinInfo.pFilter->Release();
00167 p_output_pin->Release ();
00168 return S_FALSE;
00169 }
00170
00171 LONG inputPinCount, outputPinCount;
00172 if( FAILED(pXbar->get_PinCounts(&outputPinCount, &inputPinCount)) )
00173 {
00174 pXbar->Release();
00175 pinInfo.pFilter->Release();
00176 p_output_pin->Release ();
00177 return S_FALSE;
00178 }
00179
00180 LONG inputPinIndexRelated, outputPinIndexRelated;
00181 LONG inputPinPhysicalType = 0, outputPinPhysicalType;
00182 LONG inputPinIndex = 0, outputPinIndex;
00183 if( FAILED(GetCrossbarIndexFromIPin( pXbar, &outputPinIndex,
00184 FALSE, p_output_pin )) ||
00185 FAILED(pXbar->get_CrossbarPinInfo( FALSE, outputPinIndex,
00186 &outputPinIndexRelated,
00187 &outputPinPhysicalType )) )
00188 {
00189 pXbar->Release();
00190 pinInfo.pFilter->Release();
00191 p_output_pin->Release ();
00192 return S_FALSE;
00193 }
00194
00195
00196
00197
00198 if( physicalType == 0 )
00199 {
00200
00201 physicalType = PhysConn_Video_Tuner;
00202 if( SUCCEEDED(pXbar->get_IsRoutedTo(outputPinIndex, &inputPinIndex)) )
00203 {
00204
00205 if( SUCCEEDED( pXbar->get_CrossbarPinInfo( TRUE, inputPinIndex,
00206 &inputPinIndexRelated, &inputPinPhysicalType )) )
00207 {
00208
00209 physicalType = inputPinPhysicalType;
00210
00211 msg_Dbg( p_this, "Found Existing Route For ouput %ld (type %ld) to input %ld (type %ld)",
00212 outputPinIndex, outputPinPhysicalType, inputPinIndex,
00213 inputPinPhysicalType );
00214
00215
00216
00217
00218 }
00219 }
00220 else {
00221
00222 inputPinIndex = 0;
00223 }
00224 }
00225
00226
00227
00228
00229 for( ; (S_OK != result) && (inputPinIndex < inputPinCount); ++inputPinIndex )
00230 {
00231 if( FAILED(pXbar->get_CrossbarPinInfo( TRUE, inputPinIndex,
00232 &inputPinIndexRelated, &inputPinPhysicalType )) ) continue;
00233
00234
00235 if( inputPinPhysicalType != physicalType ) continue;
00236
00237
00238 if( FAILED(pXbar->CanRoute(outputPinIndex, inputPinIndex)) ) continue;
00239
00240
00241 IPin *pPin;
00242 if( FAILED(GetCrossbarIPinAtIndex( pXbar, inputPinIndex,
00243 TRUE, &pPin)) ) continue;
00244
00245 result = FindCrossbarRoutes( p_this, p_sys, pPin,
00246 physicalType, depth+1 );
00247
00248 if( S_OK == result || (S_FALSE == result &&
00249 physicalType == inputPinPhysicalType &&
00250 (p_sys->i_crossbar_route_depth = depth+1) < MAX_CROSSBAR_DEPTH) )
00251 {
00252
00253 pXbar->AddRef();
00254
00255
00256 p_sys->crossbar_routes[depth].pXbar = pXbar;
00257 p_sys->crossbar_routes[depth].VideoInputIndex = inputPinIndex;
00258 p_sys->crossbar_routes[depth].VideoOutputIndex = outputPinIndex;
00259 p_sys->crossbar_routes[depth].AudioInputIndex = inputPinIndexRelated;
00260 p_sys->crossbar_routes[depth].AudioOutputIndex = outputPinIndexRelated;
00261
00262 msg_Dbg( p_this, "Crossbar at depth %d, Found Route For "
00263 "ouput %ld (type %ld) to input %ld (type %ld)", depth,
00264 outputPinIndex, outputPinPhysicalType, inputPinIndex,
00265 inputPinPhysicalType );
00266
00267 result = S_OK;
00268 }
00269 }
00270
00271 pXbar->Release();
00272 pinInfo.pFilter->Release();
00273 p_output_pin->Release ();
00274
00275 return result;
00276 }