Lab031: evaluate FEC packet interleaving
This commit is contained in:
@@ -117,3 +117,25 @@ git version 2.51.1.windows.1
|
|||||||
- Режим 8+4 оставлен контрольным.
|
- Режим 8+4 оставлен контрольным.
|
||||||
- Подтверждено, что без перемежения продолжительные серии потерь не исправляются.
|
- Подтверждено, что без перемежения продолжительные серии потерь не исправляются.
|
||||||
- Следующая лабораторная посвящена перемежению пакетов.
|
- Следующая лабораторная посвящена перемежению пакетов.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Запись 006
|
||||||
|
|
||||||
|
## Дата
|
||||||
|
|
||||||
|
29 июля 2026 года
|
||||||
|
|
||||||
|
## Тема
|
||||||
|
|
||||||
|
Завершение Lab031: перемежение блоков исправления ошибок.
|
||||||
|
|
||||||
|
## Выполнено
|
||||||
|
|
||||||
|
- Исследовано перемежение блоков исправления ошибок.
|
||||||
|
- Проверены глубины D=1, 2, 4 и 8.
|
||||||
|
- Подтверждено, что глубокое перемежение повышает задержку сильнее, чем полезность для операторского видеопотока.
|
||||||
|
- D=1 оставлен основным режимом.
|
||||||
|
- D=2 сохранён как резервный вариант.
|
||||||
|
- D=4 и D=8 исключены из основной линии разработки.
|
||||||
|
- Следующая лабораторная подбирает размер блока и количество проверочных пакетов.
|
||||||
|
|||||||
BIN
data/processed/lab031/lab031_block_recovery.png
Normal file
BIN
data/processed/lab031/lab031_block_recovery.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 158 KiB |
BIN
data/processed/lab031/lab031_composite_success.png
Normal file
BIN
data/processed/lab031/lab031_composite_success.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
BIN
data/processed/lab031/lab031_depth_tradeoff.png
Normal file
BIN
data/processed/lab031/lab031_depth_tradeoff.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
BIN
data/processed/lab031/lab031_mode_comparison.png
Normal file
BIN
data/processed/lab031/lab031_mode_comparison.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
BIN
data/processed/lab031/lab031_no_image_duration.png
Normal file
BIN
data/processed/lab031/lab031_no_image_duration.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 KiB |
BIN
data/processed/lab031/lab031_publication_delay.png
Normal file
BIN
data/processed/lab031/lab031_publication_delay.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
93
data/processed/lab031/lab031_report.txt
Normal file
93
data/processed/lab031/lab031_report.txt
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
Lab031. Перемежение пакетов между FEC-блоками
|
||||||
|
|
||||||
|
Исходные данные и неизменные слои
|
||||||
|
- Видео: data\raw\lab026_rover_source.mp4
|
||||||
|
- 63 реальных синхронных пар BASE/ROI, 3 fps; длительность источника 20.766667 с.
|
||||||
|
- BASE 240x135 grayscale JPEG Q23; ROI 320x180 grayscale JPEG Q33.
|
||||||
|
- Внутренний транспорт Lab028: payload 512 байт, packet CRC32, object CRC32, атомарная публикация BASE+ROI.
|
||||||
|
- Внешний формат и GF(256) Lab030 используются без изменений; k=8, parity r=2 или r=4.
|
||||||
|
|
||||||
|
Точное правило перестановки
|
||||||
|
- Последовательные готовые FEC-блоки делятся на группы не более D блоков.
|
||||||
|
- Для symbol_index=0,1,2,... передаётся символ с этим индексом блока 0, затем блока 1, ... блока D-1.
|
||||||
|
- Если блок короче, отсутствующий symbol_index пропускается. Внутри блока сохраняется порядок systematic, затем parity.
|
||||||
|
- Перестановка не изменяет байты, block_id или symbol_index и не добавляет пакеты.
|
||||||
|
|
||||||
|
Формирование и буферизация групп
|
||||||
|
- Полная группа D>1 выпускается после готовности D-го последовательного блока; все её пакеты получают это время доступности перед FIFO-передатчиком.
|
||||||
|
- Неполная последняя группа выпускается в момент окончания видеопотока; синтетические блоки и символы не добавляются.
|
||||||
|
- D=1 сохраняет порядок и времена доступности Lab030 и имеет нулевую добавочную задержку ожидания группы.
|
||||||
|
- Размер группы формируется в порядке возрастания block_id; полные группы имеют D блоков, последняя — остаток.
|
||||||
|
- Средний буфер — среднее заполнение после каждого прихода готового блока (1..размер группы); максимум включает момент непосредственно перед выпуском группы.
|
||||||
|
|
||||||
|
Семь фиксированных режимов и статические метрики
|
||||||
|
mode | k+r | D | groups | final group | source/parity packets | outer kbit/s | overhead | wait mean/max s | buffer mean/max | queue mean/max | symbol gap/span ms
|
||||||
|
----:|----:|--:|-------:|------------:|----------------------:|-------------:|---------:|----------------:|----------------:|---------------:|-------------------:
|
||||||
|
Без FEC | none | 1 | 0 | 0 | 862/0 | 168.396 | 6.310% | 0.000000/0.000000 | 0.000/0 | 13.717/15 | 0.000/0.000
|
||||||
|
8+2, D=1 | 8+2 | 1 | 108 | 1 | 862/216 | 226.951 | 30.483% | 0.000000/0.000000 | 1.000/1 | 17.210/21 | 19.547/175.558
|
||||||
|
8+2, D=2 | 8+2 | 2 | 54 | 2 | 862/216 | 226.951 | 30.483% | 0.098765/0.333333 | 1.500/2 | 20.635/38 | 29.178/262.058
|
||||||
|
8+2, D=4 | 8+2 | 4 | 27 | 4 | 862/216 | 226.951 | 30.483% | 0.290123/0.666667 | 2.500/4 | 39.929/40 | 58.283/523.467
|
||||||
|
8+2, D=8 | 8+2 | 8 | 14 | 4 | 862/216 | 226.951 | 30.483% | 0.651852/1.666667 | 4.426/8 | 79.506/80 | 114.400/1027.482
|
||||||
|
8+4, D=1 | 8+4 | 1 | 108 | 1 | 862/431 | 274.659 | 42.558% | 0.000000/0.000000 | 1.000/1 | 20.859/26 | 16.379/179.710
|
||||||
|
8+4, D=4 | 8+4 | 4 | 27 | 4 | 862/431 | 274.659 | 42.558% | 0.290123/0.666667 | 2.500/4 | 51.026/57 | 58.817/645.351
|
||||||
|
|
||||||
|
Временная модель и статистика
|
||||||
|
- Непрерывные чередующиеся экспоненциальные Good/Bad интервалы Lab029B, средняя доля Bad около 2%.
|
||||||
|
- Средние Bad: 10, 50, 200, 1000 мс; 200 повторов на условие; seeds 310310...310313.
|
||||||
|
- Пакет теряется при любом пересечении интервала его передачи с Bad; скорость FIFO 300 кбит/с.
|
||||||
|
- Учитываются фактическая длина каждого внутреннего и внешнего пакета, ожидание группы и накопление очереди.
|
||||||
|
- Приёмник группирует внешние символы по block_id, декодирует после любых k принятых символов и передаёт восстановленные внутренние пакеты в CompositeReassembler.
|
||||||
|
- Соседние composite_frame_id не смешиваются; неполный BASE+ROI кадр не публикуется.
|
||||||
|
|
||||||
|
Результаты при средней Bad 200 мс
|
||||||
|
mode | composite | no-image mean/p95/max s | publication mean/p95/max s | affected blocks | all blocks | unrecoverable | delivered kbit/s | incomplete run mean/p95/max
|
||||||
|
----:|----------:|------------------------:|-------------------------:|----------------:|-----------:|--------------:|----------------:|------------------------:
|
||||||
|
Без FEC | 0.960079 | 0.780292/1.322480/2.001440 | 0.185041/0.203013/0.209680 | 0.000000 | 0.000000 | 0.000000 | 150.735 | 1.393/3.000/5
|
||||||
|
8+2, D=1 | 0.963095 | 0.827615/1.346867/2.032160 | 0.246248/0.275067/0.464720 | 0.152235 | 0.971898 | 0.028102 | 150.452 | 1.520/3.000/5
|
||||||
|
8+2, D=2 | 0.957143 | 1.026629/1.727381/2.670480 | 0.509783/0.670480/0.933093 | 0.225694 | 0.969028 | 0.030972 | 147.820 | 2.134/4.000/7
|
||||||
|
8+2, D=4 | 0.958333 | 1.387432/2.317012/3.306267 | 0.923445/1.134053/1.536720 | 0.408333 | 0.967130 | 0.032870 | 147.993 | 3.017/5.000/10
|
||||||
|
8+2, D=8 | 0.964921 | 2.088808/3.261775/4.919493 | 1.724311/2.252480/2.735360 | 0.644555 | 0.970231 | 0.029769 | 145.481 | 3.946/6.000/10
|
||||||
|
8+4, D=1 | 0.964048 | 0.875715/1.383067/2.062880 | 0.295702/0.336507/0.481920 | 0.247453 | 0.976065 | 0.023935 | 150.049 | 1.647/3.000/5
|
||||||
|
8+4, D=4 | 0.974841 | 1.338860/1.827840/2.774213 | 0.966677/1.152507/1.665707 | 0.669316 | 0.980741 | 0.019259 | 148.676 | 2.805/4.000/7
|
||||||
|
|
||||||
|
Когда 8+2 с перемежением превосходит 8+4 без него
|
||||||
|
- Критерий ниже: строго более высокая доля атомарно восстановленных составных кадров; задержки приведены рядом как цена перемежения.
|
||||||
|
- Bad 50 мс, 8+2, D=4: composite 0.972063 > 0.958175; P95 no-image 1.660629 с против 1.017307 с; P95 публикации 1.150264 с против 0.338693 с.
|
||||||
|
- Bad 50 мс, 8+2, D=8: composite 0.989603 > 0.958175; P95 no-image 2.456107 с против 1.017307 с; P95 публикации 2.271840 с против 0.338693 с.
|
||||||
|
- Bad 200 мс, 8+2, D=8: composite 0.964921 > 0.964048; P95 no-image 3.261775 с против 1.383067 с; P95 публикации 2.252480 с против 0.336507 с.
|
||||||
|
|
||||||
|
Функциональные проверки
|
||||||
|
- PASS d1_matches_lab030: D=1 wire order is byte-identical to Lab030
|
||||||
|
- PASS permutation_preserves_packets: all 1078 packets preserved
|
||||||
|
- PASS each_packet_once: every protected-mode packet appears exactly once
|
||||||
|
- PASS identifiers_preserved: block_id and symbol_index survived permutation
|
||||||
|
- PASS inverse_distribution: inverse grouping passed for D=[2, 4, 8]
|
||||||
|
- PASS decoded_inner_byte_exact: decoded inner packets are byte-exact
|
||||||
|
- PASS inner_outer_crc: outer and recovered Lab028 CRC32 checks passed
|
||||||
|
- PASS zero_bad_100_percent: all seven modes restored 100% of frames without Bad
|
||||||
|
- PASS fixed_seed_reproducibility: identical seed produced identical result fields
|
||||||
|
- PASS atomic_incomplete_composite: missing final ROI fragment prevented publication
|
||||||
|
- PASS depth_increases_symbol_distance: D=1/2/4/8 strictly increase intrablock symbol spacing
|
||||||
|
- PASS group_wait_in_publication_delay: D=4 group wait 0.290123 s is reflected in publication delay
|
||||||
|
- PASS final_partial_group: final 4-block group emitted 38 packets at end of stream
|
||||||
|
|
||||||
|
Допущения модели
|
||||||
|
- Видеопрофиль конечный и детерминированный; JPEG кодируются в памяти один раз перед Monte Carlo.
|
||||||
|
- Устройство знает конец потока и только тогда выпускает неполную последнюю группу D>1.
|
||||||
|
- Время готовности FEC-блока равно максимальному времени генерации его исходных пакетов; вычислительная задержка GF(256) считается нулевой.
|
||||||
|
- D=1 определён как точный режим Lab030; поэтому он не ждёт завершения блока перед отправкой уже готовых systematic symbols.
|
||||||
|
- Передатчик и канал общие FIFO; параллельные радиоканалы, ARQ, повторные передачи, команды, телеметрия, модуляция и реальный SDR не моделируются.
|
||||||
|
- Потеря является стиранием полного внешнего пакета; отдельные битовые ошибки не добавляются.
|
||||||
|
- Publication delay считается от frame_id/3 до конца пакета, завершившего атомарную сборку; no-image включает время до следующего опубликованного кадра или конца расписания.
|
||||||
|
- Intrablock symbol gap измеряется между временами конца последовательных symbol_index; span — от первого до последнего символа блока.
|
||||||
|
|
||||||
|
Артефакты
|
||||||
|
- CSV: data\processed\lab031\lab031_results.csv
|
||||||
|
- Отчёт: data\processed\lab031\lab031_report.txt
|
||||||
|
- Доля восстановленных кадров: data\processed\lab031\lab031_composite_success.png
|
||||||
|
- Отсутствие нового изображения: data\processed\lab031\lab031_no_image_duration.png
|
||||||
|
- Задержка публикации: data\processed\lab031\lab031_publication_delay.png
|
||||||
|
- Доля восстановленных блоков: data\processed\lab031\lab031_block_recovery.png
|
||||||
|
- Устойчивость/задержка от D: data\processed\lab031\lab031_depth_tradeoff.png
|
||||||
|
- Итоговое сравнение: data\processed\lab031\lab031_mode_comparison.png
|
||||||
|
- JPEG, внешние пакеты и бинарные дампы на диск не сохранялись.
|
||||||
29
data/processed/lab031/lab031_results.csv
Normal file
29
data/processed/lab031/lab031_results.csv
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
mode,label,source_block_size,nominal_parity_count,interleaving_depth,mean_bad_duration_ms,mean_good_duration_ms,target_bad_time_fraction,actual_bad_time_fraction,monte_carlo_repetitions,seed,source_jpeg_bitrate_kbps,inner_packet_stream_bitrate_kbps,outer_fec_stream_bitrate_kbps,service_and_parity_percent,control_stream_bitrate_kbps,schedule_duration_seconds,interleaving_group_count,final_group_block_count,mean_group_wait_delay_seconds,p95_group_wait_delay_seconds,max_group_wait_delay_seconds,mean_queue_length_packets,max_queue_length_packets,mean_buffered_blocks,max_buffered_blocks,mean_intrablock_symbol_gap_seconds,mean_intrablock_symbol_span_seconds,max_intrablock_symbol_span_seconds,transmitted_source_packets,transmitted_parity_packets,lost_source_packets,lost_parity_packets,recovered_source_packets,fec_recovered_blocks,fec_unrecoverable_blocks,fec_affected_block_recovery_rate,fec_all_block_success_rate,fec_unrecoverable_block_rate,base_objects_completed,roi_objects_completed,atomic_composite_frames_completed,composite_success_rate,base_only_frames,roi_only_frames,incomplete_frames,effective_delivered_video_bitrate_kbps,mean_publication_delay_seconds,p95_publication_delay_seconds,max_publication_delay_seconds,mean_no_new_image_duration_seconds,p95_no_new_image_duration_seconds,max_no_new_image_duration_seconds,mean_consecutive_incomplete_frames,p95_consecutive_incomplete_frames,max_consecutive_incomplete_frames
|
||||||
|
none,Без FEC,8,0,1,10.0,490.0,0.02,0.019635234668464615,200,310310,157.76975922953451,168.39601926163724,168.39601926163724,6.3102798265039075,300.0,20.869679999999992,0,0,0.0,0.0,0.0,13.7169373549884,15,0.0,0,0.0,0.0,0.0,172400,0,7830,0,0,0,0,0.0,0.0,0.0,10803,9768,8554,0.6788888888888889,2249,1214,4046,106.50128607625994,0.184895562310024,0.20301333333332394,0.20967999999999998,0.8071357862085417,1.3423520000000007,2.6819999999999897,1.4481030780243378,3.0,7
|
||||||
|
8+2_D1,"8+2, D=1",8,2,1,10.0,490.0,0.02,0.01989276611622791,200,310310,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,20.974640000000022,108,1,0.0,0.0,0.0,17.209647495361782,21,1.0,1,0.0195466666666667,0.1755580246913583,0.2513600000000018,172400,43200,8234,2146,5581,4099,951,0.8116831683168317,0.9559722222222222,0.04402777777777778,12107,11879,11591,0.9199206349206349,516,288,1009,143.66791706556094,0.26030441549478167,0.3947733333333314,0.466560000000003,0.7235130475086914,1.0172773333333234,1.8285600000000155,1.1691772885283893,2.0,4
|
||||||
|
8+2_D2,"8+2, D=2",8,2,2,10.0,490.0,0.02,0.020419285815139677,200,310310,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.216053333333374,54,2,0.09876543209876544,0.3333333333333339,0.3333333333333357,20.634508348794064,38,1.5,2,0.029177621993127328,0.2620582716049399,0.27303999999999107,172400,43200,8513,2185,7407,6267,424,0.9366312957704379,0.9803703703703703,0.01962962962962963,12377,12258,12143,0.9637301587301588,234,115,457,148.79314028873705,0.5255043553213112,0.67048,0.9482399999999895,0.7850378666666681,1.1956960000000163,1.693359999999986,1.406153846153846,2.0,4
|
||||||
|
8+2_D4,"8+2, D=4",8,2,4,10.0,490.0,0.02,0.020419285815139677,200,310310,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.216053333333374,27,4,0.29012345679012347,0.666666666666667,0.6666666666666679,39.929499072356215,40,2.5,4,0.05828288659793857,0.5234666666666705,0.5352533333333276,172400,43200,8403,2263,7823,6862,242,0.9659346846846847,0.9887962962962963,0.011203703703703704,12453,12398,12316,0.9774603174603175,137,82,284,150.92200183006048,0.955103273790194,1.1987733333333424,1.5428266666666461,0.7946769333333339,1.3154093333333325,1.825786666666668,1.42,2.0,3
|
||||||
|
8+2_D8,"8+2, D=8",8,2,8,10.0,490.0,0.02,0.019783831729573317,200,310310,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.729893333333457,14,4,0.6518518518518518,1.333333333333334,1.666666666666666,79.50649350649351,80,4.425925925925926,8,0.11440010996563674,1.0274824691358113,1.0638933333334109,172400,43200,8326,2151,7778,6865,228,0.9678556323135485,0.9894444444444445,0.010555555555555556,12465,12402,12335,0.9789682539682539,130,67,265,147.5914653975897,1.7776782315903348,2.299730666666638,2.73535999999996,0.6972641975308679,1.7551626666666769,2.463786666666663,1.402116402116402,2.0,3
|
||||||
|
8+4_D1,"8+4, D=1",8,4,1,10.0,490.0,0.02,0.020272932566179635,200,310310,157.76975922953451,168.39601926163724,274.6586195826645,42.55787075997801,300.0,21.051440000000028,108,1,0.0,0.0,0.0,20.85924207269915,26,1.0,1,0.016378644163150546,0.17971012345679074,0.2513600000000018,172400,86200,8349,4418,7753,4836,157,0.9685559783697176,0.9927314814814815,0.007268518518518519,12505,12460,12416,0.9853968253968254,89,44,184,153.336186028129,0.3085311168384899,0.4101333333333308,0.4960266666666602,0.7172980645161281,1.0115039999999988,1.0841333333333387,1.1870967741935483,2.0,2
|
||||||
|
8+4_D4,"8+4, D=4",8,4,4,10.0,490.0,0.02,0.02028471209220386,200,310310,157.76975922953451,168.39601926163724,274.6586195826645,42.55787075997801,300.0,21.48064000000025,27,4,0.29012345679012347,0.666666666666667,0.6666666666666679,51.02552204176334,57,2.5,4,0.05881681012658274,0.6453511111111162,0.6581333333333261,172400,86200,8379,4498,8345,7029,9,0.9987212276214834,0.9995833333333334,0.0004166666666666667,12593,12593,12589,0.9991269841269841,4,4,11,152.39649470406664,0.9972173421240931,1.2425066666666575,1.6595999999999744,0.6450566666666556,1.2836946666666527,1.5891466666666396,1.375,2.6499999999999995,3
|
||||||
|
none,Без FEC,8,0,1,50.0,2450.0,0.02,0.01904752893886233,200,310311,157.76975922953451,168.39601926163724,168.39601926163724,6.3102798265039075,300.0,20.869679999999992,0,0,0.0,0.0,0.0,13.7169373549884,15,0.0,0,0.0,0.0,0.0,172400,0,4146,0,0,0,0,0.0,0.0,0.0,12068,11771,11478,0.910952380952381,590,293,1122,143.00240540343697,0.1850171179647958,0.20301333333332394,0.20967999999999998,0.695712680514342,1.0000266666666668,1.3480800000000013,1.1097922848664687,2.0,3
|
||||||
|
8+2_D1,"8+2, D=1",8,2,1,50.0,2450.0,0.02,0.019583724988700386,200,310311,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,20.974640000000022,108,1,0.0,0.0,0.0,17.209647495361782,21,1.0,1,0.0195466666666667,0.1755580246913583,0.2513600000000018,172400,43200,4350,1111,964,668,893,0.4279308135810378,0.9586574074074075,0.04134259259259259,12205,11976,11788,0.9355555555555556,417,188,812,146.1207896774389,0.24840877502545095,0.27522666666668627,0.45397333333333023,0.7019893258949336,1.0052693333333333,1.358746666666665,1.1324965132496514,2.0,3
|
||||||
|
8+2_D2,"8+2, D=2",8,2,2,50.0,2450.0,0.02,0.020611137780154415,200,310311,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.216053333333374,54,2,0.09876543209876544,0.3333333333333339,0.3333333333333357,20.634508348794064,38,1.5,2,0.029177621993127328,0.2620582716049399,0.27303999999999107,172400,43200,4525,1128,1855,1386,762,0.6452513966480447,0.9647222222222223,0.035277777777777776,12202,12084,11923,0.9462698412698413,279,161,677,146.11615606798344,0.5131737180239886,0.67048,0.9482399999999895,0.8504971698113227,1.2140000000000006,2.1241066666666635,1.596698113207547,2.0,4
|
||||||
|
8+2_D4,"8+2, D=4",8,2,4,50.0,2450.0,0.02,0.020611137780154415,200,310311,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.216053333333374,27,4,0.29012345679012347,0.666666666666667,0.6666666666666679,39.929499072356215,40,2.5,4,0.05828288659793857,0.5234666666666705,0.5352533333333276,172400,43200,4598,1155,3293,2645,445,0.8559870550161812,0.9793981481481482,0.02060185185185185,12377,12308,12248,0.9720634920634921,129,60,352,150.10497334094154,0.9336452906597018,1.1502639999999997,1.5428266666666461,1.0794554732510333,1.6606293333333362,3.3212533333333107,2.1728395061728394,3.0,8
|
||||||
|
8+2_D8,"8+2, D=8",8,2,8,50.0,2450.0,0.02,0.019261484934125217,200,310311,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.729893333333457,14,4,0.6518518518518518,1.333333333333334,1.666666666666666,79.50649350649351,80,4.425925925925926,8,0.11440010996563674,1.0274824691358113,1.0638933333334109,172400,43200,4342,1090,3932,3450,161,0.9554140127388535,0.9925462962962963,0.007453703703703704,12508,12491,12469,0.9896031746031746,39,22,131,149.20466429655653,1.7412040548560521,2.271839999999967,2.73535999999996,1.0850114553990724,2.4561066666666633,3.22338666666667,1.8450704225352113,5.0,6
|
||||||
|
8+4_D1,"8+4, D=1",8,4,1,50.0,2450.0,0.02,0.019588623960636035,200,310311,157.76975922953451,168.39601926163724,274.6586195826645,42.55787075997801,300.0,21.051440000000028,108,1,0.0,0.0,0.0,20.85924207269915,26,1.0,1,0.016378644163150546,0.17971012345679074,0.2513600000000018,172400,86200,4310,2179,2061,996,474,0.6775510204081633,0.9780555555555556,0.021944444444444444,12327,12214,12073,0.9581746031746031,254,141,527,149.08571005118867,0.29811151495071847,0.3386933333333566,0.49543999999999855,0.738907046714174,1.017306666666654,1.3934133333333296,1.2517814726840855,2.0,3
|
||||||
|
8+4_D4,"8+4, D=4",8,4,4,50.0,2450.0,0.02,0.018896970593780017,200,310311,157.76975922953451,168.39601926163724,274.6586195826645,42.55787075997801,300.0,21.48064000000025,27,4,0.29012345679012347,0.666666666666667,0.6666666666666679,51.02552204176334,57,2.5,4,0.05881681012658274,0.6453511111111162,0.6581333333333261,172400,86200,4201,2094,3982,2847,49,0.9830801104972375,0.9977314814814815,0.0022685185185185187,12572,12563,12555,0.9964285714285714,17,8,45,151.98650878185947,0.9761674020974541,1.2002133333333127,1.6510666666666776,1.098252631578969,1.6198666666666914,1.6359466666666824,2.3684210526315788,4.0,4
|
||||||
|
none,Без FEC,8,0,1,200.0,9800.0,0.02,0.021768052926612245,200,310312,157.76975922953451,168.39601926163724,168.39601926163724,6.3102798265039075,300.0,20.869679999999992,0,0,0.0,0.0,0.0,13.7169373549884,15,0.0,0,0.0,0.0,0.0,172400,0,3950,0,0,0,0,0.0,0.0,0.0,12258,12177,12097,0.9600793650793651,161,80,503,150.73476737544615,0.18504139318287638,0.20301333333332394,0.20967999999999998,0.7802921514312094,1.3224799999999997,2.001439999999989,1.3933518005540166,3.0,5
|
||||||
|
8+2_D1,"8+2, D=1",8,2,1,200.0,9800.0,0.02,0.019093901593380775,200,310312,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,20.974640000000022,108,1,0.0,0.0,0.0,17.209647495361782,21,1.0,1,0.0195466666666667,0.1755580246913583,0.2513600000000018,172400,43200,3550,907,161,109,607,0.15223463687150837,0.9718981481481481,0.028101851851851854,12292,12214,12135,0.9630952380952381,157,79,465,150.45183707563024,0.24624820546628343,0.27506666666666346,0.4647199999999989,0.8276151633986941,1.3468666666666853,2.0321599999999878,1.5196078431372548,3.0,5
|
||||||
|
8+2_D2,"8+2, D=2",8,2,2,200.0,9800.0,0.02,0.019876605364394936,200,310312,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.216053333333374,54,2,0.09876543209876544,0.3333333333333339,0.3333333333333357,20.634508348794064,38,1.5,2,0.029177621993127328,0.2620582716049399,0.27303999999999107,172400,43200,3716,939,289,195,669,0.22569444444444445,0.9690277777777778,0.030972222222222224,12233,12146,12060,0.9571428571428572,173,86,540,147.81991309725186,0.5097829695964634,0.67048,0.9330933333333231,1.0266287220026378,1.7273813333333339,2.67048,2.1343873517786562,4.0,7
|
||||||
|
8+2_D4,"8+2, D=4",8,2,4,200.0,9800.0,0.02,0.019876605364394936,200,310312,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.216053333333374,27,4,0.29012345679012347,0.666666666666667,0.6666666666666679,39.929499072356215,40,2.5,4,0.05828288659793857,0.5234666666666705,0.5352533333333276,172400,43200,3501,985,669,490,710,0.4083333333333333,0.9671296296296297,0.03287037037037037,12225,12144,12075,0.9583333333333334,150,69,525,147.99297450232626,0.9234452472049709,1.1340533333333287,1.5367199999999794,1.3874324904214599,2.3170120000000005,3.306266666666649,3.0172413793103448,5.0,10
|
||||||
|
8+2_D8,"8+2, D=8",8,2,8,200.0,9800.0,0.02,0.020349130050647177,200,310312,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.729893333333457,14,4,0.6518518518518518,1.333333333333334,1.666666666666666,79.50649350649351,80,4.425925925925926,8,0.11440010996563674,1.0274824691358113,1.0638933333334109,172400,43200,3769,942,1577,1166,643,0.6445550027639579,0.9702314814814815,0.029768518518518517,12263,12201,12158,0.964920634920635,105,43,442,145.48062208619442,1.7243108340187623,2.252479999999979,2.73535999999996,2.0888080952381114,3.261774666666647,4.919493333333319,3.9464285714285716,6.0,10
|
||||||
|
8+4_D1,"8+4, D=1",8,4,1,200.0,9800.0,0.02,0.019604503383780177,200,310312,157.76975922953451,168.39601926163724,274.6586195826645,42.55787075997801,300.0,21.051440000000028,108,1,0.0,0.0,0.0,20.85924207269915,26,1.0,1,0.016378644163150546,0.17971012345679074,0.2513600000000018,172400,86200,3604,1812,413,170,517,0.24745269286754004,0.9760648148148148,0.023935185185185184,12296,12229,12147,0.964047619047619,149,82,453,150.0487852612456,0.295702434071515,0.33650666666666273,0.48192000000000323,0.8757147151515156,1.3830666666666662,2.0628799999999847,1.6472727272727272,3.0,5
|
||||||
|
8+4_D4,"8+4, D=4",8,4,4,200.0,9800.0,0.02,0.02040848762305882,200,310312,157.76975922953451,168.39601926163724,274.6586195826645,42.55787075997801,300.0,21.48064000000025,27,4,0.29012345679012347,0.666666666666667,0.6666666666666679,51.02552204176334,57,2.5,4,0.05881681012658274,0.6453511111111162,0.6581333333333261,172400,86200,3708,1890,1660,842,416,0.6693163751987281,0.9807407407407407,0.01925925925925926,12361,12328,12283,0.9748412698412698,78,45,317,148.67567260565622,0.9666773524383458,1.1525066666667954,1.6657066666666411,1.3388604129793618,1.827840000000003,2.7742133333332575,2.8053097345132745,4.0,7
|
||||||
|
none,Без FEC,8,0,1,1000.0,49000.0,0.02,0.02189344857431169,200,310313,157.76975922953451,168.39601926163724,168.39601926163724,6.3102798265039075,300.0,20.869679999999992,0,0,0.0,0.0,0.0,13.7169373549884,15,0.0,0,0.0,0.0,0.0,172400,0,3802,0,0,0,0,0.0,0.0,0.0,12305,12289,12269,0.9737301587301588,36,20,331,152.87799908767172,0.18504089113483205,0.20301333333332394,0.20967999999999998,1.468867087719298,3.339362666666659,3.6820266666666566,3.4842105263157896,9.0,10
|
||||||
|
8+2_D1,"8+2, D=1",8,2,1,1000.0,49000.0,0.02,0.02188397349572346,200,310313,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,20.974640000000022,108,1,0.0,0.0,0.0,17.209647495361782,21,1.0,1,0.0195466666666667,0.1755580246913583,0.2513600000000018,172400,43200,3809,957,36,26,522,0.04744525547445255,0.9758333333333333,0.024166666666666666,12303,12284,12260,0.973015873015873,43,24,340,152.00213400563712,0.24599688961392194,0.27506666666666346,0.43664000000000414,1.5143336170212773,3.4397426666666786,4.036026666666666,3.617021276595745,9.349999999999994,11
|
||||||
|
8+2_D2,"8+2, D=2",8,2,2,1000.0,49000.0,0.02,0.022829618385024127,200,310313,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.216053333333374,54,2,0.09876543209876544,0.3333333333333339,0.3333333333333357,20.634508348794064,38,1.5,2,0.029177621993127328,0.2620582716049399,0.27303999999999107,172400,43200,3980,1016,69,46,557,0.07628524046434494,0.974212962962963,0.025787037037037035,12276,12253,12230,0.9706349206349206,46,23,370,149.90435921478297,0.5096241548105763,0.67048,0.9282666666666639,1.7479460606060633,3.630441333333325,4.003600000000002,4.204545454545454,10.0,11
|
||||||
|
8+2_D4,"8+2, D=4",8,2,4,1000.0,49000.0,0.02,0.022829618385024127,200,310313,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.216053333333374,27,4,0.29012345679012347,0.666666666666667,0.6666666666666679,39.929499072356215,40,2.5,4,0.05828288659793857,0.5234666666666705,0.5352533333333276,172400,43200,4007,1050,98,77,615,0.11127167630057803,0.9715277777777778,0.02847222222222222,12259,12218,12198,0.9680952380952381,61,20,402,149.49624183951244,0.9220254096299959,1.1219999999999963,1.4781066666666742,2.195163636363639,4.007194666666669,5.646800000000001,5.220779220779221,10.0,15
|
||||||
|
8+2_D8,"8+2, D=8",8,2,8,1000.0,49000.0,0.02,0.022771430179993328,200,310313,157.76975922953451,168.39601926163724,226.95139646869984,30.4830189704105,300.0,21.729893333333457,14,4,0.6518518518518518,1.333333333333334,1.666666666666666,79.50649350649351,80,4.425925925925926,8,0.11440010996563674,1.0274824691358113,1.0638933333334109,172400,43200,4017,1006,164,121,696,0.1481028151774786,0.9677777777777777,0.03222222222222222,12214,12171,12157,0.9648412698412698,57,14,443,145.4897597288397,1.7153148156069298,2.1772533333333026,2.73535999999996,3.137030303030318,4.9471199999999556,7.46471999999997,6.712121212121212,11.75,19
|
||||||
|
8+4_D1,"8+4, D=1",8,4,1,1000.0,49000.0,0.02,0.02223910448390382,200,310313,157.76975922953451,168.39601926163724,274.6586195826645,42.55787075997801,300.0,21.051440000000028,108,1,0.0,0.0,0.0,20.85924207269915,26,1.0,1,0.016378644163150546,0.17971012345679074,0.2513600000000018,172400,86200,3857,1938,68,29,507,0.054104477611940295,0.9765277777777778,0.02347222222222222,12299,12278,12246,0.9719047619047619,53,32,354,151.28060028197575,0.2955365735750469,0.33650666666666273,0.34253333333332137,1.566540709219859,3.4289906666666816,4.075946666666653,3.765957446808511,9.349999999999994,11
|
||||||
|
8+4_D4,"8+4, D=4",8,4,4,1000.0,49000.0,0.02,0.023171676201598494,200,310313,157.76975922953451,168.39601926163724,274.6586195826645,42.55787075997801,300.0,21.48064000000025,27,4,0.29012345679012347,0.666666666666667,0.6666666666666679,51.02552204176334,57,2.5,4,0.05881681012658274,0.6453511111111162,0.6581333333333261,172400,86200,4013,2044,279,134,568,0.1908831908831909,0.9737037037037037,0.026296296296296297,12272,12248,12223,0.9700793650793651,49,25,377,147.95045399019597,0.9617925004772583,1.1378933333333352,1.6425333333333096,2.2056548356807713,4.033480000000006,5.626773333333361,5.309859154929577,10.0,16
|
||||||
|
178
protocol/fec_interleaver.py
Normal file
178
protocol/fec_interleaver.py
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
"""
|
||||||
|
Packet interleaving for consecutive packet-erasure FEC blocks.
|
||||||
|
|
||||||
|
The interleaver is deliberately independent from GF(256). It accepts fully
|
||||||
|
encoded outer symbols from ``packet_erasure_fec`` and only changes their wire
|
||||||
|
order. A group contains up to ``depth`` consecutive blocks. Symbols are
|
||||||
|
emitted by symbol index across the blocks:
|
||||||
|
|
||||||
|
block0[0], block1[0], ..., block0[1], block1[1], ...
|
||||||
|
|
||||||
|
If a block is shorter than the others, its missing symbol index is skipped.
|
||||||
|
No packet is added, removed, or modified.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
from protocol.packet_erasure_fec import (
|
||||||
|
OuterSymbol,
|
||||||
|
decode_outer_symbol,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InterleaverError(ValueError):
|
||||||
|
"""An interleaving group or outer-symbol sequence is inconsistent."""
|
||||||
|
|
||||||
|
|
||||||
|
def _decode_block(
|
||||||
|
wire_block: Sequence[bytes],
|
||||||
|
) -> tuple[int, tuple[bytes, ...], tuple[OuterSymbol, ...]]:
|
||||||
|
if not wire_block:
|
||||||
|
raise InterleaverError("FEC block is empty")
|
||||||
|
|
||||||
|
packets = tuple(wire_block)
|
||||||
|
symbols = tuple(decode_outer_symbol(packet) for packet in packets)
|
||||||
|
first = symbols[0]
|
||||||
|
expected_count = first.source_count + first.parity_count
|
||||||
|
if len(symbols) != expected_count:
|
||||||
|
raise InterleaverError(
|
||||||
|
f"block {first.block_id} has {len(symbols)} symbols, "
|
||||||
|
f"expected {expected_count}"
|
||||||
|
)
|
||||||
|
metadata = (
|
||||||
|
first.block_id,
|
||||||
|
first.source_count,
|
||||||
|
first.parity_count,
|
||||||
|
first.symbol_size,
|
||||||
|
)
|
||||||
|
for expected_index, symbol in enumerate(symbols):
|
||||||
|
current = (
|
||||||
|
symbol.block_id,
|
||||||
|
symbol.source_count,
|
||||||
|
symbol.parity_count,
|
||||||
|
symbol.symbol_size,
|
||||||
|
)
|
||||||
|
if current != metadata:
|
||||||
|
raise InterleaverError("outer symbols have inconsistent metadata")
|
||||||
|
if symbol.symbol_index != expected_index:
|
||||||
|
raise InterleaverError(
|
||||||
|
f"block {first.block_id} is not in symbol-index order"
|
||||||
|
)
|
||||||
|
return first.block_id, packets, symbols
|
||||||
|
|
||||||
|
|
||||||
|
def interleave_group(
|
||||||
|
wire_blocks: Sequence[Sequence[bytes]],
|
||||||
|
) -> tuple[bytes, ...]:
|
||||||
|
"""
|
||||||
|
Interleave one non-empty group of complete consecutive FEC blocks.
|
||||||
|
|
||||||
|
Source symbols remain before parity symbols inside every individual block
|
||||||
|
because each block is traversed by increasing ``symbol_index``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not wire_blocks:
|
||||||
|
raise InterleaverError("interleaving group is empty")
|
||||||
|
|
||||||
|
decoded = tuple(_decode_block(block) for block in wire_blocks)
|
||||||
|
block_ids = tuple(item[0] for item in decoded)
|
||||||
|
if len(set(block_ids)) != len(block_ids):
|
||||||
|
raise InterleaverError("interleaving group repeats a block_id")
|
||||||
|
if any(
|
||||||
|
right != left + 1
|
||||||
|
for left, right in zip(block_ids, block_ids[1:])
|
||||||
|
):
|
||||||
|
raise InterleaverError("FEC blocks are not consecutive")
|
||||||
|
|
||||||
|
packets_by_block = tuple(item[1] for item in decoded)
|
||||||
|
maximum_symbols = max(len(block) for block in packets_by_block)
|
||||||
|
return tuple(
|
||||||
|
block[symbol_index]
|
||||||
|
for symbol_index in range(maximum_symbols)
|
||||||
|
for block in packets_by_block
|
||||||
|
if symbol_index < len(block)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def interleave_blocks(
|
||||||
|
wire_blocks: Sequence[Sequence[bytes]],
|
||||||
|
depth: int,
|
||||||
|
) -> tuple[bytes, ...]:
|
||||||
|
"""
|
||||||
|
Interleave a stream in groups of ``depth`` blocks.
|
||||||
|
|
||||||
|
The final group may contain fewer than ``depth`` blocks and is emitted
|
||||||
|
without synthetic padding.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not isinstance(depth, int) or isinstance(depth, bool) or depth < 1:
|
||||||
|
raise ValueError("interleaving depth must be a positive integer")
|
||||||
|
blocks = tuple(tuple(block) for block in wire_blocks)
|
||||||
|
if not blocks:
|
||||||
|
return ()
|
||||||
|
|
||||||
|
block_ids = tuple(_decode_block(block)[0] for block in blocks)
|
||||||
|
if any(
|
||||||
|
right != left + 1
|
||||||
|
for left, right in zip(block_ids, block_ids[1:])
|
||||||
|
):
|
||||||
|
raise InterleaverError("FEC block stream is not consecutive")
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for start in range(0, len(blocks), depth):
|
||||||
|
group = blocks[start:start + depth]
|
||||||
|
result.extend(interleave_group(group))
|
||||||
|
return tuple(result)
|
||||||
|
|
||||||
|
|
||||||
|
def deinterleave_symbols(
|
||||||
|
wire_symbols: Sequence[bytes],
|
||||||
|
) -> tuple[tuple[bytes, ...], ...]:
|
||||||
|
"""
|
||||||
|
Group received symbols by ``block_id`` and restore symbol-index order.
|
||||||
|
|
||||||
|
Lost symbols are simply absent, so the returned blocks may be incomplete.
|
||||||
|
Blocks are returned in first-seen order. A conflicting duplicate symbol
|
||||||
|
is rejected; a byte-identical duplicate is retained only once.
|
||||||
|
"""
|
||||||
|
|
||||||
|
block_order = []
|
||||||
|
grouped: dict[int, dict[int, bytes]] = {}
|
||||||
|
metadata: dict[int, tuple[int, int, int]] = {}
|
||||||
|
for wire_packet in wire_symbols:
|
||||||
|
symbol = decode_outer_symbol(wire_packet)
|
||||||
|
if symbol.block_id not in grouped:
|
||||||
|
block_order.append(symbol.block_id)
|
||||||
|
grouped[symbol.block_id] = {}
|
||||||
|
metadata[symbol.block_id] = (
|
||||||
|
symbol.source_count,
|
||||||
|
symbol.parity_count,
|
||||||
|
symbol.symbol_size,
|
||||||
|
)
|
||||||
|
current_metadata = (
|
||||||
|
symbol.source_count,
|
||||||
|
symbol.parity_count,
|
||||||
|
symbol.symbol_size,
|
||||||
|
)
|
||||||
|
if current_metadata != metadata[symbol.block_id]:
|
||||||
|
raise InterleaverError(
|
||||||
|
f"block {symbol.block_id} metadata changed"
|
||||||
|
)
|
||||||
|
existing = grouped[symbol.block_id].get(symbol.symbol_index)
|
||||||
|
if existing is not None and existing != wire_packet:
|
||||||
|
raise InterleaverError(
|
||||||
|
f"conflicting duplicate block={symbol.block_id}, "
|
||||||
|
f"symbol={symbol.symbol_index}"
|
||||||
|
)
|
||||||
|
grouped[symbol.block_id][symbol.symbol_index] = wire_packet
|
||||||
|
|
||||||
|
return tuple(
|
||||||
|
tuple(
|
||||||
|
symbols[index]
|
||||||
|
for index in sorted(symbols)
|
||||||
|
)
|
||||||
|
for block_id in block_order
|
||||||
|
for symbols in (grouped[block_id],)
|
||||||
|
)
|
||||||
1576
tests/lab031_fec_interleaving.py
Normal file
1576
tests/lab031_fec_interleaving.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user