TV 오디오 미리 보기
[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드에서 DirectShow 대신 MediaPlayer, IMFMediaEngine 및 오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]
TV 오디오를 미리 보려면 크로스바 필터의 오디오 디코더 핀을 오디오 튜너 핀으로 라우팅합니다. 오디오를 음소거하려면 다음 다이어그램과 같이 오디오 디코더 핀을 -1로 라우팅합니다. (크로스바 필터는 크로스바 작업에 설명되어 있습니다.)
기본 방법은 다음과 같습니다.
- ICaptureGraphBuilder2::FindInterface 메서드를 사용하여 크로스바 필터를 찾습니다.
- IAMCrossbar::get_CrossbarPinInfo 메서드를 사용하여 크로스바 필터의 입력 및 출력 핀을 열거합니다. 오디오 디코더 출력 핀과 오디오 튜너 입력 핀을 검색합니다.
- 올바른 핀을 찾으면 IAMCrossbar::Route 를 호출하여 핀을 라우팅합니다. 그렇지 않은 경우 다른 크로스바를 업스트림 보고 프로세스를 반복합니다.
- 오디오를 음소거하려면 오디오 디코더 핀을 -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);
이러한 예제 함수는 동일한 함수 호출을 많이 반복합니다. 예를 들어 매번 크로스바 핀을 열거합니다. 실제 애플리케이션에서는 이 정보 중 일부를 캐시할 수 있습니다.
관련 항목