25 FPS в 720p через 3G: как на RK3588 перестали жечь JPEG и погнали H.264

· ·

25 FPS в 720p через 3G: как на RK3588 перестали жечь JPEG и погнали H.264

PrimeCoder · 2026 · формат: tech

Разбор новинки простыми словами: что это, кому нужно и брать ли.

Кейс показывает, что мобильный видеомониторинг упирается не в канал, а в архитектуру: проброс готового H.264 в fMP4 вместо повторного кодирования кадров снимает нагрузку с бортового CPU и влезает в 128 кбит/с — шаблон для любого продукта с удалённым наблюдением через LTE/3G.

Связанные услуги: каталог, AI Boost Team, стать клиентом.

25 кадров в секунду, 720p, 128 килобит в секунду, канал 3G. Цифры выглядят как опечатка, пока не увидишь, что именно из тракта убрали. Инженер Unibot Лев Ларин довёл живой просмотр с камер робота-доставщика SpeedyBot (Alfa Robotics) до состояния, в котором картинка не пересобирается на борту ни разу. Камеры сами отдают сжатый H.264, борт только меняет упаковку на fMP4, браузер собирает поток через MediaSource.

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

Что собрали на борту

Четыре обзорные IP-камеры Vatilon H46 стоят по периметру робота. Передняя и задняя закреплены с поворотом на 90 градусов, поэтому сырой кадр лежит на боку. Камеры общаются с бортовым компьютером по внутренней Ethernet-сети, уже сжатым потоком по RTSP. Плата сообщает о себе как Rockchip RK3588 ZYSJ 2288K v01, внутри восемь ядер: четыре Cortex-A76 и четыре Cortex-A55. На этом же железе крутятся Linux, ROS, локализация с навигацией и связь с платформой.

Новый тракт выглядит так: H46 отдаёт H.264 по RTSP/TCP, PyAV 16.0.1 на борту делает demux и mux, получается fMP4, фрагменты уходят отдельным WebSocket на сервер Fleet (FastAPI), браузер (React/TypeScript) забирает их как video/mp4 и отдаёт в обычный тег video. Декодирования нет, кодирования нет. Поворот кадра вынесен в CSS: rotate(90deg) плюс перестановка ширины и высоты блока. Картинка для оператора правильная, пакеты при этом не трогают.

Штатный видеорегистратор продолжает писать суточный архив с дополнительного потока. Для живого просмотра берут основной поток одной выбранной камеры. Четыре камеры на корпусе и четыре одновременные трансляции через LTE это разные вещи, и в кейсе их не путают.

Как было раньше и почему не влезало

Первый вариант жил двумя кадрами в секунду: FFmpeg декодировал RTSP, поворачивал, ужимал до 640×480 и кодировал заново в JPEG. Дальше захотелось нормального видео, и арифметика перестала сходиться. Десять JPEG в секунду с квантователем -q:v 8 дали средний кадр 33,3 КБ и поток 2,665 Мбит/с. Вариант с -q:v 12 снизил кадр до 24,9 КБ и поток до 1,989 Мбит/с. Измеренная отдача LTE на трёх HTTPS-загрузках по 2 МиБ: 1,785, 2,056 и 1,928 Мбит/с.

Итог простой: картинки съедали канал целиком ещё до TCP, TLS и WebSocket. Дальше по кругу пошли бы компромиссы по качеству. Вместо этого команда посмотрела, что умеет сама камера. H.264 сжимает не каждый кадр отдельно, а разницу между ними, и на H46 это уже работало. JPEG-кадence выбрасывал результат работы камерного кодировщика и заказывал ту же работу бортовому CPU второй раз.

По дороге выяснилось, что камере нельзя верить на слово. ONVIF описывал основной поток как H.264, ffprobe нашёл HEVC 1920×1080 и фактические 10 FPS, при этом r_frame_rate показывал 25. Считать реальную частоту приходится по временным меткам видеопакетов. Ещё один сюрприз: настройка кодировщика через ONVIF отвечала успехом, но камера держала прежний GOP около четырёх секунд. Пришлось идти в родной HTTP API /cgi-bin/web.cgi.

ONVIF SetVideoEncoderConfiguration отвечал успехом, но H46 сохранял четырёхсекундный GOP. Поэтому ONVIF оставили для поиска URI, а настройки меняем родным API камеры: /cgi-bin/web.cgi.

Целевой GOP около одной секунды. Разница практическая: подключившись между ключевыми кадрами при старом GOP, оператор ждал картинку секундами. Цена перехода видна в первом ключевом фрагменте: 24 622 байта при 256 кбит/с против 5 822 байт при 128 кбит/с, по четырём направлениям разброс 24,6–32,8 КБ и 5,8–9,3 КБ. Ключевой кадр дороже обычного, и его частота прямо влияет на бюджет.

Факт и что из него следует

Факт из кейсаЧто это значит для продукта
Камеры H46 кодируют H.264 сами и отдают по RTSPБортовой CPU не обязан заниматься видео. Проверьте, что вы не платите за уже выполненную работу
GOP сократили с ~4 с до ~1 сВремя до первой картинки у оператора падает. Это настройка камеры, а не код клиента
ONVIF рапортовал успех, камера его игнорировалаСтандартный протокол не гарантирует результат. Нужна проверка по факту, по пакетам
ffprobe показал HEVC 1080p и 10 FPS там, где заявлен H.264 720p 25 FPSМетаданные потока врут. Частоту считают по PTS, битрейт по сумме размеров пакетов
128 кбит/с вместо 2,665 Мбит/с у JPEG-каденсаЗапас канала вырос примерно в двадцать раз при выросшем разрешении и частоте
Поворот кадра вынесен в CSSОриентация это задача отображения, а не повод гонять видео через декодер

Кому это нужно и где применить

Шаблон ложится на любой продукт с удалённым наблюдением через LTE или 3G: бортовые камеры на транспорте, мобильные посты, сельхозтехника, стройплощадки, роботизированные тележки на складах, где Wi-Fi не добивает. Везде, где на объекте стоит IP-камера с собственным кодировщиком, а канал узкий и дорогой.

Логика переноса простая. Сначала проверить, что камера кодирует сама и что вы не декодируете её поток ради переупаковки. Потом убедиться, что настройки применились: частота по PTS, интервал ключевых кадров, реальный кодек. Потом выбрать упаковку под браузер (в кейсе H.264 и fMP4 через WebSocket и MediaSource) и отдать ориентацию интерфейсу. Настройки камеры менять тем API, который действительно работает, даже если стандартный отвечает «ок». Для веб-клиента это ещё и отсутствие плагинов: обычный тег video.

Ограничения, которые не спрятать

128 кбит/с для 720p это жёсткий режим. Плавный обзор есть, мелких деталей нет.

128 кбит/с для 720p — жёсткое сжатие. Мелкие детали при таком бюджете страдают; нам был нужен плавный обзор для оператора.

Практический вывод: читать номера, лица и надписи на такой ширине канала не получится, для этого нужен другой сценарий и другой бюджет. Дальше идут вещи эксплуатационные. Камеры приходится настраивать через вендорский HTTP API, а он у каждого производителя свой, так что универсальной кнопки не будет. Реальную частоту и битрейт надо измерять самостоятельно, потому что заявленному верить нельзя. И на борту всё равно остаётся серверная часть с WebSocket и FastAPI, плюс аккуратная работа с очередями TCP: подвисание одного зрителя не должно тормозить остальных.

Брать или подождать

Брать, если у вас уже стоят IP-камеры с собственным кодировщиком и вы платите за канал, а не за железо. Схема «проброс готового H.264 в fMP4, поворот в CSS» проверяется за день-два на одном направлении и не требует замены парка камер.

Подождать, если задача в деталях: распознавание номеров, лица, мелкий текст в кадре. Тут 128 кбит/с не помощник, и снижение битрейта до этого уровня сломает сценарий. Также стоит повременить, если камеры не умеют отдавать H.264 или вы не готовы разбираться с их частным API.

Вопросы, которые задают первыми

Почему H.264, если камеры умеют H.265?

В кейсе для браузерного плеера выбрали H.264, 1280×720 и ключевой кадр примерно раз в секунду. Это выбор под конкретный клиент, а не оценка кодеков вообще.

Можно обойтись без своего сервера?

В описанной схеме сервер есть: отдельный WebSocket, FastAPI на стороне Fleet, раздача video/mp4 в браузер. Это часть архитектуры, а не деталь реализации.

Почему не настроить всё через ONVIF?

Потому что камера отвечает успехом и сохраняет старые параметры. ONVIF в этом кейсе оставили для поиска URI, а конфигурацию меняют родным API.

25 FPS это реальные кадры?

Фактические 25 при заказанных 30. Считать надо по временным меткам видеопакетов, а не по строке r_frame_rate.

Если у вас в проекте есть удалённое видео через мобильную сеть, начните с одного вопроса: сколько раз кадр пересобирается по дороге от матрицы до экрана оператора. В этом кейсе ответ сократили до нуля и получили 720p на 128 кбит/с. Посчитайте свой бюджет по пакетам, а не по спецификации камеры, и станет видно, где именно вы теряете канал.

Читайте также