크로스바 작업

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

비디오 캡처 카드 두 개 이상의 물리적 입력이 있거나 데이터에 대해 둘 이상의 하드웨어 경로를 지원하는 경우 필터 그래프에 아날로그 비디오 크로스바 필터가 포함될 수 있습니다. 캡처 그래프 작성기가 필요할 때 이 필터를 자동으로 추가합니다. 캡처 필터에서 업스트림. 하드웨어에 따라 필터 그래프에 크로스바 필터의 instance 둘 이상이 포함될 수 있습니다.

크로스바 필터는 특정 입력을 특정 출력으로 라우팅하는 데 사용할 수 있는 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 핀은 PhysConn_Video_SVideo 값을 반환합니다.

    get_CrossbarInfo 메서드는 두 핀이 서로 관련되어 있는지 여부도 나타냅니다. 예를 들어 비디오 튜너 핀은 오디오 튜너 핀과 관련이 있을 수 있습니다. 관련 핀은 핀 방향이 동일하며 일반적으로 카드 동일한 물리적 잭 또는 커넥터의 일부입니다.

  • 입력 핀을 특정 출력 핀으로 라우팅할 수 있는지 여부를 확인하려면 IAMCrossbar::CanRoute 메서드를 호출합니다.

  • 핀 간의 현재 라우팅을 확인하려면 IAMCrossbar::get_IsRoutedTo 메서드를 호출합니다.

이전 메서드는 모두 인덱스 번호별로 핀을 지정하며 출력 핀과 입력 핀은 모두 0에서 인덱싱됩니다. 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-비디오 입력은 S-비디오 출력으로 라우팅됩니다. 비디오 튜너 입력이 비디오 튜너 출력으로 라우팅됩니다. 현재 아무것도 오디오 디코더로 라우팅되지 않지만 의 오디오 라인 또는 오디오 튜너를 오디오 디코더로 라우팅할 수 있습니다.

IAMCrossbar::Route 메서드를 호출하여 기존 라우팅을 변경할 수 있습니다.