다음을 통해 공유


TV 오디오 미리 보기

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

TV 오디오를 미리 보려면 크로스바 필터의 오디오 디코더 핀을 오디오 튜너 핀으로 라우팅합니다. 오디오를 음소거하려면 다음 다이어그램과 같이 오디오 디코더 핀을 -1로 라우팅합니다. (크로스바 필터는 크로스바 작업에 설명되어 있습니다.)

오디오 디코더 핀 라우팅

기본 방법은 다음과 같습니다.

  1. ICaptureGraphBuilder2::FindInterface 메서드를 사용하여 크로스바 필터를 찾습니다.
  2. IAMCrossbar::get_CrossbarPinInfo 메서드를 사용하여 크로스바 필터의 입력 및 출력 핀을 열거합니다. 오디오 디코더 출력 핀과 오디오 튜너 입력 핀을 검색합니다.
  3. 올바른 핀을 찾으면 IAMCrossbar::Route 를 호출하여 핀을 라우팅합니다. 그렇지 않은 경우 다른 크로스바를 업스트림 보고 프로세스를 반복합니다.
  4. 오디오를 음소거하려면 오디오 디코더 핀을 -1로 라우팅합니다.

대부분의 TV 튜너에서는 단일 크로스바 필터를 사용하지만 일부는 두 개의 크로스바 필터를 사용합니다. 따라서 첫 번째 크로스바가 실패하는 경우 두 번째 크로스바를 검색해야 할 수 있습니다.

참고

튜너 카드 사운드 카드 사이에 물리적 연결이 있기 때문에 예상되는 것과 달리 오디오를 미리 보는 데 오디오 캡처 필터 또는 오디오 렌더러가 필요하지 않습니다.

 

다음 코드에서는 이러한 단계를 더 자세히 보여 있습니다. 먼저 크로스바 필터에서 지정된 핀 유형을 검색하는 도우미 함수는 다음과 같습니다.

HRESULT FindCrossbarPin(
    IAMCrossbar *pXBar,                 // Pointer to the crossbar.
    PhysicalConnectorType PhysicalType, // Pin type to match.
    PIN_DIRECTION Dir,                  // Pin direction.
    long *pIndex)       // Receives the index of the pin, if found.
{
    BOOL bInput = (Dir == PINDIR_INPUT ? TRUE : FALSE);

    // Find out how many pins the crossbar has.
    long cOut, cIn;
    HRESULT hr = pXBar->get_PinCounts(&cOut, &cIn);
    if (FAILED(hr)) return hr;
    // Enumerate pins and look for a matching pin.
    long count = (bInput ? cIn : cOut);
    for (long i = 0; i < count; i++)
    {
        long iRelated = 0;
        long ThisPhysicalType = 0;
        hr = pXBar->get_CrossbarPinInfo(bInput, i, &iRelated,
            &ThisPhysicalType);
        if (SUCCEEDED(hr) && ThisPhysicalType == PhysicalType)
        {
            // Found a match, return the index.
            *pIndex = i;
            return S_OK;
        }
    }
    // Did not find a matching pin.
    return E_FAIL;
}

다음 함수는 bActivate 매개 변수의 값에 따라 오디오를 활성화하거나 음소거하려고 시도합니다. 지정된 크로스바 필터에서 필요한 핀을 검색합니다. 찾을 수 없는 경우 오류 코드를 반환합니다.

HRESULT ConnectAudio(IAMCrossbar *pXBar, BOOL bActivate)
{
    // Look for the Audio Decoder output pin.
    long i = 0;
    HRESULT hr = FindCrossbarPin(pXBar, PhysConn_Audio_AudioDecoder,
        PINDIR_OUTPUT, &i);
    if (SUCCEEDED(hr))
    {
        if (bActivate)  // Activate the audio. 
        {
            // Look for the Audio Tuner input pin.
            long j = 0;
            hr = FindCrossbarPin(pXBar, PhysConn_Audio_Tuner, 
                PINDIR_INPUT, &j);
            if (SUCCEEDED(hr))
            {
                return pXBar->Route(i, j);
            }
        }
        else  // Mute the audio
        {
            return pXBar->Route(i, -1);
        }
    }
    return E_FAIL;
}

다음 함수는 필터 그래프에서 크로스바 필터를 검색합니다. 오디오를 찾으면 오디오를 활성화하거나 음소거하려고 시도합니다(이전 함수 사용). 해당 작업이 실패하면 메서드는 업스트림 두 번째 크로스바를 검색하고 다시 시도합니다. 그래프에서 여러 크로스바 필터를 관리하는 보다 일반화된 방법은 AmCap 샘플 애플리케이션의 CCrossbar 클래스를 참조하세요.

HRESULT ActivateAudio(ICaptureGraphBuilder2 *pBuild, IBaseFilter *pSrc,
  BOOL bActivate)
{
    // Search upstream for a crossbar.
    IAMCrossbar *pXBar1 = NULL;
    HRESULT hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pSrc,
        IID_IAMCrossbar, (void**)&pXBar1);
    if (SUCCEEDED(hr)) 
    {
        hr = ConnectAudio(pXBar1, bActivate);
        if (FAILED(hr))
        {
            // Look for another crossbar.
            IBaseFilter *pF = NULL;
            hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**)&pF);
            if (SUCCEEDED(hr)) 
            {
                // Search upstream for another one.
                IAMCrossbar *pXBar2 = NULL;
                hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pF,
                    IID_IAMCrossbar, (void**)&pXBar2);
                pF->Release();
                if (SUCCEEDED(hr))
                {
                    hr = ConnectAudio(pXBar2, bActivate);
                    pXBar2->Release();
                }
            }
        }
        pXBar1->Release();
    }
    return hr;
}

다음 코드에서는 이러한 함수를 호출하는 방법을 보여 줍니다.

// Build the analog TV graph (not shown).
// Activate the audio.
hr = ActivateAudio(pBuild, pCap, TRUE);
// Later, mute the audio.
hr = ActivateAudio(pBuild, pCap, FALSE);

이러한 예제 함수는 동일한 함수 호출을 많이 반복합니다. 예를 들어 매번 크로스바 핀을 열거합니다. 실제 애플리케이션에서는 이 정보 중 일부를 캐시할 수 있습니다.

아날로그 텔레비전 오디오

크로스바 작업