Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.9.170] |
|
Сообщ.
#1
,
|
|
|
Добрый вечер!
Я написал фильтр DirectShow, который получает аудиопоток PCM из сети и передает его следующему фильтру (динамику). Фильтр написан на основе примера из SDK (bouncing ball). Хотелось бы понять, как правильно ставить timestamp-ы у сэмпла. В примере из SDK (у меня – так же) простановка time stamp-ов в методе CBallStream(это потомок CSourceStream)::FillBuffer для каждого mediasample делается так: (0) Время начала (m_rtSampleTime) = время окончания предыдущего сэмпла, время окончания = время начал + продолжительность. Мне не совсем понятно: (1) почему время начала сэмпла не устанавливается путем вызова StreamTime: HRESULT ok_time = m_pFilter->StreamTime(m_rtSampleTime); (2) в чем кардинальная разница между методом (0) и (1) ? Какой более правильный ? (3) также мне не совсем понятно – для чего нужно использовать IMediaSample::SetMediaTime ? Если я вызываю его для сэмпла или не вызываю – ничего не меняется. Для чего он нужен ? Не могли бы Вы подсказать по вопросам (1), (2), (3) ? |
Сообщ.
#2
,
|
|
|
Отвечу на ваши вопросы по порядку:
1. Почему время начала сэмпла не устанавливается путем вызова StreamTime: HRESULT ok_time = m_pFilter->StreamTime(m_rtSampleTime); Метод StreamTime является вспомогательным методом, который позволяет установить значение времени начала потока (stream time). Время начала потока – это абсолютное значение времени, которое используется для синхронизации потоков в системе. Например, если в системе работают два потока – аудио и видео – то время начала каждого сэмпла в этих потоках должно соответствовать времени начала друг друга, чтобы видео и аудио были синхронизированы. Метод FillBuffer, в свою очередь, использует механизм относительного времени начала (sample time), то есть времени начала каждого сэмпла относительно предыдущего сэмпла. Это значение устанавливается с помощью переменной m_rtSampleTime. При этом значение m_rtSampleTime устанавливается не вручную, а вычисляется на основе времени окончания предыдущего сэмпла, как вы уже указали. 2. В чем кардинальная разница между методом (0) и (1)? Какой более правильный? Метод (0), который вы описали, использует механизм относительного времени начала (sample time) для установки времени начала каждого сэмпла относительно предыдущего. Метод (1), который вы предложили, использует абсолютное значение времени начала потока (stream time) для установки времени начала каждого сэмпла. Вообще говоря, оба метода можно использовать для установки времени начала сэмпла, но в зависимости от конкретной ситуации может быть предпочтительнее использовать один из них. Например, если вы работаете с несколькими потоками и хотите, чтобы время начала каждого сэмпла было синхронизировано между потоками, то следует использовать метод StreamTime. Если же вы работаете только с одним потоком, то можно использовать механизм относительного времени начала. 3. Для чего нужно использовать IMediaSample::SetMediaTime? Если я вызываю его для сэмпла или не вызываю – ничего не меняется. Для чего он нужен? (3) Метод SetMediaTime используется для установки временных меток, которые связаны с данными, а не с временем, прошедшим с момента начала воспроизведения потока. Это может быть полезно, например, при использовании потокового видео, когда на экране может быть отображено несколько видео-потоков, каждый из которых начинается в разное время, но должен быть синхронизирован с другими потоками. В этом случае временные метки могут помочь гарантировать синхронизацию. В целом, использование метода SetMediaTime необязательно, и если вы не сталкиваетесь с проблемами синхронизации, то можете не беспокоиться о нем. |