Управление через интернет

Korogodsky

UncleSam, спасибо за ценную информацию!

SGordon:

интересно, быстрей чем луноход будет?

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

Добавлю: причина предположительно в том, что VLC разбивает каждый кадр на разные пакеты и отправляет кадр по-кусочкам, при этом после прохождения по UDP, пакеты приходят не в том порядке, в котором отправлялись, и кадр склеивается не правильно. Плюс еще потери пакетов.

UncleSam
Korogodsky:

UncleSam, спасибо за ценную информацию!

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

Добавлю: причина предположительно в том, что VLC разбивает каждый кадр на разные пакеты и отправляет кадр по-кусочкам, при этом после прохождения по UDP, пакеты приходят не в том порядке, в котором отправлялись, и кадр склеивается не правильно. Плюс еще потери пакетов.

Скорее всего проблема именно в потере пакетов.
Картинка упаковывается, затем разбивается на блоки максимум 1500 байт и передается. При потере одного пакета или при их перестановке картинку собрать не получится.
Думаю обычные кодеки тут не подойдут нужно делать что то свое.

Имхо необходимо программно контролировать своевременность и порядок доставки пакетов.
Например разрезать весь кадр на области, каждая из которых при сжатии гарантированно займет места не больше 1400 байт, добавить туда информацию о номере кадра и местоположении области в кадре. Получится всю информацию о конкретной области упаковать. Таким образом умещаем все в одну датаграмму, потеря которой не затронет остальную картинку и перестановка пакетов местами не скажется.
При получении такой датаграммы, мы знаем номер кадра к которому она относится и местоположение данных.
Если датаграмма устарела (кадр уже показан) убиваем ее сразу.
Если кадр еще не показан распаковываем данные в соответствующее место кадра. Если какая либо область кадра не была обновлена (датаграмма утеряна), подставляем данные из предыдущего кадра. (Можно организовать небольшой буфер максимум 2-3 кадра).
Используя черезстрочную развертку для 640х480 можно передавать кадры 320х480, качество ухудшится незначительно, уменьшим видеопоток вдвое (в телевизоре именно так все работает).
В общем для видео рулит оптимизация под конкретную задачу и отказ от стандартных кодеков.

Korogodsky
UncleSam:

разрезать весь кадр на области, каждая из которых при сжатии гарантированно займет места не больше 1400 байт

Почему 1400 байт? Максимальный размер датаграммы - 64Кб, я пробовал передавать JPEG размером около 50Кб. Проблема в том, что в 64Кб нужно уложить 1 секунду видео, потому как Yota больше не потянет, по моим замерам выходило 300-500Кбит/сек.

Korogodsky

Получилось передать видео отдельными JPEGами, идет без потерь пакетов. Теперь нужно поработать над снижением битрейта, т.к. через несколько секунд начинает накапливаться задержка и продолжает расти, может у кого-то будут мысли как это побороть?

UncleSam
Korogodsky:

Почему 1400 байт? Максимальный размер датаграммы - 64Кб, я пробовал передавать JPEG размером около 50Кб. Проблема в том, что в 64Кб нужно уложить 1 секунду видео, потому как Yota больше не потянет, по моим замерам выходило 300-500Кбит/сек.

Это вы можете сделать датаграмму размером 64k, в реальности у всех систем передачи есть параметр MTU - максимальная длина передаваемого кадра, для ethernet - 1500 байт, для GPRS -1400, для DSL - 1492, для WiFi - 1500. (На самом деле тут все сильно зависит от оборудования).
Все что длиннее будет разбито на блоки такой длины, либо непосредственно вашим компьютером (информация разбивается на пакеты c длиной MTU вашей системы), либо транзитным оборудованием (фрагментация пакетов).
Засада в том, что если пакет фрагментирован, он не будет передан с сетевого уровня операционной системы на уровень приложений до тех пор, пока не придут все кадры и система не сможет из них собрать полный пакет. В результате один задержавшийся пакет создает задержку для всех остальных, а один потерянный пакет гробит всю датаграмму, так как она не может быть верно собрана. В общем таким образом поучаете минимум лишнюю задержку.
Лучше изначально закладывать передачу блоками по 1400-1450 байт.

Korogodsky:

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

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

В общем за работу респект и уважуха.

Stas#

интересно, быстрей чем луноход будет? Сколько секунд до луны и обратно шел сигнал, 2?

В луноходе минимальный лаг был 2.5с - это время сигнала туда-сюда. На практике лаг был 10-15с, т.к. там использовалось малокадровое телевидение с переменной частотой кадров, кот. зависила от к-ва приема.

Использование быстрой ЭВМ на борту позволяет снизить задержку вызываемую сжатием сигнала (у IP камеры все же другие задачи и задержка там обычное дело).

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

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

Так можно и отображение черезстрочно организовать. Сначала 1 полувину растра, а потом вторую. Как в ТВ. А вообще, если не вредничать, то картинки 320х240 вполне достаточно. Вспомните как раньше смотрели фильмы на VCD.

Korogodsky

Такие мысли по оптимизации:

  1. Отправка кадров по таймеру 60-80 миллисекунд (во вчерашней эксперементальной программе - отправка нон-стоп)
  2. Отправка кадров порциями по 2-3 секунды до поступания команды на отправку следующей порции с базы
    2.1 Команда с базы на отправку следующей порции кадров при опустошении очереди
  3. Проверка времени отправки кадра на борту и отбрасывание устаревших кадров перед отправкой
  4. Снижение качества JPEG для уменьшения битрейта (разрешение, % качества JPEG, уменьшение количества цветов, черезстрочность, “широкоформатный” режим)
msv

Когда-то баловался передачей видео по сети DirectShow+UDP. Тестовая программулька где-то осталась в BCB, если хотите (ну там кодеками поиграться…) могу поискать, скинуть с исходниками.

Korogodsky
msv:

Когда-то баловался передачей видео по сети DirectShow+UDP.

Какие у вас были результаты? Какого FPS удалось добиться, при каком разрешении? Какая задержка была, насколько пригодно для FPV в реальном времени?

msv:

DirectShow+UDP

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

msv

Проект начинался для видеоконференции в локалке, но умер не родившись по независившим от меня причинам… В приципе комп-комп все работало дуплексом без проблем в 100мб-сетке (ну еще бы… 😃). От разрешения и выбранного кодека изменялась только загрузка сети. Задержки в большей степени зависили от кодека и его настроек… У Вас несравнимо более сложная задача и по требованиям к задержке, и по ширине да еще и нестабильности канала…

Korogodsky
msv:

От разрешения и выбранного кодека изменялась только загрузка сети

Я так понял с кодеками для этой задачи связываться вообще не стоит.

msv:

сложная задача и по требованиям к задержке, и по ширине да еще и нестабильности канала

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

loigray
Korogodsky:

Я так понял с кодеками для этой задачи связываться вообще не стоит.

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

Korogodsky
loigray:

тот же googletalk и skype

Было бы интересно узнать какие кодеки они используют.

loigray:

а jpeg-и слать с каждым кадром - слишком хороший канал нужен для приличного качества

По моим экспериментам качество изображения получается приемлемое для управления (на мой взгляд), я еще не весь потенциал оптимизации использовал 😃 Наслаждаться 1080p 60fps, конечно не выйдет, но оценить курс куда лететь/ехать/ползти/бежать и т.д. и т.п. 😃 можно. До начала практических работ c JPEGом, мне эта тема казалась вообще бесперспективной, но на практике все оказалось не так плохо. То “видео” из JPEGов, которое я вчера передавал, временами было очень близко к реальному времени, но с периодическими достаточно частыми подвисаниями на 1-2 секунды. Кстати не исключено что skype использует что-то такое.

UncleSam
loigray:

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

-Stas- прав, здесь есть противоречие, для того чтобы добиться максимального качества при минимальном битрейте почти все кодеки (и скайп с гуглом тоже) используют межкадровую компрессию, сжимают не отдельные кадры, а блоки по 5-10 кадров. Для этого им необходим буфер из нескольких кадров, в результате задержка. В видеоконференции задаржка 0,5 - 0,7с ничего не значит. в FPV она критична.
Думаю действительно стоит отказаться от стандартных кодеков и пробовать сделать что то самому.

loigray
Korogodsky:

Было бы интересно узнать какие кодеки они используют.

скайп испллььзует вроде как vp7
гуглтолк h264 и h263, хотя оне с недавных пор 264 невзлюбили, перестают поддерживать и заменяют на vp8. скорее всего по политическим пичинам.
лучше всего использовать h263 - он разрабатывался специально для передачи по слабым каналам. 264 конечно лучше, но он проц сильно грузить будет при кодировании, а дял бортового компа это критично.

и ещё. видеопоток стоит предавать конечно по udp. для преодаления nat можно использовать протокол stun. но данные надо бы завернуть в какой нибудь предназначеный для этих целей протокльчек. по уму - в rtp. не будет проблем с неправильным порядком пришедших пакетов, и совместно с используемым вместе с ним протоколом контроля передачи можно будет регулировать параметры кодека - фреймрейт, размер гоп структуры, разрешение, чтобы видео при проседании канала не замирало, а просто ухудшало качество, и потом восстанавливалось при улучшении связи

да, и програмиовать бэкэнд, по крайней мере, лучше на каком нить другом языке. умные люди такое делают на си. ленивые на с++. а на языках с jit и garbage collector только смелые экспериментаторы 😃

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

UncleSam:

-Stas- прав, здесь есть противоречие, для того чтобы добиться максимального качества при минимальном битрейте почти все кодеки (и скайп с гуглом тоже) используют межкадровую компрессию, сжимают не отдельные кадры, а блоки по 5-10 кадров. Для этого им необходим буфер из нескольких кадров, в результате задержка. В видеоконференции задаржка 0,5 - 0,7с ничего не значит. в FPV она критична.
Думаю действительно стоит отказаться от стандартных кодеков и пробовать сделать что то самому.

дык любой кодек может использовать только i-фреймы 😃 если даже гоп-структуру зделать размером 4 кадра всё равно будет ощутимый прирост в степени сжатия, и это всего 100 милисекунд, а данные доступны для отправки раньше прихода следующего ключевого кадра. задержка не в этом. в цепочке передачи видео от камеры, через интернет, до монитора довольно много всяких буверов, в которых задержка накапривается, я в принципе представляю себе где там что и как, но, как мне кажется, слать жпеги - всё равно не лучший вариант
да. лаги в любом случае будут. и использовать инет для fvp, там где, полсекунды играют критическую роль, мне кажется, не самое грамотное решение. другое дело поставить это на большой самолётик, с автопилотом, летающим по вейпоинтам, а видио использовать для контроля полёта.

Korogodsky
loigray:

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

Будет хорошо, если Вы реализуете небольшую программу передающую видео в “реальном” времени с вэбкамеры через интернет с использованием кодека.

msv

Так если Вы уже пользуете DirectShow стройте граф с любыми кодеками, установленными в системе… Даже проще чем самому в jpeg перегонять…

Korogodsky
msv:

Так если Вы уже пользуете DirectShow стройте граф с любыми кодеками, установленными в системе… Даже проще чем самому в jpeg перегонять…

Возможно… Я в сторону использования кодеков там не смотрел, и если loigray в этом не плохо разбирается, я не против доверить это ему. А я пока посмотрю что там с jpeg может получиться.

loigray
Korogodsky:

Будет хорошо, если Вы реализуете небольшую программу передающую видео в “реальном” времени с вэбкамеры через интернет с использованием кодека.

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

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

Korogodsky
loigray:

если даже гоп-структуру зделать размером 4 кадра всё равно будет ощутимый прирост в степени сжатия, и это всего 100 милисекунд

loigray:

то так дела не делаются - не слать же в bmp всё, раз канал позволяет

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

Добавка:
С кодеками - 1% потерь и вы не увидите изображения, пока не придет следующий блок, и опять картинка будет видна пока не потеряется пакет. UDP+Yota=потери, такая формула получена эмпирическим путем 😃
C jpeg каждый кадр идет одним куском, при сбое теряем только один кадр, если в секунду один кадр из 20 или 15 будет теряться мы этого даже не заметим.
Парируйте! 😃

loigray
Korogodsky:

С кодеками - 1% потерь и вы не увидите изображения, пока не придет следующий блок, и опять картинка будет видна пока не потеряется пакет. UDP+Yota=потери, такая формула получена эмпирическим путем 😃
C jpeg каждый кадр идет одним куском, при сбое теряем только один кадр, если в секунду один кадр из 20 или 15 будет теряться мы этого даже не заметим.
Парируйте! 😃

jpeg не идёт одним куском, если он больше mtu, (обычно 1500 байт) 😃

а при сжатии видео 263 кодком, если пропадёт пакет из ключевого кадра то на экране будет небольшой артефакт размером с макроблок, в котором лежал пропавший пакет, длительностью gop_size*frame_duration. а так как ключевые кадры редки, то вероятность этого небольшая. если пропадёт пакет из b-frame или p-frame то артефакта вообще не заметите, его длительность будет frame_duration. в вашем случае неудачный результат скорее всего был связан не с невозможностью передачи сжатого видео через udp, а скорее, не в обиду будет сказано, с неумением это делать. возможно там не всё так просто как может показаться на первый взгляд, но совершенно не означает что невозможно. я видел как такое работает у других с минимальными задержками и без разрушения картинки. значит это возможно 😃