Могу ли я написать фильтр преобразования DirectShow, используя асинхронное преобразование? - PullRequest
0 голосов
/ 20 октября 2011

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

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

// on main thread
lib->RegisterCallback(callback function)
lib->write(raw data bytes)

void callback(frame)
{
  // here is your frame (on a worker thread)
}

Когда я смотрю на чисто виртуальный CTransformFilter.TransformФункция ожидает преобразование быть синхронным.Теперь я могу настроить это так, чтобы оно блокировало событие, которое установлено в обратном вызове, но что произойдет, если данных, поступающих в функцию Transform, недостаточно для генерации полного нового кадра?Я бы заблокировал функцию.

Мой единственный вариант - вернуться к разработчику библиотеки и запросить синхронный декодер?

Я только что посмотрел на функцию приема CTransformFilter.Это то, что вызывает (переопределенную) функцию Transform.Затем он вызывает m_pOutput-> m_pInputPin-> Receive (pOutSample), чтобы передать образец дальше.Могу ли я вызвать эту функцию получения из рабочего потока в обратном вызове или мне нужно сохранить все в одном потоке?

Спасибо

1 Ответ

1 голос
/ 20 октября 2011

Вы все еще можете достичь того, что вы хотите. Обратите внимание, что фильтр не требуется для вывода выборки мультимедиа в том же потоке и / или в вызове, в который он получает выборку мультимедиа ввода. CTransformFilter однако сделан с учетом этого предположения.

Таким образом, в основном ваши простые решения:

  • отойдите от CTransformFilter и используйте его предка для наследования, чтобы реализовать доставку образца выходного носителя из обратного вызова [рабочего потока]
  • ожидание в функции Transform асинхронного завершения (имеет смысл, если внутренняя библиотека все еще декодирует 1 выходной кадр для 1 входного кадра) и затем подтягивается и доставляет вывод; вам также придется ждать там запросов на паузу и прерывать ожидание, чтобы не блокировать выполнение
...