预览电视音频
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 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);
请注意,这些示例函数重复许多相同的函数调用。 例如,它们每次枚举横线引脚。 在实际应用程序中,可能会缓存其中一些信息。
相关主题