Trabalhando com barras cruzadas
[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]
Se uma captura de vídeo cartão tiver mais de uma entrada física ou oferecer suporte a mais de um caminho de hardware para dados, o grafo de filtro poderá conter o Filtro de Barra Cruzada de Vídeo Analógico. O Capture Graph Builder adiciona automaticamente esse filtro quando necessário; ele será upstream do filtro de captura. Dependendo do hardware, o grafo de filtro pode conter mais de uma instância do filtro de barra cruzada.
O filtro de barra cruzada expõe a interface IAMCrossbar , que você pode usar para rotear uma entrada específica para uma saída específica. Por exemplo, um vídeo cartão pode ter um conector coaxial e uma entrada S-Video. Eles seriam representados como pinos de entrada no filtro de barra cruzada. Para selecionar uma entrada, encaminhe o pino de entrada correspondente para o pino de saída da barra cruzada, usando o método IAMCrossbar::Route .
Para localizar filtros de barra cruzada no grafo, você pode usar o método ICaptureGraphBuilder2::FindInterface para pesquisar filtros que dão suporte a IAMCrossbar. Por exemplo, o código a seguir pesquisa duas barras cruzadas:
// Search upstream for a crossbar.
IAMCrossbar *pXBar1 = NULL;
hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pSrc,
IID_IAMCrossbar, (void**)&pXBar1);
if (SUCCEEDED(hr))
{
// Found one crossbar. Get its IBaseFilter interface.
IBaseFilter *pFilter = NULL;
hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**)&pFilter);
if (SUCCEEDED(hr))
{
// Search upstream for another crossbar.
IAMCrossbar *pXBar2 = NULL;
hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pFilter,
IID_IAMCrossbar, (void**)&pXBar2);
pFilter->Release();
if (SUCCEEDED(hr))
{
/* ... */
pXBar2->Release();
}
}
pXBar1->Release();
}
Para obter uma abordagem mais generalizada, consulte a classe CCrossbar no Exemplo de AmCap.
Depois de ter um ponteiro para a interface IAMCrossbar , você poderá obter informações sobre o filtro de barra cruzada, incluindo o tipo físico de cada pino e a matriz da qual os pinos de entrada podem ser roteado para os pinos de saída.
Para determinar o tipo de conector físico ao qual um pino corresponde, chame o método IAMCrossbar::get_CrossbarPinInfo . O método retorna um membro da enumeração PhysicalConnectorType . Por exemplo, um pin S-Video retorna o valor PhysConn_Video_SVideo.
O método get_CrossbarInfo também indica se dois pinos estão relacionados entre si. Por exemplo, um pino de sintonizador de vídeo pode estar relacionado a um pino de sintonizador de áudio. Os pinos relacionados têm a mesma direção de pino e normalmente fazem parte da mesma tomada física ou conector na cartão.
Para determinar se você pode rotear um pino de entrada para um determinado pino de saída, chame o método IAMCrossbar::CanRoute .
Para determinar o roteamento atual entre os pinos, chame o método IAMCrossbar::get_IsRoutedTo .
Todos os métodos anteriores especificam pinos por número de índice, com pinos de saída e pinos de entrada indexados de zero. Chame o método IAMCrossbar::get_PinCounts para localizar o número de pinos no filtro.
Por exemplo, o código a seguir exibe informações sobre um filtro de barra cruzada para a janela do console:
// Helper function to associate a name with the type.
const char * GetPhysicalPinName(long lType)
{
switch (lType)
{
case PhysConn_Video_Tuner: return "Video Tuner";
case PhysConn_Video_Composite: return "Video Composite";
case PhysConn_Video_SVideo: return "S-Video";
case PhysConn_Video_RGB: return "Video RGB";
case PhysConn_Video_YRYBY: return "Video YRYBY";
case PhysConn_Video_SerialDigital: return "Video Serial Digital";
case PhysConn_Video_ParallelDigital: return "Video Parallel Digital";
case PhysConn_Video_SCSI: return "Video SCSI";
case PhysConn_Video_AUX: return "Video AUX";
case PhysConn_Video_1394: return "Video 1394";
case PhysConn_Video_USB: return "Video USB";
case PhysConn_Video_VideoDecoder: return "Video Decoder";
case PhysConn_Video_VideoEncoder: return "Video Encoder";
case PhysConn_Audio_Tuner: return "Audio Tuner";
case PhysConn_Audio_Line: return "Audio Line";
case PhysConn_Audio_Mic: return "Audio Microphone";
case PhysConn_Audio_AESDigital: return "Audio AES/EBU Digital";
case PhysConn_Audio_SPDIFDigital: return "Audio S/PDIF";
case PhysConn_Audio_SCSI: return "Audio SCSI";
case PhysConn_Audio_AUX: return "Audio AUX";
case PhysConn_Audio_1394: return "Audio 1394";
case PhysConn_Audio_USB: return "Audio USB";
case PhysConn_Audio_AudioDecoder: return "Audio Decoder";
default: return "Unknown Type";
}
}
void DisplayCrossbarInfo(IAMCrossbar *pXBar)
{
HRESULT hr;
long cOutput = -1, cInput = -1;
hr = pXBar->get_PinCounts(&cOutput, &cInput);
for (long i = 0; i < cOutput; i++)
{
long lRelated = -1, lType = -1, lRouted = -1;
hr = pXBar->get_CrossbarPinInfo(FALSE, i, &lRelated, &lType);
hr = pXBar->get_IsRouted(i, &lRouted);
printf("Output pin %d: %s\n", i, GetPhysicalPinName(lType));
printf("\tRelated out: %d, Routed in: %d\n", lRelated, lRouted);
printf("\tSwitching Matrix: ");
for (long j = 0; j < cInput; j++)
{
hr = pXBar->CanRoute(i, j);
printf("%d-%s", j, (S_OK == hr ? "Yes" : "No"));
}
printf("\n\n");
}
for (i = 0; i < cInput; i++)
{
long lRelated = -1, lType = -1;
hr = pXBar->get_CrossbarPinInfo(TRUE, i, &lRelated, &lType);
printf("Input pin %d - %s\n", i, GetPhysicalPinName(lType));
printf("\tRelated in: %d\n", lRelated);
}
}
Para uma cartão hipotética, essa função pode produzir a seguinte saída:
Output pin 0: S-Video
Related out: 2, Routed in: 0
Switching Matrix: 0-Yes 1-No 2-No 3-No
Output pin 1 - Video Tuner
Related out: 2, Routed in: 1
Switching Matrix: 0-No 1-Yes 2-No 3-No
Output pin 2 - Audio decoder
Related out: 1, Routed in: -1
Switching Matrix: 0-No 1-No 2-Yes 3-Yes
Input pin 0 - S-Video
Related in: 2
Input pin 1 - Video Tuner
Related in: 3
Input pin 2 - Audio line
Related in: 0
Input pin 3 - Audio tuner
Related in: 1
No lado da saída, o S-Video e o sintonizador de vídeo estão relacionados ao decodificador de áudio. No lado de entrada, o sintonizador de vídeo está relacionado ao sintonizador de áudio e o S-Video está relacionado à linha de áudio em. A entrada S-Video é roteada para a saída S-Video; e a entrada do sintonizador de vídeo é roteada para a saída do sintonizador de vídeo. Atualmente, nada é roteado para o decodificador de áudio, mas a linha de áudio em ou o sintonizador de áudio pode ser roteado para ele.
Você pode alterar o roteamento existente chamando o método IAMCrossbar::Route .