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

Есть ли способ определить, что граф фильтра 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, медленная сетевая файловая система, потеря сетевого соединения, медленный декодер и т. д.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 071
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вот чем я занимаюсь до сих пор. К сожалению, ожидание может завершиться неудачно по нескольким причинам (истинный eof, медленная сетевая файловая система, потеря сетевого соединения, медленный декодер и т. д.).

Mr Fooz 28.11.2008 02:43

Да, это правда - к сожалению, это лучшее решение, которое я нашел, потому что, как вы также обнаружили, IMediaDet никогда не возвращает правильную информацию, особенно если на графике есть фильтры сторонних производителей, такие как ffdshow (я также делал много кадров в последнее время).

Greg Beech 28.11.2008 02:52
Ответ принят как подходящий

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

Другие вопросы по теме