Отчёт: анализ видео на RK3562 с использованием YOLO на NPU
1. Постановка задачи
Разработать систему анализа видеофайлов стандартных форматов (mp4, avi, mov) на плате RK3562 с использованием нейросетевой детекции объектов на NPU. Результат обработки должен быть playable-видео с нарисованными рамками вокруг найденных объектов.
Требования:
вход — любой стандартный видеоформат;
декодирование через аппаратные средства платы;
детекция объектов через нейросеть на NPU;
отрисовка рамок и подписей классов на кадрах;
кодирование результата обратно в видео;
запуск одной командой без ручного указания параметров.
2. Аппаратная и программная база
Плата: RK3562 (NPU RKNPU2, 1 TOPS).
Драйвер NPU: версия 0.9.8.
Runtime RKNN: librknnrt.so 2.3.0.
Операционная система: Buildroot 2024.02.
Аппаратные кодеки: MPP (Media Process Platform) — поддерживает H.264/H.265 декодирование и H.264 кодирование.
Аппаратный 2D-акселератор: RGA (Raster Graphic Acceleration).
GStreamer: 1.22.9 с плагинами Rockchip.
Среда разработки: виртуальная машина Lubuntu с Buildroot-тулчейном aarch64-linux-gcc 12.3.0.
3. Выбранные модели
Для сравнения взяты две модели детекции объектов, обе сконвертированы в формат RKNN с квантизацией INT8:
YOLOv5n:
источник: rknn_model_zoo/examples/yolov5
вход: 640 на 640, RGB
выход: 3 тензора (80 на 80, 40 на 40, 20 на 20)
размер .rknn: 2.7 МБ
YOLOv8n:
источник: rknn_model_zoo/examples/yolov8
вход: 640 на 640, RGB
выход: 1 тензор
размер .rknn: 4.1 МБ
Обе модели обучены на датасете COCO (80 классов: человек, машина, мяч, бутылка и т.д.).
4. Схема обработки видео
Пайплайн состоит из пяти этапов:
Этап 1 — декодирование.
Входной mp4/avi/mov читается через GStreamer с аппаратным декодером mppvideodec. Видеопоток конвертируется в один из двух форматов:
RGB888 (для разрешений до 640x360)
NV12 (для разрешений больше 640x360)
Этап 2 — инференс.
Каждый кадр подаётся в YOLO-модель на NPU. Модель возвращает список найденных объектов с координатами рамок и вероятностями.
Этап 3 — отрисовка.
Рамки и подписи классов рисуются прямо на кадре через функции draw_rectangle и draw_text из состава rknn_model_zoo. Функции умеют работать и с RGB888, и с NV12 без промежуточной конвертации.
Этап 4 — кодирование.
Результат подаётся в аппаратный энкодер mpph264enc, на выходе — H.264-поток.
Этап 5 — упаковка.
H.264-поток упаковывается в контейнер MPEG-TS через mpegtsmux. Формат MPEG-TS выбран потому, что mp4mux в имеющейся сборке GStreamer не может работать с потоком от mpph264enc из-за отсутствия PTS (временных меток).
5. Ключевая техническая проблема: RGB против NV12
В процессе работы выявлена фундаментальная особенность RK3562: аппаратный 2D-акселератор RGA не может обработать RGB-буферы большого размера, выделенные через стандартный malloc.
Симптом: при разрешении 768x432 в RGB-режиме RGA падал с ошибкой IOMMU page fault. В логе ядра было видно:
rk_iommu ff440f00.iommu: iova = 0x00000000ffe69000: page fault
Причина: RGA работает через IOMMU и требует, чтобы буферы были либо ниже 4 ГБ, либо выделены через DMA-heap. При malloc в 64-битной системе буфер может оказаться в «верхней» части памяти, недоступной для RGA.
Размеры буферов для 768x432:
RGB888: 768 x 432 x 3 = 995 328 байт — RGA падает
NV12: 768 x 432 x 1.5 = 497 664 байт — RGA работает
Для 640x360:
RGB888: 640 x 360 x 3 = 691 200 байт — RGA работает
NV12: 640 x 360 x 1.5 = 345 600 байт — тоже работает
Практическое правило: до 640x360 можно использовать RGB, для больших разрешений нужно использовать NV12.
6. Вторая техническая проблема: stride при декодировании
Аппаратный декодер MPP выравнивает высоту кадра до кратной 8 или 16 пикселям. При декодировании 640x360 реальный размер кадра оказался 353 280 байт вместо ожидаемых 345 600. Разница 7680 байт — это выравнивание.
Из-за этого при попытке читать NV12-поток с фиксированным шагом 345 600 байт каждый следующий кадр начинался со смещением, и картинка «плыла» сверху вниз с искажением цветности.
Решение: пропустить вывод декодера через videoscale и videoconvert с явным указанием формата NV12 и разрешения. Это гарантирует, что на выходе будет чистый поток без паддинга.
Пример команды:
gst-launch-1.0 -q filesrc location=input.mp4 ! qtdemux ! h264parse ! mppvideodec ! videoscale ! videoconvert ! video/x-raw,format=NV12,width=768,height=432 ! filesink location=output.nv12
Проверка: размер файла должен делиться нацело на width x height x 1.5. Например, для 768x432: 306 063 360 / 497 664 = 615 кадров ровно.
7. Третья техническая проблема: упаковка в MP4
Изначально планировалось упаковывать результат в mp4. Однако mp4mux наотрез отказался работать с потоком от mpph264enc:
Buffer has no PTS (Could not multiplex stream)
Причины:
mpph264enc не записывает временные метки (PTS) в поток;
mp4mux требует PTS для каждого кадра;
ни h264parse, ни h264timestamper, ни matroskamux не смогли восстановить PTS из потока;
в сборке GStreamer на плате отсутствуют элементы avenc_mp4 и videoparse/rawvideoparse.
Решение: использовать mpegtsmux. Формат MPEG-TS не требует PTS от предыдущих элементов и корректно упаковывает поток. Файл открывается в VLC, mpv, ffplay и большинстве других плееров.
8. Производительность моделей
Сравнение на одном видео (futbol.mp4, 615 кадров, разрешение 768x432, NV12):
YOLOv5n:
время обработки: 28.85 сек
скорость: 21.3 FPS
найдено объектов: 2700
объектов на кадр: 4.4
размер модели: 2.7 МБ
YOLOv8n:
время обработки: 29.90 сек
скорость: 20.6 FPS
найдено объектов: 2499
объектов на кадр: 4.1
размер модели: 4.1 МБ
Вывод: модели сопоставимы по скорости (разница 4%), YOLOv5n немного быстрее и находит больше объектов, при этом занимает втрое меньше дискового пространства.
9. Тест на сложной сцене
На видео futbol1.mp4 (960 кадров, 768x432, NV12) с футболистами, снятыми сверху с большой высоты, обе модели показали низкое количество детекций:
YOLOv8n: 338 объектов (0.35 на кадр)
Причина: футболисты занимают в кадре очень мало пикселей (удалены от камеры). YOLO-модели, обученные на COCO, плохо детектируют объекты размером меньше 32x32 пикселя. Это ограничение архитектуры, а не ошибка конвертации.
Для таких сцен нужны либо модели, обученные специально на спортивных трансляциях, либо предварительное увеличение разрешения.
10. Пакетный скрипт process_video.sh
Итоговый скрипт автоматизирует весь пайплайн. Он выполняет шесть шагов:
Шаг 0 — определяет параметры входного видео через gst-discoverer-1.0 (разрешение, FPS).
Шаг 1 — автоматически выбирает режим (RGB для разрешений до 640x360, NV12 для больших).
Шаг 2 — декодирует видео в выбранный формат.
Шаг 3 — запускает YOLO-демо на NPU.
Шаг 4 — кодирует результат в H.264 и упаковывает в MPEG-TS.
Шаг 5 — проверяет результат через gst-discoverer-1.0.
Шаг 6 — удаляет промежуточные файлы.
Использование:
process_video.sh input.mp4 output.ts
Например:
process_video.sh bd.mp4 bd_final.ts
Скрипт сам определит, что bd.mp4 имеет разрешение 640x360, и выберет RGB-режим. Для futbol.mp4 (768x432) он выберет NV12.
11. Итоговые результаты по всем тестовым видео
Обработано четыре видеофайла с разными разрешениями и частотой кадров.
bd.mp4 (640x360, 1189 кадров, 29.83 FPS):
режим: RGB
модель: YOLOv5n
время: 48.59 сек
скорость: 24.5 FPS
найдено объектов: 3409
futbol.mp4 (768x432, 615 кадров, 25 FPS):
режим: NV12
модель: YOLOv5n
время: 28.85 сек
скорость: 21.3 FPS
найдено объектов: 2700
futbol.mp4 (768x432, 615 кадров, 25 FPS):
режим: NV12
модель: YOLOv8n
время: 29.90 сек
скорость: 20.6 FPS
найдено объектов: 2499
futbol1.mp4 (768x432, 960 кадров, 29.97 FPS):
режим: NV12
модель: YOLOv8n
время: 36.98 сек
скорость: 26.0 FPS
найдено объектов: 338 (маленькие объекты вдали, сложная сцена)
pd.mp4 (768x432, 596 кадров, 12 FPS):
режим: NV12
модель: YOLOv5n
время: 25 сек
скорость: 23.8 FPS
найдено объектов: 444
итоговое видео: pd_final.ts (3.2 МБ, длительность 49.6 сек, 768x432, 12 FPS)
12. Созданные артефакты
На виртуальной машине:
Демо-бинарники (в install/rk356x_linux_aarch64/):
rknn_yolov5_demo — обработка одного изображения YOLOv5
rknn_yolov5_video_demo — обработка видео в RGB YOLOv5
rknn_yolov5_video_nv12_demo — обработка видео в NV12 YOLOv5
rknn_yolov8_demo — обработка одного изображения YOLOv8
rknn_yolov8_demo_zero_copy — zero-copy версия для одного изображения
rknn_yolov8_video_demo — обработка видео в RGB YOLOv8
rknn_yolov8_video_nv12_demo — обработка видео в NV12 YOLOv8
Модели:
yolov5.rknn (2.7 МБ, INT8)
yolov8.rknn (4.1 МБ, INT8)
Скрипт process_video.sh — автоматический пайплайн.
На плате (в /root/video/):
все демо-бинарники;
обе модели в /root/video/model/;
файл классов coco_80_labels_list.txt;
скрипт process_video.sh;
библиотеки librknnrt.so и librga.so в /root/video/lib/.
13. Что можно улучшить
Ускорение обработки на 20-30 процентов: использовать zero-copy режим. Это требует правок в C++ коде — выделения буферов через rknn_tensor_mem_alloc или DMA-heap. На текущий момент zero-copy реализован только для обработки одиночных изображений, но не для видео.
Обработка видео быстрее реального времени: пропускать каждый второй кадр при инференсе. Реализуется одной строкой в main_video.cc. Для видео с людьми это нормально, поскольку объекты не исчезают между соседними кадрами. Позволит обрабатывать 30 FPS видео в реальном времени на скорости 24.5 FPS.
14. Выявленные ограничения платформы
Ограничение RGA по размеру буфера. RGB-буферы больше 800 КБ (при 640x360 и выше) могут вызывать IOMMU page fault при выделении через malloc. Обход — использовать NV12 или DMA-heap.
Отсутствие PTS в потоке mpph264enc. Аппаратный энкодер не записывает временные метки, что исключает упаковку в mp4 напрямую. Обход — использовать MPEG-TS.
Ограниченный набор элементов GStreamer. В сборке отсутствуют videoparse, rawvideoparse, avenc_mp4. Это сужает набор доступных конвейеров.
Чувствительность к выравниванию высоты кадра. MPP декодер выравнивает высоту до кратной 16, из-за чего при чтении NV12-потока без videoscale/videoconvert возникает эффект «плывущей» картинки.
15. Сравнение с другими задачами на RK3562
За время работы на плате запущены три класса задач:
LLM Qwen2-0.5B (NPU): 11.5 токенов в секунду, память 690 МБ.
ASR Whisper-base (NPU): RTF 0.41 для русского языка.
ASR Zipformer russian (CPU): RTF 0.70, streaming.
Детекция YOLO (NPU): 20-26 FPS на видео 768x432.
Все три задачи работают локально, без интернета. NPU на RK3562 справляется с LLM и ASR поочерёдно (не одновременно), детекция YOLO может идти параллельно с CPU-задачами.
16. Итог
Система анализа видео на RK3562 полностью работает. Входной mp4 обрабатывается автоматически, результат сохраняется в MPEG-TS с нарисованными рамками детекции. Пакетный скрипт сам определяет разрешение и выбирает оптимальный режим (RGB или NV12). Две модели (YOLOv5n и YOLOv8n) показали сопоставимую скорость, при этом YOLOv5n быстрее и компактнее.
Обработано четыре тестовых видео с разными характеристиками: от 12 FPS до 30 FPS, от 640x360 до 768x432. Для всех файлов результат получен корректно, длительность итогового видео совпадает с исходной.
Выявлены и обойдены три технических ограничения платформы: лимит RGA по размеру буфера, отсутствие PTS в потоке от mpph264enc, выравнивание кадров в аппаратном декодере.
Производительность системы достаточна для обработки видео с разрешением до 768x432 в темпе, близком к реальному времени.
Attachment file: uploads/forum/forum_yolo_rk3562_video.zip