Media Foundation - Проблемы с использованием совокупного источника медиа с захватом аудио / видео - PullRequest
1 голос
/ 08 апреля 2019

Мне было поручено создать приложение, которое принимает вход для захвата аудио / видео (используя Elgato Cam Link) и выводит его обратно пользователю.Согласно документации Microsoft Audio / Video Capture в Media Foundation , предлагается « Если вы хотите объединить захват звука с захватом видео, используйте совокупный источник мультимедиа. »

Я снял большую часть кода, который мне был нужен, из исходного кода topoedit, но topoedit нигде не использует агрегатные источники, поэтому я не совсем понимаю, как их правильно использовать.

Я сталкиваюсь с двумя различными проблемами при использовании совокупного источника мультимедиа.

  1. Частота кадров У меня есть одно устройство захвата (Elgato Cam Link), которое успешно воспроизводит аудио и видео, когда я использую совокупный источник мультимедиа, но по какой-то причине частота кадров хуже, чем если бы я просто запускал две совершенно разные топологии (одну для видео, однудля аудио).

  2. Ошибка MF_E_TOPO_CODEC_NOT_FOUND (0xC00D5212) при вызове IMFTopoloader :: Load () Когда я пытаюсь использовать совокупный источник мультимедиа на двух разных ноутбуках (используя любую встроенную веб-камеру / микрофон), я сталкиваюсь с этой ошибкой.Эта ошибка меня смущает, потому что она работает нормально, если я использую две совершенно разные топологии (одну для видео, другую для аудио).

Первичная настройка:

  • ОС: Windows 10
  • Устройство захвата: Elgato Cam Link (USB-накопитель с входом HDMI)
  • Язык: C ++

Просто чтобы заранее исключить некоторые предложения ...

  • Просто используйте DirectShow! Мне бы хотелось, чтобы я мог.Единственная причина, по которой мне было поручено это, заключается в том, что наше решение DirectShow имеет серьезные проблемы с частотой кадров для устройства Elgato Cam Link.Мы не могли понять, почему, поэтому Media Foundation показался нам лучшим выбором.

  • Используйте две отдельные топологии! Вот как у меня это сейчас работает.Это просто чувствует неправильно, понимаешь?В документации написано, что нужно использовать совокупный источник, поэтому я хотел провести тщательную проверку.В конце концов, если я не получу ответ на этот вопрос, я, по крайней мере, могу спокойно отдыхать, зная, что у меня есть что-то функциональное, но я в основном задаю этот вопрос на случай, если я могу что-то сделатьлучше.Скайп должен делать что-то вроде этого, верно?(Если подумать, 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.

И вот где я вызываю IMFTopoloader :: Load(), если вы более заинтересованы в решении задачи № 2 (опять же, исключая проверку ошибок для краткости).

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 Клиент, для которого он был написан, кажется, недостаточно заботится о том, чтобы предоставить мне какой-либо отзыв (хороший или плохой), поэтому мне все равно, чтобы следить за этим странным выпуск.

...