DirectShow DirectShow 의 사용법 비디오 캡춰 비디오 캡춰 태스크 크로스바의 조작   [목차열람] [주소복사] [슬롯비우기]
크로스바의 조작
 
Microsoft DirectX 9.0

크로스바의 조작

비디오 캡쳐 카드가 복수의 물리 입력을 가지는지, 데이터용의 복수의 하드웨어 패스를 지원 하고 있는 경우, 필터 그래프에는아날로그 비디오 크로스바 필터가 들어가 있는 일이 있다. Capture Graph Builder 는 필요에 따라서 자동적으로 이 필터를 추가한다. 이 필터는, 캡춰 필터로부터는 업 스트림이 된다. 하드웨어에 따라서는, 필터 그래프에 크로스바 필터의 복수의 인스턴스가 포함되는 일이 있다.

크로스바 필터는 IAMCrossbar 인터페이스를 공개한다. 이 인터페이스를 사용하면 특정의 입력을 특정의 출력에 루팅 할 수 있다. 예를 들어, 비디오 카드는 같은 축 연결기와 S 비디오 입력을 갖추고 있는 일이 있다. 이것들은, 크로스바 필터의 입력 핀으로서 나타낸다. 입력을 선택하려면 ,IAMCrossbar::Route 를 사용해, 대응하는 입력 핀을 크로스바의 출력 핀에 루팅 한다.

그래프의 크로스바 필터를 검색하려면 ,ICaptureGraphBuilder2::FindInterface 메서드를 사용해,IAMCrossbar 를 지원 하는 필터를 검색한다. 예를 들어, 다음 코드는 2 개의 크로스바를 검색한다.

// 업 스트림 방향으로 크로스바를 검색한다.
IAMCrossbar *pXBar1 = NULL;
hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pSrc,
        IID_IAMCrossbar, (void**) &pXBar1);
if (SUCCEEDED(hr)) 
{
    // 1 개의 크로스바를 찾아냈다. 그 IBaseFilter 인터페이스를 얻어온다.
    IBaseFilter *pFilter = NULL;
    hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**) &pFilter);
    if (SUCCEEDED(hr)) 
    {
        // 업 스트림 방향으로 다른 크로스바를 검색한다.
        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 인터페이스의 포인터를 얻어온다와 각 핀의 물리 타입, 어느 입력 핀이 어느 출력 핀에 루팅 되는지를 나타내는 행렬 등, 크로스바 필터에 관한 정보를 취득할 수 있다.

get_CrossbarInfo 메서드는, 2 개의 핀을 서로 관련지을 수 있는지도 가리킨다. 예를 들어, 비디오 튜너 핀은 오디오 튜너 핀에 관련지을 수 있는 일이 있다. 관련지을 수 있었던 핀은 같은 핀 방향을 가져, 보통은 카드의 같은 물리 잭 또는 연결기의 일부이다.

전의 메서드는 모두 인덱스 번호로 핀을 지정한다. 출력 핀과 입력 핀의 인덱스는 0 으로부터 시작된다. 필터 위에의 핀의 수를 조사하려면 ,IAMCrossbar::get_PinCounts 메서드를 호출한다.

예를 들어, 다음 코드는 크로스바 필터에 관한 정보를 콘솔 윈도우에 표시한다.

// 타입과 이름을 관련짓는 헬퍼-함수.
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 비디오와 비디오 튜너는 어느쪽이나 오디오 디코더에 관련지을 수 있다. 입력측에서는, 비디오 튜너는 오디오 튜너에 관련지을 수 있어 S 비디오는 오디오 라인 입력에 관련지을 수 있다. S 비디오 입력은 S 비디오 출력에 루팅 된다. 비디오 튜너 입력은 비디오 튜너 출력에 루팅 된다. 현재, 오디오 디코더에는 아무것도 루팅 하고 있지 않지만, 오디오 라인 입력 또는 오디오 튜너를 루팅 할 수 있다.

기존의 루팅을 변경하려면 ,IAMCrossbar::Route 메서드를 호출한다.

↑TOP