Media Foundation-将聚合媒体源与音频/视频捕获结合使用的问题

时间:2019-04-08 19:07:21

标签: video-capture ms-media-foundation audio-capture

我的任务是创建一个应用程序,该应用程序接收音频/视频捕获输入(使用Elgato Cam Link)并将其输出回用户。  根据Microsoft的Audio/Video Capture in Media Foundation文档,建议“ 如果要将音频捕获与视频捕获结合使用,请使用聚合媒体源。

我从topoedit的源代码中删除了我需要的大部分代码,但是topoedit并未在任何地方使用聚合源,因此在正确使用它们方面我有些盲目。

使用聚合媒体源时遇到两个不同的问题。

  1. 帧频
    我有一个捕获设备(Elgato Cam Link),当我使用聚合媒体源时可以成功播放音频和视频,但是由于某些原因,帧速率比我只运行两种完全独立的拓扑(一种用于视频,一种用于音频)更糟糕。

  2. 调用IMFTopoloader :: Load()时出现错误MF_E_TOPO_CODEC_NOT_FOUND(0xC00D5212)
    当我尝试在两台不同的笔记本电脑上使用聚合媒体源时(使用任何内置的网络摄像头) /麦克风组合),我遇到此错误。这个错误使我感到困惑,因为如果我使用两种完全独立的拓扑(一种用于视频,一种用于音频),它运行得很好。

主要设置:

  • 操作系统:Windows 10
  • 捕获设备:Elgato Cam Link(带有HDMI输入的USB棒)
  • 语言:C ++

只是提前排除一些建议...

  • 只需使用DirectShow!
    我希望我能。我受此困扰的唯一原因是因为我们的DirectShow解决方案在Elgato Cam Link设备上出现严重帧速率问题。我们无法弄清楚为什么,所以Media Foundation似乎是我们最好的选择。

  • 使用两个单独的拓扑!
    这就是我目前正在使用的方式。这只是感觉错误,您知道吗?该文档说要使用汇总源,因此我想尽职调查。最后,如果我没有得到这个问题的答案,我至少可以轻松自在地知道我具有 something 功能,但是我主要是在问这个问题,以防万一更好的东西。 Skype必须做这样的事情吗? (再三考虑,Skype不会将音频输出回自己的扬声器,所以也许不会)。肯定有人在那里知道如何使用聚合源。

鉴于我的程序可以在Elgato设备上成功运行,我怀疑我没有做任何可怕的错误。如果有问题,可能是我没有使用的代码,而不是我可以显示的任何内容。

话虽如此,我在这里创建聚合源(不包括为简洁起见进行错误检查)。

HRESULT GenerateAggregateSource(IMFMediaSource*& pAggSource, IMFMediaSource* pSource1, IMFMediaSource* pSource2)
{
    pAggSource = NULL;

    HRESULT hr = S_OK;

    IMFCollection* pSourceCollection = NULL;
    hr = ::MFCreateCollection(&pSourceCollection);

    hr = pSourceCollection->AddElement(pSource1);

    hr = pSourceCollection->AddElement(pSource2);

    hr = ::MFCreateAggregateSource(pSourceCollection, &pAggSource);
    pSourceCollection->Release();   // Done with this

    return hr;
}

然后我将EVR连接到流描述符0,将SAR连接到流描述符1。

如果您更想解决第2个问题(同样,不包括为简便起见而进行的错误检查),那么这里就是我称之为IMFTopoloader :: Load()的地方。

HRESULT ResolveTopology(IMFTopology*& pTopology, IMFMediaSession* pMediaSession)
{
    HRESULT hr = S_OK;

    IMFTopoLoader* pTopoLoader = NULL;
    hr = ::MFCreateTopoLoader(&pTopoLoader);

    IMFTopology* pFullTopology = NULL;
    hr = pTopoLoader->Load(pTopology, &pFullTopology, NULL);
    // Laptop webcams seem to encounter this error here
    //MF_E_TOPO_CODEC_NOT_FOUND

    hr = pMediaSession->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, pFullTopology);

    // Swap the topology we're holding
    pTopology->Release();
    pTopology = pFullTopology;

    // Done with this
    pTopoLoader->Release();

    return hr;
}

使用请求的拓扑更新:

这是我的局部拓扑的粗略示例。这可能是您所期望的,因为我不想做任何花哨的事情。

                 ⇗ EVR
Agg. Source (A/V)
                 ⇘ SAR

一旦我解析了拓扑,还会注入什么额外的东西?我不知道该如何走链并查询拓扑中的所有内容。如果您相信topoedit分别处理音频和视频源的功能,那么它看起来像这样。

                 ⇗ {CF862982-23B0-4E3D-8C76-D03FEF084AF8} ⇒ EVR
Agg. Source (A/V)
                 ⇘ SAR

什么是{CF862982-23B0-4E3D-8C76-D03FEF084AF8}?我不确定,也不确定如何找出答案。

当我再次访问Elgato时,我将更新上述拓扑。我目前没有它。

更新2 所写的客户似乎不太关心向我提供任何反馈(好坏),因此我不太在意对此进行跟进奇怪的问题。

0 个答案:

没有答案