Bagikan melalui


Bekerja dengan Crossbar

[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Tangkapan Audio/Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine dan Audio/Video Capture di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]

Jika kartu pengambilan video memiliki lebih dari satu input fisik, atau mendukung lebih dari satu jalur perangkat keras untuk data, grafik filter mungkin berisi Filter Bilah Silang Video Analog. Capture Graph Builder secara otomatis menambahkan filter ini saat diperlukan; itu akan upstram dari filter tangkapan. Bergantung pada perangkat keras, grafik filter mungkin berisi lebih dari satu instans filter crossbar.

Filter crossbar mengekspos antarmuka IAMCrossbar , yang dapat Anda gunakan untuk merutekan input tertentu ke output tertentu. Misalnya, kartu video mungkin memiliki konektor koaksial dan input S-Video. Ini akan direpresentasikan sebagai pin input pada filter crossbar. Untuk memilih input, rutekan pin input yang sesuai ke pin output crossbar, menggunakan metode IAMCrossbar::Route .

Untuk menemukan filter crossbar dalam grafik, Anda dapat menggunakan metode ICaptureGraphBuilder2::FindInterface untuk mencari filter yang mendukung IAMCrossbar. Misalnya, kode berikut mencari dua crossbar:

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

Untuk pendekatan yang lebih umum, lihat kelas CCrossbar di Sampel AmCap.

Setelah Anda memiliki penunjuk ke antarmuka IAMCrossbar , Anda bisa mendapatkan informasi tentang filter crossbar, termasuk jenis fisik setiap pin, dan matriks pin input mana yang dapat dirutekan ke pin output mana.

  • Untuk menentukan jenis konektor fisik yang sesuai dengan pin, panggil metode IAMCrossbar::get_CrossbarPinInfo . Metode mengembalikan anggota enumerasi PhysicalConnectorType . Misalnya, pin S-Video mengembalikan nilai PhysConn_Video_SVideo.

    Metode get_CrossbarInfo juga menunjukkan apakah dua pin terkait satu sama lain. Misalnya, pin penyetel video mungkin terkait dengan pin penyetel audio. Pin terkait memiliki arah pin yang sama, dan biasanya merupakan bagian dari jack fisik atau konektor yang sama pada kartu.

  • Untuk menentukan apakah Anda dapat merutekan pin input ke pin output tertentu, panggil metode IAMCrossbar::CanRoute .

  • Untuk menentukan perutean saat ini antara pin, panggil metode IAMCrossbar::get_IsRoutedTo .

Semua metode sebelumnya menentukan pin menurut nomor indeks, dengan pin output dan pin input yang diindeks dari nol. Panggil metode IAMCrossbar::get_PinCounts untuk menemukan jumlah pin pada filter.

Misalnya, kode berikut menampilkan informasi tentang filter crossbar ke jendela konsol:

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

Untuk kartu hipotetis, fungsi ini mungkin menghasilkan output berikut:

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

Di sisi output, S-Video dan tuner video keduanya terkait dengan dekoder audio. Di sisi input, tuner video terkait dengan tuner audio, dan S-Video terkait dengan garis audio di. Input S-Video dirutekan ke output S-Video; dan input tuner video dirutekan ke output tuner video. Saat ini tidak ada yang dirutekan ke dekoder audio, tetapi baik garis audio di atau tuner audio dapat dirutekan ke dalamnya.

Anda dapat mengubah perutean yang ada dengan memanggil metode IAMCrossbar::Route .