预览电视音频

[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayerIMFMediaEngine音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

若要预览电视音频,请将横线筛选器上的音频解码器引脚路由到音频调谐器引脚。 若要将音频静音,请将音频解码器引脚路由到 -1,如下图所示。 使用 Crossbars.) 中介绍了 (交叉条筛选器

路由音频解码器引脚

基本方法如下:

  1. 使用 ICaptureGraphBuilder2::FindInterface 方法查找横线筛选器。
  2. 使用 IAMCrossbar::get_CrossbarPinInfo 方法枚举横线筛选器的输入和输出引脚。 搜索音频解码器输出引脚和音频调谐器输入引脚。
  3. 如果找到正确的图钉,请调用 IAMCrossbar::Route 来路由图钉。 如果没有,请上游查找另一个横线并重复此过程。
  4. 若要将音频静音,请将音频解码器引脚路由到 -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);

请注意,这些示例函数重复许多相同的函数调用。 例如,它们每次枚举横线引脚。 在实际应用程序中,可能会缓存其中一些信息。

模拟电视音频

使用交叉条