-
Скачан видеоролик (720p, 30 FPS)
-
При помощи утилиты
ffmpeg
ролик был разбит на 6572 кадра, каждый был записан в отдельном файле с именем в формате "frame-%06d"; -
При помощи утилиты
convert
от Imagemagick было с каждым кадром было сделано следующее:- масштабирование до размеров 85x64 (по высоте экрана);
- глубина цвета была уменьшена до 1 бита;
- были добавлены 3 белых пикселя, чтобы ширина фрейма составляла 88 точек;
- инвертирование цветов;
Для этого, конечно же, был написан небольшой bash-скрипт (
convert.sh
); -
Написана небольшая программа на C++ (
pack.cpp
) для создания бинарного файла, содержащего друг за другом битмапы всех фреймов; -
Написан небольшой bash-скрипт (
send.sh
) для отправки получившегося бинарника на плату через последовательный порт; -
Написан сам скетч, который принимает данные с порта, записывает их в буфер, а затем буфер отправляет на экран.
-
convert
при использовании его шелл-версии в цикле работает несколько медленней, чем он же, но в имплементации C++, поэтому все фреймы конвертировались около 5-ти минут; -
именно из-за скорости работы (попиксельного анализа всех фреймов) я и воспользовался более нативным вариантом, иначе бы скрипт обрабатывал изображения около трех дней подряд;
-
чтобы фреймы можно было отправлять встроенной в либу функцией
drawBitmap()
, которая среди прочего в аргументы принимает фрейм-буфер, длина которого должна быть кратна 8, именно поэтому пришлось увеличить длину фреймам до 88; -
потребовалось сделать минимальную синхронизацию отправки-принятия данных, чтобы корректно передавать данные через 64-байтовый буфер последовательного порта платы (причем данные передавались в итоге пакетами по 44 байта, ибо вместо 64 байт прилетает только 63);
-
синхронизацию можно описать следующим образом: компьютер отправляет одну из 16 частей фрейма в виде 44 байт (704 / 44 = 16), а затем ждёт один байт из порта; в это время плата ждёт от компьютера 44 байта с таймаутом в одну секунду, чтобы записать их сначала в собственный фрейм-буфер, а затем, как только будут отправлены все 16 частей, в буфер экрана, при получении очередной части плата отправляет в порт один байт, чтобы вывести компьютер из режима ожидания;
-
плата нестабильно работает на максимальной скорости последовательного порта (2 млн бод/с), с этим я разбирался больше всего, ибо именно это было причиной глитчей в буфере и несостыковок во время передачи (потребовалось 3 дня, чтобы понять, что скорость порта нужно понизить, в моём случае, до 1 млн бод/с было достаточно);
-
в целом плата могла бы выдать и больше 20 FPS, однако с экраном работала лишь древняя версия библиотеки, в ином случае можно было бы еще передавать и аудио-дорожку, воспроизводя её через встроенный в скелет с экраном спикер.