Настройка и получение позиции

[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngineи захват аудио и видео в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и Аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]

Граф фильтров поддерживает два значения позиции, текущую позицию и позицию остановки. Они определены следующим образом:

  • При запуске графика текущая позиция определяется как позиция воспроизведения относительно начала источника. Когда граф остановлен или приостановлен, текущая позиция — это точка, в которой потоковая передача начнется в следующей команде запуска.
  • Позиция остановки — это точка, в которой будет заканчиваться поток. Когда граф достигает позиции остановки, больше данных не передается, а диспетчер графов фильтров отправляет событие EC_COMPLETE. (Однако граф не переключается на остановленное состояние. Дополнительные сведения см. в разделе реагирование на события.)

Чтобы получить эти значения, вызовите метод IMediaSeeking::GetPositions. Возвращаемые значения всегда относятся к исходному источнику мультимедиа. По умолчанию значения указаны в единицах опорного времени. В некоторых случаях можно изменить единицы времени; дополнительные сведения см. в Форматы времени для команд поиска.

Чтобы найти новую позицию или задать новую позицию остановки, вызовите метод IMediaSeeking::SetPositions, как показано в следующем примере:

#define ONE_SECOND 10000000
REFERENCE_TIME rtNow  = 2 * ONE_SECOND, 
               rtStop = 5 * ONE_SECOND;

hr = pSeek->SetPositions(
    &rtNow,  AM_SEEKING_AbsolutePositioning, 
    &rtStop, AM_SEEKING_AbsolutePositioning
    );

Заметка

Одна секунда — 10 000 000 единиц эталонного времени. Для удобства пример определяет это значение как ONE_SECOND. Если вы используете библиотеку базовых классов DirectShow, константы UNITS имеют то же значение.

 

Параметр rtNow указывает новую текущую позицию. Второй параметр — это флаг, определяющий способ интерпретации rtNow. В этом примере флаг AM_SEEKING_AbsolutePositioning указывает, что rtNow указывает абсолютную позицию в источнике. Таким образом, граф фильтра будет стремиться к позиции два секунды с начала потока. Параметр rtStop дает время остановки. Последний параметр указывает, что rtStop также является абсолютной позицией.

Чтобы указать позицию относительно предыдущего значения позиции, используйте флаг AM_SEEKING_RelativePositioning. Чтобы оставить одно из значений позиции без изменений, используйте флаг AM_SEEKING_NoPositioning. В этом случае соответствующий параметр времени может быть NULL. Следующий пример ищет вперед на 10 секунд, но оставляет позицию остановки без изменений:

REFERENCE_TIME rtNow = 10 * ONE_SECOND;
hr = pSeek->SetPositions(
    &rtNow, AM_SEEKING_RelativePositioning, 
    NULL, AM_SEEKING_NoPositioning
    );

Если граф фильтров остановлен, средство отрисовки видео не обновляет изображение после операции поиска. Пользователю будет отображаться, как если бы поиск не произошел. Чтобы обновить изображение, приостанавливайте график после операции поиска. Приостановка графа подготавливает новый кадр для рендера видео. Вы можете использовать метод IMediaControl::StopWhenReady, который приостанавливает граф и останавливает его.