Compartir a través de


Trabajar con barras cruzadas

[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.

Si una tarjeta de captura de vídeo tiene más de una entrada física o admite más de una ruta de acceso de hardware para los datos, el gráfico de filtros puede contener el filtro de barra cruzada de vídeo analógico. Capture Graph Builder agrega automáticamente este filtro cuando sea necesario; será ascendente desde el filtro de captura. En función del hardware, el gráfico de filtros puede contener más de una instancia del filtro de barra cruzada.

El filtro de barra cruzada expone la interfaz IAMCrossbar , que puede usar para enrutar una entrada determinada a una salida determinada. Por ejemplo, una tarjeta de vídeo podría tener un conector coaxial y una entrada de S-Video. Estos se representarían como patillas de entrada en el filtro de barra cruzada. Para seleccionar una entrada, enrute el pin de entrada correspondiente al pin de salida de la barra cruzada mediante el método IAMCrossbar::Route .

Para buscar filtros de barra cruzada en el gráfico, puede usar el método ICaptureGraphBuilder2::FindInterface para buscar filtros que admitan IAMCrossbar. Por ejemplo, el código siguiente busca dos 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 obtener un enfoque más generalizado, consulte la clase CCrossbar en el ejemplo de AmCap.

Una vez que tenga un puntero a la interfaz IAMCrossbar , puede obtener información sobre el filtro de barra cruzada, incluido el tipo físico de cada patilla, y la matriz de qué patillas de entrada se pueden enrutar a qué patillas de salida.

  • Para determinar el tipo de conector físico al que corresponde un pin, llame al método IAMCrossbar::get_CrossbarPinInfo . El método devuelve un miembro de la enumeración PhysicalConnectorType . Por ejemplo, un pin de S-Video devuelve el valor PhysConn_Video_SVideo.

    El método get_CrossbarInfo también indica si dos patillas están relacionadas entre sí. Por ejemplo, un pin de tuner de vídeo podría estar relacionado con un pin de tuner de audio. Las patillas relacionadas tienen la misma dirección de patilla y normalmente forman parte del mismo conector o conector físico en la tarjeta.

  • Para determinar si puede enrutar un pin de entrada a un pin de salida determinado, llame al método IAMCrossbar::CanRoute .

  • Para determinar el enrutamiento actual entre patillas, llame al método IAMCrossbar::get_IsRoutedTo .

Todos los métodos anteriores especifican patillas por número de índice, con patillas de salida y patillas de entrada tanto indizadas desde cero. Llame al método IAMCrossbar::get_PinCounts para buscar el número de patillas en el filtro.

Por ejemplo, el código siguiente muestra información sobre un filtro de barra cruzada en la ventana de la consola:

// 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 una tarjeta hipotética, esta función podría producir la siguiente salida:

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

En el lado de salida, el S-Video y el tuner de vídeo están relacionados con el descodificador de audio. En el lado de entrada, el tuner de vídeo está relacionado con el tuner de audio y el S-Video está relacionado con la línea de audio en. La entrada S-Video se enruta a la salida de S-Video; y la entrada de tuner de vídeo se enruta a la salida del tuner de vídeo. Actualmente no se enruta nada al descodificador de audio, pero la línea de audio en o el tuner de audio se puede enrutar a él.

Puede cambiar el enrutamiento existente llamando al método IAMCrossbar::Route .