Files
SDR-Rover/docs/video/VIDEO_003.md

27 KiB
Raw Permalink Blame History

VIDEO-003: видеокодек и радиоформат, программная проверка

16 сентября 2026 года. Worktree SDR_Rover_Video, ветка video-development, исходный HEAD af7c05f. Передача через эфир и обращения к SDR не выполнялись. Число 600 кбит/с здесь служит инженерной целью, а не условием зачёта работы.

Что проверено

Результаты разделены по происхождению:

Уровень Смысл в этом отчёте
CALCULATED MAXIMUM Арифметика формата PHY, кода, преамбулы, защитных интервалов и паузы при нулевых потерях.
IMPLEMENTED Действующий генератор Lab045 формирует пакет с нагрузкой protocol.packet ровно 256 байт, BPSK 500 ксимв/с, FEC 1/2. VIDEO-003 его не меняет.
OFFLINE VERIFIED Новый отдельный приёмник декодировал программный сигнал: поиск известной преамбулы, оценка фазы/частоты, PHY-заголовок, FEC и CRC. Это не проверка производственного передатчика или приёмника.

Исходник H.264 тот же, что в VIDEO-001/002: data/raw/video001/udacity_project_video.mp4, SHA-256 651949922042c223375d40bf8929def97dbb62c6ade651d1f5b08eea47127d5f. Сравнивались два шестисекундных окна. Размеры кадров режима CURRENT побайтно совпали с сохранёнными результатами VIDEO-001 во всех шести проверенных сочетаниях окна и разрешения.

Предел PHY и полезная нагрузка

Длина полного пакета в PHY Lab045 ограничена 1024 байтами. Внутри него protocol.packet занимает 8 байт заголовка и 4 байта CRC-32. Максимальная нагрузка этого пакета равна 1024 − 8 − 4 = 1012 байтам. Формат VIDEO-002 содержит 17-байтный видеозаголовок, поэтому максимум данных видео в одном фрагменте равен 995 байтам. Это граница формата; генератор Lab045 пока принимает только 256 байт нагрузки, что оставило бы 239 байт видео в формате VIDEO-002. Производственный TX/RX с фрагментом 995 байт не проверялся.

Видеозаголовок VIDEO-002 состоит из флагов версии/типа кадра (1 байт), stream_id (4), frame_id (4), индекса (2), числа фрагментов (2), возраста кадра (2) и длины данных (2). Поток и номер кадра нужны для разделения потоков и отказа от старых кадров; индекс и число фрагментов нужны при перестановке и потере; тип кадра нужен декодеру; возраст нужен каждому фрагменту для ограничения срока доставки. Длина уже выводится из CRC-проверенного внешнего пакета. Отдельная пробная версия укладывает индекс и count−1 в байт каждый и убирает повтор длины, сохраняя 32-битные stream_id и frame_id: 13 байт, экономия 4 байта, или 23,5% заголовка. Она даёт 999 байт видео на пакет и увеличивает верхнюю скорость лишь с 574,149 до 576,457 кбит/с. Это не основной способ увеличить пропускную способность; формат VIDEO-002 остался исходным.

Радиобюджет

Расчёт использует 1280 BPSK-символов преамбулы, 144 символа защищённого PHY-заголовка и 42 символьных интервала защитных областей/RRC. В тело FEC входят все биты полного пакета и шесть хвостовых битов свёрточного кода. Прокалывание применяется к существующему коду R=1/2; фактическое число передаваемых битов посчитано по маске, включая неполный последний период. В QPSK тело несёт два кодовых бита на символ, преамбула и PHY-заголовок остаются BPSK. Оценка занятой полосы Rs × (1 + 0,35) учитывает скругление RRC и не является измеренной полосой излучения.

Для размеров нагрузки PHY 256, 512, 768 и 1012 байт и пауз 5 / 2 / 1 / 0,5 / 0 мс сохранено 140 строк в data/processed/video003/design_space.json. В таблице ниже приведён максимум каждой группы: 1012 байт нагрузки, 0 мс, нулевые потери.

Модуляция, ксимв/с FEC Сырая скорость, кбит/с Эфирное время пакета, мс Видео, кбит/с Расчётная полоса, кГц
BPSK 500 1/2 500 35,724 222,819 675
QPSK 250 1/2 500 38,656 205,919 337,5
QPSK 250 2/3 500 30,460 261,326 337,5
QPSK 250 3/4 500 27,728 287,074 337,5
QPSK 500 1/2 1000 19,328 411,838 675
QPSK 500 2/3 1000 15,230 522,653 675
QPSK 500 3/4 1000 13,864 574,149 675

Символ длится 4 мкс при 250 ксимв/с и 2 мкс при 500 ксимв/с. При частоте дискретизации 8 Мвыб/с это 32 и 16 выборок на символ. Для кандидата QPSK 500, FEC 2/3, нагрузка 1012 байт изменение паузы даёт:

Пауза, мс Эфирное время, мс Доля времени передачи Видео, кбит/с Накладная доля
5 15,230 75,28% 393,475 60,65%
2 15,230 88,39% 461,985 53,80%
1 15,230 93,84% 490,450 50,96%
0,5 15,230 96,82% 506,039 49,40%
0 15,230 100% 522,653 47,73%

Здесь накладная доля равна 1 − видео-биты / (сырая скорость × период пакета); она включает FEC, преамбулу, заголовки и паузу. Нулевой интервал проверен только программно. Передача пакетов без паузы через SDR не разрешена этим опытом.

Даже при нулевой паузе, полном пакете и FEC 3/4 максимум 574,149 кбит/с. Без видеозаголовка получилось бы 583,958 кбит/с. Для перехода за 600 кбит/с при сохранении остальных параметров нужна символьная скорость не ниже 522 513 символов/с. При неизменных 8 Мвыб/с ближайшее большее целое отношение выборок к символу — 15, то есть 533 333 символа/с; арифметическая скорость тогда составила бы 612,425 кбит/с. Это минимальное изменение одного параметра в расчёте, а не готовая настройка RF: потребуются новый тактовый режим PHY, проверка полосы, синхронизации и скорости обработки. Другие одиночные расчётные варианты: полный пакет не меньше 1248 байт при 500 ксимв/с и FEC 3/4 либо сокращение фиксированной части кадра минимум на 299 символов. Оба требуют изменения PHY и отдельной проверки.

QPSK и FEC: автономный приём

Отображение Gray зафиксировано как 00=(-1−j)/√2, 01=(-1+j)/√2, 11=(1+j)/√2, 10=(1−j)/√2; энергия каждого QPSK-символа равна единице. Приёмник ищет PRBS7-преамбулу, оценивает частотный сдвиг и начальную фазу только по известным символам, проверяет повторённый PHY-заголовок, затем декодирует тело и CRC. Второе уточнение фазы использует уже проверенный PHY-заголовок. Исходные биты полезной нагрузки передаются только измерителю ошибок после завершения приёма. Проверены поворот на 90°, случайная фаза, сдвиг 73 Гц, шум и поиск после 11 начальных шумовых символов. Отдельный контроль RRC при 250 и 500 ксимв/с прошёл с 32/16 выборками на символ при идеальной тактовой синхронизации; он не доказывает захват тактов из IQ.

Прокалывание штатного кода K=7: для 2/3 повторяется маска 1110, для 3/4 — 111001, для 1/2 сохраняются все биты. Удалённые биты возвращаются в декодер Витерби как нулевые мягкие метрики. Эталонные векторы, длины кода, включая хвост, декодирование без ошибок и отказ при неверной длине проверены тестами. Код R=1/2 не заменён.

AWGN-контроль содержит 32 реализации на каждую точку 0/3/6/9 dB Eb/N0, семь сочетаний модуляции/скорости/FEC, всего 896 прогонов, затравка 20260916. Es=1, Eb=Es × число символов тела / число информационных битов; учтён и добавочный бит при нечётной длине QPSK-тела. Фиксированные расходы кадра учтены отдельно в радиобюджете. Это сравнение при одинаковом Eb/N0, а не при одинаковой мощности или Es/N0. BER до FEC считается только для достигнутых тел пакета, BER после FEC — для выданных декодером пакетов; оба знаменателя записаны в JSON. Успех полного пакета и прохождение CRC учитываются отдельно.

QPSK 500 ксимв/с CRC при 3 dB CRC при 6 dB CRC при 9 dB
FEC 1/2 26/32 32/32 32/32
FEC 2/3 13/32 32/32 32/32
FEC 3/4 3/32 32/32 32/32

Нулевая частота ошибок в 32 реализациях не доказывает малую вероятность потери на длинном потоке. Ставка 3/4 повышает расчётную скорость, но на 3 dB в этом опыте уступила 2/3 по прохождению CRC.

Дополнительно переданы 32 последовательных максимальных пакета без межпакетной паузы через программный канал с 42 переходными символами на пакет. При Eb/N0=9 dB и сдвиге 73 Гц QPSK 500 с FEC 2/3 и 3/4 получили по 32/32 CRC и по 32/32 правильно разобранных видеозаголовка. Приёмник выводил длину очередного пакета из принятого PHY-заголовка и не получал границы или payload от генератора. Полезные скорости коротких потоков: 522,653 и 574,149 кбит/с за 0,487 и 0,444 с сигнального времени. Время программной обработки оказалось в 5,57 и 6,20 раза больше длительности сигнала. Поэтому проверен короткий автономный поток, а обработка в реальном времени и длительная устойчивая доставка — NOT_RUN.

Исходной IQ-записи Lab066 в данном worktree нет. Частотная неравномерность по её сводным JSON не воспроизводится однозначно; отдельная модель по Lab066 не строилась. AWGN не объявляется эквивалентом OTA-канала.

H.264 через PyAV

Использован PyAV 16.0.1 с библиотеками FFmpeg: libavcodec 62.11.100, libavformat 62.3.100, libavutil 60.8.100. FFmpeg CLI не вызывался. Для каждого из 60 прогонов рядом с размерами кадров сохранены имя кодека, разрешение, частота кадров, формат пикселей, целевой и предельный потоки, размер VBV, GOP, число B-кадров, preset, tune, фактический профиль, intra-refresh, time_base и точные x264-params. Профиль всех проверенных потоков декодер определил как High; B-кадров нет. CURRENT повторил VIDEO-001 с GOP 1 с и VBV 1 с. CURRENT_VBV, SHORT_GOP и INTRA_REFRESH проверены при 300/400/500 кбит/с и VBV 0,2 с. Короткий GOP равен 5 кадрам при 10 кадрах/с и 3 кадрам при 5 кадрах/с. Запрошенный intra refresh уменьшил отдельные пики, но в испытании с потерей кадра восстанавливал точное изображение позже короткого GOP.

В таблице приведено худшее из двух окон для потока и размера кадра, худшее время восстановления после удаления одного кадра и меньшее среднее PSNR из двух окон. Пик за 100 мс отражает один крупный кадр, его нельзя подменять средним потоком.

Режим H.264 Средний, кбит/с Пик 100 мс Пик 1 с Макс. кадр, байт P95 кадра, байт Восстановление, мс PSNR, dB
NORMAL CURRENT 354,0 1116,1 375,8 13951 12784 900 33,8
NORMAL SHORT_GOP 400k 361,4 740,2 408,8 9252 9114 400 33,3
HIGH QUALITY CURRENT 357,2 1034,6 455,6 12933 7892 900 33,2
HIGH QUALITY SHORT_GOP 400k 391,8 751,7 427,1 9396 9080 400 33,1
720p/5 CURRENT 345,5 1164,0 440,6 14550 11653 800 33,0
720p/5 SHORT_GOP 400k 340,2 736,6 345,5 9208 9122 600 32,1

Порог 300 кбит/с снижал размер пиков сильнее, но ухудшал PSNR. Порог 500 кбит/с повышал пиковый поток и требовал большего радиобюджета. Вариант SHORT_GOP 400k выбран для совместного расчёта по размеру кадров и сроку восстановления, без утверждения о проверенном операторском качестве. Контрольных сцен с мелкими препятствиями и оценки оператором не было.

Сопоставление видео и радио

Измерения VIDEO-001/002 и требуемые запасы:

Видео Средний, кбит/с Пик 1 с, кбит/с Нужно +20%, кбит/с Нужно +50%, кбит/с
ROBUST 320×240/5 117,2 171,7 206,0 257,5
NORMAL 640×360/10 354,0 375,8 451,0 563,7
HIGH QUALITY 854×480/10 357,2 455,6 546,7 683,3
720p/5 345,5 440,6 528,8 661,0

Для расчётного QPSK 500, FEC 2/3, пакет 1024 байта, пауза 0 мс исходные пики дают запас 522,653/peak: NORMAL 1,391, HIGH QUALITY 1,147, 720p/5 1,186. После SHORT_GOP 400k пики 408,8 / 427,1 / 345,5 кбит/с дают запас 1,278 / 1,224 / 1,512. По одному лишь расчётному фильтру все три превышают 1,2; при исходном кодировании HIGH QUALITY и 720p/5 порог 1,2 не проходили. Эти числа не учитывают ошибки PHY, занятость процессора и серийные потери пакетов.

Модель VIDEO-002 повторена на настоящих H.264 пакетах с рассчитанным временем передачи каждого полного пакета. Очередь ограничена двумя кадрами, срок — 300 мс, потери 0/1/2/5/10% независимы по передаваемому пакету, фиксированная затравка 20260916. Отдельно сохранены серии из 2/5/10 потерянных пакетов; их нельзя трактовать как независимую вероятность. Ниже для SHORT_GOP 400k + QPSK 500 / FEC 2/3 / 1012 байт / 0 мс показано число отображённых кадров в окнах «белая / чёрная машина»:

Потеря пакетов NORMAL, из 60 HIGH QUALITY, из 60 720p/5, из 30
0% 60 / 60 60 / 60 30 / 30
1% 54 / 55 56 / 55 27 / 25
2% 45 / 42 47 / 46 23 / 20
5% 27 / 22 28 / 25 11 / 12
10% 16 / 16 16 / 13 5 / 5

Без потерь максимальные и P95 возрасты показанных кадров в этих прогонах не превысили 152,3 мс; сбросов по устареванию не было. При потере пакетов возраст остаётся ограниченным, но неполные кадры не показываются. При 5% потерь до оператора доходит меньше половины кадров NORMAL и HIGH QUALITY в одном или обоих окнах. Время восстановления после первой потерянной части записано отдельно для каждого прогона в JSON; например, при 1% потерь диапазон для этих трёх режимов составил 252–752 мс. Это конкретные короткие реализации, а не оценка вероятности для длительного канала.

Статус и ограничения

Поле Результат
VIDEO-003 STATUS PARTIAL: программный PHY и видео проверены по отдельности и в модели доставки; производственный TX/RX, real-time и OTA не проверены.
MAX PHY PACKET SIZE 1024 байта полного пакета.
CURRENT IMPLEMENTED PAYLOAD LIMIT Ровно 256 байт нагрузки protocol.packet у генератора Lab045; видео в производственный TX/RX не встроено.
MAX CALCULATED VIDEO PAYLOAD 995 байт при текущем 17-байтном заголовке.
BEST H264 PROFILE SHORT_GOP 400k, GOP 0,5 с при 10 кадрах/с, VBV 0,2 с; операторское качество не проверялось.
BEST BPSK CONFIGURATION 500 ксимв/с, FEC 1/2, PHY payload 1012 байт, 0 мс: 222,819 кбит/с только расчёт; действующий размер 256 байт и пауза 5 мс дают 115,654 кбит/с при нулевых потерях.
BEST QPSK 250K CONFIGURATION FEC 3/4, payload 1012 байт, 0 мс: 287,074 кбит/с только расчёт.
BEST QPSK 500K CONFIGURATION По скорости FEC 3/4, payload 1012 байт, 0 мс: 574,149 кбит/с; по балансу с ошибками и SHORT_GOP 400k кандидат FEC 2/3: 522,653 кбит/с. Оба только программные.
BEST FEC RATE 2/3 как следующий диагностический кандидат; при 3 dB получил 13/32 CRC против 3/32 у 3/4, а расчётный поток после смены GOP даёт запас более 1,2 для трёх видеорежимов.
BEST CALCULATED USEFUL RATE 574,149 кбит/с при нулевых потерях.
BEST OFFLINE-VERIFIED USEFUL RATE 574,149 кбит/с на коротком 32-пакетном синтетическом потоке при 9 dB, 32/32 CRC; CPU/signal = 6,20, поэтому это не real-time goodput.
600 KBIT/S TARGET WITH CURRENT PHY NOT_REACHABLE в проверенной матрице при пакете до 1024 байт, скоростях до 500 ксимв/с и FEC до 3/4.
MINIMUM ARCHITECTURAL CHANGE REQUIRED Для арифметического превышения 600 кбит/с при FEC 3/4 поднять скорость минимум до 522 513 символов/с; при Fs=8 Мвыб/с и целых выборках на символ следующий вариант 533 333 символа/с (15 выборок/символ). Требуются новые PHY/RX и тесты.
NORMAL VIDEO FITS WITH 20% HEADROOM YES только в расчёте для SHORT_GOP 400k + QPSK 500/FEC 2/3/1012/0: запас 1,278.
HIGH QUALITY VIDEO FITS WITH 20% HEADROOM YES только в том же расчёте: 1,224; исходный режим VIDEO-001 давал 1,147.
720P5 FITS WITH 20% HEADROOM YES только в том же расчёте: 1,512; исходный режим давал 1,186.
BEST NEXT RF CANDIDATE Предмет отдельной разработки и будущего разрешённого опыта: QPSK 500 ксимв/с, FEC 2/3, полный пакет 1024 байта, пауза 0 мс, SHORT_GOP 400k. Сейчас real-time декодирование и устойчивость к потерям не подтверждены.
WHY 2/3 заметно лучше 3/4 в AWGN-контроле 3 dB; расчёт 522,653 кбит/с покрывает пики нового H.264 с запасом ≥1,2. В модели при 0% потерь показаны все кадры; при 5% большая доля кадров теряется.
ENCODER API PyAV 16.0.1; версии библиотек и точные параметры каждого прогона — в codec_results.json.
FFMPEG CLI USED NO.
VIDEO-SPECIFIC GATE PASS: 123 целевых теста, сверка результатов, импортов и отсутствия аппаратных импортов в проверяемых модулях.
RF TX 0.
COMMIT / PUSH NOT PERFORMED / NOT PERFORMED.

Файлы и повторение

  • protocol/punctured_fec.py, protocol/video003_modem.py: автономный кодер и приёмник; производственный BPSK и SDR receiver не изменены.
  • protocol/video003_compact_header.py: отдельная проба 13-байтного заголовка, версия VIDEO-002 остаётся исходной.
  • tools/video003_design.py: design_space.json и точный расчёт.
  • tools/video003_synthetic.py: synthetic_phy.json, 896 реализаций AWGN.
  • tools/video003_stream.py: continuous_stream.json, короткий непрерывный поток.
  • tools/video003_codec.py: codec_results.json, 60 прогонов PyAV.
  • tools/video003_transport.py: transport_results.json, 784 прогона доставки.
  • tools/video_gate.py: целевой шлюз проверки без исторических RF-данных.

Запуск из корня worktree после установки requirements-video.txt:

python -B -X utf8 -m tools.video003_design
python -B -X utf8 -m tools.video003_synthetic
python -B -X utf8 -m tools.video003_stream
python -B -X utf8 -m tools.video003_codec
python -B -X utf8 -m tools.video003_transport
python -B -X utf8 -m tools.video_gate

Последние две программы читают результаты предыдущих. video_gate проверяет только файлы VIDEO-001/002/003 и используемые модули protocol, запускает тесты без аппаратных entry point. Статический запрет аппаратных импортов в этих модулях и отсутствие аппаратного запуска в перечисленных командах не служат доказательством качества радиоканала. Следующий опыт с RF требует отдельного прямого разрешения и новой подготовки PHY.

При независимой проверке общий python tools/quick_gate.py завершился с ошибкой: 1059 тестов прошли, один тест Lab065 и его функциональная проверка не нашли исторический data/raw/lab064/tx_metadata.json в VIDEO worktree. Этот файл не создавался для VIDEO-003. Целевой video_gate прошёл отдельно: 123 теста и сверка сохранённых результатов.