0,0
рейтинг
31 августа 2015 в 03:42

Дизайн → Трансляция онлайн-видео с минимальной задержкой

Не так давно к нам обратился клиент, который занимается видео-трансляциями аукционов и лошадиных скачек в прямом эфире. Сами мероприятия проходят в Австралии, а вот ставки на них делаются игроками в Макао — игровой столице Юго-Восточной Азии. Разумеется, он столкнулся с задержкой сигнала — как без неё. Задержка — это время между взятием кадра и его появлением на экране конечного устройства. И если обычному зрителю задержка в 5 или даже 10 секунд не критична, то тем, кто ставит на тотализаторе, подобная разница может стоить огромных денег. Отсюда возникла задача — свести к минимуму время прохождения видео от источника к зрителю.

В итоге задача была решена, удалось снизить задержку во всей цепочке до 500 мс. Вспомнился заодно случай, когда с помощью нашего софта другой клиент уменьшил время вещания видео с Андроида на экран компьютера до 1-2 секунд, что оказалось лучшим показателем по сравнению в другими вариантами, которые он пробовал.

Мы подумали, что некоторые техники, которые мы применили, будут интересны не только нам.

Итак, цепочку доставки видео схематично можно разделить на 6 этапов: съёмку, сжатие, передачу по локальной сети от энкодера к медиа-серверу, передача через интернет, декодирование и отображение на устройстве пользователя.



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

1. Съёмка видео


Тут всё просто — всё зависит от камеры, которая используется в съёмке. Задержка здесь — меньше 1 мс, поэтому при выборе устройства можно сосредоточиться на потребительских качествах — кодеках и протоколах, качестве картинки, цене и т.п.

2. Сжатие (энкодинг)


Сжатие видео (encoding) — это обработка исходного видео с целью уменьшить размер передаваемых данных. Цель — пожать поток с помощью подходящего для задачи кодека. В настоящее время стандартом де-факто является видео в H.264 с аудио в AAC.

Работа на этом шаге влияет на всю цепочку в дальнейшем.

Предпочтение лучше отдать аппаратным решениям, т.к. программные добавляют время, нужное для работы с ресурсами, и накладные расходы операционной системы. Правильно настроенный энкодер не добавляет сколько-нибудь ощутимой задержки, но он задаёт битрейт результирующего потока и его тип. Различают переменный битрейт (variable bitrate, VBR) и постоянный (constant bitrate, CBR).

Главное преимущество VBR — он выдаёт поток с наилучшим соотношением качества изображения и количества занимаемых данных. Однако для него нужно больше вычислительных мощностей. Кроме того, если битрейт в отдельный момент времени превосходит пропускную способность канала, это далее повлечет за собой буферизацию на этапе декодирования. Поэтому для передачи видео в реальном времени с малой задержкой рекомендуется использовать CBR.

Однако с CBR тоже не всё так просто. На деле постоянный битрейт не является постоянным в каждый отдельный момент времени, т.к. поток H.264 содержит кадры разной величины. Поэтому в энкодере есть контроль усреднения битрейта на отдельных промежутках времени, чтобы объём данных был одинаковым на протяжении всей трансляции. Усреднение это делается, конечно же, в ущерб качеству. Чем меньше период усреднения, тем меньше буфер на этапе декодирования и тем хуже качество передаваемого видео.

Энкодеры промышленного уровня предоставляют разнообразные средства управления битрейтом, призванные давать CBR минимальным воздействием на качество. Их описание выходит за рамки нашей статьи, можно лишь упомянуть о таких параметрах как гранулярность контроля битрейта (Rate Control Granularity) и контентно-адаптивный контроль битрейта (Content-Adaptive Rate Control).

3. Передача от энкодера к медиа-серверу


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

Протокол передачи данных нужно выбирать исходя из возможностей энкодера и медиа-сервера, который будет раздавать данные конечным пользователям. Для передачи видео в реальном времени наиболее подходят RTSP, RTMP или MPEG2-TS.

4. Передача через Интернет на устройство пользователя


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

Первый фактор в этой цепочке — буферизация внутри медиа-сервера при транзмаксинге (перепаковке) потока из одного протокола в другой.

Второй фактор связан со спецификой каждого протокола.
Если собираетесь использовать протоколы на базе HTTP, например HLS или MPEG-DASH, будьте готовы к существенному увеличению задержки. Дело здесь в самом принципе работы этих протоколов — они основаны на разбиении контента на сегменты, или чанки, которые выдаются последовательно. Размер сегментов зависит от протокола и параметров передачи, однако их не рекомендуется делать меньше 2 секунд. Apple рекомендует размет чанков в 10 секунд. Поэтому при использовании HLS надо или уменьшать размер, или смириться с потерями времени.
Можно предположить, что можно построить доставку на HLS или DASH, максимально уменьшив размер сегментов и сведя все остальные потери времени к минимуму. И для большинства кейсов это сработает. Однако для передачи в реальном масштабе времени (ведь в нашем примере — аукционы) нужно использовать протоколы RTMP или RTSP.

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


(полная версия карты кабелей — здесь)

Возможен вариант, когда между исходных медиа-сервером и зрителем вы решите поставить так называемый edge, то есть промежуточный кеширующий медиа-сервер для снижения нагрузки на систему при большом числе одновременных подключений. Если так, то не забудьте накинуть соответствующую задержку ещё и для эджа. Конечно, для максимальной оптимизации вы эджи будете ставить только для обычных зрителей, которым задержка не критична, однако помнить об этом тоже нужно.

5. Декодирование


Это шаг может сильно влиять на скорость передачи. Чтобы отыграть возможную недостачу данных при передаче (помним про предыдущие шаги), буфер проигрывания должен содержать данные одного полного усреднённого периода с учетом сетевых задержек. Поэтому буфер может содержать от нескольких GOP-ов (GOP = group of pictures) до нескольких кадров, в зависимости от параметров энкодера и состояния сети. Многие плееры принимают минимальное значение буфера проигрывания равным 1 секунде и меняют его по ходу работы. Минимально возможный буфер достигается при использовании аппаратных декодеров (плееров), например на базе Raspberry Pi.

6. Отображение


Здесь, как и на первом шаге, время задержки пренебрежимо мало — всё покрывается возможностями железа.

Возвращаясь к примеру с нашим клиентом, цепочка доставки строилась из следующих частей. Видео снималось камерой и отдавалось на аппаратный энкодер Beneston VMI-EN001-HD. Далее от него поток по RTMP шёл на Nimble Streamer, который был настроен на максимальную производительность. В Макао данные шли также по RTMP, где в зале для приёма ставок стоит Raspberry Pi для декодировки и отображения на больших мониторах. Пинг от Австралии до Макао составил 140 мс. В RTMP-плеере на Raspberry Pi буфер был выставлен на 300 мс. Результирующая задержка сигнала для потока 1080p30 варьировалась между 500 и 600 миллисекундами, что вполне покрывает требования заказчика. Простые зрители по всему миру видят картинку с опозданием 3-4 секунды — не с последнюю очередь потому, что предпочитают смотреть через HLS на мобильных устройствах. В данном случае эта величина также приемлема.

В общем, живое вещание — штука непростая во всех смыслах. Достижение высоких показателей производительности — серьёзная задача и уменьшение времени прохождения сигнала требует подбора правильных компонент и их кропотливой настройки.
Юрий Удовиченко @Aquary
карма
98,2
рейтинг 0,0
nimblestreamer.ru
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Дизайн

Комментарии (32)

  • +6
    Где технические детали?
    Где хайлоад?
    Гоняли SD или HD и какой битрейт?
    Как вы замеряли результирующую задержку?
    Где техники которые вы придумали? (увидел только название коробочек которые нужно покупать)

    1. милли = 10 ^ -3, притом что кадров обычно 30 в секунду, то задержка никак не меньше 1/30 или 3,3 мс или 2,5 мс для 25 кадров/сек, не считая того сколько оно в камере прокручивается через электронику. Это время между кадрами — те даже если кадр куда то там приезжает быстрее то это всё равно не имеет особого смысла.
    Учитывая тесты телеков из п6 (см ниже) можно прикинуть что с учётом минимальной обработки в камере — никак не меньше 5 мс, и запросто до 100 и более может оказаться.
    Без специального оборудования этого не замерить.

    2. Вроде как чисто аппаратных решений нет, те много «аппаратных» решений это писюк где энкодит интел квик синк или какой то gpu.
    «накладные расходы ОС» тут вообще не при делах — их практически нет, если конечно там не винда какая то.

    4. можно так же гнать и в MPEG2-TS поверх udp или tcp. Хотя это не всегда оптимально.
    Конкретно RTMP или RTSP они же могут и по TCP ходить, а там куча нюансов с тюнингом ОС на обоих концах.
    А если это RTP для транспорта на udp то там тоже могут быть задержки, особенно в случае потерь и реордерингов пакетов, и есть довольно интересный параметр как окно приёма — сколько мы ждём потерявшийся пакет.
    Тема не раскрыта совсем.

    5. Плееры любят кешировать, но их можно и отучить, в том же vlc и mpv есть крутилки.
    Со встроенными в телеки хуже, в самсунге на уровне виджета можно подкручивать буфера в определённых пределах.

    Впрочем, я задержкой по времени никогда не интересовался, меня интересовала скорость переключения каналов и устойчивость к потерям, поэтому я буфера наоборот выкручивал на максимум, а из своей софтины msd/msd_lite ( http://www.netlab.linkpc.net/wiki/ru:software:msd:index ) новым клиентам отдаю сразу 4-8 мегабайт из кеша, чтобы у них буфер моментально заполнился. Собственно отсутствие возможности влить клиенту сразу хх мегабайт и побудило написать, а то так бы и пользовался udpxy.

    6. Никаких 1мс и менее тут и близко нет!
    В современных телеках куча «улучшайзеров» и если их не отключить то можно легко нарваться на ощутимую задержку. А иногда они не отключаются вовсе.

    Геймеры от этого страдают. Гуглить на «Input lag»
    https://en.wikipedia.org/wiki/Input_lag
    http://www.fighting.ru/forum/viewtopic.php?t=4403

    тесты телеков:
    http://www.displaylag.com/new-2015-4k-hdtvs-tested-for-input-lag-samsung-sony-lg-sharp/
    http://www.rtings.com/tv/reviews/by-test-results/input-lag
    (от 17 до 154 мс по этим двум ссылкам)
    • 0
      Спасибо за фидбек.

      Какие именно детали интересуют?

      Про хайлоуд речи не шло, речь о высокой производительности, а не о высоких нагрузках.
      Битрейт потоков был разный, на максимуме — 3.2Мбит/с, HD насколько помню.
      Задержку мерял клиент, у него свои методы. А после всех настроек для наглядности демонстрации он пускал изображение часов с миллисекундами, делая срезы в разные моменты времени, довольно занятно получалось
      Насчёт придуманных техник — я не писал, что мы что-то придумали. Мы показываем, как можно существующие техники применить, они совсем не очевидны местами.

      По пунктам.

      1. ОК, возможно про 1мс погорячился, но разница с пару мс тут не существенна для данной задачи.

      2. Насчёт аппаратов не соглашусь — если алгоритм кодирования зашит в железо, это по определению будет быстрее софтового решения на базе десктопной ОСи.

      4. Вариантов масса, у меня нет цели рассказать про все. Описан конкретный сценарий, где речи про udp вообще не может идти. Описание разницы в работе протоколов займёт не одну отдельную статью. Да, ты тоже любим MPEG-TS, у нас в сервере он реализован в самых разнообразных кейсах. Но повторюсь — мы описали конкретный сценарий, который неплохо показывает целый класс подобных задач, и там ему места не нашлось.

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

      6. Не знал, спасибо за инфу.
      По итогу всё равно вышло, что бОльшая часть задержки связана с конкретными шагами, которые клиент и «докрутил». Теле-оборудование на их площадках, видимо также заточено под большую скорость работы.

      Что до геймеров — у них своя специфика, что-то применимо взаимно, что-то нет. Будет интересно почитать статьи и про их подходы к уменьшению.
      • +4
        > Какие именно детали интересуют?
        Я повторю вопрос в G+: методика измерения задержки :) Или это ноу-хау заказчика и вы не в курсе?

        > А после всех настроек для наглядности демонстрации он пускал изображение часов с миллисекундами, делая срезы в разные моменты времени, довольно занятно получалось
        Если это и есть техника, то довольно забавно, что практически у всех сходится к:
        — Все машины точно или почти точно синхронизированы по времени
        — Часы на источнике (или метка прямо в поток)
        — Приёмник просто делает срезы, сохраняя время оного.

        По срезу же потом уже вручную смотрится время среза и время на картинке?

        2. Смотря что и как считать аппаратом: Intel QSV это аппаратное кодирование (ну там софтовый бакенд тоже есть, но не про него сейчас)? Для него используются аппаратные блоки GPU, значит аппаратное. Но там тоже можно получить задержки (прикручивал для одних людей к ffmpeg, правда пока прикручивал другие люди сами сделали и заинтегрировали оное в FFmpeg: >= 2.7.1). nVidia NVENC техника тоже может дать задержку. Насколько я понимаю, это особенности алгоритмов сжатия в h264 — там нужно тюнить, в т.ч. параметрами для железа. Конкретно я получался задержку с двумя перекодировками при помощи FFmpeg меньше чем 1 сек (мерили грубо, можно сказать на глаз), цепочка была такая: Камера (5шт) — PC+ffmpeg (5шт) — nginx-rtmp — сервер-обработки(5 входящих потоков и 1 исходящий) — nginx-rtmp — клиент. В исходном варианте латенси была около 10 сек, просто подобрали параметры FFmpeg.

        6. Мы с этим на HDMI столкнулись, до 100-200 мс как пить дать задержки дать может. Теперь понимаю, почему VGA до сих пор не умер :)
        • +1
          По измерениям — всё так и есть, между машинами максимальная синхронизация.

          Вообще, как и во многих других вещах по этой задаче, всё исходит из разумной необходимости. Например, если даже часы будут расходиться на 1 мс — да и ладно, время реакции человека всё равно на порядки больше. Поэтому после выведения лейтенси за величину 500 мс все дополнительные приседания уже были лишними. Это не операции на мозге через теле-управление, утаскивать показатель вниз на очередные — 100 мс уже излишество, которое не окупится.

          2. Тут речь больше о том, что не стоит юзать вещи типа FMLE или облачные энкодеры. Понятно, что можно и ffmpeg затюнить за безобразия, сделать уникальную сборку яра линукса и самого ффпмег под конкретное железо и получить ещё 100 мс выигрыша. Вопрос — сколько это займёт времени и, как следствие, денег. Тут важно вовремя остановиться :)

          6. Идеальных решений не бывает, чего уж там.
          • +2
            да не ffmpeg затюнить, а воспользоваться рекомендациями Ясона для libx264.
            • +1
              И это тоже, да.
            • +1
              Да, я это и имел ввиду.
      • 0
        Жать один поток это не высокая производительность, даже по меркам одного десктопа :)
        Вроде в малине или рапсе есть аппаратный h.264 энкодер, а у меня он даже в вебкамеру встроен.

        2. AES тоже «зашит» в процы, но для его использования всё ещё нужна обычная ОС.
        Притом, что AES относительно простой: дал блок — получил блок, и его реализации всё же есть без ОС, но вот кодирование видео по сложнее, особенно когда речь заходит о работе с сетью.

        Пересобирать ядро ОС для лишних 10мс не нужно, в том смысле что само ядро задержек таких не даёт, но можно крутить крутилки чтобы оно немного эффективнее работало с данной задачей. В своё время я игрался с параметром HZ на ядре фрибсд, на слабой армовской коробочке выставление HZ=100 вместо 1000 давало очень ощутимый прирост скорости отдачи файла по сети через nginx.

        4. RTMP — это TCP! (судя по вики)
        TCP — это полное отсутствие контроля за задержками со стороны приложений.

        Если требование заказчика — минимальные задержки то RTMP фейл.
        У вас если где то лаганёт то начнётся буферизация на обоих концах TCP трубы, когда лаг закончится задержка воспроизведения никуда не денется и так и будет до реконекта проигрывать видео с отставанием.
        Я не зря спросил про RTP — он ходит по UDP, при этом позволяет переживать реордеринг пакетов в пределах окна приёма.
        Сам лично гонял UDP с Иркутска в Иркутск через Москву, задержка была от 140 мс, выпавшие пакеты — ерунда, кодек mpeg2 это очень легко переживал, да и было их относительно мало, на глаз не заметно.

        MAG245/250 вроде умеют мультикаст показывать без буферизации, по крайней мере стартуют быстро.

        2 spot62:
        Не извращайтесь, браузер для просмотра текстов и картинок, если нужно видео — есть куча приличных видеоплееров.
        • 0
          Жать один поток это не высокая производительность, даже по меркам одного десктопа :)


          Не просто пожать, а доставить с минимальной задержкой. Вы путаете нагрузку и производительность, это не всегда одно и то же.

          Сам лично гонял UDP с Иркутска в Иркутск через Москву,


          Кто ж спорит, можно и на UDP построить, даже у нас во Владе бывают удачные дни, без перебоев и с хорошим пингом. Но в конкретном случае нашего клиента UDP не ехал.

          Не извращайтесь, браузер для просмотра текстов и картинок,


          Расскажите это Ютюбу и многочисленным онлайн-кинотеатрам, например.
          • 0
            Странная ситуация когда UDP не едет.
            Разбираться пробовали?

            У всех онлайн кинотеатров общая боль — браузер у клиента хер пойми какой и может тормозить.
            Мозила вылизывает код, но на 1к+ вкладок + ХД всё равно тормозит.
            ИЕ, Хром, Опера — рожают по процессу на вкладку, и уже поле 200+ вкладок ОС начинает ощутимо лагать.
            Пока это на халяву — никто не возникает. Особенно обычные пользователи, которые сами себе попу подтереть не могут, не то что поставить или настроить что то.

            В целом оно конечно работает, даже сносно, но если сравнить то как видео показывает браузер и как оно смотрится в любимом плеере то плеер выигрывает безоговорочно.
            Ютуп я смотрю в mpv, в фф есть кнопочка «смотреть в mpv» и для контекстных менюх тоже, один щелчёк и через 5 секунд видео уже в mpv, который не тормозит, гарантированно декодит на видюхе, перематывается колёсиком и тп. И главное по бокам нет мусора с сайта, ни что не отвлекает.
            • +1
              Боюсь, что такой подход, скорее исключение, чем правило. Товар в основном ориентируют на массовую публику.
  • 0
    Я бы такое на udp протоколах начал бы делать.
    • +1
      В данном случае RTMP зарекомендовал себя значительно лучше, чем UDP, — речь всё ж про передачу между разными континентами через сеть с очень неоднородным поведением.
      Кроме того, в конце цепочки стоял кастомный плеер, у которого на вход требуется именно RTMP.
  • 0
    т.е. live streaming в браузер с приемлемой задержкой ( < 1 c) для h.264 все еще невозможен.
    • +1
      Теоретически возможен, но уже на грани. Всё от постановки задачи зависит. Если работа идёт в рамках одной сети (например, корпоративной), то почему бы и нет.
      • 0
        Задача стандартная: отображение информации с камер видео-наблюдения в веб-браузере.
        Что можно использовать в качестве контейнера для отображения h.264 потока? Для HLS задержка даже еще выше чем для flash проигрывателей.
        • +1
          Сразу вопрос — насколько вообще в таком сценарии нужна задержка меньше секунд? Если зритель находится не на охраняемом объекте, то и 1-2 секунды вполне покроют требования. Если же он рядом, там вполне можно добиться всё той же 1 секунды и даже меньше.
          В любом случае можно рассмотреть вариант RTMP (т.е. Flash-based плееры).
          Если хочется HLS (для iOS/Android), то от него можно добиться 3-4 секунды задержки. Это, опять же, не сильно повлияет на ряд сценариев в вашем случае.
          • 0
            Допустим, это охранная система или какой-то тех.процесс. Видео видимо должно коррелировать с состоянием датчиков?
            Или такое из жизни: осветители и звукооператоры ведут спектакли по репликам или действию из закрытого помещения, которое не имеет прямого контакта с залом, сценой.
            • +2
              В этих случаях поможет применение или RTMP с флеш-плеером или MPEG-TS по UDP.
    • +1
      в webrtc возможно предположительно почти возможен.

      Во флеше очень всё плохо, потому что насколько я помню во флеше до сих пор не убрали багу, которая в режиме zero delay начинает накапливать delay до повисания флеш-плагина
      • 0
        В WebRTC более чем возможен, скоро мы в VoxImplant найдем время заняться стриммингом и это постараемся доказать :)
        • 0
          А rtmfp вы пробовали?
          • 0
            Пробовали, тут не только в протоколе вопрос, а еще в самом движке. Во Flash он сильно хуже.
            • 0
              AEC то в webrtc планируется?
              • 0
                Он уже там давно есть, вот вам шпаргалка iswebrtcreadyyet.com
                • 0
                  микрософт с эпплом во всей красе
                  • 0
                    Все не так безнадежно, там процесс идет тоже, мы за этим следим.
  • 0
    Протокол передачи данных нужно выбирать исходя из возможностей энкодера и медиа-сервера, который будет раздавать данные конечным пользователям. Для передачи видео в реальном времени наиболее подходят RTSP, RTMP или MPEG2-TS.
    MPEG-TS это контейнер, а не протокол.
    Если собираетесь использовать протоколы на базе HTTP, например HLS или MPEG-DASH
    Вы вполне себе можете гонять видео через HTTP, не используя дополнительный протокол для этого.
    • 0
      MPEG-TS это контейнер, а не протокол

      Да, это контейнер. Но в данном случае с точки зрения энкодера это фактически один из протоолов передачи.

      Вы вполне себе можете гонять видео через HTTP, не используя дополнительный протокол для этого.

      Для VOD это правда, можно использовать progressive download. Но как вы собираетесь делать это для живого видео? MPEG-TS поверх HTTP? Боюсь клиентский софт его не поймёт, кроме VLC, разве что.
      • 0
        Но в данном случае с точки зрения энкодера это фактически один из протоолов передачи.
        Вероятно, вы заблуждаетесь. С чего бы ему быть протоколом? Вы вполне можете вещать в любом другом контейнере.
        MPEG-TS поверх HTTP? Боюсь клиентский софт его не поймёт, кроме VLC, разве что.
        Да. Насколько я знаю, абсолютно любой видеоплеер такое воспроизводить умеет, раньше это был стандарт де-факто. Более того, с использованием хаков VLC-муксера можно вещать разные кодеки видео и аудио без перекодировки и без переподключения к потоку. Я так разные видеофайлы вещаю без перекодировки.
        • 0
          Вероятно, вы заблуждаетесь.

          Повторю — современные энкодеры могут выдавать H.264/AAC через RTMP, RTSP и MPEG-TS поверх UDP и TCP. Что именно вас смутило?

          Насколько я знаю, абсолютно любой видеоплеер такое воспроизводить умеет

          Веб-плееры не умеют. Для живых потоков работают: RTMP через Флэш, HLS через Флэш и встренную поддержку браузера, чуть реже — MPEG-DASH, если браузер умеет.
          • 0
            Энкодеры выдают битстрим или уже замукшенный файл. Вы, вероятно, имеете ввиду то ПО, которое раздает видео.
            Веб-плееры, да, не умеют.

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