Управление через интернет
UncleSam, спасибо за ценную информацию!
интересно, быстрей чем луноход будет?
Сервы реагируют очень хорошо, меня полностью устраивает скорость реакции, замеров не производил, но там может миллисекунд 200. Видео посредством библиотек VLC в MJPEG передается очень плохо, дело не в задержках, а в потерях пакетов, не видно ничего кроме сплошных сбоев.
Добавлю: причина предположительно в том, что VLC разбивает каждый кадр на разные пакеты и отправляет кадр по-кусочкам, при этом после прохождения по UDP, пакеты приходят не в том порядке, в котором отправлялись, и кадр склеивается не правильно. Плюс еще потери пакетов.
UncleSam, спасибо за ценную информацию!
Сервы реагируют очень хорошо, меня полностью устраивает скорость реакции, замеров не производил, но там может миллисекунд 200. Видео посредством библиотек VLC в MJPEG передается очень плохо, дело не в задержках, а в потерях пакетов, не видно ничего кроме сплошных сбоев.
Добавлю: причина предположительно в том, что VLC разбивает каждый кадр на разные пакеты и отправляет кадр по-кусочкам, при этом после прохождения по UDP, пакеты приходят не в том порядке, в котором отправлялись, и кадр склеивается не правильно. Плюс еще потери пакетов.
Скорее всего проблема именно в потере пакетов.
Картинка упаковывается, затем разбивается на блоки максимум 1500 байт и передается. При потере одного пакета или при их перестановке картинку собрать не получится.
Думаю обычные кодеки тут не подойдут нужно делать что то свое.
Имхо необходимо программно контролировать своевременность и порядок доставки пакетов.
Например разрезать весь кадр на области, каждая из которых при сжатии гарантированно займет места не больше 1400 байт, добавить туда информацию о номере кадра и местоположении области в кадре. Получится всю информацию о конкретной области упаковать. Таким образом умещаем все в одну датаграмму, потеря которой не затронет остальную картинку и перестановка пакетов местами не скажется.
При получении такой датаграммы, мы знаем номер кадра к которому она относится и местоположение данных.
Если датаграмма устарела (кадр уже показан) убиваем ее сразу.
Если кадр еще не показан распаковываем данные в соответствующее место кадра. Если какая либо область кадра не была обновлена (датаграмма утеряна), подставляем данные из предыдущего кадра. (Можно организовать небольшой буфер максимум 2-3 кадра).
Используя черезстрочную развертку для 640х480 можно передавать кадры 320х480, качество ухудшится незначительно, уменьшим видеопоток вдвое (в телевизоре именно так все работает).
В общем для видео рулит оптимизация под конкретную задачу и отказ от стандартных кодеков.
разрезать весь кадр на области, каждая из которых при сжатии гарантированно займет места не больше 1400 байт
Почему 1400 байт? Максимальный размер датаграммы - 64Кб, я пробовал передавать JPEG размером около 50Кб. Проблема в том, что в 64Кб нужно уложить 1 секунду видео, потому как Yota больше не потянет, по моим замерам выходило 300-500Кбит/сек.
Получилось передать видео отдельными JPEGами, идет без потерь пакетов. Теперь нужно поработать над снижением битрейта, т.к. через несколько секунд начинает накапливаться задержка и продолжает расти, может у кого-то будут мысли как это побороть?
Почему 1400 байт? Максимальный размер датаграммы - 64Кб, я пробовал передавать JPEG размером около 50Кб. Проблема в том, что в 64Кб нужно уложить 1 секунду видео, потому как Yota больше не потянет, по моим замерам выходило 300-500Кбит/сек.
Это вы можете сделать датаграмму размером 64k, в реальности у всех систем передачи есть параметр MTU - максимальная длина передаваемого кадра, для ethernet - 1500 байт, для GPRS -1400, для DSL - 1492, для WiFi - 1500. (На самом деле тут все сильно зависит от оборудования).
Все что длиннее будет разбито на блоки такой длины, либо непосредственно вашим компьютером (информация разбивается на пакеты c длиной MTU вашей системы), либо транзитным оборудованием (фрагментация пакетов).
Засада в том, что если пакет фрагментирован, он не будет передан с сетевого уровня операционной системы на уровень приложений до тех пор, пока не придут все кадры и система не сможет из них собрать полный пакет. В результате один задержавшийся пакет создает задержку для всех остальных, а один потерянный пакет гробит всю датаграмму, так как она не может быть верно собрана. В общем таким образом поучаете минимум лишнюю задержку.
Лучше изначально закладывать передачу блоками по 1400-1450 байт.
Теперь нужно поработать над снижением битрейта, т.к. через несколько секунд начинает накапливаться задержка и продолжает расти, может у кого-то будут мысли как это побороть?
Попробуй черезстрочную развертку - уменьшишь битрейт 2 раза при той же частоте кадров. Правда получишь расческу при резких поворотах камеры, но с ней можно бороться фильтрами.
Подумай над возможностью синхронизации видео путем пропуска кадров.
В общем за работу респект и уважуха.
интересно, быстрей чем луноход будет? Сколько секунд до луны и обратно шел сигнал, 2?
В луноходе минимальный лаг был 2.5с - это время сигнала туда-сюда. На практике лаг был 10-15с, т.к. там использовалось малокадровое телевидение с переменной частотой кадров, кот. зависила от к-ва приема.
Использование быстрой ЭВМ на борту позволяет снизить задержку вызываемую сжатием сигнала (у IP камеры все же другие задачи и задержка там обычное дело).
Тут дело не в ресурсах ЦПУ, а в технологии сжатия. Задержка вызвана применением межкадровой компрессии с большой длиной блока. иначе надо будет очень большой поток.
Попробуй черезстрочную развертку - уменьшишь битрейт 2 раза при той же частоте кадров. Правда получишь расческу при резких поворотах камеры, но с ней можно бороться фильтрами.
Так можно и отображение черезстрочно организовать. Сначала 1 полувину растра, а потом вторую. Как в ТВ. А вообще, если не вредничать, то картинки 320х240 вполне достаточно. Вспомните как раньше смотрели фильмы на VCD.
Такие мысли по оптимизации:
- Отправка кадров по таймеру 60-80 миллисекунд (во вчерашней эксперементальной программе - отправка нон-стоп)
- Отправка кадров порциями по 2-3 секунды до поступания команды на отправку следующей порции с базы
2.1 Команда с базы на отправку следующей порции кадров при опустошении очереди - Проверка времени отправки кадра на борту и отбрасывание устаревших кадров перед отправкой
- Снижение качества JPEG для уменьшения битрейта (разрешение, % качества JPEG, уменьшение количества цветов, черезстрочность, “широкоформатный” режим)
Когда-то баловался передачей видео по сети DirectShow+UDP. Тестовая программулька где-то осталась в BCB, если хотите (ну там кодеками поиграться…) могу поискать, скинуть с исходниками.
Когда-то баловался передачей видео по сети DirectShow+UDP.
Какие у вас были результаты? Какого FPS удалось добиться, при каком разрешении? Какая задержка была, насколько пригодно для FPV в реальном времени?
DirectShow+UDP
Я сейчас тоже использую эту связку и приятно удивлен скоростью, если с VLC при передаче видео с компа на самого себя уже возникала задержка около секунды, то тут ее практически нет.
Проект начинался для видеоконференции в локалке, но умер не родившись по независившим от меня причинам… В приципе комп-комп все работало дуплексом без проблем в 100мб-сетке (ну еще бы… 😃). От разрешения и выбранного кодека изменялась только загрузка сети. Задержки в большей степени зависили от кодека и его настроек… У Вас несравнимо более сложная задача и по требованиям к задержке, и по ширине да еще и нестабильности канала…
От разрешения и выбранного кодека изменялась только загрузка сети
Я так понял с кодеками для этой задачи связываться вообще не стоит.
сложная задача и по требованиям к задержке, и по ширине да еще и нестабильности канала
Вчера поигрался с качеством JPEG, погонял видео с вэбкамеры через Yotу, в общем есть неплохие шансы на более-менее успешное завершение проекта.
Я так понял с кодеками для этой задачи связываться вообще не стоит.
почему же не стоит? ведь есть всякие интернет телефоны, тот же googletalk и skype. они довольно быстро передают видео по узким каналам. а jpeg-и слать с каждым кадром - слишком хороший канал нужен для приличного качества
тот же googletalk и skype
Было бы интересно узнать какие кодеки они используют.
а jpeg-и слать с каждым кадром - слишком хороший канал нужен для приличного качества
По моим экспериментам качество изображения получается приемлемое для управления (на мой взгляд), я еще не весь потенциал оптимизации использовал 😃 Наслаждаться 1080p 60fps, конечно не выйдет, но оценить курс куда лететь/ехать/ползти/бежать и т.д. и т.п. 😃 можно. До начала практических работ c JPEGом, мне эта тема казалась вообще бесперспективной, но на практике все оказалось не так плохо. То “видео” из JPEGов, которое я вчера передавал, временами было очень близко к реальному времени, но с периодическими достаточно частыми подвисаниями на 1-2 секунды. Кстати не исключено что skype использует что-то такое.
почему же не стоит? ведь есть всякие интернет телефоны, тот же googletalk и skype. они довольно быстро передают видео по узким каналам. а jpeg-и слать с каждым кадром - слишком хороший канал нужен для приличного качества
-Stas- прав, здесь есть противоречие, для того чтобы добиться максимального качества при минимальном битрейте почти все кодеки (и скайп с гуглом тоже) используют межкадровую компрессию, сжимают не отдельные кадры, а блоки по 5-10 кадров. Для этого им необходим буфер из нескольких кадров, в результате задержка. В видеоконференции задаржка 0,5 - 0,7с ничего не значит. в FPV она критична.
Думаю действительно стоит отказаться от стандартных кодеков и пробовать сделать что то самому.
Было бы интересно узнать какие кодеки они используют.
скайп испллььзует вроде как vp7
гуглтолк h264 и h263, хотя оне с недавных пор 264 невзлюбили, перестают поддерживать и заменяют на vp8. скорее всего по политическим пичинам.
лучше всего использовать h263 - он разрабатывался специально для передачи по слабым каналам. 264 конечно лучше, но он проц сильно грузить будет при кодировании, а дял бортового компа это критично.
и ещё. видеопоток стоит предавать конечно по udp. для преодаления nat можно использовать протокол stun. но данные надо бы завернуть в какой нибудь предназначеный для этих целей протокльчек. по уму - в rtp. не будет проблем с неправильным порядком пришедших пакетов, и совместно с используемым вместе с ним протоколом контроля передачи можно будет регулировать параметры кодека - фреймрейт, размер гоп структуры, разрешение, чтобы видео при проседании канала не замирало, а просто ухудшало качество, и потом восстанавливалось при улучшении связи
да, и програмиовать бэкэнд, по крайней мере, лучше на каком нить другом языке. умные люди такое делают на си. ленивые на с++. а на языках с jit и garbage collector только смелые экспериментаторы 😃
это хорошо, конечно что канала у ёты для передачи jpeg-ов хватает, и возможно для эксперементов этого достаточно. но если смотреть на будующее, то так дела не делаются - не слать же в bmp всё, раз канал позволяет 😃 надо расчитывать что мобильный инет не такая надёжная штука, и не везе стабильно работает. и лучше стремиться к максимальному качеству изображения при доступной ширене канала
-Stas- прав, здесь есть противоречие, для того чтобы добиться максимального качества при минимальном битрейте почти все кодеки (и скайп с гуглом тоже) используют межкадровую компрессию, сжимают не отдельные кадры, а блоки по 5-10 кадров. Для этого им необходим буфер из нескольких кадров, в результате задержка. В видеоконференции задаржка 0,5 - 0,7с ничего не значит. в FPV она критична.
Думаю действительно стоит отказаться от стандартных кодеков и пробовать сделать что то самому.
дык любой кодек может использовать только i-фреймы 😃 если даже гоп-структуру зделать размером 4 кадра всё равно будет ощутимый прирост в степени сжатия, и это всего 100 милисекунд, а данные доступны для отправки раньше прихода следующего ключевого кадра. задержка не в этом. в цепочке передачи видео от камеры, через интернет, до монитора довольно много всяких буверов, в которых задержка накапривается, я в принципе представляю себе где там что и как, но, как мне кажется, слать жпеги - всё равно не лучший вариант
да. лаги в любом случае будут. и использовать инет для fvp, там где, полсекунды играют критическую роль, мне кажется, не самое грамотное решение. другое дело поставить это на большой самолётик, с автопилотом, летающим по вейпоинтам, а видио использовать для контроля полёта.
любой кодек может использовать только i-фреймы если даже гоп-структуру зделать размером 4 кадра всё равно будет ощутимый прирост в степени сжатия, и это всего 100 милисекунд, а данные доступны для отправки раньше прихода следующего ключевого кадра.
Будет хорошо, если Вы реализуете небольшую программу передающую видео в “реальном” времени с вэбкамеры через интернет с использованием кодека.
Так если Вы уже пользуете DirectShow стройте граф с любыми кодеками, установленными в системе… Даже проще чем самому в jpeg перегонять…
Так если Вы уже пользуете DirectShow стройте граф с любыми кодеками, установленными в системе… Даже проще чем самому в jpeg перегонять…
Возможно… Я в сторону использования кодеков там не смотрел, и если loigray в этом не плохо разбирается, я не против доверить это ему. А я пока посмотрю что там с jpeg может получиться.
Будет хорошо, если Вы реализуете небольшую программу передающую видео в “реальном” времени с вэбкамеры через интернет с использованием кодека.
как раз подумывал над этим. тоже хочу себе самолётик с интернетом 😃
жаль времени сейчас совсем нет 😦
ведь если всё делать по уму то не такая уж и небольшая, в плане объёма исходников, програмка получится.
мабуть начну в следующие выходные. я уже примерно себе представляю как это должно работать. делать планирую на qt, изначально под линупс, но кросплатформено. винды у меня нет. беден. так что если появятся обладатели маков и компов с виндой, желающих присоединиться - велком
если даже гоп-структуру зделать размером 4 кадра всё равно будет ощутимый прирост в степени сжатия, и это всего 100 милисекунд
то так дела не делаются - не слать же в bmp всё, раз канал позволяет
Тут получается дилемма - забить канал под завязку либо сэкономить немного времени. Делайте, а там посмотрим что лучше, выбор - это есть хорошо! В конце концов это может быть переключатель в финальном релизе.
Добавка:
С кодеками - 1% потерь и вы не увидите изображения, пока не придет следующий блок, и опять картинка будет видна пока не потеряется пакет. UDP+Yota=потери, такая формула получена эмпирическим путем 😃
C jpeg каждый кадр идет одним куском, при сбое теряем только один кадр, если в секунду один кадр из 20 или 15 будет теряться мы этого даже не заметим.
Парируйте! 😃
С кодеками - 1% потерь и вы не увидите изображения, пока не придет следующий блок, и опять картинка будет видна пока не потеряется пакет. UDP+Yota=потери, такая формула получена эмпирическим путем 😃
C jpeg каждый кадр идет одним куском, при сбое теряем только один кадр, если в секунду один кадр из 20 или 15 будет теряться мы этого даже не заметим.
Парируйте! 😃
jpeg не идёт одним куском, если он больше mtu, (обычно 1500 байт) 😃
а при сжатии видео 263 кодком, если пропадёт пакет из ключевого кадра то на экране будет небольшой артефакт размером с макроблок, в котором лежал пропавший пакет, длительностью gop_size*frame_duration. а так как ключевые кадры редки, то вероятность этого небольшая. если пропадёт пакет из b-frame или p-frame то артефакта вообще не заметите, его длительность будет frame_duration. в вашем случае неудачный результат скорее всего был связан не с невозможностью передачи сжатого видео через udp, а скорее, не в обиду будет сказано, с неумением это делать. возможно там не всё так просто как может показаться на первый взгляд, но совершенно не означает что невозможно. я видел как такое работает у других с минимальными задержками и без разрушения картинки. значит это возможно 😃