Введение
Приветствую профессиональное сообщество Хабра.
В этой статье описана прошивка IPTV приставки MOTOROLA VIP1003 ARRIS для получения удалённого доступа, а также портирование приложения на целевую архитектуру с целью добавления функционала воспроизведения контента с источников, требующих авторизации.
В заключительной части подведены итоги описанной в статье работы, а также рассмотрена область использования IPTV приставки MOTOROLA VIP1003 ARRIS.
Со всей серьёзностью заявляю, что написание простейшей программы, первой для IPTV приставки MOTOROLA VIP1003 ARRIS, печатающей на экран терминала сообщение “Hello World” является важным моментом, рассматривающим техническую возможность портирования более сложных проектов. Имеются особенности, которые необходимо рассмотреть.
Для конечных пользователей модифицированного устройства приведено Руководство пользователя.
Содержание
Интерфейс UART. Подключение диагностического вывода к терминалу.
Настройки. Перечисление и описание функции настроек приставки в интерактивном конфигурационном меню.
Программное обеспечение. Описание используемого программного обеспечения. Выход в Интернет необходим только в этом разделе.
Подготовка к прошивке. Пошаговое руководство для подготовки к процессу прошивки. Дополнительную информацию можно найти в предыдущих разделах.
Процесс прошивки. Комментарии к сообщениям терминала.
Воспроизведение контента. Здесь описывается функция новой прошивки.
Первая программа для IPTV приставки. Особенности сборки простейшей программы для целевой архитектуры и её запуска на целевой системе. Обман вообщем.
Портирование FFmpeg на архитектуру SuperH SH. Настройка кросс-компиляции популярного проекта FFmpeg и его запуск на целевой системе.
Воспроизведение контента с источника RTSP, требующего basic авторизации. Применение FFmpeg для реализации поддержки функции.
Проблема портирования приложений для архитектуры SuperH SH. Чем ограничено расширение функционала?
Целесообразность модификации приставки. Что за ерундой мы только что занимались?
Руководство пользователя. Инструкция по использованию модифицированной приставки для конечного пользователя.
Обзор IPTV приставки MOTOROLA VIP1003 ARRIS
![Общий вид. [1] Общий вид. [1]](https://habrastorage.org/r/w780/extt/34/24/78/34247831857f5f7ac00fb8accfbf3b1a.jpg)
Управление производится с пульта ДУ. Например от Ростелекома.
![Пульт управления [6] Пульт управления [6]](https://habrastorage.org/r/w780/extt/36/82/26/3682263fd3af626aea747a51f99c7721.webp)
![Вид сзади. [2] Вид сзади. [2]](https://habrastorage.org/r/w780/extt/f1/30/b5/f130b540610b5845dd46215956eaddbb.jpg)
Питание 12В/1A. Выход HDMI. Функционал HDCP предоставляется. Композитный видеовыход. Коаксиальный выход S/PDIF интерфейса. Существуют модели, имеющие разьём SCART, вместо композитки. Форма корпуса диктуется, вероятно, вопросами совместимости с разьёмами SCART.
Внутренняя компоновка довольно просторная.
![Вид изнутри. [3] Вид изнутри. [3]](https://habrastorage.org/r/w780/extt/fb/53/e4/fb53e4d6112aaf4ae774ce3e27aab55a.jpg)
По центру расположен чип, в котором обьединены микропроцессор RISC архитектуры SuperH SH STx7105 и процессорное ядро архитектуры VLIW ST231. На базе ST231 реализован декодер видео H.264. Такая специфика по всей видимости и позволяет устройству работать с большим обьёмом видеоданных без перегрева.
Контактные площадки, которые расположены слева — это интерфейсы UART и EJTAG. Как видите, расположены они обособленно, так что подпаяться к ним можно не испортив другие компоненты. Обратим внимание на UART
Интерфейс UART
Оба крайних вывода — GND, средний вывод — питание 3В. Вывод ближе к задней стенке — TX. Интерфейс работает с уровнями TTL — 3В. Для подключения требуется преобразователь TTL/RS232 (или TTL/USB). О выводах RX мне известно лишь то, что он работает не у всех моделей.
Но нам и этого будет достаточно. Информация о ходе процесса перепрошивки выводится в последовательный интерфейс (UART). Параметры передачи: 115 200 бод 8N1 Информацию о любом сбое можно получить исключительно оттуда. Через видеовыход выводится лишь общее сообщение о неудавшейся загрузке ПО.
Настройки

Приставка обладает большим количеством настроек, доступных в меню. В подменю TV доступны настройки видеорежима PAL/NTSC.
Подменю сетевых настроек IP и дополнительных настроек Advanced открываются путём набора на пульте управления последовательности цифр 2357 и 7532 соответственно. В подменю IP настраивается метод получения адреса STATIC/DHCP и стандартные адреса шлюза, подсети, маска, а также разрешается или запрещается загрузка при неудачном получении сетевого адреса. В подменю Advanced настраивается порядок загрузки, адрес загрузки, адрес NFS сервера.
Приставка поддерживает несколько способов загрузки: Multicast, TFTP, HTTP и LS. Загрузка с NFS сервера не поддерживается, настройка предназначена для некоторых типов прошивок, которые используют NFS сервер вместо памяти устройства. Порядок загрузки задаётся настройками Kernel protocol и Splash protocol. Настройка Kernel protocol касается загрузки образа ядра, настройка Splash protocol — экранной заставки. Если в порядке загрузки указать 2 — приставка будет пытаться загрузить образ с TFTP сервера. Если в порядке загрузки указать 6 — приставка будет пытаться загрузить образ с HTTP сервера. Очень много настроек, касающихся загрузки с TFTP сервера. Приставка поддерживает загрузку с пула TFTP серверов 4 (четырёх) нод. Задаётся количество попыток загрузки с одной ноды и количество попыток подключения к пулу, таймаут а также размер блока. Адрес ноды может анонсироваться DHCP сервером и необходимость в указании адреса отпадает. Задать можно имена загружаемых файлов. Если адрес загружаемого файла анонсирует DHCP сервер и в настройках указан метод получения адреса от DHCP сервера, имя файла, указанное в настройках, не будет иметь силы.
Выполненные настройки не сохраняются автоматически. Я намеренно не описал ещё одно подменю. Ниже поймёте почему.
Программное обеспечение.
Желательно заранее загрузить и верифицировать программное обеспечение, необходимое для прошивки и программирования устройства.
Ниже приведен список программного обеспечения для загрузки.
kreatv‑kernel‑SMARTLABS.bin — загрузочное ядро.
rt firmvare ver. 5.24246.191016 (legacy) — прошивка (первичная) от Rostelecom.
PHP‑MOTO1003VIP — прошивка с php сервером и telnet. Перед прошивкой на приставке в ОБЯЗАТЕЛЬНОМ порядке должна стоять версия LEGACY 5.24246.191016 (ТОЛЬКО ОНА И НИКАКАЯ ИНАЧЕ).
toolchain_st40_2.5.0.tar.bz2 — утилиты для сборки собственных приложений
FFmpeg - популярный кроссплатформенный проект.
После загрузки проверьте хэши прошивок sha265. Эти прошивки проверить очень важно.
SHA265: 5fae869425b054a34975dd1f62ba99cc40f7e69c98af504301a5f15af7939f6c kreatv‑kernel‑SMARTLABS.bin
SHA265: b5976a0a6a4d023ab9318ff274fa5dec369b2a47014cad682bfe79249f777e8a firmware_vip19×3_5.24246.191016.bin
Опишем каждый компонент подробнее.
Ядро kreatv‑kernel‑SMARTLABS.bin загружается с FTP сервера. При последуюих запусках ядро ищет файл firmware.bin на флеш‑карте или на сетевом ресурсе. Дальнейшей загрузки не происходит. Если прошивка найдена, ядро начинает её запись в память. Если быть точным, то ядро запускает файл, чем бы он ни был. Ядро может запустить подписанный скрипт, и уже этот скрипт записывает прошивку. Содержимое скрипта не проверяется. Технически можно скопировать легитимный скрипт в корень флешки под именем firmware.bin и видоизменить его содержимое под произвольные нужды. Например, для удобства, запуск другого скрипта. Помимо подписи, скрипт должен содержать код для поиска и монтирования флешки Загрузочное ядро содержит утилиту wget, таким образом возможна даже загрузка скрипта из сети. Это можно использовать например для получения информации от утилит dmesg, uname, ps
Прошивка rt firmvare ver. 5.24246.191016 (legacy) содержит SSH сервер, однако доступ невозможно получить так как применяются ассиметричные ключи RSA. Состоит из одного файла firmware.bin. После перепрошивки файл переименуется в firmware_done.bin
Прошивка PHP‑MOTO1003VIP содержит PHP сервер и TELNET. PHP сервер предоставляет веб‑интерфейс, доступ к которому возможен по URL http://[IP]/index.php. Веб интерфейс предоставляет возможность загрузки плейлиста пункты которого затем станут доступны в приложении для их выбора с пульта. Приложение загружается и работает автономно, воспроизведение контента возможно из локальной сети. Логин: root/12341234. Сообщения, которые выводятся в UART, дублируются в файле /var/log/messages.
Состоит прошивка из четырёх файлов
branding.bin (CRC32: 0D A7 4F FB) — фирменное приложение
firmware.bin (CRC32: D8 12 47 D9) — подписанный скрипт
rootfs.bin (CRC32: 7B 74 4E 7F) — загружаемый образ системы
splashimage.bmp (CRC32: AB 3D C3 93) — экранная заставка
Toolchain для сборки приложений располагается внутри архива SDK: kreatv‑kit‑oss_4.2_st40.tgz, который можно загрузить из Интернета. Вы можете выбрать версию SDK для загрузки. Компилятор, входящий в toolchain, поддерживает компиляцию исходного кода на языке C в устаревшем стандарте — c99 Есть стандартная библиотека языка C, реализующая поддержку большинства функций, например printf. Целевая архитектура для компилятора — Renesas / SuperH SH Приложение, собранное для целевой машины, использует динамический линковщик ld‑uClibc.so.0. Все необходимые для запуска приложений библиотеки содержатся в sdk. Разработчик — STMicroelectronics. Версия GCC — 4.6.3 20120313. Версия GNU LD — 2.22.
FFmpeg [5] поддерживает кросс компиляцию.
Коммит id:52c7366c83aba4dc92ceedecbee592d629c98e29 совместим с устаревшим стандартом языка C - с99.
Вот что пишет git про данный коммит.
Author: Martin Storsjö <martin@martin.st> Date: Thu Dec 1 11:10:19 2016 +0200 aarch64: vp9itxfm: Restructure the idct32 store macros This avoids concatenation, which can't be used if the whole macro is wrapped within another macro. This is also arguably more readable. This is cherrypicked from libav commit 58d87e0f49bcbbc6f426328f53b657bae7430cd2. Signed-off-by: Martin Storsjö <martin@martin.st>
Подготовка к прошивке
-
Поднимаем DHCP (isc‑dhcp‑server) и TFTP (tftpd‑hpa)
В настройках DHCP (/etc/dhcp/dhcpd.conf) указываем файл kreatv‑kernel‑SMARTLABS.bin
В каталог /srv/tftp копируем kreatv‑kernel‑SMARTLABS.bin
-
Подготавливаем флеш карту
Флеш карту форматируем в ext3
В корень копируем прошивку rt firmvare ver. 5.24246.191016 под именем firmware.bin
Добавляем в корень файл firmware.bin.config с содержимым force=1
В корне создаём каталог PHP‑MOTO1003VIP и копируем туда все четыре файла прошивки
-
Настраиваем приставку.
Включаем приставку и после включения жмём MENU на пульте
Метод получения сетевого адреса адреса устанавливаем в DHCP
Запрещаем загрузку без получения сетевого адреса
Kernel protocol устанавливаем в 323.
Убеждаемся что Ignore VCI установлен в NO
Стираем старое ПО System → Remove Software.
Сохраняем настройки и отключаем приставку
ВНИМАНИЕ! Прежде чем выполнять пункт 3.6, прочитайте все описания и выполните все рекомендации выше. Лучше отключить приставку и вернуться к настройке позже, когда всё будет подготовлено. Эта функция не скрыта по умолчанию и сделать из устройства нерабочий кирпич очень легко.
Процесс прошивки
В процессе прошивки желательно исключить риск пропадания питания. Также заранее подключаем UART, поднимаем Ethernet соединение и подключаем флеш‑карту, поскольку процесс происходит быстрее, чем вы захотите мяукнуть.
Всё подготовлено? Включаем приставку в сеть. Всё внимание на терминал.
System memory: 256 MB Using Slot 1 Unpacking Image ...Done
Первые «шаги»
TFTP: Server node attempt 2 of 2 Connecting to 192.168.1.100 Sending read request for kreatv-kernel-SMARTLABS.bin
Если сервер действительно работает и указанный файл присутствует, загрузка начинается просто. В терминал выводятся указанный в настройках размер блока, полученный размер файла и таймаут.
Negotiation block size = 512 Negotiation transfer size = 3376610 Negotiation data timeout = 5 seconds Download completed Verifying image...
Последние шаги
Image in Local Storage is not up-to-date Storing kernel image in Local Storage
Это значит, что ядро загрузилось и больше не будет дёргаться с TFTP сервера
Kernel loaded successfully Starting new kernel kexec information
Это значит что ядро запустилось. Ловим строчку
KreaTV bootimage is ... Changed, disabling boot until upgrade
Дальнейшая загрузка производиться не будет до тех пор, пока устройство не найдёт прошивку
MASSSTORAGE_DEVICES = /dev/sda kjournald starting. Commit interval 5 seconds EXT3 FS on sda, internal journal EXT3-fs: mounted filesystem with ordered data mode. Successfully mounted /dev/sda to /tmp/sda
Это значит, что флешка примонтировалась.
Upgrade sources: --url="http://upgrade.riskymeije.ru/vip1963x" --url="file:///tmp/sda/firmware.bin"
Это источники, где приставка будет искать прошивку. Если флешка отсутствует, приставка попытается найти прошивку ещё раз.
Splash message: Successfully flashed new firmware. Rebooting ...
Сообщение после прошивки образа rt firmvare ver. 5.24246.191016 (legacy)
Restarting system. Watchdog reset!
Приставка перезагрузится. При следующих перезагрузках приставка будет распаковывать образ из локальной памяти.
Loading kernel image Using Local Storage LS: Image found Will not search for new images on the network Using kernel image in flash Copying 3392028 bytes... Verifying image... Uncompressing image...
Прошивка также подтягивается из локальной памяти
Actual bootimage hash - 3edd21ecd89032b18b51c8472d7c8603 Expected bootimage hash - 3edd21ecd89032b18b51c8472d7c8603 KreaTV bootimage is ... Unchanged.
Выключаем приставку и подготавливаем прошивку PHP‑MOTO1003VIP. Если вы всё сделали так, как написано, достаточно её скопировать из каталога в корень флешки.
Прошиваем с флешки и ожидаем подключения через TELNET
Подготовка прошивки к записи на флеш память
Upgrade sources: --url="http://upgrade.riskymeije.ru/vip1963x" --url="file:///tmp/sda/firmware.bin" download/download.c(2580) [ 0 s]: Command line arguments values: download/download.c(2582) [ 0 s]: - vendor: Motorola download/download.c(2584) [ 0 s]: - device: vip19x3 download/download.c(2586) [ 0 s]: - hw revision: 0 download/download.c(2588) [ 0 s]: - version: 7.41484.230401 download/download.c(2597) [ 0 s]: - localization file: /etc/branding/messages.l10n download/download.c(2600) [ 0 s]: - certificates dir: /etc/branding/certificates download/download.c(2602) [ 0 s]: - timeout per retry: 5 download/download.c(2604) [ 0 s]: - max retries: 2 download/source_http.c(0505) [ 0 s]: Not a direct firmware URL http://upgrade.riskymeije.ru/vip1963x download/source_http.c(0173) [ 0 s]: Downloading http://upgrade.riskymeije.ru/vip1963x/check_version_ext?output=text&board=vip19x3&mac=00%3A02%3A9B%3AA9%3A99%3AA5&serial=M91443EG0205¤t_firmware_version=7%2E41484%2E230401 ... download/source_file.c(0040) [ 0 s]: Config file "/tmp/sda/firmware.bin.config" found download/source_http.c(0324) [ 0 s]: Unexpected wget exit code: 256 download/source_http.c(0173) [ 0 s]: Downloading http://upgrade.riskymeije.ru/vip1963x/check_version?output=text&board=vip19x3&mac=00%3A02%3A9B%3AA9%3A99%3AA5&serial=M91443EG0205¤t_firmware_version=7%2E41484%2E230401 ... download/source_http.c(0324) [ 0 s]: Unexpected wget exit code: 256 download/download.c(1296) [ 0 s]: Discarding unresolved http://upgrade.riskymeije.ru/vip1963x download/download.c(1438) [ 0 s]: Callback failed with code -1 download/download.c(2699) [ 0 s]: Firmware candidates: download/download.c(2709) [ 0 s]: - 5.24246.191016 (hw rev. 0) force : file:///tmp/sda/firmware.bin download/download.c(2743) [ 0 s]: Best URL: file:///tmp/sda/firmware.bin download/download.c(0526) [ 0 s]: -1% Please wait. Preparing to download firmware ... download/download.c(2033) [ 0 s]: Verifying firmware checksums and RSA signature ... download/verify.c(0087) [ 0 s]: Loading the CA root certificate ... download/verify.c(0106) [ 0 s]: Loading certificates from "/etc/branding/certificates" ... download/verify.c(0163) [ 0 s]: Loading cerificate from file "/etc/branding/certificates/rostelecom-generic-cert.pem" ... download/download.c(1721) [ 0 s]: Block 1 (signed) @ addr = 0x0x29558278 download/download.c(1722) [ 0 s]: data size : 0x0033c21c (3392028) byte(s) download/download.c(1723) [ 0 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 0 s]: type : 2 (Linux Kernel Image) download/download.c(1725) [ 0 s]: CRC32 : 0x4bcf4722 download/download.c(1728) [ 0 s]: signature[0] length : 256 download/download.c(1728) [ 0 s]: signature[1] length : 256 download/download.c(1735) [ 0 s]: SHA1 : e4644884a8fdde2df91aadf831c41d5c7ba34553 download/download.c(1738) [ 0 s]: content : unknown download/verify.c(0272) [ 1 s]: Signature check failed download/verify.c(0272) [ 1 s]: Signature check failed download/download.c(1721) [ 1 s]: Block 2 (signed) @ addr = 0x0x298946bc download/download.c(1722) [ 1 s]: data size : 0x02960000 (43384832) byte(s) download/download.c(1723) [ 1 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 1 s]: type : 3 (Root FS Image) download/download.c(1725) [ 1 s]: CRC32 : 0xd8b09ef7 download/download.c(1728) [ 1 s]: signature[0] length : 256 download/download.c(1728) [ 1 s]: signature[1] length : 256 download/download.c(1735) [ 1 s]: SHA1 : 9dd5db805dda709258f90c1402ba1e416048ce68 download/download.c(1738) [ 1 s]: content : JFFS2 download/verify.c(0272) [ 9 s]: Signature check failed download/verify.c(0272) [ 9 s]: Signature check failed download/download.c(1721) [ 9 s]: Block 3 (signed) @ addr = 0x0x2c1f48e4 download/download.c(1722) [ 9 s]: data size : 0x00005000 (20480) byte(s) download/download.c(1723) [ 9 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 9 s]: type : 5 (Branding Image) download/download.c(1725) [ 9 s]: CRC32 : 0x052d237b download/download.c(1728) [ 9 s]: signature[0] length : 256 download/download.c(1728) [ 9 s]: signature[1] length : 256 download/download.c(1735) [ 9 s]: SHA1 : 0b864ea8110807b5accac300254cf410faa801b6 download/download.c(1738) [ 9 s]: content : Cramfs download/verify.c(0272) [ 9 s]: Signature check failed download/verify.c(0272) [ 9 s]: Signature check failed download/download.c(0526) [ 9 s]: 75% Please wait. Flashing firmware ... download/download.c(1721) [ 9 s]: Block 1 (signed) @ addr = 0x0x29558278 download/download.c(1722) [ 9 s]: data size : 0x0033c21c (3392028) byte(s) download/download.c(1723) [ 9 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 9 s]: type : 2 (Linux Kernel Image) download/download.c(1725) [ 9 s]: CRC32 : 0x4bcf4722 download/download.c(1728) [ 9 s]: signature[0] length : 256 download/download.c(1728) [ 9 s]: signature[1] length : 256 download/download.c(1735) [ 9 s]: SHA1 : e4644884a8fdde2df91aadf831c41d5c7ba34553 download/download.c(1738) [ 9 s]: content : unknown File /flash2/.bootimage is successfully written. download/download.c(1721) [ 10 s]: Block 2 (signed) @ addr = 0x0x298946bc download/download.c(1722) [ 10 s]: data size : 0x02960000 (43384832) byte(s) download/download.c(1723) [ 10 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 10 s]: type : 3 (Root FS Image) download/download.c(1725) [ 10 s]: CRC32 : 0xd8b09ef7 download/download.c(1728) [ 10 s]: signature[0] length : 256 download/download.c(1728) [ 10 s]: signature[1] length : 256 download/download.c(1735) [ 10 s]: SHA1 : 9dd5db805dda709258f90c1402ba1e416048ce68 download/download.c(1738) [ 10 s]: content : JFFS2 download/download.c(2319) [ 10 s]: Preparing to flash block #2 ('rootfs') to '/dev/mtd6' ('rootfs') ... flash_eraseall(): entering...
В слитой в сеть документации ООО Смартлабс детально описывается структура прошивок для IP приставок
Устанавливаем подключение через TELNET и открываем файл tail -f /var/log/messages. В лог сообщений выводится куча полезной информации.
Поддерживаемые видеорежимы.
Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.135 34 1080p30 16:9 1920x1080p @ 29.97/30Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.136 33 1080p25 16:9 1920x1080p @ 25Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.138 32 1080p24 16:9 1920x1080p @ 23.98/24Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.139 18 576pH 16:9 720x576p @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.140 3 480pH 16:9 720x480p @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.141 20 1080i25 16:9 1920x1080i @ 50Hz* Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.143 5 1080i 16:9 1920x1080i @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.144 19 720p50 16:9 1280x720p @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.145 4 720p 16:9 1280x720p @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.146 31 1080p50 16:9 1920x1080p @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.147 1 DMT0659 4:3 640x480p @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.148 22 576iH 16:9 720(1440)x576i @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.150 21 576i 4:3 720(1440)x576i @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.151 17 576p 4:3 720x576p @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.152 7 480iH 16:9 720(1440)x480i @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.153 6 480i 4:3 720(1440)x480i @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.154 2 480p 4:3 720x480p @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.155 16 1080p 16:9 1920x1080p @ 59.94/60Hz
Поддерживаемые форматы контента.
Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.594 player/info : Supported video codecs: Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.596 player/info : - MPEG-2 video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.598 player/info : - H.264/14496-10 video (MPEG-4/AVC) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.599 player/info : - 14496-2 Visual (MPEG-4 part 2 video, DivX) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.601 player/info : - SMPTE 421M video (VC1) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.602 player/info : - FLV video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.603 player/info : - VP6 video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.604 player/info : - VP6F video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.606 player/info : - Motion JPEG video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.633 audio/info : Supported audio codecs: Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.635 audio/info : - ISO/IEC 13818-3 audio (MPEG-2) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.636 audio/info : - ISO/IEC 13818-7 audio with ADTS transport syntax (AAC) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.637 audio/info : - ISO/IEC 14496-3 audio with LATM transport syntax (14496-3/AMD 1) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.639 audio/info : - ATSC A/52 audio (AC3) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.640 audio/info : - ATSC A/52B audio (EAC3) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.641 audio/info : - PCM audio Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.643 audio/info : - LPCM audio Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.644 audio/info : - WMA Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.645 audio/info : - ISO/IEC 11172-3/13818-3 audio (MP3) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.646 audio/info : - FLAC audio Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.648 audio/info : - Vorbis audio Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.649 audio/info : - ISO/IEC 11172-3 audio (MPEG-1)
Прошивка завершена.
Воспроизведение контента
Плейлист со ссылкой на произвольный контент можно поместить по пути /mnt/persistent/server/play.m3u8 с содержимым вида
#EXTM3U8, #EXTINF:-1,Youtube http://127.0.0.1/youtube.m3u8
Далее плейлист необходимо добавить через веб интерфейс http://IP_адрес_приставки/player.php
Поддерживается воспроизведение по протоколам FTP, HTTP, UDP (Multicast), RTSP (без авторизации). TLS не поддерживается. Поддерживается стандарт сжатия H.264 и не поддерживается H.265.
Выключаем приставку, подключаем видеовыход и Интернет. Приставкой можно пользоваться.

С жителями страны, которые просто любят смотреть кастомный контент на телевизоре, мы прощаемся, для остальных технических гурманов мы продолжим.
И вот о чём расскажем далее...
Первая программа для IPTV приставки
Напишем исходный код и сохраним в файл main.c с надеждой, что выстрелит.
#include <stdio.h> #include <stdlib.h> int main(void) { printf("%s","Hello World\n"); }
«Ты меня учить будешь? Свободен. Нужно будет — позвоню.»
© К/ф «Бой с тенью»
Людей можно понять. Но для начала скомпилируем код. Для этого распакуем SDK и зададим переменные окружения. Предполагаем, что тулчейн находится в домашнем каталоге.
sh4gcc="~/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-gcc" sh4ld="~/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-ld" sh4readelf="~/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-readelf" sh4nm="~/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-nm" sh4strip="~/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-strip"
Подключим библиотеки
LDFLAGS=~/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/sys-root/usr/lib/crt1.o -L~/toolchain/st40/2.5.0/lib -L~/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/sys-root/lib -L~/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/sys-root/usr/lib -L~/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/lib -L. -L~/toolchain/st40/2.5.0/lib/gcc/sh4-motorola-linux-uclibc/4.6.3 -lc -lgcc -ldl -lm -lutil -lnsl -lcrypt -lresolv -luargp -lrt -lpthread -rpath . --dynamic-linker ld-uClibc.so.0
Теперь можно компилировать
sh4gcc -c main.c -o main.o sh4ld $LDFLAGS main.o -o main.bin
Рассмотрим обьектный файл
Главное. Таблица символов и текстовая секция
architecture: sh4, flags 0x00000011: HAS_RELOC, HAS_SYMS start address 0x00000000 Sections: Idx Name Size VMA LMA File off Algn 0 .text 00000038 00000000 00000000 00000034 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 1 .data 00000000 00000000 00000000 0000006c 2**0 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000000 00000000 00000000 0000006c 2**0 ALLOC 3 .rodata 00000034 00000000 00000000 0000006c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .debug_info 0000008c 00000000 00000000 000000a0 2**0 CONTENTS, RELOC, READONLY, DEBUGGING 5 .debug_abbrev 00000041 00000000 00000000 0000012c 2**0 CONTENTS, READONLY, DEBUGGING 6 .debug_loc 00000020 00000000 00000000 0000016d 2**0 CONTENTS, READONLY, DEBUGGING 7 .debug_aranges 00000020 00000000 00000000 0000018d 2**0 CONTENTS, RELOC, READONLY, DEBUGGING 8 .debug_line 00000074 00000000 00000000 000001ad 2**0 CONTENTS, RELOC, READONLY, DEBUGGING 9 .debug_str 00000115 00000000 00000000 00000221 2**0 CONTENTS, READONLY, DEBUGGING 10 .comment 0000002f 00000000 00000000 00000336 2**0 CONTENTS, READONLY 11 .note.GNU-stack 00000000 00000000 00000000 00000365 2**0 CONTENTS, READONLY 12 .debug_frame 00000028 00000000 00000000 00000368 2**2 CONTENTS, RELOC, READONLY, DEBUGGING objdump: /home/sandrabullok/motorola_developer/develop/tmp.aWAM.d/tmp.ZBbU.o: not a dynamic object SYMBOL TABLE: 00000000 l df *ABS* 00000000 tmp.ZBbU.c 00000000 l d .text 00000000 .text 00000000 l d .data 00000000 .data 00000000 l d .bss 00000000 .bss 00000000 l d .rodata 00000000 .rodata 00000000 l d .debug_info 00000000 .debug_info 00000000 l d .debug_abbrev 00000000 .debug_abbrev 00000000 l d .debug_loc 00000000 .debug_loc 00000000 l d .debug_aranges 00000000 .debug_aranges 00000000 l d .debug_line 00000000 .debug_line 00000000 l d .debug_str 00000000 .debug_str 00000000 l d .note.GNU-stack 00000000 .note.GNU-stack 00000000 l d .debug_frame 00000000 .debug_frame 00000000 l d .comment 00000000 .comment 00000000 g F .text 00000038 main 00000000 *UND* 00000000 printf 00000000 *UND* 00000000 puts DYNAMIC SYMBOL TABLE: no symbols Disassembly of section .text: 00000000 <main>: #include </home/sandrabullok/motorola_developer/develop/tmp.aWAM.d/tmp.ZBbU.h> int main(void) { 0: 22 4f sts.l pr,@-r15 printf("%s","This is a stub program for "); 2: 08 d2 mov.l 24 <main+0x24>,r2 ! 0 <main> 4: 08 d1 mov.l 28 <main+0x28>,r1 ! 4 6: 23 64 mov r2,r4 8: 13 65 mov r1,r5 a: 08 d1 mov.l 2c <main+0x2c>,r1 ! 0 <main> c: 0b 41 jsr @r1 e: 09 00 nop printf("%s","the target machine\n"); 10: 07 d1 mov.l 30 <main+0x30>,r1 ! 20 12: 13 64 mov r1,r4 14: 07 d1 mov.l 34 <main+0x34>,r1 ! 0 <main> 16: 0b 41 jsr @r1 18: 09 00 nop 1a: 00 e1 mov #0,r1 } 1c: 13 60 mov r1,r0 1e: 26 4f lds.l @r15+,pr 20: 0b 00 rts 22: 09 00 nop 24: 00 00 .word 0x0000 24: R_SH_DIR32 .rodata 26: 00 00 .word 0x0000 28: 04 00 mov.b r0,@(r0,r0) 28: R_SH_DIR32 .rodata 2a: 00 00 .word 0x0000 2c: 00 00 .word 0x0000 2c: R_SH_DIR32 printf 2e: 00 00 .word 0x0000 30: 20 00 .word 0x0020 30: R_SH_DIR32 .rodata 32: 00 00 .word 0x0000 34: 00 00 .word 0x0000 34: R_SH_DIR32 puts ...
Код на языке Ассемблера
00000000 <main>: #include </home/sandrabullok/motorola_developer/develop/tmp.aWAM.d/tmp.ZBbU.h> int main(void) { 0: 22 4f sts.l pr,@-r15 printf("%s","This is a stub program for "); 2: 08 d2 mov.l 24 <main+0x24>,r2 ! 0 <main> 4: 08 d1 mov.l 28 <main+0x28>,r1 ! 4 6: 23 64 mov r2,r4 8: 13 65 mov r1,r5 a: 08 d1 mov.l 2c <main+0x2c>,r1 ! 0 <main> c: 0b 41 jsr @r1 e: 09 00 nop printf("%s","the target machine\n"); 10: 07 d1 mov.l 30 <main+0x30>,r1 ! 20 12: 13 64 mov r1,r4 14: 07 d1 mov.l 34 <main+0x34>,r1 ! 0 <main> 16: 0b 41 jsr @r1 18: 09 00 nop 1a: 00 e1 mov #0,r1 } 1c: 13 60 mov r1,r0 1e: 26 4f lds.l @r15+,pr 20: 0b 00 rts 22: 09 00 nop
Как можно увидеть, система команд, применяемая в коде, совершенно специфическая. Это система команд микропроцессора STx7105. Ссылка на документацию [4] к сожалению умерла.
Всего регистров - 16. Обозначаются как rN - где N - номер регистра от 0 до 15. Команда перемещения между регистрами такая же, как в системе команд процессоров Intel - mov. Команды копирования по адресу в памяти слева в регистр справа: mov.l - копирование двойных слов, mov.w - копирование слов, mov.b - копирование байт. Команды sts и lds с аналогичными суффиксами - сохранение и загрузка содержимого регистров.
Переход к подпрограмме - jsr. Возврат из подпрограммы - rts. Передача операндов через регистры.
Рассмотрим исполняемый файл
Код
Disassembly of section .plt: 004002f0 <printf@plt-0x1c>: 4002f0: 05 d0 mov.l 400308 <printf@plt-0x4>,r0 ! 410544 4002f2: 02 60 mov.l @r0,r0 4002f4: 06 2f mov.l r0,@-r15 4002f6: 03 d0 mov.l 400304 <printf@plt-0x8>,r0 ! 410548 4002f8: 02 60 mov.l @r0,r0 4002fa: 2b 40 jmp @r0 4002fc: f6 60 mov.l @r15+,r0 4002fe: 09 00 nop 400300: 09 00 nop 400302: 09 00 nop 400304: 48 05 .word 0x0548 400306: 41 00 .word 0x0041 400308: 44 05 mov.b r4,@(r0,r5) 40030a: 41 00 .word 0x0041 0040030c <printf@plt>: 40030c: 04 d0 mov.l 400320 <printf@plt+0x14>,r0 ! 41054c 40030e: 02 60 mov.l @r0,r0 400310: 02 d1 mov.l 40031c <printf@plt+0x10>,r1 ! 4002f0 400312: 2b 40 jmp @r0 400314: 13 60 mov r1,r0 400316: 03 d1 mov.l 400324 <printf@plt+0x18>,r1 ! 0 400318: 2b 40 jmp @r0 40031a: 09 00 nop 40031c: f0 02 .word 0x02f0 40031e: 40 00 .word 0x0040 400320: 4c 05 mov.b @(r0,r4),r5 400322: 41 00 .word 0x0041 400324: 00 00 .word 0x0000 ... 00400328 <puts@plt>: 400328: 04 d0 mov.l 40033c <puts@plt+0x14>,r0 ! 410550 40032a: 02 60 mov.l @r0,r0 40032c: 02 d1 mov.l 400338 <puts@plt+0x10>,r1 ! 4002f0 40032e: 2b 40 jmp @r0 400330: 13 60 mov r1,r0 400332: 03 d1 mov.l 400340 <puts@plt+0x18>,r1 ! c 400334: 2b 40 jmp @r0 400336: 09 00 nop 400338: f0 02 .word 0x02f0 40033a: 40 00 .word 0x0040 40033c: 50 05 .word 0x0550 40033e: 41 00 .word 0x0041 400340: 0c 00 mov.b @(r0,r0),r0 ... 00400344 <abort@plt>: 400344: 04 d0 mov.l 400358 <abort@plt+0x14>,r0 ! 410554 400346: 02 60 mov.l @r0,r0 400348: 02 d1 mov.l 400354 <abort@plt+0x10>,r1 ! 4002f0 40034a: 2b 40 jmp @r0 40034c: 13 60 mov r1,r0 40034e: 03 d1 mov.l 40035c <abort@plt+0x18>,r1 ! 18 400350: 2b 40 jmp @r0 400352: 09 00 nop 400354: f0 02 .word 0x02f0 400356: 40 00 .word 0x0040 400358: 54 05 mov.b r5,@(r0,r5) 40035a: 41 00 .word 0x0041 40035c: 18 00 sett ... 00400360 <_init@plt>: 400360: 04 d0 mov.l 400374 <_init@plt+0x14>,r0 ! 410558 400362: 02 60 mov.l @r0,r0 400364: 02 d1 mov.l 400370 <_init@plt+0x10>,r1 ! 4002f0 400366: 2b 40 jmp @r0 400368: 13 60 mov r1,r0 40036a: 03 d1 mov.l 400378 <_init@plt+0x18>,r1 ! 24 40036c: 2b 40 jmp @r0 40036e: 09 00 nop 400370: f0 02 .word 0x02f0 400372: 40 00 .word 0x0040 400374: 58 05 .word 0x0558 400376: 41 00 .word 0x0041 400378: 24 00 mov.b r2,@(r0,r0) ... 0040037c <__uClibc_main@plt>: 40037c: 04 d0 mov.l 400390 <__uClibc_main@plt+0x14>,r0 ! 41055c 40037e: 02 60 mov.l @r0,r0 400380: 02 d1 mov.l 40038c <__uClibc_main@plt+0x10>,r1 ! 4002f0 400382: 2b 40 jmp @r0 400384: 13 60 mov r1,r0 400386: 03 d1 mov.l 400394 <__uClibc_main@plt+0x18>,r1 ! 30 400388: 2b 40 jmp @r0 40038a: 09 00 nop 40038c: f0 02 .word 0x02f0 40038e: 40 00 .word 0x0040 400390: 5c 05 mov.b @(r0,r5),r5 400392: 41 00 .word 0x0041 400394: 30 00 .word 0x0030 ... 00400398 <_fini@plt>: 400398: 04 d0 mov.l 4003ac <_fini@plt+0x14>,r0 ! 410560 40039a: 02 60 mov.l @r0,r0 40039c: 02 d1 mov.l 4003a8 <_fini@plt+0x10>,r1 ! 4002f0 40039e: 2b 40 jmp @r0 4003a0: 13 60 mov r1,r0 4003a2: 03 d1 mov.l 4003b0 <_fini@plt+0x18>,r1 ! 3c 4003a4: 2b 40 jmp @r0 4003a6: 09 00 nop 4003a8: f0 02 .word 0x02f0 4003aa: 40 00 .word 0x0040 4003ac: 60 05 .word 0x0560 4003ae: 41 00 .word 0x0041 4003b0: 3c 00 mov.b @(r0,r3),r0 ... Disassembly of section .text: 004003b4 <_start>: 4003b4: 00 ee mov #0,r14 4003b6: f6 65 mov.l @r15+,r5 4003b8: f3 66 mov r15,r6 4003ba: 66 2f mov.l r6,@-r15 4003bc: 46 2f mov.l r4,@-r15 4003be: 07 d0 mov.l 4003dc <L_fini>,r0 ! 400398 <_fini@plt> 4003c0: 06 2f mov.l r0,@-r15 4003c2: 04 d4 mov.l 4003d4 <L_main>,r4 ! 4003e8 <main> 4003c4: 04 d7 mov.l 4003d8 <L_init>,r7 ! 400360 <_init@plt> 4003c6: 06 d1 mov.l 4003e0 <L_uClibc_main>,r1 ! 40037c <__uClibc_main@plt> 4003c8: 0b 41 jsr @r1 4003ca: 09 00 nop 4003cc: 05 d1 mov.l 4003e4 <L_abort>,r1 ! 400344 <abort@plt> 4003ce: 2b 41 jmp @r1 4003d0: 09 00 nop 4003d2: 09 00 nop 004003d4 <L_main>: 4003d4: e8 03 .word 0x03e8 4003d6: 40 00 .word 0x0040 004003d8 <L_init>: 4003d8: 60 03 .word 0x0360 4003da: 40 00 .word 0x0040 004003dc <L_fini>: 4003dc: 98 03 .word 0x0398 4003de: 40 00 .word 0x0040 004003e0 <L_uClibc_main>: 4003e0: 7c 03 mov.b @(r0,r7),r3 4003e2: 40 00 .word 0x0040 004003e4 <L_abort>: 4003e4: 44 03 mov.b r4,@(r0,r3) 4003e6: 40 00 .word 0x0040
Символы подпрограмм fini@plt, init@plt экспортируются в подключаемом обьектном файле crt1.o. Подпрограмма _start является точкой входа в программу и помимо вызова main выполняет кучу других вещей.
Полученный исполняемый файл не получится запустить, он предназначается для другой архитектуры. В чём мы сейчас убедимся.
sh-5.1$ $sh4readelf -h main.bin ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Renesas / SuperH SH Version: 0x1 Entry point address: 0x4003b4 Start of program headers: 52 (bytes into file) Start of section headers: 1536 (bytes into file) Flags: 0x9, sh4 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 6 Size of section headers: 40 (bytes) Number of section headers: 16 Section header string table index: 13
Копируем исполняемый файл в единый каталог вместе с библиотеками
итого 4236 -rwxrwxr-x 1 sandrabullok sandrabullok 4038 июл 22 13:07 app.bin -r-xr-xr-x 1 sandrabullok sandrabullok 96925 июл 22 13:07 ld-uClibc.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 28676 июл 22 13:07 libcrypt.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 3200747 июл 22 13:07 libc.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 32815 июл 22 13:07 libdl.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 160246 июл 22 13:07 libm.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 6219 июл 22 13:07 libnsl.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 567364 июл 22 13:07 libpthread.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 6234 июл 22 13:07 libresolv.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 96503 июл 22 13:07 librt.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 96053 июл 22 13:07 libuargp.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 14626 июл 22 13:07 libutil.so.0
Особенно заостряю ваше внимание на библиотеке ld‑uClibc.so.0. Динамический компоновщик редактирует связи с динамическими библиотеками непосредственно в памяти устройства. Сделано так, возможно, для экономии оперативной памяти: оверлей программы подгружается, когда он необходим, в произвольном порядке и на лету редактируется. Если данную библиотеку не подключить, программа будет вылетать в SEGFAULT, потому что при запуске программа делает первый шаг и делает его в пропасть — в таблицах адресов ничего нет.
Далее начинается то, ради чего полстатьи маялись. Упакуйте в TAR архив и разместите на HTTP сервере. Устанавливаем подключение к приставке через TELNET и скачиваем архив командой wget. Например
wget http://192.168.1.100/$APP_NAME.tar tar -xf $APP_NAME.tar rm $APP_NAME.tar ls - la
Запускаем программу и видим текст
Hello World
Эта программа работает на целевой машине (IPTV приставке MOTOROLA VIP1003)!
А это значит, что технически возможно портировать крупный проект.
Портирование FFmpeg на архитектуру SuperH SH
Есть проблема. Приставка не может воспроизвести контент с источника RTSP потока, требующего basic аутентификацию.
Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: OPTIONS rtsp://login:pass@[IP]/path RTSP/1.0 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: User-Agent: Restream/7.999.9999 (vip19x3; Motorola_VIP1003) SmartSDK/1.5.63-rt-38-22-g950636f Qt/4.7.3 API/0.30.0 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: CSeq: 1 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.818 rtsp/info : Response Header: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: RTSP/1.0 200 OK Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: CSeq: 1 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: Public: OPTIONS, DESCRIBE, PLAY, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.823 rtsp/debug : Outgoing RTSP command: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: DESCRIBE rtsp://login:pass@[IP]/path RTSP/1.0 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: Accept: application/x-rtsp-mh, application/sdp Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: User-Agent: Restream/7.999.9999 (vip19x3; Motorola_VIP1003) SmartSDK/1.5.63-rt-38-22-g950636f Qt/4.7.3 API/0.30.0 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: CSeq: 2 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.833 rtsp/info : Response Header: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: RTSP/1.0 401 Unauthorized Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: CSeq: 2 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: WWW-Authenticate: Digest realm="RTSP SERVER", nonce="1b5eff39c311f943304b9c10bc8efba7", stale="FALSE" Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: WWW-Authenticate: Basic realm="RTSP SERVER" Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: Date: Fri, 03 Jul 2026 18:23:12 GMT Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.836 rtsp/error : invalid response status code 401 from RTSP server. Aborting ... Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.838 rtsp/error : RTSP protocol failure !!!
А можно ли добавить в приставку поддержку какого‑нибудь недостающего сетевого протокола, например. Теперь есть полные основания портировать для IPTV приставки серьёзный проект. И таким проектом будет FFmpeg.
Подразумеваем, что исходники подготовлены, далее выполняем сборку проекта. Сборка пока что происходит для компьютера.
Как уже было замечено, коммит древний — 2016 года и поддерживает устаревший стандарт языка C — c99. Новые коммиты будут падать с ошибками компиляции.
Свободной памяти в устройстве немного, так что придётся поторговаться. Отключаем по умолчанию все кодеры, миксеры, поддержку устройств и сетевых протоколов. И выбираем только то что нужно.
# Individual component option INDIVIDUAL_OPTIONS="" INDIVIDUAL_OPTIONS+="--disable-encoders " INDIVIDUAL_OPTIONS+="--disable-decoders " INDIVIDUAL_OPTIONS+="--disable-muxers " INDIVIDUAL_OPTIONS+="--disable-demuxers " INDIVIDUAL_OPTIONS+="--disable-protocols " INDIVIDUAL_OPTIONS+="--disable-devices " INDIVIDUAL_OPTIONS+="--enable-protocol=rtp " INDIVIDUAL_OPTIONS+="--enable-protocol=udp " INDIVIDUAL_OPTIONS+="--enable-muxer=mpegts " INDIVIDUAL_OPTIONS+="--enable-demuxer=rtsp "
В расширении флагов компоновки указываем библиотеки с поддержкой целевой архитектуры.
EXTRA_LDFLAGS="-L." EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/sys-root/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/sys-root/usr/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/lib/gcc/sh4-motorola-linux-uclibc/4.6.3 " EXTRA_LDFLAGS+="-lc -lgcc -ldl -lm -lutil -lnsl -lcrypt -lresolv -luargp " EXTRA_LDFLAGS+="-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample "
Давайте посмотрим сюда.
EXTRA_CXXFLAGS+="-std=c99 " # Assume that the input sources are for <standard> EXTRA_CXXFLAGS+="-m4 " # Generate SH4 code EXTRA_CXXFLAGS+="-mglibc " # Use GNU C library EXTRA_CXXFLAGS+="-pthread "
Флаги -std=c99 и -m4 предписывают системе сборки компилировать код для целевой архитектуры и использовать совместимый стандарт языка C. Чем библиотека glibc лучше или хуже чем libc не понимаю.
Компилироваться будет только ffmpeg
Следующий флажок включает кросс-компиляцию. Также необходимо прописать путь к тулчейну для целевой архитектуры.
--enable-cross-compile
Полный код скрипта настройки сборки.
#!/bin/bash # Head # ARCH=sh CPU=STx7105 TARGET_OS=linux TOOLCHAIN_PATH=~/ffmpeg/toolchain/st40/2.5.0 # $TOOLCHAIN_PATH CROSS_PREFIX="${TOOLCHAIN_PATH}/bin/sh4-motorola-linux-uclibc-" CROSS_PREFIX_ENABLED=0 ENABLE_CROSS_COMPILE=1 PROGS_SUFFIX='' DIST=~/ffmpeg/dist ######## if [ $ENABLE_CROSS_COMPILE -ne 0 ] then LOG=configure_cross.log else LOG=configure_nocross.log fi if [ $CROSS_PREFIX_ENABLED -eq 0 ] then ### set use tools from toolchain ### NM=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-nm #use nm tool NM [nm -g] AR=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-ar #use archive tool AR [ar] AS=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-as #use assembler AS [] #LN_S STRIP=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-strip #use strip tool STRIP [strip] CC=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-gcc #use C compiler CC [gcc] STDC=c99 #use C standard STDC [c17] CXX=$TOOLCHAIN_PATH/bin/sh4-motorola-uclibc-g++ #use C compiler CXX [g++] STDCXX=c++17 #use C standard STDCXX [c++17] LD=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-ld #use linker LD [] RANLIB=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-ranlib #use ranlib RANLIB [ranlib] SIZE=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-size ### set use tools from toolchain ### fi #PATH=$PATH:${TOOLCHAIN_PATH}/bin:${DIST}/bin BSG_SRC=../../.. BSG_INCLUDE=${DIST}/st40/include # Standard options STANDARD_OPTIONS="" #STANDARD_OPTIONS+="--quiet " STANDARD_OPTIONS+="--logfile=$LOG " # Program options PROGRAM_OPTIONS="" # Documentation options: DOCUMENTATION_OPTIONS="" DOCUMENTATION_OPTIONS+="--disable-doc " # do not build documentation DOCUMENTATION_OPTIONS+="--disable-htmlpages " # do not build HTML documentation pages DOCUMENTATION_OPTIONS+="--disable-manpages " # do not build man documentation pages DOCUMENTATION_OPTIONS+="--disable-podpages " # do not build POD documentation pages DOCUMENTATION_OPTIONS+="--disable-txtpages " # do not build text documentation pages # Component options COMPONENT_OPTIONS="" COMPONENT_OPTIONS+="--disable-swscale " COMPONENT_OPTIONS+="--disable-avresample " COMPONENT_OPTIONS+="--disable-avdevice " COMPONENT_OPTIONS+="--disable-avfilter " # Individual component option INDIVIDUAL_OPTIONS="" INDIVIDUAL_OPTIONS+="--disable-encoders " INDIVIDUAL_OPTIONS+="--disable-decoders " INDIVIDUAL_OPTIONS+="--disable-muxers " INDIVIDUAL_OPTIONS+="--disable-demuxers " INDIVIDUAL_OPTIONS+="--disable-protocols " INDIVIDUAL_OPTIONS+="--disable-devices " INDIVIDUAL_OPTIONS+="--enable-protocol=rtp " INDIVIDUAL_OPTIONS+="--enable-protocol=udp " INDIVIDUAL_OPTIONS+="--enable-muxer=mpegts " INDIVIDUAL_OPTIONS+="--enable-demuxer=rtsp " # External library support ELIBRARY_SUPPORT="" ELIBRARY_SUPPORT+="--disable-sdl2 " # disable sdl2 [autodetect] # Toolchain options TOOLCHAIN_OPTIONS="" if [ $ENABLE_CROSS_COMPILE -ne 0 ] then echo 'Set flag ENABLE_CROSS_COMPILE' TOOLCHAIN_OPTIONS+="--enable-cross-compile " #assume a cross-compiler is used fi TOOLCHAIN_OPTIONS+="--arch=$ARCH " # select architecture [] TOOLCHAIN_OPTIONS+="--cpu=$CPU " # select the minimum required CPU (affects # instruction selection, may crash on older CPUs) if [ ! $CROSS_PREFIX_ENABLED -eq 0 ] then echo 'Set flag CROSS_PREFIX_ENABLED' TOOLCHAIN_OPTIONS+="--cross-prefix=$CROSS_PREFIX " # use PREFIX for compilation tools [] fi TOOLCHAIN_OPTIONS+="--build-suffix=$PROGS_SUFFIX " # program name suffix [] TOOLCHAIN_OPTIONS+="--target-os=$TARGET_OS " #compiler targets OS [] #TOOLCHAIN_OPTIONS+="--sysroot=$SYSROOT " #root of cross-build tree #TOOLCHAIN_OPTIONS+="--sysinclude=$SYSINCLUDE " #location of cross-build system headers #TOOLCHAIN_OPTIONS+="--target-exec=$TARGET_EXEC " #command to run executables on target #TOOLCHAIN_OPTIONS+="--target-path=$TARGET_PATH " #path to view of build directory on target #TOOLCHAIN_OPTIONS+="--target-samples=$TARGET_SAMPLES " #path to samples directory on target #TOOLCHAIN_OPTIONS+="--tempprefix=$TEMPPREFIX " #force fixed dir/prefix instead of mktemp for checks #TOOLCHAIN_OPTIONS+="--toolchain=$TOOLCHAIN " #set tool defaults according to NAME #(<tool>[-sanitizer[-...]], e.g. clang-asan-ubsan #tools: gcc, clang, llvm, msvc, icl, gcov, llvm-cov, # valgrind-memcheck, valgrind-massif, hardened #sanitizers: asan, fuzz, lsan, msan, tsan, ubsan) if [ $CROSS_PREFIX_ENABLED -eq 0 ] then TOOLCHAIN_OPTIONS+="--nm=$NM --ar=$AR --as=$AS --cc=$CC --ld=$LD " #TOOLCHAIN_OPTIONS+="--ln_s=$LN_S " #use symbolic link tool LN_S [ln -s -f] #TOOLCHAIN_OPTIONS+="--windres=$WINDRES " #use windows resource compiler WINDRES [windres] #TOOLCHAIN_OPTIONS+="--x86asmexe=$X86ASMEXE " #use nasm-compatible assembler EXE [nasm] #TOOLCHAIN_OPTIONS+="--objcc=$OBJCC " #use ObjC compiler OCC [gcc] #TOOLCHAIN_OPTIONS+="--dep-cc=$DEPCC " #use dependency generator DEPCC [gcc] #TOOLCHAIN_OPTIONS+="--glslc=$GLSLC " #use GLSL compiler GLSLC [glslc] #TOOLCHAIN_OPTIONS+="--nvcc=$NVCC " #use Nvidia CUDA compiler NVCC or clang [] #TOOLCHAIN_OPTIONS+="--metalcc=$METALCC " #use metal compiler METALCC [xcrun -sdk macosx metal] #TOOLCHAIN_OPTIONS+="--metallib=$METALLIB " #use metal linker METALLIB [xcrun -sdk macosx metallib] #TOOLCHAIN_OPTIONS+="--pkg-config=$PKGCONFIG " #use pkg-config tool PKGCONFIG [pkg-config] #TOOLCHAIN_OPTIONS+="--pkg-config-flags=$PKGCONFIG_FLAGS " #pass additional flags to pkgconf [] #TOOLCHAIN_OPTIONS+="--doxygen=$DOXYGEN " #use DOXYGEN to generate API doc [doxygen] #TOOLCHAIN_OPTIONS+="--makeinfo=$MAKEINFO " #use MAKEINFO to generate documentation [makeinfo] # --strip=$STRIP --cxx=$CXX --stdcxx=$STDCXX --stdc=$STDC --ranlib=$RANLIB fi HOST_CC="gcc" #use host C compiler HOSTCC HOST_CFLAGS="-m32" #use HCFLAGS when compiling for host HOST_CXX="g++" HOST_CPPFLAGS="" #use HCPPFLAGS when compiling for host HOST_LD="ld" #use host linker HOSTLD HOST_LDFLAGS="-m32" #use HLDFLAGS when linking for host HOST_EXTRALIBS="" #use libs HLIBS when linking for host HOST_OS="" #compiler host OS [] TOOLCHAIN_OPTIONS+="--host-cc=$HOST_CC " #use host C compiler HOSTCC TOOLCHAIN_OPTIONS+="--host-cflags=$HOST_CFLAGS " #use HCFLAGS when compiling for host #TOOLCHAIN_OPTIONS+="--host-cppflags=$HOST_CPPFLAGS " #use HCPPFLAGS when compiling for host TOOLCHAIN_OPTIONS+="--host-ld=$HOST_LD " #use host linker HOSTLD TOOLCHAIN_OPTIONS+="--host-ldflags=$HOST_LDFLAGS " #use HLDFLAGS when linking for host #TOOLCHAIN_OPTIONS+="--host-extralibs=$HOST_EXTRALIBS " #use libs HLIBS when linking for host TOOLCHAIN_OPTIONS+="--host-os=$HOST_OS " #compiler host OS [] ### set linked library ### EXTRA_LDFLAGS="-L." EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/sys-root/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/sys-root/usr/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/lib/gcc/sh4-motorola-linux-uclibc/4.6.3 " EXTRA_LDFLAGS+="-lc -lgcc -ldl -lm -lutil -lnsl -lcrypt -lresolv -luargp " EXTRA_LDFLAGS+="-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample " #EXTRA_LDFLAGS+="-L${DIST}/st40/lib " #EXTRA_LDFLAGS+="-L${DIST}/st40/3pp/lib " #EXTRA_LDFLAGS+="-L${DIST}/st40/vip19x3/lib " #EXTRA_LDFLAGS+="-L${DIST}/st40/3pp/vip19x3/lib " ### set linked library ### ENV="LD_LIBRARY_PATH=~/FFmpeg/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/lib" #; \ #/usr/local/motorola/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/sys-root/usr/lib; \ #~/FFmpeg/dist/st40/lib; \ #~/FFmpeg/dist/st40/3pp/lib; \ #~/FFmpeg/dist/st40/vip19x3/lib; \ #~/FFmpeg/dist/st40/3pp/vip19x3/lib " echo $ENV EXTRA_CFLAGS=" -I. " EXTRA_CFLAGS+="-I${DIST}/st40/include " EXTRA_CFLAGS+="-I${DIST}/st40/3pp/vip19x3/include " EXTRA_CFLAGS+="-I${DIST}/st40/3pp/vip19x3/linux/include " EXTRA_CFLAGS+="-I${DIST}/st40/3pp/include " EXTRA_CFLAGS+="-I${DIST}/stb-noarch/include " EXTRA_CFLAGS+="-I${DIST}/stb-noarch/3pp/include " EXTRA_CFLAGS+="-I${DIST}/noarch/include " EXTRA_CFLAGS+="-I${DIST}/noarch/3pp/include " EXTRA_CFLAGS+="-g -Os -finline-limit=50 -D__ST40__=1 -D__VIP19X3__=1 " EXTRA_CFLAGS+="-O0 " # Set optimization level to <number> EXTRA_CFLAGS+="-std=c99 " # Assume that the input sources are for <standard> EXTRA_CFLAGS+="-m4 " # Generate SH4 code EXTRA_CFLAGS+="-mglibc " # Use GNU C library EXTRA_CFLAGS+="-pthread " EXTRA_CXXFLAGS="-fvisibility-inlines-hidden -I. " EXTRA_CXXFLAGS+="-I${DIST}/st40/include " EXTRA_CXXFLAGS+="-I${DIST}/st40/3pp/vip19x3/include " EXTRA_CXXFLAGS+="-I${DIST}/st40/3pp/vip19x3/linux/include " EXTRA_CXXFLAGS+="-I${DIST}/st40/3pp/include " EXTRA_CXXFLAGS+="-I${DIST}/stb-noarch/include " EXTRA_CXXFLAGS+="-I${DIST}/stb-noarch/3pp/include " EXTRA_CXXFLAGS+="-I${DIST}/noarch/include " EXTRA_CXXFLAGS+="-I${DIST}/noarch/3pp/include " EXTRA_CXXFLAGS+="-g -Os -finline-limit=50 -D__ST40__=1 -D__VIP19X3__=1 " EXTRA_CXXFLAGS+="-g -Os -finline-limit=50 -D__ST40__=1 -D__VIP19X3__=1 " EXTRA_CXXFLAGS+="-O0 " # Set optimization level to <number> EXTRA_CXXFLAGS+="-std=c99 " # Assume that the input sources are for <standard> EXTRA_CXXFLAGS+="-m4 " # Generate SH4 code EXTRA_CXXFLAGS+="-mglibc " # Use GNU C library EXTRA_CXXFLAGS+="-pthread " echo "EXTRA_LDFLAGS=$EXTRA_LDFLAGS" TOOLCHAIN_OPTIONS+="--extra-ldflags=\"$EXTRA_LDFLAGS\" " #add ELDFLAGS to LDFLAGS [] echo "EXTRA_CFLAGS=$EXTRA_CFLAGS" TOOLCHAIN_OPTIONS+="--extra-cflags=\"$EXTRA_CFLAGS\" " #add ECFLAGS to CFLAGS [] echo "EXTRA_CXXFLAGS=$EXTRA_CXXFLAGS" TOOLCHAIN_OPTIONS+="--extra-cxxflags=\"$EXTRA_CXXFLAGS\" " #add ECFLAGS to CXXFLAGS [] CPPFLAGS=" -I. " CPPFLAGS+="-I${DIST}/st40/include " CPPFLAGS+="-I${DIST}/st40/3pp/vip19x3/include " CPPFLAGS+="-I${DIST}/st40/3pp/vip19x3/linux/include " CPPFLAGS+="-I${DIST}/st40/3pp/include " CPPFLAGS+="-I${DIST}/stb-noarch/include " CPPFLAGS+="-I${DIST}/stb-noarch/3pp/include " CPPFLAGS+="-I${DIST}/noarch/include " CPPFLAGS+="-I${DIST}/noarch/3pp/include" #TOOLCHAIN_OPTIONS+="--extra-objcflags=$EXTRA_OBJFLAGS " #add FLAGS to OBJCFLAGS [] #TOOLCHAIN_OPTIONS+="--extra-ldexeflags=$EXTRA_LDEXEFLAGS " #add ELDFLAGS to LDEXEFLAGS [] #TOOLCHAIN_OPTIONS+="--extra-ldsoflags=$EXTRA_LDSOFLAGS " #add ELDFLAGS to LDSOFLAGS [] #TOOLCHAIN_OPTIONS+="--extra-libs=$EXTRA_LIBS " #add ELIBS [] #TOOLCHAIN_OPTIONS+="--extra-version=$EXTRA_VERSION " #version string suffix [] #TOOLCHAIN_OPTIONS+="--optflags=$OPTFLAGS " #override optimization-related compiler flags #TOOLCHAIN_OPTIONS+="--glslcflags=$GLSLCFLAGS " #extra glslc flags [] #TOOLCHAIN_OPTIONS+="--nvccflags=$NVCCFLAGS " #override nvcc flags [] #TOOLCHAIN_OPTIONS+="--build-suffix=$BUILD_SUFFIX " #library name suffix [] #TOOLCHAIN_OPTIONS+="--enable-pic " #build position-independent code #TOOLCHAIN_OPTIONS+="--enable-thumb " #compile for Thumb instruction set #TOOLCHAIN_OPTIONS+="--enable-lto[=$arg] " #use link-time optimization TOOLCHAIN_OPTIONS+="--env=\"$ENV\" " #override the environment variables #TOOLCHAIN_OPTIONS+="--disable-response-files #Don't pass the list of objects to linker in a file [autodetect] # Optimization options OPTIMIZATION_OPTIONS="" OPTIMIZATION_OPTIONS+="--disable-mmx " OPTIMIZATION_OPTIONS+="--disable-sse " OPTIMIZATION_OPTIONS+="--disable-sse2 " OPTIMIZATION_OPTIONS+="--disable-sse3 " OPTIMIZATION_OPTIONS+="--disable-sse4 " OPTIMIZATION_OPTIONS+="--disable-avx " #OPTIMIZATION_OPTIONS+="--disable-avx2 " #OPTIMIZATION_OPTIONS+="--disable-avx512 " #OPTIMIZATION_OPTIONS+="--disable-fma3 " #OPTIMIZATION_OPTIONS+="--disable-fma4 " # Other OTHER="" OTHER+="--disable-zlib " # All options OPTIONS="" echo "STANDARD_OPTIONS=$STANDARD_OPTIONS" OPTIONS+=$STANDARD_OPTIONS echo "PROGRAM_OPTIONS=$PROGRAM_OPTIONS" OPTIONS+=$PROGRAM_OPTIONS echo "DOCUMENTATION_OPTIONS=$DOCUMENTATION_OPTIONS" OPTIONS+=$DOCUMENTATION_OPTIONS echo "COMPONENT_OPTIONS=$COMPONENT_OPTIONS" OPTIONS+=$COMPONENT_OPTIONS echo "INDIVIDUAL_OPTIONS=$INDIVIDUAL_OPTIONS" #OPTIONS+=$INDIVIDUAL_OPTIONS echo "ELIBRARY_SUPPORT=$ELIBRARY_SUPPORT" OPTIONS+=$ELIBRARY_SUPPORT echo "OTHER=$OTHER" OPTIONS+=$OTHER if [ $ENABLE_CROSS_COMPILE -ne 0 ] then echo "TOOLCHAIN_OPTIONS=$TOOLCHAIN_OPTIONS" OPTIONS+=$TOOLCHAIN_OPTIONS fi echo "OPTIMIZATION_OPTIONS=$OPTIMIZATION_OPTIONS" OPTIONS+=$OPTIMIZATION_OPTIONS # Cmdline echo '*** Cmdline ***' CMDLINE="./configure $OPTIONS" echo Usage: $CMDLINE echo "Log: $LOG" echo "$(date): Execute configure... " eval $CMDLINE 1>$LOG 2>$LOG echo "Exit code (configure): $?" [ ! $?=0 ] && exit echo "$(date): Execute make " #make clean #make 1>>$LOG 2>>$LOG # -n --recon echo "Exit code (make): $?" echo "$(date): Done "
ENABLE_CROSS_COMPILE=1
Makefile требуется изменить следующим образом.
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF) $(info file $<) # $(CP) $< $@ # $(STRIP) $@
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS) $(info Запуск сборки...) $(info linker $(LD)) $(info output $(LD_O)) $(info objects $(OBJS-$*)) # instead $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
Среда сборки вместо линковки выведет необходимую информацию. Линкуем вручную. Там есть какие‑то конфликтующие зависимости, я даже разбираться не стал. Заработало — и всё тут.
После успешной сборки копируем архив с исполняемым файлом и сопутствующими. Запускаем? Или не хочется опять поймать сегфолт какой‑нибудь?
# ./ffmpeg --help ffmpeg version N-83801-g52c7366c83 Copyright (c) 2000-2017 the FFmpeg developers built with gcc 4.6.3 (STMicroelectronics Base) 20120313
Огонь! Программа работает даже под нагрузкой, что далее будет подтверждено.
Воспроизведение контента с источника RTSP, требующего basic авторизации.
Произведём предварительные настройки сетевых буферов
sudo sysctl -w net.core.wmem_max=10485760 sudo sysctl -w net.core.wmem_default=1048576 sudo sysctl -w net.core.rmem_max=10485760 sudo sysctl -w net.core.rmem_default=1048576
Сейчас приставка сможет воспроизвести контент с источника RTSP, требующего basic авторизации. В прошивке не было такой возможности. Добавляем плейлист.
#EXTM3U8, #EXTINF:-1,FFmpeg udp://127.0.0.1:1234
и запускаем FFmpeg
/root/ffmpeg/ffmpeg -buffer_size 1M -r 50 -i rtsp://login:password@[IP]/[path] -c copy -f mpegts udp://127.0.0.1:1234?pkt_size=1316
Логи с сообщениями приложения, к сожалению, не сохранились. Демультиплексированный RTSP поток датаграмм мультиплексируется в UDP поток контейнеров MPEGTS и отдаётся в адрес локальной петли. Перекодирование потока не требуется. Далее поток остаётся выбрать в меню и включить воспроизведение. UDP поток хорош тем, что при сбоях передачи воспроизведение не останавливается. Приложение может отправить поток в петлю в любой момент, и видеосигнал будет восстановлен. Кстати, откуда RTSP поток можно взять, не догадываетесь?
Готовы?

Разрешение - 1920x1080 (2 мп). Частота кадров - 25 Гц. Прогрессивная развёртка.
Во избежание мерцания кадра, желательно согласовать частоту кадров.
Битрейт потока - 4 Мбит/с. На удивление, узким местом оказались не характеристики микропроцессора, а малые размеры сетевых буферов. Показатель FPS мог упасть до 3 -2.
Автозапуск FFmpeg можно прописать в скрипте. Зачем, думаю не нужно обьяснять. Формат адреса может быть иным в вашем случае.
cat > /root/smapp << EOF #!/bin/sh cd /root/ffmpeg (while [ 1 ]; do sleep 3; sh -c "nohup /root/ffmpeg/ffmpeg -buffer_size 1M -r 50 -i rtsp://admin:password@192.168.1.2/1/1 -c copy -f mpegts udp://127.0.0.1:1234?pkt_size=1316 "; done) & cd /root /root/smapp.rt -qws EOF
Соответственно, для IPTV приставки задаём статические настройки сетевого адреса. Например 192.168.1.1.
Проблема портирования приложений для архитектуры SuperH SH
В linux присутствует устройство фреймбуфера /dev/fb0, /dev/fb1. Они предназначены для вывода видео в HD и SD режимах. Настроить режим можно утилитой fbset
Фреймбуферы доступны до запуска приложения.
Некоторые медиаплееры с открытым исходным кодом поддерживают вывод во фреймбуфер. Например:
mplayer -vo fbdev video.avi
Но портировать подобные проекты сложно. Кодовые базы проектов требуют поддержки стандартов c11, c17 от компиляторов для целевой архитектуры.
Целесообразность модификации приставки.
Целесообразна ли подобная модификация приставки? Взвесим все за и против.
С учётом технических параметров IPTV приставки MOTOROLA VIP1003 ARRIS, таких как наличие видеовыхода HDMI, физическая компактность в сравнении со специфическими решениями, такими как видеорегистраторы, и автономность работы её ПО, использование её в системах видеонаблюдения выглядит выгодным вариантом. Во что это вырастает? Грубо говоря, если можно приставку поставить на полку под потолком рядом с видеокамерой, а цифровой сигнал с HDMI сконвертировать для дальней передачи по оптоволокну, например, то можно обеспечить большую совместимость и удобство работы (купи и подключи), по сравнению с сетевой техникой. А также избавиться от недостатков сетевой техники, таких как нестабильность выделяемой пропускной способности для передачи данных, таким образом придав системе видеонабюдения надёжность передачи данных за счёт использования оборудования, совместимого с HDMI.
Однако, использование IPTV приставки MOTOROLA VIP1003 ARRIS там, где требуется удобство монтажа, пожарная безопасность, устойчивость к физическим воздействиям и аномалиям питания, ограничено, поскольку приставка разработана для бытового использования. Также, вместе с отказом от сетевой технологии, появляются ограничения, связанные с беспроводной передачей сигнала. Увеличивается задержка сигнала с момента изменения обьекта наблюдения. Разрешение ограничено требованием совместимости с видеорежимами IPTV приставки.
Я описал в красках, но выбор остаётся за вами. Ниже приведено руководство для конечного пользователя.
Руководство пользователя
IPTV приставка MOTOROLA VIP1003 ARRIS данной модификации может использоваться в качестве клиента для IP камер в системе видеонаблюдения.
Технические характеристики:
Питание - 12V/1A DC
Поддерживаемый видеорежим - 1920x1080p @ 25Hz
Поддерживаемый видеокодек - H.264/14496-10 video (MPEG-4/AVC)
Поддержка BASIC аутентификации.
Пропускная способность - 4 Мбит/с.
Порядок первичной настройки.
Задайте параметры аутентификации для вашей камеры видеонаблюдения. Пользователь - admin. Пароль - password.
Задайте статические настройки сетевого адреса для вашей камеры видеонаблюдения Адрес - 192.168.1.2. Маска сети - 255.255.255.0. Шлюз - 192.168.1.1.
Задайте поддерживаемый видеорежим и формат потока для вашей камеры видеонаблюдения.
Задайте битрейт потока - 4 Мбит/c
Подключите камеру видеонаблюдения к порту Ethrenet IPTV приставки.
Подключите видеовыход HDMI к приёмнику сигнала.
Порядок использования.
Включите питание IP камеры и IPTV приставки.
Дождитесь загрузки и появления меню приложения.
Направьте пульт управления к приставке и нажмите кнопку TOGGLE (переключить режим меню/просмотра).
Проверьте наличие видеосигнала.
Резюме
Работа завершена. Описание работы получилось обьёмным. Коротко о главном, что и зачем мы делали. С чем столкнулись и что получилось. Какое преимущество и недостаток у того, что получили. Приведём общие положения.
Целью работы, описанной в статье, является портирование приложения для IPTV приставки MOTOROLA VIP1003 ARRIS для обеспечения функционала воспроизведения контента, с источников, требующих авторизации, таких как IP камеры.
Инструментом для достижения цели работы, описанной в статье, является удалённый доступ к системе, получаемый путём прошивки IPTV приставки MOTOROLA VIP1003 ARRIS программным обеспечением, поддерживающим данный функционал.
Выводом из работы, описанной в статье, является необходимость учитывать поддерживаемую версию языка разработки при портировании для IPTV приставки MOTOROLA VIP1003 ARRIS новых проектов.
Итогом работы, описанной в статье, является возможность использования IPTV приставки MOTOROLA VIP1003 ARRIS в качестве клиента для IP камер в системе видеонаблюдения.
Преимуществом устройства, модифицированного в результате выполнения работы, описанной в статье, является повышение надёжности передачи видеопотока IP камер за счёт использования оборудования, совместимого с HDMI.
Недостатком устройства, которое рассматривается в работе, описанной в статье, является ограничение использования в приложениях с повышенными требованиями к безопасности эксплуатации и полноте передаваемых данных.
Спасибо за внимание!

Василий
Специалист
Почта: vasyusha.artemov.95@mail.ru

Вы можете поделиться ссылкой на данную статью с помощью QR кода на вашем экране.
26 Октября 2026 г.