Jump to content
Калькуляторы

Multicast -> HLS -> internet -> HLS -> Multicast Передать поток по сети, что бы он не дергался

Кто-то у меня спрашивал, можно ли с помощью erlyvideo (или с помощью чего-либо ещё) сделать так, что бы поток передался по интернету и с другой стороны плавно отправлялся по UDP по локальной сети.

 

Проблема простая: jitter, который надо компенсировать буфером.

 

Я эту проблему решил с помощью HLS клиента в erlyvideo, который накапливает буфер и из него монотонно, плавно, выдает кадры. А кто как ещё это решает?

Share this post


Link to post
Share on other sites

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

На входе в туннель стоял ng_bpf для фильтрации, чтобы только мультикаст лез в туннель и только с одной стороны, igmp в обе.

Поскольку оно юдп - никаких доп задержек из за потерь не возникало.

Share this post


Link to post
Share on other sites

Для h264 это не годится. UDP — это потери, приводящие к потере до 5 секунд видео.

Share this post


Link to post
Share on other sites

h264 не было - потому ничего не скажу.

Ходило петлёй через 5 часовых поясов (10 в сумме), источник - getstream (mpeg-ts, udp), потери если и были то на изображении это не сказывалось, те не так много потерь было в диком инете.

Share this post


Link to post
Share on other sites

maxlapshin, не прошло и года.

а HLS мультибитрейт использует? Один оптимальный поток или все сразу?

Share this post


Link to post
Share on other sites

Вспомнил: вместо udp можно было настроить ноду на tcp, для tcp поставить cc = htcp и тоже должно не плохо работать, только нужно приглядывать как то за состоянием соединения и реконектить при обрыве.

Share this post


Link to post
Share on other sites

Есть идея написать софтину для туннелирования udp в интернете. Суть в том, что софтина на входе забирает мультикаст, к каждому пакету добавляет номер и таймстамп и отправляет это юникастом по udp другой стороне. Другая же сторона принимает пакеты, накапливает их в буфер (например на 1-5 секунд), извлекает заголовок, восстанавливает очередность, перезапрашивает потерянные пакеты, и по истечении времени хранения в буфере выплевывает их мультикастом далее в соответствии с таймстампами.

 

По идее, такая схема обещает отлично работать на любых публичных каналах с любыми разумными потерями. Кто что думает?

Share this post


Link to post
Share on other sites

Номер добавлять это вы про RTP?

Что-то вы мудрите: свой протокол писать собрались... Вон, в первом сообщении ваше решение и описано, собственно:)

Share this post


Link to post
Share on other sites

vladd: вы сейчас рискуете повторить ошибку авторов uTorrent, которые решили сделать протокол, совмещающий скорость UDP и надежность TCP. В итоге получилась надежность хуже чем у UDP, а скорость ниже чем у TCP.

 

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

 

 

MrCloud: ваши сообщения тут в личной переписке потерялись. Лучше писать сразу на info@erlyvideo.org, если что-то конкретное хочется.

Share this post


Link to post
Share on other sites

Есть идея написать софтину для туннелирования udp в интернете. Суть в том, что софтина на входе забирает мультикаст, к каждому пакету добавляет номер и таймстамп и отправляет это юникастом по udp другой стороне. Другая же сторона принимает пакеты, накапливает их в буфер (например на 1-5 секунд), извлекает заголовок, восстанавливает очередность, перезапрашивает потерянные пакеты, и по истечении времени хранения в буфере выплевывает их мультикастом далее в соответствии с таймстампами.

Откройте для себя тюнинг TCP.

То что вы описали реализуется так:

юдп сокет с буффером отправки 128 байт и приёма 256кб, rcvlowat выставляется где то на 32кб, хотя бы (чтобы не сильно часто отвлекаться) и джойнится к мультикаст группе

и тсп сокет с буфером приёма на 128 байт и отправки на 1 метр, выставляются всякие nodelay, sndlowat=32кб и глобально сс=htcp

и промежуточный буфер в софтине на 64кб (rcvlowat * 2)

с другой стороны зеркально...

Share this post


Link to post
Share on other sites

То что вы описали реализуется так

Есть канал 20 мбит/с, из них потери 5%, вдобавок еще RTT 100 ms. И через него получится без затыков передавать HD-канал со скорость 15 мбит/с в один tcp-поток? Очень большие сомнения, буду рад заблуждаться.

Share this post


Link to post
Share on other sites

По UDP затыки могут быть легко, с TCP будет лучше однозначно.

 

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

 

А вот что будет, когда в HD канале пропадет keyframe, догадаться несложно.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Перекрутил все, к сожалению, какой-то 1% потерь (non-congestion packet loss) при rtt>50ms не позволяет достичь скорости более 5-10 мбит/c на любом tcp-алгоритме и на канале любой ширины. От того и понадобилось делать подобное решение, оно по идее позволит утилизировать любой паршивый канал, и будет достаточно простым.

Share this post


Link to post
Share on other sites

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

 

Т.е. если кадр не дошел за 3 секунды, то что уж тут поделать.

 

Городить тут ничего нового не надо, RTP прекрасно подходит, там даже есть готовые команды в RTCP для ретрансмита, осталось только сесть и запрогать клиент-сервер. При желании работа на месяц (т.е. на один вечер, который растянется в месяц).

Share this post


Link to post
Share on other sites

"Запрогать" это круто, конечно...

Но вроде как на один поток и готовые realtime сервера можно найти, а клиенты RTP как таковой поддерживают все (правда, про поддежку "ретрансмита" я не слышал).

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

Share this post


Link to post
Share on other sites

Нет. Готовых с ретрансмитом нет. Под клиентом я, конечно же, подразумевал не пользовательскую программу, а ответную часть, умеющую просить досылать пакеты.

Share this post


Link to post
Share on other sites

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

Это как раз то что надо, продолжать шпарить поток.

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

РТК, обычно потери не более 0.1-0.2% до нужного узла, но периодические перегрузки стыков на маршруте, пиринговые войны, прочие необъяснимые затыки - в общем то, что называется публичный интернет. Тема же как раз про то как через него что-то стабильно передать :)

Share this post


Link to post
Share on other sites

Я тут тоже потоками балуюсь, и есть нюансы.

Хорошо если "клиент" свой, и его можно "затюнить" как нужно.

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

Ещё нюанс в том, что пакеты могут теряться ещё до поступления в передающую софтину.

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

С rtp можно возится а можно и нет, технически достаточно к каждому пакету в конец порядковый номер (в конец - потому что легче откусывать) и каждые n принятых пакетов перезапрашивать пропущенные номера. Номер может быть даже индексом в кольцевом буфере, раз кольца нужно синкать.

Share this post


Link to post
Share on other sites

В "классическом" RTP пакеты нумеруются скорее для компенсации джиттера - в буфере приемника могут по порядку выстраиваться если, например, разными маршрутами пришли в неправильном порядке. Мысль перезапрашивать недостающие пакеты в реалтаймовском потоке считаю странной: держать придется слишком большой буфер и на сервере и на клиенте. Кроме того: отправлять два пакета с одинаковым номером - вообще дико.

 

На мой взгляд стоит бороться именно с потерями пакетов, 1% это слишком много даже для ростелекома - ищите, тюнингуйте канал.

Share this post


Link to post
Share on other sites

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

При постоянной нумерации можно использовать битмап в запросах на повторную отправку, вместо перечисления полных номеров. Номер пакета vs индекс в кольцевом буфере - суть не меняется, они так же будут упорядочиваться по индексам.

Share this post


Link to post
Share on other sites

Ну вот я не просто так упомянул понятие "реалтаймовский": просто-напросто буфер заберет весь реалтайм и вы будете смотреть на новый год бой курантов на 15 секунд после остальных - оно Вам надо?

512 метров на канал, понятно что утрировано, но это в ряде случаев ЧАС... а вопрос про несколько каналов и растущий буфер вообще открыт.

Share this post


Link to post
Share on other sites

В случае с цифровым видео бой курантов так и так смотреть с отставанием от аналога.

 

При передаче через интернет _надо_ приготовиться к 30-секундному лагу.

Share this post


Link to post
Share on other sites

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

 

Скоро будет готов первый вариант софтины, и проведу тесты :)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.