# VIDEO-005 — приём IQ и проверка видеотракта 17 сентября 2026 года. Статус: **PARTIAL**. Это программный эксперимент в `video-development`, без доступа к SDR и без передачи в эфир. Исходная точка — `95f6640`; история Git сохранена. Измерения и SHA записаны в `data/processed/video005/benchmark.json` (seed `20260917`). ## Рабочая цепочка Приёмник `receive_iq_stream()` получает одномерный complex IQ и выбранный режим радиоканала. Он не получает границы пакета, момент выборки, истинный CFO/фазу, payload или CRC. Цепочка: цифровое смещение несущей → согласованный RRC → поиск известной преамбулы по всему потоку → дробное уточнение момента → оценка CFO и фазы по преамбуле → разрешение квадранта QPSK → блочное слежение за фазой тела по решениям QPSK → PHY/внутренний FEC 2/3/CRC → фрагменты → внешний FEC 8+1 с усилением опорного блока → сборка H.264 → декодированные кадры. Эталонные пакеты и пиксели используются после обработки только для подсчёта ошибок. Использованы прежние QPSK mapping, RRC, FEC, Viterbi, CRC и видеотранспорт. Новые поиск преамбулы, восстановление такта и несущей находятся в отдельных модулях. Порог корреляции 0,5 отсекает наблюдавшиеся боковые пики PRBS7 около 0,4. Формат преамбулы не менялся. `CURRENT PREAMBLE INSUFFICIENT = NO` **только для проверенной сетки**; это не доказательство устойчивости в эфире. ## Проверки сигнала На одном полном пакете и в комбинированных трёхпакетных потоках проверены дробные сдвиги `0`, `±0,1`, `±0,25`, `±0,4` символа; CFO `0`, `±1`, `±5`, `±20`, `±100` Гц; начальная фаза `0`, `±15`, `±45`, `90`, `180` градусов. Синтетическое фазовое отклонение тела от 0 до 0,35 рад уменьшалось решающим QPSK-трекером. Все заявленные строгие проверки восстановили исходный пакет. Дрейф частоты дискретизации не вводился: `SAMPLE CLOCK OFFSET = NOT MODELED IN VIDEO-005`. AWGN, 16 полных пакетов на точку, фиксированная затравка: при `Eb/N0` 0, 3, 6, 9 дБ получено соответственно **0/16, 1/16, 16/16, 16/16** точных CRC-пакетов; неверных принятых пакетов — 0. Это наблюдение для выбранного потока, не кривая ошибок или оценка вероятности для любого канала. `LAB066-LIKE DIAGNOSTIC CHANNEL MODEL`: медиана измеренной неравномерности полосы 2,870 дБ и средний показатель matched/residual 5,546 дБ. Суррогат содержит двухотводный FIR с задержкой 8 отсчётов и вторым коэффициентом 0,176194, а также белый остаток. Он дал **30/32** точных CRC-пакетов, неверных принятых — 0. Фильтр согласован по одному сводному показателю; модель не воспроизводит распределение помех, меняющийся канал, аппаратные искажения или саму запись Lab066. Это не измерение RF-приёма. ## Скорость и профиль Канонический сигнал: 32 полных пакета, 3 886 112 комплексных отсчётов, 8 Мвыб/с, длительность **0,485764 с**, SHA-256 IQ `d34c4fbba04708180f60ed759cef8bfa9f67827a57ea5ff201d94701bf32afd2`. Передача 500 ксимв/с, QPSK, inner FEC 2/3. Первый запуск с JIT занял **1,203 с**. Три прогретых замера `perf_counter()` — 0,281 / 0,299 / 0,268 с; медиана **0,281 с**, фактор **0,578**, скорость **1,729×** реального времени. Получено 32/32 пакета с точным SHA и CRC; целевой фактор ≤0,67 выполнен, предпочтительный ≤0,50 — нет. Эти числа зависят от нагрузки данного ПК. В таблице времена этапов взяты из последнего прогретого запуска (0,268 с), проценты относятся к нему. Числа вызовов взяты из отдельного `cProfile`; его времена не складываются с таблицей. Копии/буферы перечислены по коду, точное число выделений NumPy не измерялось. | Этап | Время, мс | Доля | Вызовы | Основные выделения/копии | |---|---:|---:|---:|---| | Смещение несущей | 15,3 | 5,7% | 1 | Периодический осциллятор и complex64 baseband, по 3,89 млн отсчётов | | Согласованный RRC | 61,5 | 22,9% | 1 | Выход свёртки; внутренние FFT-буферы SciPy | | Поиск преамбулы | 49,2 | 18,4% | 1 | Две корреляции/массивы энергии на прореженных фазах | | Восстановление такта | 9,2 | 3,4% | 32 | Индексы и один complex64-массив символов на кандидат | | Оценка CFO/фазы/квадранта | 12,5 | 4,7% | 32 | Корректор и исправленные символы на пакет | | Проверка PHY-заголовка | 0,6 | 0,2% | 32 | Малый массив заголовка | | Слежение за фазой QPSK | 49,9 | 18,6% | 32 | Одна копия символов пакета и векторы блоков по 64 | | Строгий PHY/FEC/CRC | 53,0 | 19,8% | 32 | Мягкие решения, depuncturing и рабочие массивы Viterbi | В `cProfile` (полный профилированный вызов 0,282 с): слежение QPSK 74,4 мс, RRC 54,6 мс, поиск 46,6 мс, Viterbi `decode_soft` 28,6 мс, depuncturing 1,41 мс, QPSK soft decisions 0,48 мс и `parse_packet`/CRC 0,36 мс. На чистом двухсекундном видео внешний FEC занял 1,10 мс, сборка фрагментов 0,86 мс, декодирование H.264 15,7 мс. Диагностическая сверка пикселей заняла ещё 11,3 мс и исключена из времени рабочего пути. Доли мелких функций из `cProfile` относятся к 0,282 с; вложенные функции нельзя суммировать. ## Видео 640×360/10 Первые 20 кадров исходного клипа (SHA-256 `651949922042c223375d40bf8929def97dbb62c6ade651d1f5b08eea47127d5f`) закодированы PyAV/libx264 в H.264 SHORT_GOP 400k. Создано 117 PHY-пакетов; длительность IQ 1,991 с. Потери и повреждение вносятся в **IQ-интервалы**, до приёмника. Возраст отсчитывается от захвата кадра до завершения радиопакета. | Сценарий | CRC-пакеты | Кадры/FPS | Потеря кадров | P50/P95/max, мс | Просрочено | Восстановлено FEC | Опорный кадр | |---|---:|---:|---:|---:|---:|---:|---:| | Без потерь | 117 | 20/20; 10,0 | 0% | 101/167/167 | 0 | 0 | — | | 1% IQ-потерь (факт 1/117) | 116 | 20/20; 10,0 | 0% | 101/167/167 | 0 | 1 | — | | 5% IQ-потерь (факт 6/117) | 111 | 17/20; 8,5 | 15% | 119/167/167 | 1 | 3 | — | | Два фрагмента опорного кадра | 115 | 20/20; 10,0 | 0% | 101/167/167 | 0 | 2 | 0 мс | | Три фрагмента опорного кадра | 114 | 15/20; 7,5 | 25% | 89/167/167 | 1 | 0 | 667 мс до следующего | | Один испорченный IQ-пакет | 116 | 20/20; 10,0 | 0% | 101/167/167 | 0 | 1 | 0 мс | Во всех сценариях нет неверного CRC-пакета, неверно собранного или декодированного кадра и повторного показа старого кадра. После невосстановленной потери опорного кадра H.264 ждёт следующий опорный кадр. Чистый путь **IQ → декодированные кадры** имеет фактор **0,576**. Полный офлайн-прогон от чтения и кодирования источника через формирование IQ и расчёт синтетического канала до показа имеет фактор **2,153**; его нельзя представлять как скорость одного приёмника. В этом прогоне 0,317 с заняли чтение/кодирование, 0,597 с — внешний FEC и PHY передатчика, 0,923 с — формирование IQ, около 1,3 с — канал и около 1,1 с — радиоприём. Сверка эталона в оба фактора не входит. ## CODE QUALITY AUDIT **BEFORE:** рабочие модули `video003_modem`, `video004_viterbi`, `video004_erasure` и четыре новых модуля `video005_*` — около 968 строк и 34 функции после реализации; радиофактор до короткой чистки в одном прогоне 0,513. Главные затраты: RRC, поиск преамбулы, слежение за фазой и FEC. | Проверка или подозрительное место | Где | Почему и категория | Решение | |---|---|---|---| | Длина IQ, конечность, параметры режима, границы интерполяции | `video005_receiver.py`, `video005_timing.py` | A: повреждённый вход и выход за буфер | KEEP | | PHY-заголовок, CRC, возраст, индексы внешнего FEC | `video005_receiver.py`, старые модули | A: обязательные барьеры до видео | KEEP | | Равенство длин строк матрицы и векторов внешнего FEC | `packet_erasure_fec.py` | A: обрезка `zip()` могла скрыть невозможное состояние | REWRITE с `strict=True` | | Предварительный PHY-заголовок и повторная проверка в строгом декодере | `video005_receiver.py` | D: длина тела нужна до FEC, строгий разбор обязателен | KEEP | | Проверка фазовых решений внутри тела | `video005_carrier.py` | E: решения QPSK нужны для слежения | KEEP, блоками по 64 символа | | Эталонные SHA пакетов и пикселей | `video005_benchmark.py`, `video005_video.py` | C: диагностика не должна решать судьбу кадра | MOVE_TO_DIAGNOSTICS после обработки | | `complex128` после интерполяции/фазовой коррекции | `video005_timing.py`, `video005_carrier.py` | Лишний объём временных векторов | REWRITE в `complex64` | | Повторный H.264 decode эталона | `video005_video.py` | C: нужен для точной пиксельной сверки, не для показа | KEEP вне измеряемого пути | | `LAB066-LIKE`, `cProfile`, графики и подробный JSON | `tools/` | C: офлайн-диагностика | KEEP вне receiver | | Периодический осциллятор, RRC/FFT-буферы | `video005_receiver.py` | Выделения велики, но RRC быстрее основной цели | KEEP; дальнейшая оптимизация требует отдельного профиля | **REMOVED / SIMPLIFIED:** временные векторы символов и фазовой коррекции стали `complex64`; эталон перестал управлять H.264-декодированием; два `zip()` внешнего FEC теперь проверяют равенство длин. **MOVED TO TESTS / DIAGNOSTICS:** точные SHA и сверка пикселей остаются в проверочном коде и выполняются после рабочего прохода. Неиспользуемых импортов Ruff не обнаружил; декодер и передатчик не содержат Lab066-ветвей или глобального изменяемого состояния. Кеш коэффициентов RRC неизменяемый. Большие функции сборки видео остаются в офлайн-инструменте; их разделение сейчас не даст доказанного выигрыша. **AFTER:** радиофактор 0,578 в финальном запуске; ускорение от изменения dtype не заявляется из-за разброса времени между прогонами. Строгие пакеты, CRC, числа кадров и сценарные выходы остались теми же. Прошли 178 тестов, `ruff`, `pyright` (0 ошибок/предупреждений), `git diff --check` и `video_gate.py`. Защита от неверных пакетов, индексов и просроченного видео не удалялась. Независимый запуск общего `tools/quick_gate.py` дал 1103 пройденных теста, 2 пропуска и один отказ Lab065: в этом worktree отсутствует игнорируемый исторический вход `data/raw/lab064/tx_metadata.json`. Это ограничение общего шлюза, а не воспроизведённый отказ VIDEO-005; целевой VIDEO gate прошёл. ## Решение и границы Предварительная политика без автоматического переключения: GOOD — NORMAL 640×360/10 с 8+1 и усилением опорных блоков; DEGRADED — снизить FPS или увеличить избыточность; POOR — ROBUST 320×240/5; CRITICAL — отключить видео или резко снизить поток. Пороги потерь не закреплены: один короткий сценарий 5% дал 17/20 кадров, а суррогат Lab066 не заменяет эфир. | Итоговое поле | Результат | |---|---| | VIDEO-005 STATUS | **PARTIAL**: радиопуть проходит цель, офлайн-генерация медленнее реального времени, есть потери кадров при 5% | | RAW IQ RECEIVER | **PASS**: 32/32 точных пакета; фактор 0,578 ≤0,67 | | PREAMBLE ACQUISITION | **PASS** в проверенных потоках | | TIMING RECOVERY | **PASS** для 0 и ±0,1/0,25/0,4 символа | | CARRIER FREQUENCY RECOVERY | **PASS** для 0 и ±1/5/20/100 Гц | | CARRIER PHASE TRACKING | **PASS** в синтетическом тесте изменения фазы | | QPSK QUADRANT RESOLUTION | **PASS** для 90°/180° и проверенных фаз | | FEC 2/3 | **PASS**, битовые/пакетные выходы точны | | OUTER ERASURE FEC | **PASS** при одном и двух стираниях; три не восстановлены | | 640x360 / 10 FPS END-TO-END | **PARTIAL**: чисто 20/20, при 5% — 17/20; полный офлайн-фактор 2,153 | | INPUT VIDEO FPS / DISPLAYED FPS / FRAME LOSS RATE | 10 / 10 / 0% чисто; 10 / 8,5 / 15% при 5% IQ-потерь | | P50 / P95 / MAX FRAME AGE | 101 / 167 / 167 мс чисто; 119 / 167 / 167 мс при 5% | | RADIO RECEIVER REALTIME FACTOR | 0,578; IQ → декодированные кадры 0,576 в отдельном видеопрогоне | | END-TO-END VIDEO REALTIME FACTOR | 2,153 от источника через офлайн-канал до кадра | | RAW IQ DURATION / JIT FIRST RUN TIME / WARM PROCESSING TIME | 0,485764 / 1,203 / медиана 0,281 с | | MAIN HOT PATH | IQ → RRC → преамбула/такт/несущая → QPSK → FEC/CRC → фрагменты → erasure FEC → H.264 | | AWGN RESULT | 0/16, 1/16, 16/16, 16/16 точных пакетов при 0/3/6/9 дБ | | LAB066-LIKE MODEL RESULT | 30/32 точных пакета; диагностический суррогат | | SAMPLE CLOCK OFFSET | **NOT MODELED IN VIDEO-005** | | RUFF / PYRIGHT / VIDEO GATE | **PASS / PASS / PASS** | | BEST NEXT RF CANDIDATE | QPSK 500 ксимв/с, inner 2/3, outer 8+1 с усилением опорного блока, H.264 SHORT_GOP 400k | | WHY | 20/20 чисто и при одном стирании; нуждается в отдельной проверке устойчивости к 5% и реальным искажениям | | RF TX / SDR HARDWARE | **0 / NOT ACCESSED** | | COMMIT / PUSH | **NOT PERFORMED / NOT PERFORMED** | STOP перед следующим этапом. RF-испытание требует отдельной постановки и разрешения; VIDEO-006 не начата.