Ой, Я Задерживаюсь. Часть 2

В предыдущая статья мы говорили о снижении задержки при видеотрансляции.

С доставкой разобрались, теперь поговорим о доставке.



Ой, я задерживаюсь.
</p><p>
 Часть 2

В клиенте есть места, где видео может скапливаться и отставать от реального времени:

  • входной сетевой буфер;
  • внутренний буфер синхронизации транспорта;
  • буфер протокола для компенсации колебаний скорости сети;
  • буфер игрока;
  • буфер декодера (видеокарта);
  • Аппаратные задержки.

И это снова буферы, буферы и еще раз буферы.

Давайте по порядку.



Ой, я задерживаюсь.
</p><p>
 Часть 2

(трубный буфер)

Входной сетевой буфер

Клиент получает данные через сетевой сокет. IP-сокеты имеют буферы, которые могут заполниться, если данные пользовательской программы не будут получены достаточно быстро.

Если буфер слишком мал, то видеотрансляция будет постоянно прерываться, а если слишком велик, то пользователю придется ждать заполнения буфера дольше необходимого времени, определяемого скоростью передачи данных.

В худшем случае, если буфер меньше мегабайта, то он может содержать до 4-8 секунд видео.

Если буфер заполнен, то восстановить реальное время можно либо быстрой перемоткой назад, либо сбросом части данных.

На самом деле такого почти никогда не происходит, потому что разработчики плееров откладывают эту функциональность на будущие выпуски.

С точки зрения близости к реальному времени большой сетевой буфер — это зло.

С точки зрения плавного воспроизведения телеканала это вполне разумная вещь, ведь ядро работает достаточно быстро и хорошо, чтобы успевать заполнять свои буферы.

Посмотреть состояние буфера на клиенте сложно, потому что если бы там был Linux, можно было бы запустить утилиту ss. А вот узнать эту информацию на Android или Windows сложнее.



Внутренний буфер синхронизации демультиплексора

В разных протоколах любят по-разному разделять аудио и видео.

Например, в MPEG-TS принято брать 3-5 аудиокадров подряд и объединять их в один пакет для уменьшения трафика.

В этом случае поток кадров из «ВАВААВАВАА» превращается в «ВВААААВВААААААААВВВААА».

При этом временные метки перемешиваются и, если в дальнейшем вы хотите, чтобы они были отсортированы (например, для вывода в RTMP это критично), то нужно создать буфер, который будет замедлять кадры.

Особенно замечательное поведение такой буфер показывает, когда звук пропадает полностью или на одном канале из пяти.

В общем, отличить полную потерю от очень большой задержки практически невозможно.

Поэтому в процессе разработки приходится писать код, который должен «чувствовать» то, что там произошло.



Буфер компенсации скорости сети

Здесь мы поговорим о буфере, который у нас есть в HLS, или о буфере, которым управляли в RTMP-плеере.

Например, плеер HLS работает так:

  • плеер загружает три сегмента;
  • Загрузив третий, плеер начинает воспроизведение потока, начиная с первого;
  • один процесс независимо извлекает самый старый сегмент, а другой заменяет первый.

В идеале в буфере сохраняются 2-3 сегмента, которые могут исчезнуть, если скорость сети начнет снижаться.

В любой плеер встроен буфер для компенсации колебаний скорости сети.

Например, для RTMP этот буфер теоретически 0, для HLS теоретически, скажем, 10 секунд, для RTSP-плееров обычно действительно 0, а в SIP именно 0. Мы говорим «теоретически», потому что при граничных параметрах ничего не будет работать.

Например, плееры HLS могут работать крайне нестабильно на 1-секундных фрагментах.

Причем это может быть связано с банальными ошибками типа учета длительности сегмента в секундах, а не миллисекундах.

А RTMP-флеш-плеер с нулевым буфером ведет себя просто «потрясающе» — начинает накапливать задержку в одну секунду в минуту и через пару часов может умереть в страшных муках.



Буфер игрока

Механизм воспроизведения почти всегда отделен от механизма загрузки видео по какому-либо протоколу.

Кадры распаковываются, отделяются от метаданных и передаются в плеер.

Дальше начинается «странное»: для начала воспроизведения Flash и MSE player может потребоваться более одного кадра.

Если это произойдет, вы снова начнете испытывать задержки и задержки.

Здесь цифры порядка 2–5 кадров, т.е.

до 200 мс.



Декодер-буфер

Хороший декодер реального времени немедленно раскодирует полученный поток и передаст его.

Блоки доступа поступают в буфер непрерывно, и скорость заполнения буфера пропорциональна скорости кодированного потока.

Блокам доступа требуется разное время для загрузки в буфер, поскольку закодированные изображения содержат разные объемы данных.

Данные выгружаются из буфера через равные промежутки времени, равные частоте кадров воспроизводимого изображения, причем выгружаются целиком и мгновенно.

Если, например, начальная задержка нового потока существенно больше конечной задержки старого потока, то после того, как последнее изображение старого потока будет воспроизведено и выгружено из буфера, вам придется долго ждать первое изображение нового потока, которое будет декодировано и воспроизведено.

Это приведет, например, к зависанию последнего изображения старого потока и заметному склеиванию.

Если скорость нового потока существенно превышает скорость старого, то слияние будет еще заметнее, так как произойдет переполнение буфера и потеря части данных.



Ой, я задерживаюсь.
</p><p>
 Часть 2

Если вы включили b-кадры при кодировании потока реального времени, что само по себе замечательная идея, то сразу на выходе вы получите задержку N*T, где:

  • N - максимальное расстояние для перестановки кадров, обычно около 4
  • Т — длительность кадра.

    Для 25 кадров в секунду это 40 мс.

Таким образом, на ровном месте мы получаем задержку не менее 160 мс.

В реальности декодер все равно может тормозить кадр-другой или просто не иметь хорошего API событий для своевременного оповещения о готовности кадра.



Аппаратные задержки на последнем метре доставки видео

Необходимо показать огромный декодированный кадр.

Если вы декодировали не на видеокарте, а на процессоре, то для отображения его необходимо скопировать в видеопамять, а это требует времени.

Видеокарты тоже могут добавлять миллисекунды, но обычно это не так уж и плохо по сравнению с тысячами миллисекунд в предыдущих случаях.



Общий

Как только вы поймете все типы задержек при доставке и получении видео, вы сможете приступить к их измерению.

В следующей статье мы расскажем, как это можно сделать.

Теги: #Работа с видео #видео #Разработка систем связи #задержка #буферы #передача видео по сети #передача видео

Вместе с данным постом часто просматривают: