共用方式為


與 Crossbars 的協作

[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngine和媒體基金會中的 音訊/視訊擷取取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayerIMFMediaEngine 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]

如果視訊擷取卡有多個實體輸入,或支援多個資料的硬體路徑,則篩選圖表可能包含 類比視訊交叉橫條篩選。 擷取圖形產生器會在需要時自動新增此篩選;它會是擷取篩選的上游。 根據硬體而定,篩選圖表可能包含多個橫條篩選條件的實例。

交叉橫條篩選會公開 IAMCrossbar 介面,您可以使用此介面將特定輸入路由傳送至特定輸出。 例如,視訊卡可能有同軸連接器和 S-Video 輸入。 這些會以交叉開關篩選器上的輸入引腳表示。 若要選取輸入,請使用 IAMCrossbar::Route 方法,將對應的輸入引腳連接至交叉開關的輸出引腳。

在圖表中定位交叉線濾鏡,您可以使用 ICaptureGraphBuilder2::FindInterface 方法來搜尋支援 IAMCrossbar 的濾鏡。 例如,下列程式代碼會搜尋兩個橫條:

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

如需更一般化的方法,請參閱 AmCap 範例中的 CCrossbar 類別

一旦您擁有指向 IAMCrossbar 介面的指標,即可獲取交叉點過濾器的相關信息,包括每個引腳的物理類型,以及輸入引腳和輸出引腳的可路由配置矩陣。

  • 若要判斷針腳對應的實體連接器類型,請呼叫 IAMCrossbar::get_CrossbarPinInfo 方法。 方法會傳回 PhysicalConnectorType 列舉的成員。 例如,S-Video pin 會傳回值PhysConn_Video_SVideo。

    get_CrossbarInfo 方法還會指出兩個參數是否彼此相關。 例如,視訊調諧器接腳可能與音訊調諧器接腳相關。 相關的引腳方向相同,通常是介面卡上相同實體插孔或連接器的一部分。

  • 若要判斷是否可以將輸入引腳路由至特定輸出引腳,請呼叫 IAMCrossbar::CanRoute 方法。

  • 若要判斷針腳之間的當前路由,請呼叫 IAMCrossbar::get_IsRoutedTo 方法。

上述方法全都會依索引編號指定針腳,輸出針腳和輸入針腳都是從零編製索引。 呼叫 IAMCrossbar::get_PinCounts 方法以查找篩選器上的針腳數目。

例如,下列程式代碼會顯示控制檯窗叉橫條篩選的相關信息:

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

針對假設卡片,此函式可能會產生下列輸出:

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

在輸出端,S-Video 和視訊微調器都與音訊譯碼器相關。 在輸入端,視訊微調器與音訊微調器相關,而 S-Video 則與 中的音訊線相關。 S-Video 輸入會路由傳送至 S-Video 輸出,視頻調諧器輸入會路由傳送至視頻調諧器輸出。 目前沒有任何訊號傳送至音訊解碼器,但可以將音訊輸入線或音訊調諧器路由至解碼器。

您可以呼叫 IAMCrossbar::Route 方法來變更現有的路由。