Partager via


Utilisation des barres croisées

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation au lieu de DirectShow, si possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Si une capture vidéo carte a plusieurs entrées physiques ou prend en charge plusieurs chemins matériels pour les données, le graphique de filtre peut contenir le filtre de barre croisée vidéo analogique. Le Générateur de graphiques de capture ajoute automatiquement ce filtre si nécessaire ; il sera amont à partir du filtre de capture. Selon le matériel, le graphique de filtre peut contenir plusieurs instance du filtre de barre croisée.

Le filtre de barre croisée expose l’interface IAMCrossbar , que vous pouvez utiliser pour acheminer une entrée particulière vers une sortie particulière. Par exemple, un carte vidéo peut avoir un connecteur coaxial et une entrée S-Video. Celles-ci sont représentées sous forme de broches d’entrée sur le filtre de barre croisée. Pour sélectionner une entrée, routez la broche d’entrée correspondante vers la broche de sortie de la barre croisée, à l’aide de la méthode IAMCrossbar::Route .

Pour localiser les filtres de barre croisée dans le graphique, vous pouvez utiliser la méthode ICaptureGraphBuilder2::FindInterface pour rechercher des filtres qui prennent en charge IAMCrossbar. Par exemple, le code suivant recherche deux barres croisées :

// 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();
}

Pour une approche plus générale, consultez la classe CCrossbar dans l’exemple AmCap.

Une fois que vous avez un pointeur vers l’interface IAMCrossbar , vous pouvez obtenir des informations sur le filtre de barre croisée, y compris le type physique de chaque broche et la matrice des broches d’entrée qui peuvent être routées vers quelles broches de sortie.

  • Pour déterminer le type de connecteur physique auquel correspond une broche, appelez la méthode IAMCrossbar::get_CrossbarPinInfo . La méthode retourne un membre de l’énumération PhysicalConnectorType . Par exemple, une broche S-Video retourne la valeur PhysConn_Video_SVideo.

    La méthode get_CrossbarInfo indique également si deux broches sont liées l’une à l’autre. Par exemple, une broche de tuner vidéo peut être liée à une broche de tuner audio. Les broches associées ont la même direction de broche et font généralement partie du même connecteur ou de la même prise physique sur le carte.

  • Pour déterminer si vous pouvez acheminer une broche d’entrée vers une broche de sortie particulière, appelez la méthode IAMCrossbar::CanRoute .

  • Pour déterminer le routage actuel entre les broches, appelez la méthode IAMCrossbar::get_IsRoutedTo .

Les méthodes précédentes spécifient toutes des broches par numéro d’index, avec des broches de sortie et d’entrée indexées à partir de zéro. Appelez la méthode IAMCrossbar::get_PinCounts pour rechercher le nombre d’épingles sur le filtre.

Par exemple, le code suivant affiche des informations sur un filtre de barre croisée dans la fenêtre de 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);
    }
}

Pour une carte hypothétique, cette fonction peut produire la sortie suivante :

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

Côté sortie, le S-Video et le tuner vidéo sont tous deux liés au décodeur audio. Du côté de l’entrée, le tuner vidéo est lié au tuner audio, et le S-Video est lié à la ligne audio dans. L’entrée S-Video est routée vers la sortie S-Video ; et l’entrée du tuner vidéo est routée vers la sortie du tuner vidéo. Actuellement, rien n’est routé vers le décodeur audio, mais la ligne audio dans ou le tuner audio peut y être acheminé.

Vous pouvez modifier le routage existant en appelant la méthode IAMCrossbar::Route .