Поддержка VPU VELcore-01
Драйвер avico
Драйвер avico управляет VPU VELcore-01 и реализует аппаратное кодирование и декодирование видео по стандарту H.264. Драйвер реализован с использованием подсистемы V4L2 и предоставляет стандартный программный интерфейс для кодирования/декодирования и управления.
Драйвер поддерживается в ядре Linux 4.4.
Кодирование видео
Поддерживается входное несжатое видео с форматом пикселей M420.
Максимальная ширина кадра — 1920 пикселей.
Максимальная высота кадра — 4096 пикселей.
Поддержка кодирования видео с разрешением кратным 2 по ширине и высоте.
Возможность установки FPS видеопотока.
Возможность установки параметра QP с помощью контролов:
V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET.
Возможность установки IDR-кадра с помощью контрола V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME.
Возможность установки размера GOP с помощью контрола V4L2_CID_MPEG_VIDEO_GOP_SIZE. Новый размер GOP применяется со следующего IDR-кадра после завершения текущего GOP. Чтобы применить новый размер GOP на следующем кадре, нужно запросить IDR-кадр с помощью контрола V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME.
Поддержка более одного потока кодирования видео. Максимальное число поддерживаемых потоков кодирования зависит от ширины и высоты кадра, количества запрошенных V4L2-буферов и объема памяти, которая может быть выделена с помощью Contiguous Memory Allocator (CMA). Теоретическое максимальное число поддерживаемых потоков кодирования можно вычислить с помощью формулы:

где M — размер памяти, которая может быть выделена с помощью CMA, W — ширина кадра, H — высота кадра,
— количество V4L2-буферов
output-интерфейса,
— количество V4L2-буферов
capture-интерфейса.
Дополнительно количество потоков n ограничивается фрагментацией CMA.
Производительность кодирования каждого видео понижается с увеличением числа потоков, т.к.
используется один аппаратный поток кодирования. Пример реального максимального числа потоков и
достигаемой при этом производительности кодирования при QP 23, четырех V4L2-буферов
output-интерфейса, четырех V4L2-буферов capture-интерфейса, размере CMA-памяти 128 МБ и частоте
VPU 312 МГц:1920x1072 — 4 потока, ~15 FPS;
1280x720 — 6 потоков, ~22 FPS;
640x480 — 19 потоков, ~18 FPS.
Пример ограничения числа потоков кодирования для обеспечения производительности кодирования ~30 FPS при QP 23, четырех V4L2-буферов output-интерфейса, четырех V4L2-буферов capture-интерфейса, размере CMA-памяти 128 МБ и частоте VPU 312 МГц:
1920x1072 — 2 потока, ~30 FPS;
1280x720 — 4 потока, ~30 FPS;
640x480 — 12 потоков, ~30 FPS.
Поддержка сжатия с постоянным битрейтом с помощью контролов:
V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE — включение/выключение контроля битрейта;
V4L2_CID_MPEG_VIDEO_BITRATE — битрейт, бит/с.
Контроль битрейта будет выключен, если число кадров в GOP меньше трёх.
Особенности очереди capture:
Поддерживаются буферы типов DMABUF и MMAP.
Буферы должны быть физически непрерывными.
Буферы типа MMAP выделяются драйвером с помощью CMA и являются физически непрерывными и некешируемыми.
Особенности очереди output:
Поддерживаются буферы типов DMABUF, MMAP и USERPTR.
Буферы типов DMABUF и MMAP должны быть физически непрерывными.
Буферы типа MMAP выделяются драйвером с помощью CMA и являются физически непрерывными и некешируемыми.
Если буферы типа USERPTR не являются физически непрерывными, выполняется копирование данных из них в непрерывную память с помощью DMA. Это снижает производительность кодирования.
Декодирование видео
Поддерживается выходное несжатое видео с форматом пикселей M420.
Поддержка декодирования видео с разрешением до 1920x1072 кратным 16 по ширине и высоте.
Поддержка контрола V4L2_CID_MPEG_VIDEO_GOP_SIZE.
Поддержка события V4L2_EVENT_SRC_CH_RESOLUTION при смене разрешения видео (в т.ч. в начальный момент момент времени, когда разрешение видео неизвестно, см. Memory-to-Memory Stateful Video Decoder Interface).
Особенности очередей capture и output:
Поддерживаются буферы типов DMABUF и MMAP.
Буферы должны быть физически непрерывными.
Буферы типа MMAP выделяются драйвером с помощью CMA и являются физически непрерывными и некешируемыми.
Ограничения драйвера
Поддерживается только один аппаратный поток кодирования и один аппаратный поток декодирования.
Несжатое видео имеет нестандартный формат пикселей (M420).
Шаг между яркостными и/или цветовыми строками должен быть кратен 16 байтам.
Для кодирования требуется 180 КиБ памяти XYRAM.
Использование с драйвером delcore30m невозможно, т.к. драйвер avico использует SDMA через API DMA-engine, драйвер delcore30m — непосредственное управление SDMA.
Поддерживается только контроль битрейта в режиме CBR. Контроль битрейта реализован на базе алгоритма, описанного в JVT-G012 и JVT-K049, только частично: при вычислении целевого параметра квантования для P-кадров не учитывается средняя абсолютная разница (MAD) кадра и его прогноза, т.к. VPU не предоставляет доступ к значению MAD, вычисляемому им на этапе оптимизации R-D. MAD может быть вычислен программно, но предполагается, что это повлечет значительное снижение производительности, поэтому вместо модели R-D, описанной в JVT-G012 и JVT-K049, используется модель R-D, описанная в Контроль битрейта при кодировании. Контроль битрейта возможен только при количестве кадров в GOP, равном 3 и более.
Нет возможности менять FPS в процессе кодирования.
Для декодирования требуется выделенная память в двух контроллерах DDR (по 8 МиБ в каждом DDR для поддержки разрешения 1920x1072).
Вне зависимости от количества потоков кодирования/декодирования драйвер avico использует один канал SDMA. Количество используемых каналов SDMA ограничено для обхода ошибки зависания rf#12990.
При декодировании сжатый кадр должен быть целиком расположен в одном output-буфере.
Примечание
Аппаратный блок декодера VPU поддерживает H.264 Constrained Baseline Profile с отключенной опцией Deblocking Filter. Видео с отключенным фильтром может быть создано кодером VPU. Возможность декодирования произвольного видео H.264 не гарантируется.
При кодировании для обхода проблемы rf#1382 драйвер использует промежуточные буферы в XYRAM для восстановленных и сжатых данных. Всего используется 4 буфера по 45 КиБ (строка макроблоков для кадра шириной 1920 пикселей в формате M420) — 2 буфера для восстановленных данных и 2 для сжатых. В результате реализации обхода проблемы, максимальная ширина кадров ограничилась 1920 пикселями.
При кодировании после каждой строки макроблоков VPU останавливается и драйвер выполняет следующие действия:
Настраивает VPU на другой промежуточный буфер.
Запускает SDMA для копирования данных из промежуточного буфера в DDR.
Запускает VPU на обработку следующей строки макроблоков.
При кодировании для обхода проблемы rf#2003 в обработчике прерывания используется задержка, состоящая из следующих действий:
Ожидание завершения чтения очередных данных исходного и референсного кадров.
Ожидание завершения 80-кратного чтения регистра EVENTS.
Ожидание снятия всех флагов регистра EVENTS, указывающих на текущую работу VDMA.
При декодировании для обхода проблемы зависания rf#1382 драйвер в начале декодирования выделяет буферы DDRx и DDRy в разных DDR, затем каждый кадр выполняет следующие действия:
Копирование входных сжатых данных из буфера пользователя в буфер DDRx с помощью SDMA. DDRx — буфер, в котором находится референсный кадр.
Копирование в VRAM первых двух строк макроблоков из буфера референсного кадра. Данное копирование стало необходимым после перемещения восстановленного кадра в отдельный буфер из общего буфера для референсного/восстановленного кадра. Восстановленный кадр теперь записывается в буфер DDRy.
Запуск декодирования, при этом референсный кадр и сжатые данные считываются из DDRx, а восстановленный кадр записывается в DDRy.
Выгрузка последней строки макроблоков из VRAM в буфер восстановленного кадра.
Копирование полученного в результате декодирования восстановленного кадра из DDRy в буфер пользователя с помощью SDMA.
Буферы DDRx и DDRy меняются местами, так что восстановленный кадр в DDRy используется как референсный кадр в DDRx для следующего кадра.
Использование драйвера
При инициализации аппаратного блока драйвер регистрирует два устройства V4L2:
index = 0 — для кодирования,
index = 1 — для декодирования.
В дистрибутиве Buildroot для устройств создаются символические ссылки в директории
/dev/v4l/by-path:
# ls -l /dev/v4l/by-path/*codec*
lrwxrwxrwx ... /dev/v4l/by-path/platform-37100000.codec-video-index0 -> ../../video0
lrwxrwxrwx ... /dev/v4l/by-path/platform-37100000.codec-video-index1 -> ../../video1
Контроль битрейта при кодировании
Контроль битрейта основан на алгоритме, описанном в JVT-G012 и JVT-K049.
Битрейт контролируется на уровне GOP и на уровне кадра. В задачи контроля битрейта входит вычисление параметра квантования, так чтобы средний битрейт видео соответствовал заданному значению.
В последующем описании используются следующие обозначения:
— частота кадров (предполагается, что не меняется в процессе кодирования);
— ширина кадра в пикселях;
— высота кадра в пикселях;
— номер GOP;
— номер кадра в пределах GOP;
— количество кадров в i-ом GOP;
— размер j-го сжатого кадра в i-ом GOP;
— число бит, оставщихся в GOP, на момент кодирования j-го кадра в i-ом GOP;
— параметр квантования j-го кадра в i-ом GOP;
— усредненный параметр квантования по всем P-кадрам в i-ом GOP;
— целевой битрейт на момент кодирования j-го кадра в i-ом GOP;
— целевой уровень виртуального буфера (число оставшихся бит) после кодирования
j-го карда в i-ом GOP;
— уровень заполнения виртуального буфера сжатых кадров (число бит в буфере
сжатых кадров гипотетического референсного декодера) на момент кодирования j-го кадра в i-ом GOP;
— целевое число бит на пиксель.
Описание алгоритма
Общее число бит для оставшихся кадров в GOP в случае сжатия с константным битрейтом вычисляется по формуле:

Уровень заполнения виртуального буфера вычисляется по формуле:

Для первого карда первого GOP значение параметра квантования выбирается на основе целевого числа бит на пиксель по формуле:

Рекомендуемые значения:
— для кадров размером QCIF/CIF;
— для кадров больше QCIF/CIF.
Для последующих GOP:


Полученное значение параметра квантования корректируется по формуле:

Перед вычислением параметра квантования P-кадров вычисляется целевой размер P-кадра.
Целевой размер P-кадра зависит от целевого уровня виртуального буфера. Целевой уровень виртуального буфера определяется для каждого P-кадра согласно размерам первого IDR-кадра и первого P-кадра.
После кодирования первого P-кадра в i-ом GOP начальное значение целевого уровня виртуального буфера устанавливается по формуле:

Целевой уровень виртуального буфера для последующих P-кадров вычисляется по формуле:

Размер, выделяемый для j-го P-кадра в i-ом GOP, вычисляется на основе целевого уровня виртуального буфера, частоты кадров, целевого битрейта и реального уровня заполненения виртуального буфера по формуле:

где
— константа, равная 0.5.
При вычислении целевого размера кадра также следует учесть число оставшихся бит в GOP для кадра, которое вычисляется по формуле:

Целевой размер P-кадра — взвешенная комбинация
и
, которая
вычисляется по формуле:

где
— константа, равная 0.5.
Для совместимости с гипотетическим референсным декодером целевой размер P-кадра должен также ограничиваться согласно Совместимость с гипотетическим референсным декодером.
В JVT-K049 и JVT-G012 целевой параметр квантования вычисляется на основе квадратичной модели R-D, в которой используется средняя абсолютная разница [1] (MAD) текущего базового элемента (кадр, макроблок или слайс) и его прогноза, полученного на этапе оптимизации R-D. VPU не предоставляет значение MAD для кадра, поэтому вычисление целевого параметра квантования выполняется другим методом.
Согласно Rate-Distortion Analysis for H.264/AVC Video Coding and its Application to Rate Control увеличение параметра квантования на единицу приводит к уменьшению битрейта на ~12.5%, таким образом целевой параметр квантования QP может быть вычислен из формулы:

где T — целевой размер кадра,
— размер кадра, полученный при значении
параметра квантования,
— коэффициенты, начальные значения которых
соответственно равны 1 и 0. Коэффициенты обновляются после кодирования каждого кадра согласно
методу наименьших квадратов.
Данный метод требует двух проходов кодирования каждого кадра, т.к. сначала требуется вычислить размер кадра для заданного QP и в случае необходимости скорректировать QP и повторно выполнить кодирование. Для выполнения одного прохода кодирования предлагается прогнозировать размер текущего кадра для заданного QP на основе размера предыдущего P-кадра по формуле [2]:

Формула аналогична модели прогнозирования MAD, описанной в JVT-G012 и JVT-K049.
где
и
— коэффициенты модели прогнозирования размера кадра,
— размер предыдущего кадра. Начальные значения коэффициентов соответственно равны 1 и 0.
Коэффициенты обновляются после кодирования каждого кадра согласно методу наименьших квадратов.
Для предотвращения резкого изменения качества видео вычисленный параметр квантования корректируется по формуле:

Полученное значение параметра квантования ограничивается диапазоном [0; 51] и передается в VPU, который выполняет оптимизацию R-D согласно значению QP.
После завершения кодирования кадра значения коэффициентов
обновляются.
Примечание - В текущей реализации алгоритма контроля битрейта коэффициенты
всегда равны начальным значениям.
Совместимость с гипотетическим референсным декодером
Чтобы удовлетворять требованиям гипотетического референсного декодера целевой размер P-кадра
также ограничивается нижней границей (
) и верхней границей (
) по
формуле:

Верхняя и нижняя границы инициализируются по формулам:

где
— число бит для оставшихся кадров в GOP с номером (i-1),
,
— константа, равная 0.9,
—
длительность удаления 1-го кадра из виртуального буфера,
— размер
данных (в битах), эквивалентный длительности t с коэффициентом преобразования, равным битрейту.
Последующие значения
и
вычисляются по формулам:

Примечание - Формулы для
и
, описанные выше, представлены в Adaptive
rate control for H.264.
Предполагается, что в JVT-K049 даны некорректные формулы
и
(в формулах вместо размера предыдущего кадра используется размер текущего кадра, который не
может быть известен на данном этапе). В документе JVT-G012 целевой размер P-кадра не ограничивается
нижней и верхней границами, поэтому формулы
и
там отсутствуют.
Пакеты пространства пользователя
Для поддержки VPU используются следующие пакеты и утилиты (все пакеты и утилиты распространяются в составе MCom-02 Buildroot):
- Пакет m2m-test
Набор утилит для тестирования устройств V4L2 memory-to-memory. Дополнительно пакет распространяется в репозитории https://github.com/elvees/m2m-test. README пакета содержит описание и примеры вызова утилит.
- Пакет v4l-utils
Стандартный пакет v4l-utils для управления устройствами V4L2.
- Скрипт fc-avico
Shell-скрипт для проверки кодирования из файла в файл. Содержится в Buildroot-пакете mcom02-linux-tests.
- Пакет ffmpeg
Стандартный пакет ffmpeg пропатчен для поддержки формата M420.
- Пакет gstreamer1
Стандартный пакет gstreamer1 пропатчен для поддержки формата M420.
Тесты кодирования
См. также
Инструкция Захват видео и RTSP-вещание
fc-avico
Скрипт fc-avico выполняет:
Сгенерировать тестовое видео с помощью ffmpeg.
Конвертировать тестовое видео в формат M420 с помощью any2m420.
Сжать тестовое видео на VPU с помощью m2m-test.
Проверить, что скорость сжатия больше 30 кадров в секунду.
Запуск скрипта и пример вывода:
$ fc-avico -c
/tmp/fc-avico /tmp/test
Input #0, yuv4mpegpipe, from 'm420.y4m':
Input #0, yuv4mpegpipe, from 'm420.y4m':
Duration: Duration: 00:00:02.00, start: 00:00:02.00, start: 0.000000, bitrate: 0.000000276481 kb/s, bitrate: 276481 kb/s
Stream #0:0 Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p(progressive), 1280x720: Video: rawvideo (I420 / 0x30323449), yuv420p(progressive), 1280x720, , 25 fps, 25 fps, 25 tbr, 25 tbr, 25 tbn, 25 tbn, 25 tbc25 tbc
Card: avico
V4L2: Control: h264_i_frame_qp_value = 28
V4L2: Control: h264_p_frame_qp_value = 28
V4L2: Control: h264_chroma_qp_index_offset = 0
V4L2: Control: video_gop_size = 60
V4L2: Control: frame_level_rate_control_enable = 0
V4L2: Control: video_bitrate = 524288
Encoding framerate: 25.00 -> 25.00 FPS
Output size: 85 KiB
Total time in main loop: 0.7 s (69.1 FPS)
Card: avico
V4L2: Control: h264_i_frame_qp_value = 28
V4L2: Control: h264_p_frame_qp_value = 28
V4L2: Control: h264_chroma_qp_index_offset = 0
V4L2: Control: video_gop_size = 60
V4L2: Control: frame_level_rate_control_enable = 0
V4L2: Control: video_bitrate = 524288
Encoding framerate: 25.00 -> 25.00 FPS
Output size: 85 KiB
Total time in main loop: 0.7 s (68.8 FPS)
Checking results for thread #0
encoded_0.264: OK
Checking results for thread #1
encoded_1.264: OK
TEST PASSED
После окончания работы тест сохранит сжатое видео в файлах /tmp/fc-avico/encoded_0.264
и /tmp/fc-avico/encoded_1.264. Файл можно проиграть на HDMI-мониторе с помощью команды:
ffmpeg -re -i /tmp/fc-avico/encoded_0.264 -pix_fmt bgra -f fbdev /dev/fb0
v4l2-compliance
Запуск и пример вывода стандартной утилиты проверки устройств V4L2:
$ v4l2-compliance --device=/dev/v4l/by-path/platform-37100000.codec-video-index0
v4l2-compliance SHA : c7dfb39ae7305d7118bb208598c2be47d1ddcf52
Driver Info:
Driver name : avico
Card type : avico
Bus info : platform:avico
Driver version: 4.4.237
Capabilities : 0x84208000
Video Memory-to-Memory
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04208000
Video Memory-to-Memory
Streaming
Extended Pix Format
Compliance test for device /dev/v4l/by-path/platform-37100000.codec-video-index0 (not using libv4l2):
...
Total: 43, Succeeded: 43, Failed: 0, Warnings: 10
Тесты декодирования
v4l-compliance для устройства декодера не поддерживается.
Примеры декодирования приведены в файле README в составе пакета m2m-test.