обнаружение eof для DirectShow

Есть ли способ определить, что файл фильтра DirectShow достиг конца? Под концом файла я подразумеваю, что filtergraph с фильтром SampleGrabber никогда не получит другого вызова SampleCB.

Вот некоторые вещи, которые не работают:

  • Доверяйте IMediaDet::get_StreamLength (часто говорят, что в видео больше кадров, чем на самом деле)
  • Trust IMediaSeeking::GetDuration (согласуется с IMediaDet, +/- один кадр)
  • Использовать IMediaControl::GetState (график фильтра продолжает работать, даже если все кадры из файла уже обработаны)

Предыстория:

Я занимаюсь обработкой видео, и у меня есть класс, который создает график фильтров с помощью SampleGrabber. Всякий раз, когда вызывается SampleGrabber::SampleCB, я блокирую его мьютексом, чтобы я мог запустить filtergraph в режиме извлечения. Когда я готов к следующему фрейму, я разблокирую мьютекс в своем основном потоке и жду, пока SampleGrabber::SampleCB отправит мне сигнал о том, что все готово. Для некоторых видео IMediaDet::get_StreamLength говорит мне, что в видео больше кадров, чем есть на самом деле. Как только я извлек последний кадр и запросил на один больше, чем существует на самом деле, основной поток блокируется навсегда, потому что SampleGrabber::SampleCB больше никогда не будет вызываться. Я хотел бы иметь возможность определить, когда SampleGrabber::SampleCB никогда не будет вызываться для источников файлов. Такие приложения, как Windows Media Player, каким-то образом могут это сделать, потому что графический интерфейс сообщает, что видео закончилось после последнего реального кадра, так что, по-видимому, есть способ сделать это.

ИЗМЕНИТЬ:

Я использую WaitForSingleObject для реализации блокировки основного потока. Обходной путь, который я использовал до сих пор, заключается в том, чтобы сделать то, что предложил Грег: иметь конечный тайм-аут. К сожалению, это становится немного сложнее. Ожидание может завершиться неудачей по многим причинам, таким как настоящий eof, медленная сетевая файловая система, потеря сетевого соединения, медленный декодер и т. д.


person Mr Fooz    schedule 27.11.2008    source источник


Ответы (2)


Возможно, с помощью интерфейса IMediaEventEx? Один из кодов событий EC_COMPLETE задокументирован как «Все данные из определенного потока обработаны».

person David Rodríguez - dribeas    schedule 28.11.2008

Предполагая, что основной поток блокируется на WaitForSingleObject, не могли бы вы указать тайм-аут для ожидания? Затем, если ожидание возвращается из-за того, что время ожидания истекло, а не из-за того, что он получил сигнал, вы будете знать, что это последний кадр.

person Greg Beech    schedule 27.11.2008
comment
Это то, что я делал до сих пор. К сожалению, ожидание может завершиться неудачно по нескольким причинам (истинный eof, медленная сетевая файловая система, потеря сетевого соединения, медленный декодер и т. д.). - person Mr Fooz; 28.11.2008
comment
Да, это правда - к сожалению, это лучшее решение, которое я нашел, потому что, как вы также обнаружили, IMediaDet никогда не возвращает правильную информацию, особенно если на графике есть фильтры не Microsoft, такие как ffdshow (я также делал в последнее время много захвата кадров). - person Greg Beech; 28.11.2008