Pull to refresh

Comments 51

Крик души для трассиров/девлайнов и прочих аксонов?
Я уже не упомню полный список, где я на это напарывался. Так что это просто уже наболело.
Во-во! Свеже-пришедшая китайчатина полный поток только через vlc и отдаёт нормально.

Думал mplayer прикрутить на просмотр, так ни через ffmpeg-обёртку в старом, ни напрямую в «новом» убунте (свежий mint накатил) RTSP 720p без артефактов не идёт… Вот-вот доделаю бокс под cubietruck, погляжу как получится…
кто, где и как настраивает размер буфера для tpc/udp-соединения?
т.е. это должно настраивать каждое приложение явным вызовом api для каждого соединения?
Есть некие значения по умолчанию, но в данном случае полагаться на них нельзя.
Отличный слог изложения!

И по теме — если приложение не использует setsockopt, то OS применяет параметры по умолчанию, их можно настраивать. Ну а если использует, но с неправильными значениями, то тут, ясно дело, баг приложения.
Если приложение занимается такой задачей и не использует setsockopt, то это тоже баг этого приложения.

TCP очень критичен к равномерности данных. Большая часть эвристик расчитана на «типичные применения» — равномерная нагрузка, максимально быстрое пропихивание слона, либо запрос-ожидание-ответ. Передача в форме пульсаций немного выбивается из схемы, и потому на умолчания полагаться нельзя.
Просто это в некоторой степени практика «а у нас всё работает».
Вот и у разработчиков видимо тестовая система стоит с голой виндой и без посторонних задач.
Не просто тестовая система с голой виндой, а ещё и прямая коммутация на одном свитче всех восьми камер с единственным компьютером, на котором даже косынку не запустишь.

При этом о том, что в реальной жизни витую пару всегда обматывают вокруг работающего перфоратора, почему-то забывают.
Да ладно тебе. Я это отлаживал на схеме Комп<=>Камера, даже без свича.
И все-таки «пульсаций» не должно быть, как минимум, теоретически. RTP протокол не зря считается real-time протоколом. В нем используется понятие jitter-буфера, так вот он как раз призван выравнивать поток. Если все грамотно реализовано, то между источником и потребителем будет непрерывный равномерный поток. Другое дело, что спецификацию либо игнорируют, либо не понимают. И если RTSP можно реализовать за несколько дней, то вот грамотная имплементация RTP/RTCP протоколов требует на порядок больше времени и глубокого понимания как RTP/RTCP спецификации, так и TCP/IP.
Пульсации будут при использовании инкапсуляции RTP внутри RTSP сессии, т.е. по TCP.

При этом исключаются (по идее) спонтанные потери отдельных RTP пакетов.

В случае с RTP по UDP — да, риалтайм. Но тогда потери данных без шанса на восстановление.
Что такое инкапсуляция внутри RTSP? Может вы tunneling имели ввиду? RTSP по отношению к TCP и к UDP работает одинаково, в том смысле, что RTSP всего навсего позволяет договориться в какие порты пойдут данные, а дальше он не участвует и ничего не инкапсулирует, до тех пор пока не потребуется закрыть сессию. Если сеть достаточно надежная и с достаточной пропускной способностью, то пульсаций и потерь не будет ни при TCP, ни при UDP, либо они будут не существенные. Если сеть не достаточно надежная или с не достаточной пропускной способностью, то ни TCP, ни UDP не будет работать и кино мы не увидим.
А не расскажете на пальцах каким образом пульсации убирает RTP на примере h264?

зю: rtp over tcp идёт мультиплексированием с доп.оберткой в том же канале что и сам rtsp, прямо параллельно с командами.
>>> прямо параллельно с командами
верно, это называется interleaved режим. Но кто-нибудь может привести use case где надо использовать interleaved режим? Я вот не встречал. Это уже точно будет работать медленнее традиционной схемы. При этом если камера еще и со звуком, то придется мультиплексировать уже 4 потока (1 — видео, 2 — контроль видео, 3 — аудио, 4 — контроль аудио). Конечно так можно обойти ограничения на разрешенные порты и работать скажем с тем же 80 портом, но это внесет существенную задержку передачи потоков и усложнит систему.

>>> каким образом пульсации убирает RTP на примере h264?
h264 это payload. RTP является payload-agnostic, ему все равно хоть h264, хоть «крокодилы». На пальцах, jitter-буфер должен накапливать пакеты так, чтобы писатель мог писать в него с одной скоростью (или с variable скоростью), а читатель мог бы извлекать с constant скоростью, при этом чтобы буфер не переполнялся никогда и не был бы пуст, т.е. его размер должен быть адаптивным.
Всегда, когда между камерой и клиентом есть какой-нибудь NAT, стоит использовать interleaved режим.

>>> читатель мог бы извлекать с constant скоростью

UDP устроен так, что пакеты должны доходить без задержек или не доходить вовсе. Должны. Можно ещё RTCP NACK вспомнить, который работает только у микрософта.

А на практике бери китайчатину и выковыривай из неё байты так, что бы доходило.
VPN? Вы ещё предложите что-нибудь из серии «пусть админ настроит» =))

А кто сказал, что в сложном проекте нельзя использовать то или иное решение? Камера может так или иначе попадать в VPN (либо с помощью спец прошивки, либо с помощью маршрутизатора) и делай с ней что хочешь, общайся по каким хочешь портам. Все ведь зависит от того какую систему делать. Если надо чтобы работало со всеми возможными камерами, то да, не вариант, а если это известные камеры, то почему нет.
А кто сказал, что мы должны ограничиваться только и исключительно сложными проектами?
Use Case простой — установление соединения = задержки; каждое новое соединение = затраты. А у нас уже есть установленное соединение. Передача по физическому уровню что одного соединения что 4х одна и та же (только добавляются лишние пакеты подтверждений, и окно настраивается для каждого соединения заново своё). То есть используя 5 соединений вместо одного мы увеличиваем накладные расходы, причем сопоставимо с использованием interleaved. И таки нет, задержку не вносит — точно так же передаётся в том виде в каком уходило бы и так — как данные пришли, мы их отправили.

>> На пальцах, jitter-буфер должен накапливать пакеты
Вот еще раз, на пальцах — есть кей-фрейм, весом в 260 пакетов, и есть delta фреймы весом в 60 пакетов. Если мы пакеты начнём выпускать с равномерной скоростью, то каждый кейфрейм будет вызывать лаг видео — ибо пока мы его целиком не примем, мы не можем отобразить ни его, ни любые последующие.
>>> установление соединения = задержки
так ли уж существенна задержка при подключении к камере? тем более что они выполняются параллельно. Накладные расходы не так велики, ибо у нас быстрее «кончится» сеть, чем вырастут накладные расходы в ОС и приложении (это я про передачу живого видео).

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

>>> Вот еще раз, на пальцах — есть кей-фрейм, весом в 260 пакетов
У декодера тоже есть своя скорость. Важно адаптивно подбирать размер буфера так, чтобы пока декодер работает буфер бы не переполнился, но и не был бы пустым к тому моменту как декодер освободится. Тогда флуктуации внутри буфера будут незаметны для декодера и видео будет плавным. Алгоритм jitter буфера описан в спецификации RTP. Я его не пробовал реализовывать, поэтому деталей не расскажу.
Вы сейчас всё говорите о посторонних вещах.

Главная и основная причина использования TCP для передачи видео от камеры к клиенту — что бы видео поменьше терялось и побольше доходило в условиях плохоконтролируемой агрессивной среды.

Так а кто спорит что TCP для надежной передачи? Но повторюсь, что в общем случае никаrих проблем нет, если сеть достаточно надежна. Т.е. в локальной сети проблем нет совсем, там хоть TCP, хоть UDP. Для интернета все зависит от того какой канал между камерой и медиасервером.
итак, то есть камера должна буферизовать видео для обработки; затем буферизовать сжатое на случай потерь и еще дополнительно буферизовать чтобы сгладить сетевые пики; плюс отсылать не когда данные есть, а когда подойдёт время гладкости.
то есть мало того, что у нас есть задержки от обработки и энкодера, мы еще добавим задержку отправки по сети, и если приёмник вдруг захочет показывать сразу что приходит — пусть идиоты наблюдают рывки.

А, ну и при этом плевать что сеть 100 мбит а поток 8 мбит, утилизовать оставшиеся 92 никак не будем, чтобы избавиться от этих рывков. Главное, чтобы бедные программисты софта приемника не напрягались.
почему приемник не должен напрягаться? буфер присутствует и на приемнике.
потому, что если до приемника дошло, он может просто показывать.
если же передатчик посылает «как пришло так и посылаю» то мы никак в сети данные не сглаживаем и пульсации все на месте.
Антон, в идеале всё именно так, как ты описываешь.

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

Всё это счастье было в глубокой древности CBR-а.
RTP interleaved RTSP. Данные идут в том же TCP канале, что и RTSP команды.

Разница в поведении TCP и UDP существенно тоньше чем «не будет работать и кино мы не увидим» и одна из этих тонкостей описывается в этой статье.
Совсем не так!

Я про потроха линукса. Я не гуру, пересказываю, что знаю:

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

Далее: при обработке прерывания ОС делает минимальное количество телодвижений, после чего делает тасклет для дальнейшей обработки данных. Это так называемая «нижняя и верхние части прерываний». Верхняя часть прерываний скедулится когда удобно линуксу (и может быть прервана другими прерываниями).

Далее: сетевая карта бывает умной, в этом случае несколько кадров обрабатываются с помощью LRO/GRO (large recieve offload/generic recieve offload), в этом случае в часть уровней ОС пропускается, а TCP получает гигантский фрейм. В tcpdump'е это выглядит как пакет с размером в 8, а то и 16кб размером (это при выключенном jumbo). Сетевуха сама проверяет чексуммы, с минимальным участием сетевого стека проверяет номера сегментов и т.д.

Это не отменяет описанного в статье, просто процесс много более тонкий и сложный. Например, сетевуха с поддержкой нескольких процессоров способна под irq утилизовать все ядра (igb/ixbe). Есть сетевухи, которые могут утилизовать только одно ядро (e1000e, bmx). Вторые, очевидно, много хуже первых держат нагрузку.

Да, про десятки милисекунд обработки, это точно не так. Микросекунд — может быть. Не милисекунд точно.
Общая обработка пакетов очень и очень утрирована — не она главное. Главное, что из канала в ОС пакет поступил, потерь в канале и на свичах — нет. Потерь на дровах — нет.
А десяток миллисекунд берётся из Task Scheduling'а — приложение тупо должно получить квант, прочитать что может, потом её вытеснят.
Но пакеты теряются на приложении… И это — обидно.
Но если сетевая карта обрабатывает данные, то данные копятся в очереди уже не сетевой карты, а линукса (и там размер буфера много больше). В современных линуксах HZ — это 1000, то есть скедулинг происходит раз в 1ms, а не раз в 20мс, как это было при HZ50.

То есть я понимаю, что любое приложение может забить буферы TCP до неприличия, но мне кажется, что схема происходящего там должна быть сильно другая, чем в посте описывается.
Таки забиваются не системные буфера, а вполне себе буфера конкретного приложения. И изменения SO_RCVBUF весьма значительно влияют на результат.
Схему происходящего восстанавливал опытом, матом и wireshark'ом. :(
Показанный на видео «хрестоматийный глюк» является в большинстве своем свидетельством использования ffmpeg и говорит, как правило, о двух причинах:

1. Непонимание как работает ffmpeg
2. Транскодирование live видео вместо трансмуксинга все тем же ffmpeg

Чтобы настроить транскодирование с помощью ffmpeg надо хорошо «покурить» ffmpeg и проработать команду, которая в консоли займет строчки 3 минимум. Но транскодирование настолько ресурсоемкий процесс, что вряд ли можно будет смасштабировать такое решение. Надо использовать трансмуксинг. Чтобы настроить трансмуксинг, надо понимать как корректно сформировать тот же H264 поток и как его упаковать в контейнерный формат. Везде пишут что ffmpeg не стабильная штука, глючит, падает, ест память и т.д. Но по факту могу сказать, что он очень стабилен, но и сложен при этом в использовании, его надо еще и правильно собрать. Проблемы с его не стабильностью исключительно в непонимании матчасти. Занимаюсь проектом, где интенсивно используется ffmpeg, проблем нет, работает 24/7, потоки с камер не закрываются месяцами.

Кому интересно могу дать доступ посмотреть как работает тут demo.webglaz.net/
на видео глюк еще до транскодирований — это просто показ во время настройки камеры. возможно, тут ffmpeg что-то и значит, но дело не в нем.
там много багов — это dev environment
ffmpeg стабилен, но только на этапе использования, а не настройки. Вам, вероятно, повезло, что вы не сталкивались с очевидными, и, что куда хуже, неочевидными багами в реализации демуксеров, муксеров, фильтров ffmpeg-а. Их, честно говоря, просто уйма, и желательно их всех знать. Спасибо, что напомнили. Пойду пофикшу давно бесящий меня баг с ремуксингом аудио в flv.
да нет, вкусил по полной, на шлифовку параметров ушел примерно год.
Переключите камеру в 10 Mbit, если она позволяет, и все пойдет как по маслу.
Это просто включается некий аппаратный шейпер, который очень хорошо сглаживает пики.
вряд ли шейпер поможет. такой артефакт может явиться следствием потери пакетов, декодер при этом пытается скомпенсировать недостаток пакетов и получается вот такой мусор. а почему пакеты теряются как раз подробно описано выше в статье.
Это очень помогает сгладить всплески от I фреймов на 100 Mbit, мы это используем в своих камерах когда в цепочки больше 3-x штук
а, ну логично, диффы весом почти в кейфрейм становятся :))
при этом системный алгоритм адаптации TCP окна начинает лучше себя вести.
Не совсем понятно, вы жалуетесь на некий софт, который не может принимать большой поток? Тогда пишите прямо, что за софт и какие параметры заявлены производителем.
Это слишком популярный глюк, чтобы называть всех. Из крупных игроков — Trassir от DSSL, Axxon Next от ITV, VideoNet от Скайрос. Точно есть на актуальных версиях Trassir и Axxon Next, VideoNet тестировал 7й, сейчас актуальный 9й. Macroscop спокойно принимает, глюков и потерь нет. Всякую остальную мелочь без аналитики даже вспоминать и тестировать опять не хочу. А! На flussonic / erlyvideo — бага нет.
Да. Но flussonic пока без аналитики.
Only those users with full accounts are able to leave comments. Log in, please.