預覽電視音訊
[與此頁面相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議使用舊版 API 的現有程式碼盡可能重寫為使用新的 API。
若要預覽電視音訊,請將交叉欄篩選上的音訊解碼器釘選路由傳送至音訊微調器釘選。 若要將音訊靜音,請將音訊解碼器釘選路由傳送至 -1,如下圖所示。 (使用 Crossbars.)
基本方法如下:
- 使用 ICaptureGraphBuilder2::FindInterface 方法來尋找交叉欄篩選。
- 使用 IAMCrossbar::get_CrossbarPinInfo 方法來列舉交叉列篩選的輸入和輸出針腳。 搜尋音訊解碼器輸出釘選和音訊微調器輸入針腳。
- 如果您找到正確的針腳,請呼叫 IAMCrossbar::Route 來路由釘選。 如果沒有,請尋找上游以尋找另一個交叉列,並重複此程式。
- 若要將音訊靜音,請將音訊解碼器釘選路由傳送至 -1。
大部分的電視微調器都會使用單一交叉橫條篩選準則,但有些則使用兩個交叉橫條篩選。 因此,如果第一個交叉欄失敗,您可能必須搜尋第二個交叉列。
注意
與您可能預期的相反,不需要音訊擷取篩選或音訊轉譯器來預覽音訊,因為微調器卡片與聲音卡之間有實體連線。
下列程式碼會更詳細地顯示這些步驟。 首先,以下是協助程式函式,可搜尋指定針腳類型的交叉欄篩選:
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);
請注意,這些範例函式會重複許多相同的函式呼叫。 例如,它們會每次列舉交叉條針腳。 在實際的應用程式中,您可能會快取其中一些資訊。
相關主題