Прежде всего, описанное поведение звучит как ошибка.То есть непреднамеренное поведение, вызывающее нежелательные эффекты.Я согласен, однако, что попытки обойти проблему требуют идентификации нарушителя и подробного расследования зарегистрированной проблемы.
Поскольку видео отстает от звука относительно количества, соответствующего длительным выборкам, и других побочных эффектов нет(например, как потерянные кадры) Я согласен с тем, что проблема заключается в том, чтобы определить, кто именно хранит образцы медиа.
Я могу предложить два метода на макушке головы.
Проверка памятиallocators
Этот метод не очень популярен по причинам, которые я опускаю для краткости, однако у него все еще есть хорошие шансы не работать.Фоном является то, что контактные соединения предполагают согласование распределения памяти.Распределитель памяти является частным бизнесом контактов, поэтому управляющее приложение в большинстве случаев не имеет прямого контроля (и даже доступа) к потоку данных.Чаще всего каждая пара выводов имеет свои собственные определения распределителя, однако иногда и не так редко несколько пар выводов используют один и тот же распределитель.Обратите внимание, что это выходной контакт на соединении, который принимает окончательное решение о распределителе.
Если вы знакомы с моим DirectShowSpy инструментом, одна из вещей, которые он делает, этоперечисление распределителей памяти:
Может отображать распределители памяти, для которых соединения совместно используют распределители памяти, и снимок подсчета буферов и количества свободных буферов.
Дляиз соображений краткости я опускаю ситуации, когда это неточно.
Еще одно важное замечание: эти данные доступны только в том случае, если вы вызываете шпионский интерфейс из процесса, в котором запущен граф DirectShow, а не для удаленного доступа к графу фильтров через RunningТаблица объектов.
Это означает, что вы должны сделать следующее:
- register spy
- ваше приложение работает (с графиком фильтра)
- из управляющего потока (обычно)
IUnknown::QueryInterface
для AlaxInfoDirectShowSpy::ISpy
из вашего IGraphBuilder
указателя интерфейса - do
ISpy::DoPropertyFrameModal
для отображенияПользовательский интерфейс
Вы можете получить AlaxInfoDirectShowSpy::ISpy
через #import
библиотеки типов шпиона.Если шпион не зарегистрирован через COM и не перехватывает объект OS Filter Graph Manager, ваш QueryInterface
в # 3 выше потерпит неудачу.
Из кода C # (как вы отметили вопрос соответственно) вы можете импортировать DirectShowSpy.dll в качестве ссылки на COM.
Несмотря на то, что этот метод не гарантированно работает, он имеет хорошие шансы показать вам обидчика с помощью визуализации состояний распределителя памяти и требует, чтобы в ваш файл было вставлено около 10 строк кода.application.
Добавление временного диагностического фильтра для отслеживания соединения по штырьковому соединению
Еще один метод, который имеет больше шансов работать в целом, но требует довольно много написания кода, - это разработка и фильтрация этого прозрачно впередданные от входа к выходному контакту, такие как CTransInPlaceFilter
с записью выборки данных мультимедиа где-то в общий вывод.Возможно, вы захотите повторно использовать анализаторный фильтр GraphStudioNext, в частности, для этой цели.
Идея состоит в том, чтобы подключить этот фильтр еще на выходных выводах демультиплексора и отслеживать / регистрировать данные по мере их поступления от фильтра ниже по потоку.Сравнивая временные метки на отдельных участках при потоковой передаче данных, вы сможете обнаружить нарушителя.Если вы видите задержку контроля выходных контактов демультиплексора, то демультиплексор является нарушителем.Если там все пойдет хорошо, вы бы переместили трассировку вниз по течению, особенно.над декодерами и изолировать преступника при перемещении фильтра трассировки.
Возможные обходные пути
После того, как нарушитель будет идентифицирован, вам придется подумать о том, чтобы обманным путем высвободить образцы носителей, которые он содержит, что, в свою очередь, может стать проблемой само по себе. Не имея никакой другой полезной информации на этом этапе, я подготовился бы к тому, чтобы как-то истощить его на ходу, отправив уведомление о завершении потока, или сброс, или используя динамическое согласование типа мультимедиа, чтобы в конечном итоге заставить его истощить свою внутреннюю очередь.