Есть ли способ определить, что граф фильтра DirectShow достиг конца своего файла? В конце своего файла я имею в виду, что граф фильтра с фильтром SampleGrabber никогда не получит другого вызова SampleCB.
Вот некоторые вещи, которые не работают:
IMediaDet::get_StreamLength (часто говорят, что в видео больше кадров, чем существует на самом деле)IMediaSeeking::GetDuration (соответствует IMediaDet, +/- один кадр)IMediaControl::GetState (граф фильтра продолжает работать, даже если все кадры уже были обработаны из файла)Фон:
Я занимаюсь обработкой видео, и у меня есть класс, который создает граф фильтра с помощью SampleGrabber. Всякий раз, когда вызывается SampleGrabber::SampleCB, я блокирую его мьютексом, чтобы можно было запустить filtergraph в режиме pull. Когда я готов к следующему кадру, я разблокирую мьютекс в своем основном потоке и жду, пока SampleGrabber::SampleCB отправит мне сигнал, что это сделано. Для некоторых видео IMediaDet::get_StreamLength сообщает мне, что в видео больше кадров, чем существует на самом деле. Как только я извлекаю последний кадр и запрашиваю на один больше, чем существует на самом деле, основной поток блокируется навсегда, потому что SampleGrabber::SampleCB больше никогда не будет вызван. Я хотел бы иметь возможность определять, когда SampleGrabber::SampleCB никогда не будет вызываться для файловых источников. Такие приложения, как Windows Media Player, могут каким-то образом делать это, потому что графический интерфейс сообщает, что видео закончилось после последнего реального кадра, поэтому, очевидно, есть способ сделать это.
Обновлено:
Я использую WaitForSingleObject для реализации блокировки основного потока. Обходной путь, который я использовал до сих пор, - это сделать то, что предложил Грег: иметь конечный тайм-аут. К сожалению, это немного сложно. Ожидание может завершиться неудачей по многим причинам, таким как истинный eof, медленная сетевая файловая система, потеря сетевого соединения, медленный декодер и т. д.





Предполагая, что основной поток блокируется на WaitForSingleObject, не могли бы вы указать тайм-аут для ожидания? Затем, если ожидание возвращается, потому что оно истекло, а не потому, что оно получило сигнал, вы будете знать, что это последний кадр.
Да, это правда - к сожалению, это лучшее решение, которое я нашел, потому что, как вы также обнаружили, IMediaDet никогда не возвращает правильную информацию, особенно если на графике есть фильтры сторонних производителей, такие как ffdshow (я также делал много кадров в последнее время).
Может с помощью интерфейса IMediaEventEx? Один из кодов событий - EC_COMPLETE, задокументированный как «Все данные из определенного потока были визуализированы».
Вот чем я занимаюсь до сих пор. К сожалению, ожидание может завершиться неудачно по нескольким причинам (истинный eof, медленная сетевая файловая система, потеря сетевого соединения, медленный декодер и т. д.).