Compare commits

...

11 Commits

Author SHA1 Message Date
LittleSam129
3dbb7afa83 Lab032: evaluate FEC block parameters 2026-07-29 12:47:10 +03:00
LittleSam129
2ac1571c40 Lab031: evaluate FEC packet interleaving 2026-07-29 12:25:51 +03:00
LittleSam129
edab87b5d2 Lab030: add packet erasure FEC 2026-07-29 11:40:37 +03:00
LittleSam129
f8575f4de3 Lab029B: simulate time-based burst losses 2026-07-27 16:28:54 +03:00
LittleSam129
a2dd58a44b Lab029: simulate packet loss and channel errors 2026-07-27 15:29:39 +03:00
LittleSam129
04ce66fdfe Lab028: add video packetization and CRC reassembly 2026-07-27 13:46:01 +03:00
LittleSam129
78258b5355 Lab027: optimize synchronized ROI video stream 2026-07-24 17:54:27 +03:00
LittleSam129
6d49036066 Lab026: benchmark low-bitrate video and 4-bit encoding 2026-07-24 11:56:41 +03:00
LittleSam129
557b082f2b lab025_wfm_audio_100_1mhz 2026-07-22 17:29:07 +03:00
LittleSam129
f3a11b29b3 Merge branch 'repair/project-layout' 2026-07-22 14:20:11 +03:00
LittleSam129
35cb25fccc Create lab024a_pluto_rx_100mhz.npy 2026-07-22 11:24:05 +03:00
86 changed files with 23325 additions and 1 deletions

View File

@@ -33,3 +33,133 @@
```text ```text
git version 2.51.1.windows.1 git version 2.51.1.windows.1
```
---
# Запись 002
## Дата
27 июля 2026 года
## Тема
Завершение Lab028: пакетирование синхронного BASE + ROI.
## Выполнено
- Реализован фиксированный бинарный заголовок размером 32 байта.
- Добавлены packet CRC32 для заголовка и payload и object CRC32 для полного JPEG.
- Исследованы размеры payload 64, 128, 256, 512 и 1024 байта.
- Размер payload 512 байт принят как рабочий кандидат.
- Окончательный выбор размера пакета перенесён в Lab029.
---
# Запись 003
## Дата
27 июля 2026 года
## Тема
Завершение Lab029: моделирование потерь и ошибок видеопакетов.
## Выполнено
- Исследованы независимые потери пакетов и независимые битовые ошибки.
- Проверены короткие, средние и длинные серии потерь по модели GilbertElliott.
- Выполнено сравнение payload 256, 512 и 1024 байта.
- Подтверждены packet CRC32, изоляция соседних кадров и атомарная сборка BASE + ROI.
- Зафиксировано ограничение пакетной временной шкалы Lab029.
- Сравнение помех одинаковой физической длительности перенесено в Lab029B.
---
# Запись 004
## Дата
27 июля 2026 года
## Тема
Завершение Lab029B: временная модель серийных потерь.
## Выполнено
- Помехи смоделированы на непрерывной временной шкале.
- Контрольная скорость передачи установлена равной 300 кбит/с.
- Исследованы средние длительности Bad 10, 50, 200 и 1000 мс.
- Payload 512 байт выбран для дальнейшей разработки.
- Payload 1024 байта оставлен резервным вариантом.
- Подтверждено, что без исправления ошибок возможны длительные прерывания видеопотока.
---
# Запись 005
## Дата
29 июля 2026 года
## Тема
Завершение Lab030: блочное исправление стираний.
## Выполнено
- Реализовано блочное исправление стираний над GF(256).
- Проверены режимы без исправления, 8+1, 8+2 и 8+4.
- Режим 8+2 выбран основным рабочим режимом.
- Режим 8+4 оставлен контрольным.
- Подтверждено, что без перемежения продолжительные серии потерь не исправляются.
- Следующая лабораторная посвящена перемежению пакетов.
---
# Запись 006
## Дата
29 июля 2026 года
## Тема
Завершение Lab031: перемежение блоков исправления ошибок.
## Выполнено
- Исследовано перемежение блоков исправления ошибок.
- Проверены глубины D=1, 2, 4 и 8.
- Подтверждено, что глубокое перемежение повышает задержку сильнее, чем полезность для операторского видеопотока.
- D=1 оставлен основным режимом.
- D=2 сохранён как резервный вариант.
- D=4 и D=8 исключены из основной линии разработки.
- Следующая лабораторная подбирает размер блока и количество проверочных пакетов.
---
# Запись 007
## Дата
29 июля 2026 года
## Тема
Завершение Lab032: параметры блочного исправления потерянных пакетов.
## Выполнено
- Исследованы параметры блочного исправления потерянных пакетов.
- Сравнивались режимы без исправления, 4+1, 8+2, 12+3, 6+2, 8+3, 4+2 и 8+4.
- Режим 12+3 выбран основным.
- Его транспортный поток составляет 226,951 кбит/с.
- Запас до контрольных 300 кбит/с составляет 73,049 кбит/с.
- Режим 8+4 оставлен усиленным экспериментальным вариантом.
- Режим 8+3 не принят из-за отсутствия устойчивого преимущества.
- Подтверждено, что продолжительные помехи нельзя компенсировать только увеличением числа проверочных пакетов.
- Следующий этап посвящён совместной передаче команд, телеметрии и видео с приоритетным обслуживанием.

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

View File

@@ -0,0 +1,29 @@
Lab025. Приём и программная WFM-демодуляция
URI Pluto+: ip:192.168.2.1
Частота станции: 100100000 Гц
RX LO: 100350000 Гц
Цифровое смещение: +250000 Гц
Частота дискретизации RX: 2400000 Гц
Полоса RX: 1500000 Гц
Количество рабочих буферов: 128
Количество IQ-сэмплов: 8388608
Длительность IQ-записи: 3.495253 с
Частота канального сигнала после децимации: 240000 Гц
Длительность итогового WAV: 3.445250 с
Частота WAV: 48000 Гц
Тип PCM: signed PCM16, mono
RMS итогового аудио: 0.389148
Пиковая амплитуда: 0.974792
Отсчёты на границе PCM16: 0.000000 %
Выходные файлы:
WAV: data\processed\lab025\lab025_wfm_audio_100_1mhz.wav
Радиоспектр: data\processed\lab025\lab025_rf_spectrum.png
Звуковая волна: data\processed\lab025\lab025_audio_waveform.png
Спектр звука: data\processed\lab025\lab025_audio_spectrum.png
Отчёт: data\processed\lab025\lab025_report.txt
Использован только приёмный канал RX1.
Передатчики TX1 и TX2 не использовались.
Необработанные IQ-сэмплы на диск не сохранялись.

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@@ -0,0 +1,33 @@
experiment,profile_name,width,height,target_fps,actual_fps,color_mode,jpeg_quality,source_duration_s,selected_frames,total_bytes,mean_frame_bytes,median_frame_bytes,p95_frame_bytes,max_frame_bytes,payload_bitrate_bps,payload_bitrate_kbps,source_file_bitrate_kbps,reduction_ratio,percent_of_source,mean_psnr_db
fps_sweep,fps_30,640,360,30.000000,30.000000,grayscale,50,20.766667,623,10219569,16403.803,16282.000,18471.500,21081,3936912.616,3936.912616,3001.342536,0.762359,131.171720,37.349661
fps_sweep,fps_10,640,360,10.000000,10.016051,grayscale,50,20.766667,208,3641634,17507.856,17509.500,18958.400,21081,1402876.661,1402.876661,3001.342536,2.139420,46.741638,36.369592
fps_sweep,fps_5,640,360,5.000000,5.008026,grayscale,50,20.766667,104,1822387,17522.952,17547.000,18910.400,21081,702043.146,702.043146,3001.342536,4.275154,23.390970,36.352519
fps_sweep,fps_2,640,360,2.000000,2.022472,grayscale,50,20.766667,42,737435,17557.976,17476.500,18926.800,21081,284084.109,284.084109,3001.342536,10.564979,9.465234,36.319782
fps_sweep,fps_1,640,360,1.000000,1.011236,grayscale,50,20.766667,21,369317,17586.524,17483.000,18935.000,21081,142273.002,142.273002,3001.342536,21.095658,4.740312,36.287711
fps_sweep,fps_0_5,640,360,0.500000,0.529695,grayscale,50,20.766667,11,191626,17420.545,17040.000,19774.000,21081,73820.610,73.820610,3001.342536,40.657244,2.459586,36.371684
fps_sweep,fps_0_2,640,360,0.200000,0.240770,grayscale,50,20.766667,5,91496,18299.200,18467.000,20651.800,21081,35247.255,35.247255,3001.342536,85.151100,1.174383,35.860330
resolution_sweep,resolution_1280x720,1280,720,5.000000,5.008026,grayscale,50,20.766667,104,5506628,52948.346,52634.000,57821.150,73994,2121333.419,2121.333419,3001.342536,1.414838,70.679484,39.607731
resolution_sweep,resolution_960x540,960,540,5.000000,5.008026,grayscale,50,20.766667,104,3411900,32806.731,32634.500,35501.600,41897,1314375.602,1314.375602,3001.342536,2.283474,43.792922,38.632041
resolution_sweep,resolution_640x360,640,360,5.000000,5.008026,grayscale,50,20.766667,104,1822387,17522.952,17547.000,18910.400,21081,702043.146,702.043146,3001.342536,4.275154,23.390970,36.352519
resolution_sweep,resolution_480x270,480,270,5.000000,5.008026,grayscale,50,20.766667,104,1120944,10778.308,10786.000,11463.200,12395,431824.334,431.824334,3001.342536,6.950378,14.387706,36.172087
resolution_sweep,resolution_320x180,320,180,5.000000,5.008026,grayscale,50,20.766667,104,590018,5673.250,5679.000,5995.750,6191,227294.254,227.294254,3001.342536,13.204656,7.573086,35.069392
resolution_sweep,resolution_160x90,160,90,5.000000,5.008026,grayscale,50,20.766667,104,210050,2019.712,2017.000,2103.400,2156,80918.138,80.918138,3001.342536,37.091097,2.696065,33.585930
quality_sweep,quality_color_q90,640,360,5.000000,5.008026,color,90,20.766667,104,5486654,52756.288,52645.500,57012.750,66227,2113638.780,2113.638780,3001.342536,1.419988,70.423111,39.694424
quality_sweep,quality_color_q70,640,360,5.000000,5.008026,color,70,20.766667,104,2901304,27897.154,27815.500,30080.600,33877,1117677.303,1117.677303,3001.342536,2.685339,37.239245,36.029412
quality_sweep,quality_color_q50,640,360,5.000000,5.008026,color,50,20.766667,104,2137169,20549.702,20514.000,22026.250,24396,823307.480,823.307480,3001.342536,3.645470,27.431307,34.439250
quality_sweep,quality_color_q30,640,360,5.000000,5.008026,color,30,20.766667,104,1572112,15116.462,15105.500,16167.600,17386,605629.021,605.629021,3001.342536,4.955744,20.178604,32.766254
quality_sweep,quality_color_q20,640,360,5.000000,5.008026,color,20,20.766667,104,1224535,11774.375,11797.000,12633.050,13098,471730.979,471.730979,3001.342536,6.362403,15.717332,31.298703
quality_sweep,quality_grayscale_q90,640,360,5.000000,5.008026,grayscale,90,20.766667,104,4697004,45163.500,44959.000,48937.750,57535,1809439.743,1809.439743,3001.342536,1.658714,60.287679,42.574562
quality_sweep,quality_grayscale_q70,640,360,5.000000,5.008026,grayscale,70,20.766667,104,2484781,23892.125,23853.000,25744.950,29385,957219.005,957.219005,3001.342536,3.135482,31.893028,38.031656
quality_sweep,quality_grayscale_q50,640,360,5.000000,5.008026,grayscale,50,20.766667,104,1822387,17522.952,17547.000,18910.400,21081,702043.146,702.043146,3001.342536,4.275154,23.390970,36.352519
quality_sweep,quality_grayscale_q30,640,360,5.000000,5.008026,grayscale,30,20.766667,104,1328179,12770.952,12821.500,13834.150,14903,511658.042,511.658042,3001.342536,5.865915,17.047639,34.701951
quality_sweep,quality_grayscale_q20,640,360,5.000000,5.008026,grayscale,20,20.766667,104,1017957,9788.048,9832.500,10597.450,11027,392150.369,392.150369,3001.342536,7.653550,13.065832,33.304362
candidate_profiles,candidate_640x360_gray_5fps_q50,640,360,5.000000,5.008026,grayscale,50,20.766667,104,1822387,17522.952,17547.000,18910.400,21081,702043.146,702.043146,3001.342536,4.275154,23.390970,36.352519
candidate_profiles,candidate_640x360_gray_2fps_q40,640,360,2.000000,2.022472,grayscale,40,20.766667,42,639531,15226.929,15187.500,16381.750,18122,246368.283,246.368283,3001.342536,12.182341,8.208603,35.588581
candidate_profiles,candidate_320x180_color_5fps_q50,320,180,5.000000,5.008026,color,50,20.766667,104,717676,6900.731,6919.500,7309.850,7475,276472.295,276.472295,3001.342536,10.855853,9.211621,32.413850
candidate_profiles,candidate_320x180_gray_5fps_q50,320,180,5.000000,5.008026,grayscale,50,20.766667,104,590018,5673.250,5679.000,5995.750,6191,227294.254,227.294254,3001.342536,13.204656,7.573086,35.069392
candidate_profiles,candidate_320x180_gray_2fps_q40,320,180,2.000000,2.022472,grayscale,40,20.766667,42,208403,4961.976,4965.000,5224.700,5400,80283.660,80.283660,3001.342536,37.384227,2.674925,34.362114
candidate_profiles,candidate_320x180_gray_1fps_q35,320,180,1.000000,1.011236,grayscale,35,20.766667,21,96733,4606.333,4611.000,4836.000,4992,37264.719,37.264719,3001.342536,80.541129,1.241602,34.035117
candidate_profiles,candidate_320x180_gray_0_5fps_q35,320,180,0.500000,0.529695,grayscale,35,20.766667,11,50124,4556.727,4493.000,4914.000,4992,19309.406,19.309406,3001.342536,155.434223,0.643359,34.165852
candidate_profiles,candidate_320x180_gray_0_2fps_q35,320,180,0.200000,0.240770,grayscale,35,20.766667,5,23618,4723.600,4815.000,4960.800,4992,9098.427,9.098427,3001.342536,329.874884,0.303145,33.741044
candidate_profiles,candidate_160x90_gray_1fps_q30,160,90,1.000000,1.011236,grayscale,30,20.766667,21,32743,1559.190,1561.000,1623.000,1632,12613.676,12.613676,3001.342536,237.943530,0.420268,32.031480
1 experiment profile_name width height target_fps actual_fps color_mode jpeg_quality source_duration_s selected_frames total_bytes mean_frame_bytes median_frame_bytes p95_frame_bytes max_frame_bytes payload_bitrate_bps payload_bitrate_kbps source_file_bitrate_kbps reduction_ratio percent_of_source mean_psnr_db
2 fps_sweep fps_30 640 360 30.000000 30.000000 grayscale 50 20.766667 623 10219569 16403.803 16282.000 18471.500 21081 3936912.616 3936.912616 3001.342536 0.762359 131.171720 37.349661
3 fps_sweep fps_10 640 360 10.000000 10.016051 grayscale 50 20.766667 208 3641634 17507.856 17509.500 18958.400 21081 1402876.661 1402.876661 3001.342536 2.139420 46.741638 36.369592
4 fps_sweep fps_5 640 360 5.000000 5.008026 grayscale 50 20.766667 104 1822387 17522.952 17547.000 18910.400 21081 702043.146 702.043146 3001.342536 4.275154 23.390970 36.352519
5 fps_sweep fps_2 640 360 2.000000 2.022472 grayscale 50 20.766667 42 737435 17557.976 17476.500 18926.800 21081 284084.109 284.084109 3001.342536 10.564979 9.465234 36.319782
6 fps_sweep fps_1 640 360 1.000000 1.011236 grayscale 50 20.766667 21 369317 17586.524 17483.000 18935.000 21081 142273.002 142.273002 3001.342536 21.095658 4.740312 36.287711
7 fps_sweep fps_0_5 640 360 0.500000 0.529695 grayscale 50 20.766667 11 191626 17420.545 17040.000 19774.000 21081 73820.610 73.820610 3001.342536 40.657244 2.459586 36.371684
8 fps_sweep fps_0_2 640 360 0.200000 0.240770 grayscale 50 20.766667 5 91496 18299.200 18467.000 20651.800 21081 35247.255 35.247255 3001.342536 85.151100 1.174383 35.860330
9 resolution_sweep resolution_1280x720 1280 720 5.000000 5.008026 grayscale 50 20.766667 104 5506628 52948.346 52634.000 57821.150 73994 2121333.419 2121.333419 3001.342536 1.414838 70.679484 39.607731
10 resolution_sweep resolution_960x540 960 540 5.000000 5.008026 grayscale 50 20.766667 104 3411900 32806.731 32634.500 35501.600 41897 1314375.602 1314.375602 3001.342536 2.283474 43.792922 38.632041
11 resolution_sweep resolution_640x360 640 360 5.000000 5.008026 grayscale 50 20.766667 104 1822387 17522.952 17547.000 18910.400 21081 702043.146 702.043146 3001.342536 4.275154 23.390970 36.352519
12 resolution_sweep resolution_480x270 480 270 5.000000 5.008026 grayscale 50 20.766667 104 1120944 10778.308 10786.000 11463.200 12395 431824.334 431.824334 3001.342536 6.950378 14.387706 36.172087
13 resolution_sweep resolution_320x180 320 180 5.000000 5.008026 grayscale 50 20.766667 104 590018 5673.250 5679.000 5995.750 6191 227294.254 227.294254 3001.342536 13.204656 7.573086 35.069392
14 resolution_sweep resolution_160x90 160 90 5.000000 5.008026 grayscale 50 20.766667 104 210050 2019.712 2017.000 2103.400 2156 80918.138 80.918138 3001.342536 37.091097 2.696065 33.585930
15 quality_sweep quality_color_q90 640 360 5.000000 5.008026 color 90 20.766667 104 5486654 52756.288 52645.500 57012.750 66227 2113638.780 2113.638780 3001.342536 1.419988 70.423111 39.694424
16 quality_sweep quality_color_q70 640 360 5.000000 5.008026 color 70 20.766667 104 2901304 27897.154 27815.500 30080.600 33877 1117677.303 1117.677303 3001.342536 2.685339 37.239245 36.029412
17 quality_sweep quality_color_q50 640 360 5.000000 5.008026 color 50 20.766667 104 2137169 20549.702 20514.000 22026.250 24396 823307.480 823.307480 3001.342536 3.645470 27.431307 34.439250
18 quality_sweep quality_color_q30 640 360 5.000000 5.008026 color 30 20.766667 104 1572112 15116.462 15105.500 16167.600 17386 605629.021 605.629021 3001.342536 4.955744 20.178604 32.766254
19 quality_sweep quality_color_q20 640 360 5.000000 5.008026 color 20 20.766667 104 1224535 11774.375 11797.000 12633.050 13098 471730.979 471.730979 3001.342536 6.362403 15.717332 31.298703
20 quality_sweep quality_grayscale_q90 640 360 5.000000 5.008026 grayscale 90 20.766667 104 4697004 45163.500 44959.000 48937.750 57535 1809439.743 1809.439743 3001.342536 1.658714 60.287679 42.574562
21 quality_sweep quality_grayscale_q70 640 360 5.000000 5.008026 grayscale 70 20.766667 104 2484781 23892.125 23853.000 25744.950 29385 957219.005 957.219005 3001.342536 3.135482 31.893028 38.031656
22 quality_sweep quality_grayscale_q50 640 360 5.000000 5.008026 grayscale 50 20.766667 104 1822387 17522.952 17547.000 18910.400 21081 702043.146 702.043146 3001.342536 4.275154 23.390970 36.352519
23 quality_sweep quality_grayscale_q30 640 360 5.000000 5.008026 grayscale 30 20.766667 104 1328179 12770.952 12821.500 13834.150 14903 511658.042 511.658042 3001.342536 5.865915 17.047639 34.701951
24 quality_sweep quality_grayscale_q20 640 360 5.000000 5.008026 grayscale 20 20.766667 104 1017957 9788.048 9832.500 10597.450 11027 392150.369 392.150369 3001.342536 7.653550 13.065832 33.304362
25 candidate_profiles candidate_640x360_gray_5fps_q50 640 360 5.000000 5.008026 grayscale 50 20.766667 104 1822387 17522.952 17547.000 18910.400 21081 702043.146 702.043146 3001.342536 4.275154 23.390970 36.352519
26 candidate_profiles candidate_640x360_gray_2fps_q40 640 360 2.000000 2.022472 grayscale 40 20.766667 42 639531 15226.929 15187.500 16381.750 18122 246368.283 246.368283 3001.342536 12.182341 8.208603 35.588581
27 candidate_profiles candidate_320x180_color_5fps_q50 320 180 5.000000 5.008026 color 50 20.766667 104 717676 6900.731 6919.500 7309.850 7475 276472.295 276.472295 3001.342536 10.855853 9.211621 32.413850
28 candidate_profiles candidate_320x180_gray_5fps_q50 320 180 5.000000 5.008026 grayscale 50 20.766667 104 590018 5673.250 5679.000 5995.750 6191 227294.254 227.294254 3001.342536 13.204656 7.573086 35.069392
29 candidate_profiles candidate_320x180_gray_2fps_q40 320 180 2.000000 2.022472 grayscale 40 20.766667 42 208403 4961.976 4965.000 5224.700 5400 80283.660 80.283660 3001.342536 37.384227 2.674925 34.362114
30 candidate_profiles candidate_320x180_gray_1fps_q35 320 180 1.000000 1.011236 grayscale 35 20.766667 21 96733 4606.333 4611.000 4836.000 4992 37264.719 37.264719 3001.342536 80.541129 1.241602 34.035117
31 candidate_profiles candidate_320x180_gray_0_5fps_q35 320 180 0.500000 0.529695 grayscale 35 20.766667 11 50124 4556.727 4493.000 4914.000 4992 19309.406 19.309406 3001.342536 155.434223 0.643359 34.165852
32 candidate_profiles candidate_320x180_gray_0_2fps_q35 320 180 0.200000 0.240770 grayscale 35 20.766667 5 23618 4723.600 4815.000 4960.800 4992 9098.427 9.098427 3001.342536 329.874884 0.303145 33.741044
33 candidate_profiles candidate_160x90_gray_1fps_q30 160 90 1.000000 1.011236 grayscale 30 20.766667 21 32743 1559.190 1561.000 1623.000 1632 12613.676 12.613676 3001.342536 237.943530 0.420268 32.031480

View File

@@ -0,0 +1,82 @@
Lab026. Исследование уменьшения видеопотока для радиоуправления ровером
Цель: исследовать уменьшение полезной нагрузки видеоканала для передачи через ретранслятор.
Исходный файл: data\raw\lab026_rover_source.mp4
Размер исходного файла: 7790985 байт
Исходное разрешение: 1280x720
Исходный FPS: 30.000000
Число кадров: 623
Длительность: 20.766667 с
Приблизительный исходный файловый битрейт: 3001.343 кбит/с
Исследуется независимое покадровое JPEG-сжатие. JPEG хранится и декодируется только в памяти.
Рассчитанный bitrate учитывает только JPEG payload.
Не учитываются заголовки радиопакетов, CRC, FEC, преамбула, интервалы, повторы и команды управления.
Результаты fps_sweep:
fps_30: 640x360, 30 кадр/с, grayscale, Q=50, кадров=623, payload=3936.913 кбит/с, PSNR=37.350 дБ, уменьшение=0.76x
fps_10: 640x360, 10 кадр/с, grayscale, Q=50, кадров=208, payload=1402.877 кбит/с, PSNR=36.370 дБ, уменьшение=2.14x
fps_5: 640x360, 5 кадр/с, grayscale, Q=50, кадров=104, payload=702.043 кбит/с, PSNR=36.353 дБ, уменьшение=4.28x
fps_2: 640x360, 2 кадр/с, grayscale, Q=50, кадров=42, payload=284.084 кбит/с, PSNR=36.320 дБ, уменьшение=10.56x
fps_1: 640x360, 1 кадр/с, grayscale, Q=50, кадров=21, payload=142.273 кбит/с, PSNR=36.288 дБ, уменьшение=21.10x
fps_0_5: 640x360, 0.5 кадр/с, grayscale, Q=50, кадров=11, payload=73.821 кбит/с, PSNR=36.372 дБ, уменьшение=40.66x
fps_0_2: 640x360, 0.2 кадр/с, grayscale, Q=50, кадров=5, payload=35.247 кбит/с, PSNR=35.860 дБ, уменьшение=85.15x
Результаты resolution_sweep:
resolution_1280x720: 1280x720, 5 кадр/с, grayscale, Q=50, кадров=104, payload=2121.333 кбит/с, PSNR=39.608 дБ, уменьшение=1.41x
resolution_960x540: 960x540, 5 кадр/с, grayscale, Q=50, кадров=104, payload=1314.376 кбит/с, PSNR=38.632 дБ, уменьшение=2.28x
resolution_640x360: 640x360, 5 кадр/с, grayscale, Q=50, кадров=104, payload=702.043 кбит/с, PSNR=36.353 дБ, уменьшение=4.28x
resolution_480x270: 480x270, 5 кадр/с, grayscale, Q=50, кадров=104, payload=431.824 кбит/с, PSNR=36.172 дБ, уменьшение=6.95x
resolution_320x180: 320x180, 5 кадр/с, grayscale, Q=50, кадров=104, payload=227.294 кбит/с, PSNR=35.069 дБ, уменьшение=13.20x
resolution_160x90: 160x90, 5 кадр/с, grayscale, Q=50, кадров=104, payload=80.918 кбит/с, PSNR=33.586 дБ, уменьшение=37.09x
Результаты quality_sweep:
quality_color_q90: 640x360, 5 кадр/с, color, Q=90, кадров=104, payload=2113.639 кбит/с, PSNR=39.694 дБ, уменьшение=1.42x
quality_color_q70: 640x360, 5 кадр/с, color, Q=70, кадров=104, payload=1117.677 кбит/с, PSNR=36.029 дБ, уменьшение=2.69x
quality_color_q50: 640x360, 5 кадр/с, color, Q=50, кадров=104, payload=823.307 кбит/с, PSNR=34.439 дБ, уменьшение=3.65x
quality_color_q30: 640x360, 5 кадр/с, color, Q=30, кадров=104, payload=605.629 кбит/с, PSNR=32.766 дБ, уменьшение=4.96x
quality_color_q20: 640x360, 5 кадр/с, color, Q=20, кадров=104, payload=471.731 кбит/с, PSNR=31.299 дБ, уменьшение=6.36x
quality_grayscale_q90: 640x360, 5 кадр/с, grayscale, Q=90, кадров=104, payload=1809.440 кбит/с, PSNR=42.575 дБ, уменьшение=1.66x
quality_grayscale_q70: 640x360, 5 кадр/с, grayscale, Q=70, кадров=104, payload=957.219 кбит/с, PSNR=38.032 дБ, уменьшение=3.14x
quality_grayscale_q50: 640x360, 5 кадр/с, grayscale, Q=50, кадров=104, payload=702.043 кбит/с, PSNR=36.353 дБ, уменьшение=4.28x
quality_grayscale_q30: 640x360, 5 кадр/с, grayscale, Q=30, кадров=104, payload=511.658 кбит/с, PSNR=34.702 дБ, уменьшение=5.87x
quality_grayscale_q20: 640x360, 5 кадр/с, grayscale, Q=20, кадров=104, payload=392.150 кбит/с, PSNR=33.304 дБ, уменьшение=7.65x
Результаты candidate_profiles:
candidate_640x360_gray_5fps_q50: 640x360, 5 кадр/с, grayscale, Q=50, кадров=104, payload=702.043 кбит/с, PSNR=36.353 дБ, уменьшение=4.28x
candidate_640x360_gray_2fps_q40: 640x360, 2 кадр/с, grayscale, Q=40, кадров=42, payload=246.368 кбит/с, PSNR=35.589 дБ, уменьшение=12.18x
candidate_320x180_color_5fps_q50: 320x180, 5 кадр/с, color, Q=50, кадров=104, payload=276.472 кбит/с, PSNR=32.414 дБ, уменьшение=10.86x
candidate_320x180_gray_5fps_q50: 320x180, 5 кадр/с, grayscale, Q=50, кадров=104, payload=227.294 кбит/с, PSNR=35.069 дБ, уменьшение=13.20x
candidate_320x180_gray_2fps_q40: 320x180, 2 кадр/с, grayscale, Q=40, кадров=42, payload=80.284 кбит/с, PSNR=34.362 дБ, уменьшение=37.38x
candidate_320x180_gray_1fps_q35: 320x180, 1 кадр/с, grayscale, Q=35, кадров=21, payload=37.265 кбит/с, PSNR=34.035 дБ, уменьшение=80.54x
candidate_320x180_gray_0_5fps_q35: 320x180, 0.5 кадр/с, grayscale, Q=35, кадров=11, payload=19.309 кбит/с, PSNR=34.166 дБ, уменьшение=155.43x
candidate_320x180_gray_0_2fps_q35: 320x180, 0.2 кадр/с, grayscale, Q=35, кадров=5, payload=9.098 кбит/с, PSNR=33.741 дБ, уменьшение=329.87x
candidate_160x90_gray_1fps_q30: 160x90, 1 кадр/с, grayscale, Q=30, кадров=21, payload=12.614 кбит/с, PSNR=32.031 дБ, уменьшение=237.94x
Candidate-профили с payload bitrate не более 100 кбит/с:
candidate_320x180_gray_2fps_q40: 320x180, 2 кадр/с, grayscale, Q=40, кадров=42, payload=80.284 кбит/с, PSNR=34.362 дБ, уменьшение=37.38x
candidate_320x180_gray_1fps_q35: 320x180, 1 кадр/с, grayscale, Q=35, кадров=21, payload=37.265 кбит/с, PSNR=34.035 дБ, уменьшение=80.54x
candidate_320x180_gray_0_5fps_q35: 320x180, 0.5 кадр/с, grayscale, Q=35, кадров=11, payload=19.309 кбит/с, PSNR=34.166 дБ, уменьшение=155.43x
candidate_320x180_gray_0_2fps_q35: 320x180, 0.2 кадр/с, grayscale, Q=35, кадров=5, payload=9.098 кбит/с, PSNR=33.741 дБ, уменьшение=329.87x
candidate_160x90_gray_1fps_q30: 160x90, 1 кадр/с, grayscale, Q=30, кадров=21, payload=12.614 кбит/с, PSNR=32.031 дБ, уменьшение=237.94x
Candidate-профили с payload bitrate не более 50 кбит/с:
candidate_320x180_gray_1fps_q35: 320x180, 1 кадр/с, grayscale, Q=35, кадров=21, payload=37.265 кбит/с, PSNR=34.035 дБ, уменьшение=80.54x
candidate_320x180_gray_0_5fps_q35: 320x180, 0.5 кадр/с, grayscale, Q=35, кадров=11, payload=19.309 кбит/с, PSNR=34.166 дБ, уменьшение=155.43x
candidate_320x180_gray_0_2fps_q35: 320x180, 0.2 кадр/с, grayscale, Q=35, кадров=5, payload=9.098 кбит/с, PSNR=33.741 дБ, уменьшение=329.87x
candidate_160x90_gray_1fps_q30: 160x90, 1 кадр/с, grayscale, Q=30, кадров=21, payload=12.614 кбит/с, PSNR=32.031 дБ, уменьшение=237.94x
Candidate-профили с payload bitrate не более 20 кбит/с:
candidate_320x180_gray_0_5fps_q35: 320x180, 0.5 кадр/с, grayscale, Q=35, кадров=11, payload=19.309 кбит/с, PSNR=34.166 дБ, уменьшение=155.43x
candidate_320x180_gray_0_2fps_q35: 320x180, 0.2 кадр/с, grayscale, Q=35, кадров=5, payload=9.098 кбит/с, PSNR=33.741 дБ, уменьшение=329.87x
candidate_160x90_gray_1fps_q30: 160x90, 1 кадр/с, grayscale, Q=30, кадров=21, payload=12.614 кбит/с, PSNR=32.031 дБ, уменьшение=237.94x
Candidate-профили с payload bitrate не более 10 кбит/с:
candidate_320x180_gray_0_2fps_q35: 320x180, 0.2 кадр/с, grayscale, Q=35, кадров=5, payload=9.098 кбит/с, PSNR=33.741 дБ, уменьшение=329.87x
Профиль с минимальным измеренным битрейтом:
candidate_320x180_gray_0_2fps_q35: 320x180, 0.2 кадр/с, grayscale, Q=35, кадров=5, payload=9.098 кбит/с, PSNR=33.741 дБ, уменьшение=329.87x
Автоматические метрики не заменяют визуальную оценку пригодности изображения для управления ровером.
Сравнительное изображение: data\processed\lab026\lab026_candidate_profiles.png
Следующий шаг: пользователь должен визуально выбрать пригодные candidate-профили.

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@@ -0,0 +1,31 @@
experiment,profile_name,mode,width,height,pixel_count,target_fps,actual_fps,bits_per_pixel_before_compression,maximum_gray_levels,maximum_colors,selected_frames,total_payload_bytes,mean_frame_bytes,median_frame_bytes,p95_frame_bytes,max_frame_bytes,payload_bitrate_bps,payload_bitrate_kbps,baseline_bitrate_kbps,difference_from_baseline_kbps,percent_of_baseline_bitrate,compression_ratio_from_unpacked_source,mean_psnr_db,header_bytes_per_frame,palette_bytes_per_frame,notes
four_bit_resolution_sweep,320x180_gray8_jpeg_2fps,gray8_jpeg,320,180,57600,2.000000,2.022472,8,256,0,42,208403,4961.976,4965.000,5224.700,5400,80283.660,80.283660,80.283660,-0.000000,100.000000,11.608278,34.362114,0,0,"Grayscale 8 bit, JPEG quality 40."
four_bit_resolution_sweep,320x180_gray4_jpeg_2fps,gray4_jpeg,320,180,57600,2.000000,2.022472,4,16,0,42,229518,5464.714,5466.000,5727.250,5822,88417.849,88.417849,80.283660,8.134189,110.131812,10.540350,32.588941,0,0,"Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40."
four_bit_resolution_sweep,320x180_gray4_packed_zlib_2fps,gray4_packed_zlib,320,180,57600,2.000000,2.022472,4,16,0,42,441074,10501.762,10444.000,11194.300,12317,169916.148,169.916148,80.283660,89.632488,211.644745,5.484794,34.397012,16,0,"Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header."
four_bit_resolution_sweep,320x180_color16_png_2fps,color16_png,320,180,57600,2.000000,2.022472,4,0,16,42,371520,8845.714,8607.500,10578.350,10794,143121.669,143.121669,80.283660,62.838009,178.269986,19.534884,25.384724,0,0,"Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG."
four_bit_resolution_sweep,320x180_color16_packed_zlib_2fps,color16_packed_zlib,320,180,57600,2.000000,2.022472,4,0,16,42,364892,8687.905,8452.000,10414.800,10652,140568.347,140.568347,80.283660,60.284687,175.089609,19.889721,25.384724,16,48,"Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette."
four_bit_resolution_sweep,400x225_gray8_jpeg_2fps,gray8_jpeg,400,225,90000,2.000000,2.022472,8,256,0,42,297273,7077.929,7063.500,7473.000,7841,114519.294,114.519294,80.283660,34.235634,142.643340,12.715585,34.942886,0,0,"Grayscale 8 bit, JPEG quality 40."
four_bit_resolution_sweep,400x225_gray4_jpeg_2fps,gray4_jpeg,400,225,90000,2.000000,2.022472,4,16,0,42,332268,7911.143,7920.500,8353.700,8554,128000.514,128.000514,80.283660,47.716854,159.435324,11.376359,32.883090,0,0,"Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40."
four_bit_resolution_sweep,400x225_gray4_packed_zlib_2fps,gray4_packed_zlib,400,225,90000,2.000000,2.022472,4,16,0,42,636862,15163.381,15120.500,16266.050,18356,245340.096,245.340096,80.283660,165.056436,305.591569,5.935352,34.399552,16,0,"Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header."
four_bit_resolution_sweep,400x225_color16_png_2fps,color16_png,400,225,90000,2.000000,2.022472,4,0,16,42,528261,12577.643,12153.000,15191.650,16128,203503.435,203.503435,80.283660,123.219775,253.480515,21.466661,25.344339,0,0,"Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG."
four_bit_resolution_sweep,400x225_color16_packed_zlib_2fps,color16_packed_zlib,400,225,90000,2.000000,2.022472,4,0,16,42,520725,12398.214,11977.000,15015.100,15966,200600.321,200.600321,80.283660,120.316661,249.864444,21.777330,25.344339,16,48,"Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette."
four_bit_resolution_sweep,448x252_gray8_jpeg_2fps,gray8_jpeg,448,252,112896,2.000000,2.022472,8,256,0,42,353578,8418.524,8413.000,8885.950,9512,136209.823,136.209823,80.283660,55.926163,169.660705,13.410427,35.301071,0,0,"Grayscale 8 bit, JPEG quality 40."
four_bit_resolution_sweep,448x252_gray4_jpeg_2fps,gray4_jpeg,448,252,112896,2.000000,2.022472,4,16,0,42,397126,9455.381,9467.500,9996.400,10450,152985.939,152.985939,80.283660,72.702279,190.556757,11.939868,33.060439,0,0,"Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40."
four_bit_resolution_sweep,448x252_gray4_packed_zlib_2fps,gray4_packed_zlib,448,252,112896,2.000000,2.022472,4,16,0,42,762082,18144.810,18111.500,19504.750,22433,293578.941,293.578941,80.283660,213.295281,365.677076,6.221945,34.399841,16,0,"Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header."
four_bit_resolution_sweep,448x252_color16_png_2fps,color16_png,448,252,112896,2.000000,2.022472,4,0,16,42,626516,14917.048,14409.500,18239.600,18695,241354.478,241.354478,80.283660,161.070818,300.627149,22.704761,25.369963,0,0,"Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG."
four_bit_resolution_sweep,448x252_color16_packed_zlib_2fps,color16_packed_zlib,448,252,112896,2.000000,2.022472,4,0,16,42,618164,14718.190,14221.500,18022.000,18517,238137.014,238.137014,80.283660,157.853354,296.619529,23.011524,25.369963,16,48,"Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette."
four_bit_resolution_sweep,480x270_gray8_jpeg_2fps,gray8_jpeg,480,270,129600,2.000000,2.022472,8,256,0,42,393752,9375.048,9365.500,9919.950,10678,151686.164,151.686164,80.283660,71.402504,188.937779,13.823930,35.412999,0,0,"Grayscale 8 bit, JPEG quality 40."
four_bit_resolution_sweep,480x270_gray4_jpeg_2fps,gray4_jpeg,480,270,129600,2.000000,2.022472,4,16,0,42,443419,10557.595,10575.500,11152.550,11737,170819.518,170.819518,80.283660,90.535858,212.769969,12.275523,33.099458,0,0,"Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40."
four_bit_resolution_sweep,480x270_gray4_packed_zlib_2fps,gray4_packed_zlib,480,270,129600,2.000000,2.022472,4,16,0,42,854354,20341.762,20276.500,21857.900,25369,329125.136,329.125136,80.283660,248.841476,409.952830,6.371130,34.401420,16,0,"Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header."
four_bit_resolution_sweep,480x270_color16_png_2fps,color16_png,480,270,129600,2.000000,2.022472,4,0,16,42,701871,16711.214,16249.500,20469.850,21005,270383.692,270.383692,80.283660,190.100032,336.785458,23.265814,25.368870,0,0,"Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG."
four_bit_resolution_sweep,480x270_color16_packed_zlib_2fps,color16_packed_zlib,480,270,129600,2.000000,2.022472,4,0,16,42,693190,16504.524,16007.500,20249.750,20809,267039.486,267.039486,80.283660,186.755826,332.619971,23.557178,25.368870,16,48,"Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette."
four_bit_resolution_sweep,560x315_gray8_jpeg_2fps,gray8_jpeg,560,315,176400,2.000000,2.022472,8,256,0,42,507535,12084.167,12068.500,12860.900,13999,195519.101,195.519101,80.283660,115.235441,243.535361,14.597614,35.954946,0,0,"Grayscale 8 bit, JPEG quality 40."
four_bit_resolution_sweep,560x315_gray4_jpeg_2fps,gray4_jpeg,560,315,176400,2.000000,2.022472,4,16,0,42,575350,13698.810,13674.500,14558.450,15458,221643.660,221.643660,80.283660,141.360000,276.075679,12.877031,33.337152,0,0,"Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40."
four_bit_resolution_sweep,560x315_gray4_packed_zlib_2fps,gray4_packed_zlib,560,315,176400,2.000000,2.022472,4,16,0,42,1093024,26024.381,25851.500,28055.650,33171,421068.636,421.068636,80.283660,340.784976,524.476133,6.778259,34.403027,16,0,"Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header."
four_bit_resolution_sweep,560x315_color16_png_2fps,color16_png,560,315,176400,2.000000,2.022472,4,0,16,42,894967,21308.738,20851.500,25906.100,27345,344770.594,344.770594,80.283660,264.486934,429.440554,24.834882,25.323519,0,0,"Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG."
four_bit_resolution_sweep,560x315_color16_packed_zlib_2fps,color16_packed_zlib,560,315,176400,2.000000,2.022472,4,0,16,42,885156,21075.143,20622.000,25686.650,27166,340991.075,340.991075,80.283660,260.707415,424.732848,25.110150,25.323519,16,48,"Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette."
four_bit_resolution_sweep,640x360_gray8_jpeg_2fps,gray8_jpeg,640,360,230400,2.000000,2.022472,8,256,0,42,639531,15226.929,15187.500,16381.750,18122,246368.283,246.368283,80.283660,166.084623,306.872261,15.131088,35.588581,0,0,"Grayscale 8 bit, JPEG quality 40."
four_bit_resolution_sweep,640x360_gray4_jpeg_2fps,gray4_jpeg,640,360,230400,2.000000,2.022472,4,16,0,42,726335,17293.690,17220.500,18557.350,19938,279808.026,279.808026,80.283660,199.524366,348.524252,13.322778,33.048695,0,0,"Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40."
four_bit_resolution_sweep,640x360_gray4_packed_zlib_2fps,gray4_packed_zlib,640,360,230400,2.000000,2.022472,4,16,0,42,1394769,33208.786,32974.500,35959.800,43514,537310.690,537.310690,80.283660,457.027030,669.265315,6.937923,34.404228,16,0,"Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header."
four_bit_resolution_sweep,640x360_color16_png_2fps,color16_png,640,360,230400,2.000000,2.022472,4,0,16,42,1140488,27154.476,26267.500,33424.950,36017,439353.323,439.353323,80.283660,359.069663,547.251237,25.454367,25.259621,0,0,"Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG."
four_bit_resolution_sweep,640x360_color16_packed_zlib_2fps,color16_packed_zlib,640,360,230400,2.000000,2.022472,4,0,16,42,1128711,26874.071,25978.500,33021.450,35603,434816.437,434.816437,80.283660,354.532777,541.600167,25.719958,25.259621,16,48,"Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette."
1 experiment profile_name mode width height pixel_count target_fps actual_fps bits_per_pixel_before_compression maximum_gray_levels maximum_colors selected_frames total_payload_bytes mean_frame_bytes median_frame_bytes p95_frame_bytes max_frame_bytes payload_bitrate_bps payload_bitrate_kbps baseline_bitrate_kbps difference_from_baseline_kbps percent_of_baseline_bitrate compression_ratio_from_unpacked_source mean_psnr_db header_bytes_per_frame palette_bytes_per_frame notes
2 four_bit_resolution_sweep 320x180_gray8_jpeg_2fps gray8_jpeg 320 180 57600 2.000000 2.022472 8 256 0 42 208403 4961.976 4965.000 5224.700 5400 80283.660 80.283660 80.283660 -0.000000 100.000000 11.608278 34.362114 0 0 Grayscale 8 bit, JPEG quality 40.
3 four_bit_resolution_sweep 320x180_gray4_jpeg_2fps gray4_jpeg 320 180 57600 2.000000 2.022472 4 16 0 42 229518 5464.714 5466.000 5727.250 5822 88417.849 88.417849 80.283660 8.134189 110.131812 10.540350 32.588941 0 0 Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40.
4 four_bit_resolution_sweep 320x180_gray4_packed_zlib_2fps gray4_packed_zlib 320 180 57600 2.000000 2.022472 4 16 0 42 441074 10501.762 10444.000 11194.300 12317 169916.148 169.916148 80.283660 89.632488 211.644745 5.484794 34.397012 16 0 Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header.
5 four_bit_resolution_sweep 320x180_color16_png_2fps color16_png 320 180 57600 2.000000 2.022472 4 0 16 42 371520 8845.714 8607.500 10578.350 10794 143121.669 143.121669 80.283660 62.838009 178.269986 19.534884 25.384724 0 0 Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG.
6 four_bit_resolution_sweep 320x180_color16_packed_zlib_2fps color16_packed_zlib 320 180 57600 2.000000 2.022472 4 0 16 42 364892 8687.905 8452.000 10414.800 10652 140568.347 140.568347 80.283660 60.284687 175.089609 19.889721 25.384724 16 48 Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette.
7 four_bit_resolution_sweep 400x225_gray8_jpeg_2fps gray8_jpeg 400 225 90000 2.000000 2.022472 8 256 0 42 297273 7077.929 7063.500 7473.000 7841 114519.294 114.519294 80.283660 34.235634 142.643340 12.715585 34.942886 0 0 Grayscale 8 bit, JPEG quality 40.
8 four_bit_resolution_sweep 400x225_gray4_jpeg_2fps gray4_jpeg 400 225 90000 2.000000 2.022472 4 16 0 42 332268 7911.143 7920.500 8353.700 8554 128000.514 128.000514 80.283660 47.716854 159.435324 11.376359 32.883090 0 0 Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40.
9 four_bit_resolution_sweep 400x225_gray4_packed_zlib_2fps gray4_packed_zlib 400 225 90000 2.000000 2.022472 4 16 0 42 636862 15163.381 15120.500 16266.050 18356 245340.096 245.340096 80.283660 165.056436 305.591569 5.935352 34.399552 16 0 Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header.
10 four_bit_resolution_sweep 400x225_color16_png_2fps color16_png 400 225 90000 2.000000 2.022472 4 0 16 42 528261 12577.643 12153.000 15191.650 16128 203503.435 203.503435 80.283660 123.219775 253.480515 21.466661 25.344339 0 0 Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG.
11 four_bit_resolution_sweep 400x225_color16_packed_zlib_2fps color16_packed_zlib 400 225 90000 2.000000 2.022472 4 0 16 42 520725 12398.214 11977.000 15015.100 15966 200600.321 200.600321 80.283660 120.316661 249.864444 21.777330 25.344339 16 48 Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette.
12 four_bit_resolution_sweep 448x252_gray8_jpeg_2fps gray8_jpeg 448 252 112896 2.000000 2.022472 8 256 0 42 353578 8418.524 8413.000 8885.950 9512 136209.823 136.209823 80.283660 55.926163 169.660705 13.410427 35.301071 0 0 Grayscale 8 bit, JPEG quality 40.
13 four_bit_resolution_sweep 448x252_gray4_jpeg_2fps gray4_jpeg 448 252 112896 2.000000 2.022472 4 16 0 42 397126 9455.381 9467.500 9996.400 10450 152985.939 152.985939 80.283660 72.702279 190.556757 11.939868 33.060439 0 0 Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40.
14 four_bit_resolution_sweep 448x252_gray4_packed_zlib_2fps gray4_packed_zlib 448 252 112896 2.000000 2.022472 4 16 0 42 762082 18144.810 18111.500 19504.750 22433 293578.941 293.578941 80.283660 213.295281 365.677076 6.221945 34.399841 16 0 Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header.
15 four_bit_resolution_sweep 448x252_color16_png_2fps color16_png 448 252 112896 2.000000 2.022472 4 0 16 42 626516 14917.048 14409.500 18239.600 18695 241354.478 241.354478 80.283660 161.070818 300.627149 22.704761 25.369963 0 0 Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG.
16 four_bit_resolution_sweep 448x252_color16_packed_zlib_2fps color16_packed_zlib 448 252 112896 2.000000 2.022472 4 0 16 42 618164 14718.190 14221.500 18022.000 18517 238137.014 238.137014 80.283660 157.853354 296.619529 23.011524 25.369963 16 48 Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette.
17 four_bit_resolution_sweep 480x270_gray8_jpeg_2fps gray8_jpeg 480 270 129600 2.000000 2.022472 8 256 0 42 393752 9375.048 9365.500 9919.950 10678 151686.164 151.686164 80.283660 71.402504 188.937779 13.823930 35.412999 0 0 Grayscale 8 bit, JPEG quality 40.
18 four_bit_resolution_sweep 480x270_gray4_jpeg_2fps gray4_jpeg 480 270 129600 2.000000 2.022472 4 16 0 42 443419 10557.595 10575.500 11152.550 11737 170819.518 170.819518 80.283660 90.535858 212.769969 12.275523 33.099458 0 0 Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40.
19 four_bit_resolution_sweep 480x270_gray4_packed_zlib_2fps gray4_packed_zlib 480 270 129600 2.000000 2.022472 4 16 0 42 854354 20341.762 20276.500 21857.900 25369 329125.136 329.125136 80.283660 248.841476 409.952830 6.371130 34.401420 16 0 Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header.
20 four_bit_resolution_sweep 480x270_color16_png_2fps color16_png 480 270 129600 2.000000 2.022472 4 0 16 42 701871 16711.214 16249.500 20469.850 21005 270383.692 270.383692 80.283660 190.100032 336.785458 23.265814 25.368870 0 0 Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG.
21 four_bit_resolution_sweep 480x270_color16_packed_zlib_2fps color16_packed_zlib 480 270 129600 2.000000 2.022472 4 0 16 42 693190 16504.524 16007.500 20249.750 20809 267039.486 267.039486 80.283660 186.755826 332.619971 23.557178 25.368870 16 48 Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette.
22 four_bit_resolution_sweep 560x315_gray8_jpeg_2fps gray8_jpeg 560 315 176400 2.000000 2.022472 8 256 0 42 507535 12084.167 12068.500 12860.900 13999 195519.101 195.519101 80.283660 115.235441 243.535361 14.597614 35.954946 0 0 Grayscale 8 bit, JPEG quality 40.
23 four_bit_resolution_sweep 560x315_gray4_jpeg_2fps gray4_jpeg 560 315 176400 2.000000 2.022472 4 16 0 42 575350 13698.810 13674.500 14558.450 15458 221643.660 221.643660 80.283660 141.360000 276.075679 12.877031 33.337152 0 0 Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40.
24 four_bit_resolution_sweep 560x315_gray4_packed_zlib_2fps gray4_packed_zlib 560 315 176400 2.000000 2.022472 4 16 0 42 1093024 26024.381 25851.500 28055.650 33171 421068.636 421.068636 80.283660 340.784976 524.476133 6.778259 34.403027 16 0 Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header.
25 four_bit_resolution_sweep 560x315_color16_png_2fps color16_png 560 315 176400 2.000000 2.022472 4 0 16 42 894967 21308.738 20851.500 25906.100 27345 344770.594 344.770594 80.283660 264.486934 429.440554 24.834882 25.323519 0 0 Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG.
26 four_bit_resolution_sweep 560x315_color16_packed_zlib_2fps color16_packed_zlib 560 315 176400 2.000000 2.022472 4 0 16 42 885156 21075.143 20622.000 25686.650 27166 340991.075 340.991075 80.283660 260.707415 424.732848 25.110150 25.323519 16 48 Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette.
27 four_bit_resolution_sweep 640x360_gray8_jpeg_2fps gray8_jpeg 640 360 230400 2.000000 2.022472 8 256 0 42 639531 15226.929 15187.500 16381.750 18122 246368.283 246.368283 80.283660 166.084623 306.872261 15.131088 35.588581 0 0 Grayscale 8 bit, JPEG quality 40.
28 four_bit_resolution_sweep 640x360_gray4_jpeg_2fps gray4_jpeg 640 360 230400 2.000000 2.022472 4 16 0 42 726335 17293.690 17220.500 18557.350 19938 279808.026 279.808026 80.283660 199.524366 348.524252 13.322778 33.048695 0 0 Grayscale quantized to 16 levels, restored to uint8, JPEG quality 40.
29 four_bit_resolution_sweep 640x360_gray4_packed_zlib_2fps gray4_packed_zlib 640 360 230400 2.000000 2.022472 4 16 0 42 1394769 33208.786 32974.500 35959.800 43514 537310.690 537.310690 80.283660 457.027030 669.265315 6.937923 34.404228 16 0 Two 4-bit grayscale indices per byte, zlib level 9, 16-byte frame header.
30 four_bit_resolution_sweep 640x360_color16_png_2fps color16_png 640 360 230400 2.000000 2.022472 4 0 16 42 1140488 27154.476 26267.500 33424.950 36017 439353.323 439.353323 80.283660 359.069663 547.251237 25.454367 25.259621 0 0 Pillow palette image, maximum 16 colors, no dithering, optimized indexed PNG.
31 four_bit_resolution_sweep 640x360_color16_packed_zlib_2fps color16_packed_zlib 640 360 230400 2.000000 2.022472 4 0 16 42 1128711 26874.071 25978.500 33021.450 35603 434816.437 434.816437 80.283660 354.532777 541.600167 25.719958 25.259621 16 48 Two 4-bit palette indices per byte, zlib level 9, 16-byte header and fixed 48-byte palette.

View File

@@ -0,0 +1,90 @@
Lab026B. Увеличение разрешения кадра за счёт глубины цвета 4 бита
Цель: проверить увеличение разрешения при битрейте, близком к контрольным 80.283660 кбит/с.
Исходное видео: data\raw\lab026_rover_source.mp4
Размер исходного видео: 7790985 байт
Исходное разрешение: 1280×720
Исходный FPS: 30.000000
Число кадров: 623
Длительность: 20.766667 с
4-битная яркость: индекс 0...15, то есть 16 уровней серого на пиксель.
4-битный индексированный цвет: один индекс 0...15 на пиксель и палитра максимум из 16 RGB-цветов.
Это не RGB444: RGB444 требует по 4 бита на каждый из трёх каналов, то есть 12 бит на пиксель.
Режимы:
gray8_jpeg — контрольный grayscale JPEG Q40.
gray4_jpeg — 16 уровней серого, восстановление uint8, JPEG Q40.
gray4_packed_zlib — 4-битные индексы, два на байт, zlib level 9 и заголовок 16 байт.
color16_png — палитра максимум 16 цветов, без дизеринга, индексированный PNG в памяти.
color16_packed_zlib — 4-битные индексы, zlib level 9, заголовок 16 байт и фиксированная палитра 48 байт.
Контрольный baseline: 80.283660 кбит/с.
CRC, FEC, радиозаголовки и пакетирование пока не учтены.
Статические метрики не учитывают задержку видеоканала.
Полные результаты 30 профилей:
320x180_gray8_jpeg_2fps: mode=gray8_jpeg, 320x180, frames=42, actual_fps=2.022472, total=208403 bytes, mean=4961.976, median=4965.000, p95=5224.700, max=5400, bitrate=80.283660 kbit/s, baseline_diff=-0.000000, baseline_percent=100.000%, compression=11.608x, PSNR=34.362114 dB
320x180_gray4_jpeg_2fps: mode=gray4_jpeg, 320x180, frames=42, actual_fps=2.022472, total=229518 bytes, mean=5464.714, median=5466.000, p95=5727.250, max=5822, bitrate=88.417849 kbit/s, baseline_diff=8.134189, baseline_percent=110.132%, compression=10.540x, PSNR=32.588941 dB
320x180_gray4_packed_zlib_2fps: mode=gray4_packed_zlib, 320x180, frames=42, actual_fps=2.022472, total=441074 bytes, mean=10501.762, median=10444.000, p95=11194.300, max=12317, bitrate=169.916148 kbit/s, baseline_diff=89.632488, baseline_percent=211.645%, compression=5.485x, PSNR=34.397012 dB
320x180_color16_png_2fps: mode=color16_png, 320x180, frames=42, actual_fps=2.022472, total=371520 bytes, mean=8845.714, median=8607.500, p95=10578.350, max=10794, bitrate=143.121669 kbit/s, baseline_diff=62.838009, baseline_percent=178.270%, compression=19.535x, PSNR=25.384724 dB
320x180_color16_packed_zlib_2fps: mode=color16_packed_zlib, 320x180, frames=42, actual_fps=2.022472, total=364892 bytes, mean=8687.905, median=8452.000, p95=10414.800, max=10652, bitrate=140.568347 kbit/s, baseline_diff=60.284687, baseline_percent=175.090%, compression=19.890x, PSNR=25.384724 dB
400x225_gray8_jpeg_2fps: mode=gray8_jpeg, 400x225, frames=42, actual_fps=2.022472, total=297273 bytes, mean=7077.929, median=7063.500, p95=7473.000, max=7841, bitrate=114.519294 kbit/s, baseline_diff=34.235634, baseline_percent=142.643%, compression=12.716x, PSNR=34.942886 dB
400x225_gray4_jpeg_2fps: mode=gray4_jpeg, 400x225, frames=42, actual_fps=2.022472, total=332268 bytes, mean=7911.143, median=7920.500, p95=8353.700, max=8554, bitrate=128.000514 kbit/s, baseline_diff=47.716854, baseline_percent=159.435%, compression=11.376x, PSNR=32.883090 dB
400x225_gray4_packed_zlib_2fps: mode=gray4_packed_zlib, 400x225, frames=42, actual_fps=2.022472, total=636862 bytes, mean=15163.381, median=15120.500, p95=16266.050, max=18356, bitrate=245.340096 kbit/s, baseline_diff=165.056436, baseline_percent=305.592%, compression=5.935x, PSNR=34.399552 dB
400x225_color16_png_2fps: mode=color16_png, 400x225, frames=42, actual_fps=2.022472, total=528261 bytes, mean=12577.643, median=12153.000, p95=15191.650, max=16128, bitrate=203.503435 kbit/s, baseline_diff=123.219775, baseline_percent=253.481%, compression=21.467x, PSNR=25.344339 dB
400x225_color16_packed_zlib_2fps: mode=color16_packed_zlib, 400x225, frames=42, actual_fps=2.022472, total=520725 bytes, mean=12398.214, median=11977.000, p95=15015.100, max=15966, bitrate=200.600321 kbit/s, baseline_diff=120.316661, baseline_percent=249.864%, compression=21.777x, PSNR=25.344339 dB
448x252_gray8_jpeg_2fps: mode=gray8_jpeg, 448x252, frames=42, actual_fps=2.022472, total=353578 bytes, mean=8418.524, median=8413.000, p95=8885.950, max=9512, bitrate=136.209823 kbit/s, baseline_diff=55.926163, baseline_percent=169.661%, compression=13.410x, PSNR=35.301071 dB
448x252_gray4_jpeg_2fps: mode=gray4_jpeg, 448x252, frames=42, actual_fps=2.022472, total=397126 bytes, mean=9455.381, median=9467.500, p95=9996.400, max=10450, bitrate=152.985939 kbit/s, baseline_diff=72.702279, baseline_percent=190.557%, compression=11.940x, PSNR=33.060439 dB
448x252_gray4_packed_zlib_2fps: mode=gray4_packed_zlib, 448x252, frames=42, actual_fps=2.022472, total=762082 bytes, mean=18144.810, median=18111.500, p95=19504.750, max=22433, bitrate=293.578941 kbit/s, baseline_diff=213.295281, baseline_percent=365.677%, compression=6.222x, PSNR=34.399841 dB
448x252_color16_png_2fps: mode=color16_png, 448x252, frames=42, actual_fps=2.022472, total=626516 bytes, mean=14917.048, median=14409.500, p95=18239.600, max=18695, bitrate=241.354478 kbit/s, baseline_diff=161.070818, baseline_percent=300.627%, compression=22.705x, PSNR=25.369963 dB
448x252_color16_packed_zlib_2fps: mode=color16_packed_zlib, 448x252, frames=42, actual_fps=2.022472, total=618164 bytes, mean=14718.190, median=14221.500, p95=18022.000, max=18517, bitrate=238.137014 kbit/s, baseline_diff=157.853354, baseline_percent=296.620%, compression=23.012x, PSNR=25.369963 dB
480x270_gray8_jpeg_2fps: mode=gray8_jpeg, 480x270, frames=42, actual_fps=2.022472, total=393752 bytes, mean=9375.048, median=9365.500, p95=9919.950, max=10678, bitrate=151.686164 kbit/s, baseline_diff=71.402504, baseline_percent=188.938%, compression=13.824x, PSNR=35.412999 dB
480x270_gray4_jpeg_2fps: mode=gray4_jpeg, 480x270, frames=42, actual_fps=2.022472, total=443419 bytes, mean=10557.595, median=10575.500, p95=11152.550, max=11737, bitrate=170.819518 kbit/s, baseline_diff=90.535858, baseline_percent=212.770%, compression=12.276x, PSNR=33.099458 dB
480x270_gray4_packed_zlib_2fps: mode=gray4_packed_zlib, 480x270, frames=42, actual_fps=2.022472, total=854354 bytes, mean=20341.762, median=20276.500, p95=21857.900, max=25369, bitrate=329.125136 kbit/s, baseline_diff=248.841476, baseline_percent=409.953%, compression=6.371x, PSNR=34.401420 dB
480x270_color16_png_2fps: mode=color16_png, 480x270, frames=42, actual_fps=2.022472, total=701871 bytes, mean=16711.214, median=16249.500, p95=20469.850, max=21005, bitrate=270.383692 kbit/s, baseline_diff=190.100032, baseline_percent=336.785%, compression=23.266x, PSNR=25.368870 dB
480x270_color16_packed_zlib_2fps: mode=color16_packed_zlib, 480x270, frames=42, actual_fps=2.022472, total=693190 bytes, mean=16504.524, median=16007.500, p95=20249.750, max=20809, bitrate=267.039486 kbit/s, baseline_diff=186.755826, baseline_percent=332.620%, compression=23.557x, PSNR=25.368870 dB
560x315_gray8_jpeg_2fps: mode=gray8_jpeg, 560x315, frames=42, actual_fps=2.022472, total=507535 bytes, mean=12084.167, median=12068.500, p95=12860.900, max=13999, bitrate=195.519101 kbit/s, baseline_diff=115.235441, baseline_percent=243.535%, compression=14.598x, PSNR=35.954946 dB
560x315_gray4_jpeg_2fps: mode=gray4_jpeg, 560x315, frames=42, actual_fps=2.022472, total=575350 bytes, mean=13698.810, median=13674.500, p95=14558.450, max=15458, bitrate=221.643660 kbit/s, baseline_diff=141.360000, baseline_percent=276.076%, compression=12.877x, PSNR=33.337152 dB
560x315_gray4_packed_zlib_2fps: mode=gray4_packed_zlib, 560x315, frames=42, actual_fps=2.022472, total=1093024 bytes, mean=26024.381, median=25851.500, p95=28055.650, max=33171, bitrate=421.068636 kbit/s, baseline_diff=340.784976, baseline_percent=524.476%, compression=6.778x, PSNR=34.403027 dB
560x315_color16_png_2fps: mode=color16_png, 560x315, frames=42, actual_fps=2.022472, total=894967 bytes, mean=21308.738, median=20851.500, p95=25906.100, max=27345, bitrate=344.770594 kbit/s, baseline_diff=264.486934, baseline_percent=429.441%, compression=24.835x, PSNR=25.323519 dB
560x315_color16_packed_zlib_2fps: mode=color16_packed_zlib, 560x315, frames=42, actual_fps=2.022472, total=885156 bytes, mean=21075.143, median=20622.000, p95=25686.650, max=27166, bitrate=340.991075 kbit/s, baseline_diff=260.707415, baseline_percent=424.733%, compression=25.110x, PSNR=25.323519 dB
640x360_gray8_jpeg_2fps: mode=gray8_jpeg, 640x360, frames=42, actual_fps=2.022472, total=639531 bytes, mean=15226.929, median=15187.500, p95=16381.750, max=18122, bitrate=246.368283 kbit/s, baseline_diff=166.084623, baseline_percent=306.872%, compression=15.131x, PSNR=35.588581 dB
640x360_gray4_jpeg_2fps: mode=gray4_jpeg, 640x360, frames=42, actual_fps=2.022472, total=726335 bytes, mean=17293.690, median=17220.500, p95=18557.350, max=19938, bitrate=279.808026 kbit/s, baseline_diff=199.524366, baseline_percent=348.524%, compression=13.323x, PSNR=33.048695 dB
640x360_gray4_packed_zlib_2fps: mode=gray4_packed_zlib, 640x360, frames=42, actual_fps=2.022472, total=1394769 bytes, mean=33208.786, median=32974.500, p95=35959.800, max=43514, bitrate=537.310690 kbit/s, baseline_diff=457.027030, baseline_percent=669.265%, compression=6.938x, PSNR=34.404228 dB
640x360_color16_png_2fps: mode=color16_png, 640x360, frames=42, actual_fps=2.022472, total=1140488 bytes, mean=27154.476, median=26267.500, p95=33424.950, max=36017, bitrate=439.353323 kbit/s, baseline_diff=359.069663, baseline_percent=547.251%, compression=25.454x, PSNR=25.259621 dB
640x360_color16_packed_zlib_2fps: mode=color16_packed_zlib, 640x360, frames=42, actual_fps=2.022472, total=1128711 bytes, mean=26874.071, median=25978.500, p95=33021.450, max=35603, bitrate=434.816437 kbit/s, baseline_diff=354.532777, baseline_percent=541.600%, compression=25.720x, PSNR=25.259621 dB
Профили 7090 кбит/с:
320x180_gray8_jpeg_2fps: mode=gray8_jpeg, 320x180, frames=42, actual_fps=2.022472, total=208403 bytes, mean=4961.976, median=4965.000, p95=5224.700, max=5400, bitrate=80.283660 kbit/s, baseline_diff=-0.000000, baseline_percent=100.000%, compression=11.608x, PSNR=34.362114 dB
320x180_gray4_jpeg_2fps: mode=gray4_jpeg, 320x180, frames=42, actual_fps=2.022472, total=229518 bytes, mean=5464.714, median=5466.000, p95=5727.250, max=5822, bitrate=88.417849 kbit/s, baseline_diff=8.134189, baseline_percent=110.132%, compression=10.540x, PSNR=32.588941 dB
Профили до baseline:
320x180_gray8_jpeg_2fps: mode=gray8_jpeg, 320x180, frames=42, actual_fps=2.022472, total=208403 bytes, mean=4961.976, median=4965.000, p95=5224.700, max=5400, bitrate=80.283660 kbit/s, baseline_diff=-0.000000, baseline_percent=100.000%, compression=11.608x, PSNR=34.362114 dB
Профили до 100 кбит/с:
320x180_gray8_jpeg_2fps: mode=gray8_jpeg, 320x180, frames=42, actual_fps=2.022472, total=208403 bytes, mean=4961.976, median=4965.000, p95=5224.700, max=5400, bitrate=80.283660 kbit/s, baseline_diff=-0.000000, baseline_percent=100.000%, compression=11.608x, PSNR=34.362114 dB
320x180_gray4_jpeg_2fps: mode=gray4_jpeg, 320x180, frames=42, actual_fps=2.022472, total=229518 bytes, mean=5464.714, median=5466.000, p95=5727.250, max=5822, bitrate=88.417849 kbit/s, baseline_diff=8.134189, baseline_percent=110.132%, compression=10.540x, PSNR=32.588941 dB
Цветные color16-профили до 100 кбит/с:
Нет.
Профили больше 320x180 и не выше baseline:
Нет.
Максимальное разрешение до baseline:
320x180_gray8_jpeg_2fps: mode=gray8_jpeg, 320x180, frames=42, actual_fps=2.022472, total=208403 bytes, mean=4961.976, median=4965.000, p95=5224.700, max=5400, bitrate=80.283660 kbit/s, baseline_diff=-0.000000, baseline_percent=100.000%, compression=11.608x, PSNR=34.362114 dB
Максимальное разрешение до 100 кбит/с:
320x180_gray8_jpeg_2fps: mode=gray8_jpeg, 320x180, frames=42, actual_fps=2.022472, total=208403 bytes, mean=4961.976, median=4965.000, p95=5224.700, max=5400, bitrate=80.283660 kbit/s, baseline_diff=-0.000000, baseline_percent=100.000%, compression=11.608x, PSNR=34.362114 dB
320x180_gray4_jpeg_2fps: mode=gray4_jpeg, 320x180, frames=42, actual_fps=2.022472, total=229518 bytes, mean=5464.714, median=5466.000, p95=5727.250, max=5822, bitrate=88.417849 kbit/s, baseline_diff=8.134189, baseline_percent=110.132%, compression=10.540x, PSNR=32.588941 dB
Сравнение gray4 и color16:
Минимальный gray4 bitrate: 88.417849 кбит/с.
Минимальный color16 bitrate: 140.568347 кбит/с.
Размер палитры packed color16: 48 байт на кадр.
Размер компактного заголовка packed-режимов: 16 байт на кадр.
Нельзя автоматически объявлять профиль безопасным для управления ровером по одной статической метрике.
Сравнительное изображение: data\processed\lab026b\lab026b_equal_bitrate_candidates.png
Следующий шаг: ручная визуальная оценка пользователем.

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -0,0 +1,10 @@
profile_name,base_width,base_height,base_fps,base_quality,roi_enabled,roi_x_min,roi_y_min,roi_x_max,roi_y_max,roi_width,roi_height,roi_fps,roi_quality,source_duration_s,selected_base_frames,selected_roi_frames,actual_base_fps,actual_roi_fps,total_base_bytes,total_roi_bytes,total_payload_bytes,mean_base_frame_bytes,mean_roi_frame_bytes,p95_base_frame_bytes,p95_roi_frame_bytes,max_base_frame_bytes,max_roi_frame_bytes,base_bitrate_kbps,roi_bitrate_kbps,total_payload_bitrate_kbps,baseline_bitrate_kbps,difference_from_baseline_kbps,percent_of_baseline,mean_base_jpeg_psnr_db,mean_roi_jpeg_psnr_db,mean_reconstructed_full_psnr_db,mean_reconstructed_roi_psnr_db
baseline_320x180_gray_2fps_q40,320,180,2.000000,40,0,0.000000,0.000000,0.000000,0.000000,0,0,0.000000,0,20.766667,42,0,2.022472,0.000000,208368,0,208368,4961.143,0.000,5226.950,0.000,5390,0,80.270177,0.000000,80.270177,80.283660,-0.013483,99.983205,34.364165,,20.757991,
base240_1fps_q25_roi320_2fps_q35,240,135,1.000000,25,1,0.200000,0.420000,0.800000,1.000000,320,180,2.000000,35,20.766667,21,42,1.011236,2.022472,50858,191270,242128,2421.810,4554.048,2554.000,5044.500,2569,5172,19.592167,73.683467,93.275634,80.283660,12.991974,116.182588,32.370927,34.103745,19.657187,19.574377
base240_0_5fps_q25_roi320_2fps_q35,240,135,0.500000,25,1,0.200000,0.420000,0.800000,1.000000,320,180,2.000000,35,20.766667,11,42,0.529695,2.022472,26348,191270,217618,2395.273,4554.048,2561.500,5044.500,2569,5172,10.150112,73.683467,83.833579,80.283660,3.549919,104.421721,32.474572,34.103745,18.613817,19.574377
base160_1fps_q25_roi320_2fps_q35,160,90,1.000000,25,1,0.200000,0.420000,0.800000,1.000000,320,180,2.000000,35,20.766667,21,42,1.011236,2.022472,29882,191270,221152,1422.952,4554.048,1484.000,5044.500,1492,5172,11.511525,73.683467,85.194992,80.283660,4.911332,106.117474,31.458773,34.103745,19.701304,19.574377
base240_1fps_q25_roi448_1fps_q30,240,135,1.000000,25,1,0.200000,0.420000,0.800000,1.000000,448,252,1.000000,30,20.766667,21,21,1.011236,1.011236,50858,147787,198645,2421.810,7037.476,2554.000,7860.000,2569,8507,19.592167,56.932392,76.524559,80.283660,-3.759101,95.317725,32.370927,34.666932,19.098790,17.871555
base240_0_5fps_q25_roi448_1fps_q30,240,135,0.500000,25,1,0.200000,0.420000,0.800000,1.000000,448,252,1.000000,30,20.766667,11,21,0.529695,1.011236,26348,147787,174135,2395.273,7037.476,2561.500,7860.000,2569,8507,10.150112,56.932392,67.082504,80.283660,-13.201156,83.556858,32.474572,34.666932,18.113877,17.871555
base320_1fps_q30_roi320_1fps_q35,320,180,1.000000,30,1,0.200000,0.420000,0.800000,1.000000,320,180,1.000000,35,20.766667,21,21,1.011236,1.011236,87901,95367,183268,4185.762,4541.286,4391.000,5048.000,4537,5172,33.862343,36.738491,70.600835,80.283660,-9.682825,87.939233,33.539230,34.103514,19.121457,17.888190
base240_1fps_q20_roi320_1fps_q30,240,135,1.000000,20,1,0.200000,0.420000,0.800000,1.000000,320,180,1.000000,30,20.766667,21,21,1.011236,1.011236,44598,86458,131056,2123.714,4117.048,2231.000,4551.000,2251,4614,17.180610,33.306453,50.487063,80.283660,-29.796597,62.885851,31.643522,33.598412,19.107784,17.873870
base160_0_5fps_q20_roi320_2fps_q30,160,90,0.500000,20,1,0.200000,0.420000,0.800000,1.000000,320,180,2.000000,30,20.766667,11,42,0.529695,2.022472,13820,173455,187275,1256.364,4129.881,1326.000,4548.450,1347,4614,5.323917,66.820546,72.144462,80.283660,-8.139198,89.861950,30.823518,33.595566,18.664976,19.549559
1 profile_name base_width base_height base_fps base_quality roi_enabled roi_x_min roi_y_min roi_x_max roi_y_max roi_width roi_height roi_fps roi_quality source_duration_s selected_base_frames selected_roi_frames actual_base_fps actual_roi_fps total_base_bytes total_roi_bytes total_payload_bytes mean_base_frame_bytes mean_roi_frame_bytes p95_base_frame_bytes p95_roi_frame_bytes max_base_frame_bytes max_roi_frame_bytes base_bitrate_kbps roi_bitrate_kbps total_payload_bitrate_kbps baseline_bitrate_kbps difference_from_baseline_kbps percent_of_baseline mean_base_jpeg_psnr_db mean_roi_jpeg_psnr_db mean_reconstructed_full_psnr_db mean_reconstructed_roi_psnr_db
2 baseline_320x180_gray_2fps_q40 320 180 2.000000 40 0 0.000000 0.000000 0.000000 0.000000 0 0 0.000000 0 20.766667 42 0 2.022472 0.000000 208368 0 208368 4961.143 0.000 5226.950 0.000 5390 0 80.270177 0.000000 80.270177 80.283660 -0.013483 99.983205 34.364165 20.757991
3 base240_1fps_q25_roi320_2fps_q35 240 135 1.000000 25 1 0.200000 0.420000 0.800000 1.000000 320 180 2.000000 35 20.766667 21 42 1.011236 2.022472 50858 191270 242128 2421.810 4554.048 2554.000 5044.500 2569 5172 19.592167 73.683467 93.275634 80.283660 12.991974 116.182588 32.370927 34.103745 19.657187 19.574377
4 base240_0_5fps_q25_roi320_2fps_q35 240 135 0.500000 25 1 0.200000 0.420000 0.800000 1.000000 320 180 2.000000 35 20.766667 11 42 0.529695 2.022472 26348 191270 217618 2395.273 4554.048 2561.500 5044.500 2569 5172 10.150112 73.683467 83.833579 80.283660 3.549919 104.421721 32.474572 34.103745 18.613817 19.574377
5 base160_1fps_q25_roi320_2fps_q35 160 90 1.000000 25 1 0.200000 0.420000 0.800000 1.000000 320 180 2.000000 35 20.766667 21 42 1.011236 2.022472 29882 191270 221152 1422.952 4554.048 1484.000 5044.500 1492 5172 11.511525 73.683467 85.194992 80.283660 4.911332 106.117474 31.458773 34.103745 19.701304 19.574377
6 base240_1fps_q25_roi448_1fps_q30 240 135 1.000000 25 1 0.200000 0.420000 0.800000 1.000000 448 252 1.000000 30 20.766667 21 21 1.011236 1.011236 50858 147787 198645 2421.810 7037.476 2554.000 7860.000 2569 8507 19.592167 56.932392 76.524559 80.283660 -3.759101 95.317725 32.370927 34.666932 19.098790 17.871555
7 base240_0_5fps_q25_roi448_1fps_q30 240 135 0.500000 25 1 0.200000 0.420000 0.800000 1.000000 448 252 1.000000 30 20.766667 11 21 0.529695 1.011236 26348 147787 174135 2395.273 7037.476 2561.500 7860.000 2569 8507 10.150112 56.932392 67.082504 80.283660 -13.201156 83.556858 32.474572 34.666932 18.113877 17.871555
8 base320_1fps_q30_roi320_1fps_q35 320 180 1.000000 30 1 0.200000 0.420000 0.800000 1.000000 320 180 1.000000 35 20.766667 21 21 1.011236 1.011236 87901 95367 183268 4185.762 4541.286 4391.000 5048.000 4537 5172 33.862343 36.738491 70.600835 80.283660 -9.682825 87.939233 33.539230 34.103514 19.121457 17.888190
9 base240_1fps_q20_roi320_1fps_q30 240 135 1.000000 20 1 0.200000 0.420000 0.800000 1.000000 320 180 1.000000 30 20.766667 21 21 1.011236 1.011236 44598 86458 131056 2123.714 4117.048 2231.000 4551.000 2251 4614 17.180610 33.306453 50.487063 80.283660 -29.796597 62.885851 31.643522 33.598412 19.107784 17.873870
10 base160_0_5fps_q20_roi320_2fps_q30 160 90 0.500000 20 1 0.200000 0.420000 0.800000 1.000000 320 180 2.000000 30 20.766667 11 42 0.529695 2.022472 13820 173455 187275 1256.364 4129.881 1326.000 4548.450 1347 4614 5.323917 66.820546 72.144462 80.283660 -8.139198 89.861950 30.823518 33.595566 18.664976 19.549559

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -0,0 +1,74 @@
Lab027. Многомасштабная передача изображения: общий кадр и область интереса
Цель: проверить совместную передачу общего кадра и фиксированной ROI при payload около 80100 кбит/с.
Исходное видео: data\raw\lab026_rover_source.mp4
Размер файла: 7790985 байт
Исходное разрешение: 1280×720
Исходный FPS: 30.000000
Число кадров: 623
Длительность: 20.766667 с
BASE: полный grayscale-кадр пониженного разрешения с собственной частотой и JPEG quality.
ROI: фиксированная центральная нижняя область исходного grayscale-кадра с независимыми разрешением, частотой и JPEG quality.
Нормализованные координаты ROI: x=0.20...0.80, y=0.42...1.00.
Пиксельные координаты ROI исходного кадра: x=256...1024, y=302...720.
Контрольный профиль: 320×180 grayscale, 2 fps, JPEG Q40.
Контрольный baseline: 80.283660 кбит/с.
Результаты всех девяти профилей:
baseline_320x180_gray_2fps_q40: BASE=320x180, 2.000 fps, Q40, base_frames=42, base=80.270177 kbit/s; ROI=0x0, 0.000 fps, Q0, roi_frames=0, roi=0.000000 kbit/s; total=80.270177 kbit/s, baseline_diff=-0.013483, baseline_percent=99.983%, BASE_JPEG_PSNR=34.364165 dB, ROI_JPEG_PSNR=нет dB, full_reconstructed_PSNR=20.757991 dB, ROI_reconstructed_PSNR=нет dB
base240_1fps_q25_roi320_2fps_q35: BASE=240x135, 1.000 fps, Q25, base_frames=21, base=19.592167 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi=73.683467 kbit/s; total=93.275634 kbit/s, baseline_diff=12.991974, baseline_percent=116.183%, BASE_JPEG_PSNR=32.370927 dB, ROI_JPEG_PSNR=34.103745 dB, full_reconstructed_PSNR=19.657187 dB, ROI_reconstructed_PSNR=19.574377 dB
base240_0_5fps_q25_roi320_2fps_q35: BASE=240x135, 0.500 fps, Q25, base_frames=11, base=10.150112 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi=73.683467 kbit/s; total=83.833579 kbit/s, baseline_diff=3.549919, baseline_percent=104.422%, BASE_JPEG_PSNR=32.474572 dB, ROI_JPEG_PSNR=34.103745 dB, full_reconstructed_PSNR=18.613817 dB, ROI_reconstructed_PSNR=19.574377 dB
base160_1fps_q25_roi320_2fps_q35: BASE=160x90, 1.000 fps, Q25, base_frames=21, base=11.511525 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi=73.683467 kbit/s; total=85.194992 kbit/s, baseline_diff=4.911332, baseline_percent=106.117%, BASE_JPEG_PSNR=31.458773 dB, ROI_JPEG_PSNR=34.103745 dB, full_reconstructed_PSNR=19.701304 dB, ROI_reconstructed_PSNR=19.574377 dB
base240_1fps_q25_roi448_1fps_q30: BASE=240x135, 1.000 fps, Q25, base_frames=21, base=19.592167 kbit/s; ROI=448x252, 1.000 fps, Q30, roi_frames=21, roi=56.932392 kbit/s; total=76.524559 kbit/s, baseline_diff=-3.759101, baseline_percent=95.318%, BASE_JPEG_PSNR=32.370927 dB, ROI_JPEG_PSNR=34.666932 dB, full_reconstructed_PSNR=19.098790 dB, ROI_reconstructed_PSNR=17.871555 dB
base240_0_5fps_q25_roi448_1fps_q30: BASE=240x135, 0.500 fps, Q25, base_frames=11, base=10.150112 kbit/s; ROI=448x252, 1.000 fps, Q30, roi_frames=21, roi=56.932392 kbit/s; total=67.082504 kbit/s, baseline_diff=-13.201156, baseline_percent=83.557%, BASE_JPEG_PSNR=32.474572 dB, ROI_JPEG_PSNR=34.666932 dB, full_reconstructed_PSNR=18.113877 dB, ROI_reconstructed_PSNR=17.871555 dB
base320_1fps_q30_roi320_1fps_q35: BASE=320x180, 1.000 fps, Q30, base_frames=21, base=33.862343 kbit/s; ROI=320x180, 1.000 fps, Q35, roi_frames=21, roi=36.738491 kbit/s; total=70.600835 kbit/s, baseline_diff=-9.682825, baseline_percent=87.939%, BASE_JPEG_PSNR=33.539230 dB, ROI_JPEG_PSNR=34.103514 dB, full_reconstructed_PSNR=19.121457 dB, ROI_reconstructed_PSNR=17.888190 dB
base240_1fps_q20_roi320_1fps_q30: BASE=240x135, 1.000 fps, Q20, base_frames=21, base=17.180610 kbit/s; ROI=320x180, 1.000 fps, Q30, roi_frames=21, roi=33.306453 kbit/s; total=50.487063 kbit/s, baseline_diff=-29.796597, baseline_percent=62.886%, BASE_JPEG_PSNR=31.643522 dB, ROI_JPEG_PSNR=33.598412 dB, full_reconstructed_PSNR=19.107784 dB, ROI_reconstructed_PSNR=17.873870 dB
base160_0_5fps_q20_roi320_2fps_q30: BASE=160x90, 0.500 fps, Q20, base_frames=11, base=5.323917 kbit/s; ROI=320x180, 2.000 fps, Q30, roi_frames=42, roi=66.820546 kbit/s; total=72.144462 kbit/s, baseline_diff=-8.139198, baseline_percent=89.862%, BASE_JPEG_PSNR=30.823518 dB, ROI_JPEG_PSNR=33.595566 dB, full_reconstructed_PSNR=18.664976 dB, ROI_reconstructed_PSNR=19.549559 dB
Профили до 80.283660 кбит/с:
baseline_320x180_gray_2fps_q40: BASE=320x180, 2.000 fps, Q40, base_frames=42, base=80.270177 kbit/s; ROI=0x0, 0.000 fps, Q0, roi_frames=0, roi=0.000000 kbit/s; total=80.270177 kbit/s, baseline_diff=-0.013483, baseline_percent=99.983%, BASE_JPEG_PSNR=34.364165 dB, ROI_JPEG_PSNR=нет dB, full_reconstructed_PSNR=20.757991 dB, ROI_reconstructed_PSNR=нет dB
base240_1fps_q25_roi448_1fps_q30: BASE=240x135, 1.000 fps, Q25, base_frames=21, base=19.592167 kbit/s; ROI=448x252, 1.000 fps, Q30, roi_frames=21, roi=56.932392 kbit/s; total=76.524559 kbit/s, baseline_diff=-3.759101, baseline_percent=95.318%, BASE_JPEG_PSNR=32.370927 dB, ROI_JPEG_PSNR=34.666932 dB, full_reconstructed_PSNR=19.098790 dB, ROI_reconstructed_PSNR=17.871555 dB
base240_0_5fps_q25_roi448_1fps_q30: BASE=240x135, 0.500 fps, Q25, base_frames=11, base=10.150112 kbit/s; ROI=448x252, 1.000 fps, Q30, roi_frames=21, roi=56.932392 kbit/s; total=67.082504 kbit/s, baseline_diff=-13.201156, baseline_percent=83.557%, BASE_JPEG_PSNR=32.474572 dB, ROI_JPEG_PSNR=34.666932 dB, full_reconstructed_PSNR=18.113877 dB, ROI_reconstructed_PSNR=17.871555 dB
base320_1fps_q30_roi320_1fps_q35: BASE=320x180, 1.000 fps, Q30, base_frames=21, base=33.862343 kbit/s; ROI=320x180, 1.000 fps, Q35, roi_frames=21, roi=36.738491 kbit/s; total=70.600835 kbit/s, baseline_diff=-9.682825, baseline_percent=87.939%, BASE_JPEG_PSNR=33.539230 dB, ROI_JPEG_PSNR=34.103514 dB, full_reconstructed_PSNR=19.121457 dB, ROI_reconstructed_PSNR=17.888190 dB
base240_1fps_q20_roi320_1fps_q30: BASE=240x135, 1.000 fps, Q20, base_frames=21, base=17.180610 kbit/s; ROI=320x180, 1.000 fps, Q30, roi_frames=21, roi=33.306453 kbit/s; total=50.487063 kbit/s, baseline_diff=-29.796597, baseline_percent=62.886%, BASE_JPEG_PSNR=31.643522 dB, ROI_JPEG_PSNR=33.598412 dB, full_reconstructed_PSNR=19.107784 dB, ROI_reconstructed_PSNR=17.873870 dB
base160_0_5fps_q20_roi320_2fps_q30: BASE=160x90, 0.500 fps, Q20, base_frames=11, base=5.323917 kbit/s; ROI=320x180, 2.000 fps, Q30, roi_frames=42, roi=66.820546 kbit/s; total=72.144462 kbit/s, baseline_diff=-8.139198, baseline_percent=89.862%, BASE_JPEG_PSNR=30.823518 dB, ROI_JPEG_PSNR=33.595566 dB, full_reconstructed_PSNR=18.664976 dB, ROI_reconstructed_PSNR=19.549559 dB
Профили до 100 кбит/с:
baseline_320x180_gray_2fps_q40: BASE=320x180, 2.000 fps, Q40, base_frames=42, base=80.270177 kbit/s; ROI=0x0, 0.000 fps, Q0, roi_frames=0, roi=0.000000 kbit/s; total=80.270177 kbit/s, baseline_diff=-0.013483, baseline_percent=99.983%, BASE_JPEG_PSNR=34.364165 dB, ROI_JPEG_PSNR=нет dB, full_reconstructed_PSNR=20.757991 dB, ROI_reconstructed_PSNR=нет dB
base240_1fps_q25_roi320_2fps_q35: BASE=240x135, 1.000 fps, Q25, base_frames=21, base=19.592167 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi=73.683467 kbit/s; total=93.275634 kbit/s, baseline_diff=12.991974, baseline_percent=116.183%, BASE_JPEG_PSNR=32.370927 dB, ROI_JPEG_PSNR=34.103745 dB, full_reconstructed_PSNR=19.657187 dB, ROI_reconstructed_PSNR=19.574377 dB
base240_0_5fps_q25_roi320_2fps_q35: BASE=240x135, 0.500 fps, Q25, base_frames=11, base=10.150112 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi=73.683467 kbit/s; total=83.833579 kbit/s, baseline_diff=3.549919, baseline_percent=104.422%, BASE_JPEG_PSNR=32.474572 dB, ROI_JPEG_PSNR=34.103745 dB, full_reconstructed_PSNR=18.613817 dB, ROI_reconstructed_PSNR=19.574377 dB
base160_1fps_q25_roi320_2fps_q35: BASE=160x90, 1.000 fps, Q25, base_frames=21, base=11.511525 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi=73.683467 kbit/s; total=85.194992 kbit/s, baseline_diff=4.911332, baseline_percent=106.117%, BASE_JPEG_PSNR=31.458773 dB, ROI_JPEG_PSNR=34.103745 dB, full_reconstructed_PSNR=19.701304 dB, ROI_reconstructed_PSNR=19.574377 dB
base240_1fps_q25_roi448_1fps_q30: BASE=240x135, 1.000 fps, Q25, base_frames=21, base=19.592167 kbit/s; ROI=448x252, 1.000 fps, Q30, roi_frames=21, roi=56.932392 kbit/s; total=76.524559 kbit/s, baseline_diff=-3.759101, baseline_percent=95.318%, BASE_JPEG_PSNR=32.370927 dB, ROI_JPEG_PSNR=34.666932 dB, full_reconstructed_PSNR=19.098790 dB, ROI_reconstructed_PSNR=17.871555 dB
base240_0_5fps_q25_roi448_1fps_q30: BASE=240x135, 0.500 fps, Q25, base_frames=11, base=10.150112 kbit/s; ROI=448x252, 1.000 fps, Q30, roi_frames=21, roi=56.932392 kbit/s; total=67.082504 kbit/s, baseline_diff=-13.201156, baseline_percent=83.557%, BASE_JPEG_PSNR=32.474572 dB, ROI_JPEG_PSNR=34.666932 dB, full_reconstructed_PSNR=18.113877 dB, ROI_reconstructed_PSNR=17.871555 dB
base320_1fps_q30_roi320_1fps_q35: BASE=320x180, 1.000 fps, Q30, base_frames=21, base=33.862343 kbit/s; ROI=320x180, 1.000 fps, Q35, roi_frames=21, roi=36.738491 kbit/s; total=70.600835 kbit/s, baseline_diff=-9.682825, baseline_percent=87.939%, BASE_JPEG_PSNR=33.539230 dB, ROI_JPEG_PSNR=34.103514 dB, full_reconstructed_PSNR=19.121457 dB, ROI_reconstructed_PSNR=17.888190 dB
base240_1fps_q20_roi320_1fps_q30: BASE=240x135, 1.000 fps, Q20, base_frames=21, base=17.180610 kbit/s; ROI=320x180, 1.000 fps, Q30, roi_frames=21, roi=33.306453 kbit/s; total=50.487063 kbit/s, baseline_diff=-29.796597, baseline_percent=62.886%, BASE_JPEG_PSNR=31.643522 dB, ROI_JPEG_PSNR=33.598412 dB, full_reconstructed_PSNR=19.107784 dB, ROI_reconstructed_PSNR=17.873870 dB
base160_0_5fps_q20_roi320_2fps_q30: BASE=160x90, 0.500 fps, Q20, base_frames=11, base=5.323917 kbit/s; ROI=320x180, 2.000 fps, Q30, roi_frames=42, roi=66.820546 kbit/s; total=72.144462 kbit/s, baseline_diff=-8.139198, baseline_percent=89.862%, BASE_JPEG_PSNR=30.823518 dB, ROI_JPEG_PSNR=33.595566 dB, full_reconstructed_PSNR=18.664976 dB, ROI_reconstructed_PSNR=19.549559 dB
Профиль с максимальным ROI-разрешением до 100 кбит/с:
base240_1fps_q25_roi448_1fps_q30: BASE=240x135, 1.000 fps, Q25, base_frames=21, base=19.592167 kbit/s; ROI=448x252, 1.000 fps, Q30, roi_frames=21, roi=56.932392 kbit/s; total=76.524559 kbit/s, baseline_diff=-3.759101, baseline_percent=95.318%, BASE_JPEG_PSNR=32.370927 dB, ROI_JPEG_PSNR=34.666932 dB, full_reconstructed_PSNR=19.098790 dB, ROI_reconstructed_PSNR=17.871555 dB
Профиль с максимальным ROI PSNR до 100 кбит/с:
base240_1fps_q25_roi320_2fps_q35: BASE=240x135, 1.000 fps, Q25, base_frames=21, base=19.592167 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi=73.683467 kbit/s; total=93.275634 kbit/s, baseline_diff=12.991974, baseline_percent=116.183%, BASE_JPEG_PSNR=32.370927 dB, ROI_JPEG_PSNR=34.103745 dB, full_reconstructed_PSNR=19.657187 dB, ROI_reconstructed_PSNR=19.574377 dB
Профиль с максимальным full-frame PSNR до 100 кбит/с:
baseline_320x180_gray_2fps_q40: BASE=320x180, 2.000 fps, Q40, base_frames=42, base=80.270177 kbit/s; ROI=0x0, 0.000 fps, Q0, roi_frames=0, roi=0.000000 kbit/s; total=80.270177 kbit/s, baseline_diff=-0.013483, baseline_percent=99.983%, BASE_JPEG_PSNR=34.364165 dB, ROI_JPEG_PSNR=нет dB, full_reconstructed_PSNR=20.757991 dB, ROI_reconstructed_PSNR=нет dB
Разделение битрейта BASE/ROI:
baseline_320x180_gray_2fps_q40: BASE=80.270177 кбит/с, ROI=0.000000 кбит/с, total=80.270177 кбит/с.
base240_1fps_q25_roi320_2fps_q35: BASE=19.592167 кбит/с, ROI=73.683467 кбит/с, total=93.275634 кбит/с.
base240_0_5fps_q25_roi320_2fps_q35: BASE=10.150112 кбит/с, ROI=73.683467 кбит/с, total=83.833579 кбит/с.
base160_1fps_q25_roi320_2fps_q35: BASE=11.511525 кбит/с, ROI=73.683467 кбит/с, total=85.194992 кбит/с.
base240_1fps_q25_roi448_1fps_q30: BASE=19.592167 кбит/с, ROI=56.932392 кбит/с, total=76.524559 кбит/с.
base240_0_5fps_q25_roi448_1fps_q30: BASE=10.150112 кбит/с, ROI=56.932392 кбит/с, total=67.082504 кбит/с.
base320_1fps_q30_roi320_1fps_q35: BASE=33.862343 кбит/с, ROI=36.738491 кбит/с, total=70.600835 кбит/с.
base240_1fps_q20_roi320_1fps_q30: BASE=17.180610 кбит/с, ROI=33.306453 кбит/с, total=50.487063 кбит/с.
base160_0_5fps_q20_roi320_2fps_q30: BASE=5.323917 кбит/с, ROI=66.820546 кбит/с, total=72.144462 кбит/с.
Фиксированная ROI не гарантирует попадания препятствия в область интереса.
PSNR не заменяет ручную оценку пригодности изображения.
Нельзя автоматически объявлять профиль безопасным для управления ровером.
Радиопротокол, радиозаголовки, CRC, FEC, фрагментация и повторные передачи не учтены.
Сравнительное изображение: data\processed\lab027\lab027_candidate_profiles.png
Следующий шаг: ручная оценка пользователем.

View File

@@ -0,0 +1,5 @@
profile_name,update_mode,base_width,base_height,base_fps,base_quality,roi_width,roi_height,roi_fps,roi_quality,source_duration_s,selected_base_frames,selected_roi_frames,synchronized_composite_frames,total_base_bytes,total_roi_bytes,total_payload_bytes,mean_base_frame_bytes,mean_roi_frame_bytes,mean_composite_frame_bytes,p95_composite_frame_bytes,max_composite_frame_bytes,base_bitrate_kbps,roi_bitrate_kbps,total_payload_bitrate_kbps,timestamp_mismatch_count,frame_id_mismatch_count
async_reference,asynchronous,240,135,1.000000,25,320,180,2.000000,35,20.766667,21,42,N/A,50858,191270,242128,2421.810,4554.048,5764.952,7477.600,7741,19.592167,73.683467,93.275634,N/A,N/A
sync_base160_q25_roi320_q35,synchronous,160,90,2.000000,25,320,180,2.000000,35,20.766667,42,42,42,59958,191270,251228,1427.571,4554.048,5981.619,6519.900,6656,23.097785,73.683467,96.781252,0,0
sync_base240_q20_roi320_q30,synchronous,240,135,2.000000,20,320,180,2.000000,30,20.766667,42,42,42,89696,173455,263151,2135.619,4129.881,6265.500,6780.400,6842,34.553836,66.820546,101.374382,0,0
sync_base240_q25_roi320_q35,synchronous,240,135,2.000000,25,320,180,2.000000,35,20.766667,42,42,42,102283,191270,293553,2435.310,4554.048,6989.357,7572.350,7741,39.402761,73.683467,113.086228,0,0
1 profile_name update_mode base_width base_height base_fps base_quality roi_width roi_height roi_fps roi_quality source_duration_s selected_base_frames selected_roi_frames synchronized_composite_frames total_base_bytes total_roi_bytes total_payload_bytes mean_base_frame_bytes mean_roi_frame_bytes mean_composite_frame_bytes p95_composite_frame_bytes max_composite_frame_bytes base_bitrate_kbps roi_bitrate_kbps total_payload_bitrate_kbps timestamp_mismatch_count frame_id_mismatch_count
2 async_reference asynchronous 240 135 1.000000 25 320 180 2.000000 35 20.766667 21 42 N/A 50858 191270 242128 2421.810 4554.048 5764.952 7477.600 7741 19.592167 73.683467 93.275634 N/A N/A
3 sync_base160_q25_roi320_q35 synchronous 160 90 2.000000 25 320 180 2.000000 35 20.766667 42 42 42 59958 191270 251228 1427.571 4554.048 5981.619 6519.900 6656 23.097785 73.683467 96.781252 0 0
4 sync_base240_q20_roi320_q30 synchronous 240 135 2.000000 20 320 180 2.000000 30 20.766667 42 42 42 89696 173455 263151 2135.619 4129.881 6265.500 6780.400 6842 34.553836 66.820546 101.374382 0 0
5 sync_base240_q25_roi320_q35 synchronous 240 135 2.000000 25 320 180 2.000000 35 20.766667 42 42 42 102283 191270 293553 2435.310 4554.048 6989.357 7572.350 7741 39.402761 73.683467 113.086228 0 0

View File

@@ -0,0 +1,44 @@
Lab027C. Динамическое сравнение асинхронного и синхронного BASE + ROI
Цель: визуально сравнить ранее выбранный асинхронный профиль BASE 1 fps + ROI 2 fps с тремя синхронными профилями BASE 2 fps + ROI 2 fps.
Исходное видео: data\raw\lab026_rover_source.mp4
Исходное разрешение: 1280x720
Исходный FPS: 30.000000
Число кадров: 623
Длительность: 20.766667 с
ROI: x=0.20...0.80, y=0.42...1.00; пиксели x=256...1024, y=302...720.
Результат ручной оценки предыдущей Lab027:
- пользователь выбрал вариант B;
- граница ROI не мешает;
- обновление BASE один раз в секунду мешает;
- рассинхронное движение BASE и ROI мешает;
- принято решение сравнить с синхронным обновлением 2 fps.
async_reference: BASE и ROI обновляются независимо. Единого logical_frame_id нет; используются отдельные BASE ID и ROI ID. Mismatch для этого режима неприменим.
Синхронные профили: BASE и ROI формируются из одного source frame, получают единые composite ID и timestamp и атомарно заменяют отображаемый составной кадр.
Фактические результаты четырёх профилей:
async_reference: mode=asynchronous, BASE=240x135, 1.000 fps, Q25, base_frames=21, base_bytes=50858, base_bitrate=19.592167 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi_bytes=191270, roi_bitrate=73.683467 kbit/s; total_bytes=242128, total_bitrate=93.275634 kbit/s, sync_frames=N/A, timestamp_mismatch=N/A, frame_id_mismatch=N/A
sync_base160_q25_roi320_q35: mode=synchronous, BASE=160x90, 2.000 fps, Q25, base_frames=42, base_bytes=59958, base_bitrate=23.097785 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi_bytes=191270, roi_bitrate=73.683467 kbit/s; total_bytes=251228, total_bitrate=96.781252 kbit/s, sync_frames=42, timestamp_mismatch=0, frame_id_mismatch=0
sync_base240_q20_roi320_q30: mode=synchronous, BASE=240x135, 2.000 fps, Q20, base_frames=42, base_bytes=89696, base_bitrate=34.553836 kbit/s; ROI=320x180, 2.000 fps, Q30, roi_frames=42, roi_bytes=173455, roi_bitrate=66.820546 kbit/s; total_bytes=263151, total_bitrate=101.374382 kbit/s, sync_frames=42, timestamp_mismatch=0, frame_id_mismatch=0
sync_base240_q25_roi320_q35: mode=synchronous, BASE=240x135, 2.000 fps, Q25, base_frames=42, base_bytes=102283, base_bitrate=39.402761 kbit/s; ROI=320x180, 2.000 fps, Q35, roi_frames=42, roi_bytes=191270, roi_bitrate=73.683467 kbit/s; total_bytes=293553, total_bitrate=113.086228 kbit/s, sync_frames=42, timestamp_mismatch=0, frame_id_mismatch=0
Количество обновлений:
async_reference: BASE=21, ROI=42, synchronized=N/A.
sync_base160_q25_roi320_q35: BASE=42, ROI=42, synchronized=42.
sync_base240_q20_roi320_q30: BASE=42, ROI=42, synchronized=42.
sync_base240_q25_roi320_q35: BASE=42, ROI=42, synchronized=42.
Mismatch-проверка:
async_reference: timestamp=N/A, frame_id=N/A.
sync_base160_q25_roi320_q35: timestamp=0, frame_id=0.
sync_base240_q20_roi320_q30: timestamp=0, frame_id=0.
sync_base240_q25_roi320_q35: timestamp=0, frame_id=0.
Preview: data\raw\lab027c_previews\lab027c_synchronous_roi_preview.mp4
Формат: MP4/mp4v.
Радиопротокол, CRC, FEC, фрагментация и служебный трафик пока не учитываются.
Программа не выбирает лучший профиль и не объявляет режим безопасным автоматически.
Следующий шаг: ручной выбор пользователем после просмотра preview-видео.

View File

@@ -0,0 +1,5 @@
profile_name,base_width,base_height,fps,base_quality,roi_width,roi_height,roi_quality,source_duration_s,selected_base_frames,selected_roi_frames,synchronized_composite_frames,total_base_bytes,total_roi_bytes,total_payload_bytes,mean_base_frame_bytes,mean_roi_frame_bytes,mean_composite_frame_bytes,p95_composite_frame_bytes,max_composite_frame_bytes,base_bitrate_kbps,roi_bitrate_kbps,total_payload_bitrate_kbps,channel_rate_fec_2_3_kbps,channel_rate_fec_1_2_kbps,timestamp_mismatch_count,frame_id_mismatch_count
sync_2fps_base_q20_roi_q30,240,135,2.000000,20,320,180,30,20.766667,42,42,42,89696,173455,263151,2135.619,4129.881,6265.500,6780.400,6842,34.553836,66.820546,101.374382,167.267730,223.023640,0,0
sync_3fps_base_q20_roi_q30,240,135,3.000000,20,320,180,30,20.766667,63,63,63,133076,249436,382512,2112.317,3959.302,6071.619,6640.800,6842,51.265233,96.090915,147.356148,243.137644,324.183525,0,0
sync_3fps_base_q23_roi_q33,240,135,3.000000,23,320,180,33,20.766667,63,63,63,144649,264895,409544,2296.016,4204.683,6500.698,7125.400,7383,55.723531,102.046228,157.769759,260.320103,347.093470,0,0
sync_3fps_base_q25_roi_q35,240,135,3.000000,25,320,180,35,20.766667,63,63,63,151516,274486,426002,2405.016,4356.921,6761.937,7421.700,7741,58.368925,105.740995,164.109920,270.781368,361.041823,0,0
1 profile_name base_width base_height fps base_quality roi_width roi_height roi_quality source_duration_s selected_base_frames selected_roi_frames synchronized_composite_frames total_base_bytes total_roi_bytes total_payload_bytes mean_base_frame_bytes mean_roi_frame_bytes mean_composite_frame_bytes p95_composite_frame_bytes max_composite_frame_bytes base_bitrate_kbps roi_bitrate_kbps total_payload_bitrate_kbps channel_rate_fec_2_3_kbps channel_rate_fec_1_2_kbps timestamp_mismatch_count frame_id_mismatch_count
2 sync_2fps_base_q20_roi_q30 240 135 2.000000 20 320 180 30 20.766667 42 42 42 89696 173455 263151 2135.619 4129.881 6265.500 6780.400 6842 34.553836 66.820546 101.374382 167.267730 223.023640 0 0
3 sync_3fps_base_q20_roi_q30 240 135 3.000000 20 320 180 30 20.766667 63 63 63 133076 249436 382512 2112.317 3959.302 6071.619 6640.800 6842 51.265233 96.090915 147.356148 243.137644 324.183525 0 0
4 sync_3fps_base_q23_roi_q33 240 135 3.000000 23 320 180 33 20.766667 63 63 63 144649 264895 409544 2296.016 4204.683 6500.698 7125.400 7383 55.723531 102.046228 157.769759 260.320103 347.093470 0 0
5 sync_3fps_base_q25_roi_q35 240 135 3.000000 25 320 180 35 20.766667 63 63 63 151516 274486 426002 2405.016 4356.921 6761.937 7421.700 7741 58.368925 105.740995 164.109920 270.781368 361.041823 0 0

View File

@@ -0,0 +1,37 @@
Lab027D. Синхронный BASE + ROI при 2 и 3 fps
Цель: сравнить текущий синхронный профиль 2 fps с тремя профилями 3 fps при разных JPEG Quality.
Результат ручной оценки Lab027C:
- лучший из показанных вариантов — нижний левый;
- синхронизация BASE и ROI устранила рассогласование;
- 2 fps недостаточно;
- BASE 160x90 слишком грубый;
- BASE 240x135 Q20 немного недостаточен по качеству.
Причина повышения FPS: ручная оценка показала, что синхронное обновление устраняет рассогласование, но частота 2 fps недостаточна для динамической сцены.
Исходное видео: data\raw\lab026_rover_source.mp4
Разрешение: 1280x720
FPS: 30.000000
Кадров: 623
Длительность: 20.766667 с
ROI: x=0.20...0.80, y=0.42...1.00; пиксели x=256...1024, y=302...720.
Все профили синхронные: BASE и ROI формируются из одного source frame, получают единый timestamp и composite frame ID и публикуются атомарно.
Фактические результаты:
sync_2fps_base_q20_roi_q30: 2.000 fps; BASE=240x135, Q20, frames=42, bytes=89696, bitrate=34.553836 kbit/s; ROI=320x180, Q30, frames=42, bytes=173455, bitrate=66.820546 kbit/s; total_bytes=263151, payload=101.374382 kbit/s; channel FEC 2/3=167.267730 kbit/s; channel FEC 1/2=223.023640 kbit/s; sync_frames=42; timestamp_mismatch=0; frame_id_mismatch=0
sync_3fps_base_q20_roi_q30: 3.000 fps; BASE=240x135, Q20, frames=63, bytes=133076, bitrate=51.265233 kbit/s; ROI=320x180, Q30, frames=63, bytes=249436, bitrate=96.090915 kbit/s; total_bytes=382512, payload=147.356148 kbit/s; channel FEC 2/3=243.137644 kbit/s; channel FEC 1/2=324.183525 kbit/s; sync_frames=63; timestamp_mismatch=0; frame_id_mismatch=0
sync_3fps_base_q23_roi_q33: 3.000 fps; BASE=240x135, Q23, frames=63, bytes=144649, bitrate=55.723531 kbit/s; ROI=320x180, Q33, frames=63, bytes=264895, bitrate=102.046228 kbit/s; total_bytes=409544, payload=157.769759 kbit/s; channel FEC 2/3=260.320103 kbit/s; channel FEC 1/2=347.093470 kbit/s; sync_frames=63; timestamp_mismatch=0; frame_id_mismatch=0
sync_3fps_base_q25_roi_q35: 3.000 fps; BASE=240x135, Q25, frames=63, bytes=151516, bitrate=58.368925 kbit/s; ROI=320x180, Q35, frames=63, bytes=274486, bitrate=105.740995 kbit/s; total_bytes=426002, payload=164.109920 kbit/s; channel FEC 2/3=270.781368 kbit/s; channel FEC 1/2=361.041823 kbit/s; sync_frames=63; timestamp_mismatch=0; frame_id_mismatch=0
Оценки channel rate иллюстративны: к payload добавлено 10% служебных данных, затем применена оценка FEC 2/3 или FEC 1/2.
Эти значения не являются окончательной архитектурой радиоканала.
Preview: data\raw\lab027d_previews\lab027d_fps_quality_preview.mp4
Формат: MP4/mp4v.
Предупреждение: оценки пока не включают окончательную модуляцию, полосу сигнала, интерливинг, повторы и команды управления.
Программа не выбирает лучший профиль автоматически.
Следующий шаг: ручной выбор пользователя после просмотра preview-видео.

View File

@@ -0,0 +1,2 @@
profile_name,playback_speed_factor,source_width,source_height,source_fps,source_frames,source_duration_s,output_width,output_height,output_fps,output_frames,output_duration_s,composite_fps,base_width,base_height,base_quality,roi_width,roi_height,roi_quality,selected_composite_frames,total_base_bytes,total_roi_bytes,total_payload_bytes,mean_base_frame_bytes,mean_roi_frame_bytes,mean_composite_frame_bytes,p95_composite_frame_bytes,max_composite_frame_bytes,base_bitrate_kbps,roi_bitrate_kbps,total_payload_bitrate_kbps,channel_rate_fec_2_3_kbps,channel_rate_fec_1_2_kbps,timestamp_mismatch_count,frame_id_mismatch_count
sync_3fps_base240_q23_roi320_q33_speed_0_5x,0.500000,1280,720,30.000000,623,20.766667,1280,720,30.000000,1246,41.533333,3.000000,240,135,23,320,180,33,125,286715,524962,811677,2293.720,4199.696,6493.416,7125.400,7890,55.226003,101.116276,156.342279,257.964761,343.953014,0,0
1 profile_name playback_speed_factor source_width source_height source_fps source_frames source_duration_s output_width output_height output_fps output_frames output_duration_s composite_fps base_width base_height base_quality roi_width roi_height roi_quality selected_composite_frames total_base_bytes total_roi_bytes total_payload_bytes mean_base_frame_bytes mean_roi_frame_bytes mean_composite_frame_bytes p95_composite_frame_bytes max_composite_frame_bytes base_bitrate_kbps roi_bitrate_kbps total_payload_bitrate_kbps channel_rate_fec_2_3_kbps channel_rate_fec_1_2_kbps timestamp_mismatch_count frame_id_mismatch_count
2 sync_3fps_base240_q23_roi320_q33_speed_0_5x 0.500000 1280 720 30.000000 623 20.766667 1280 720 30.000000 1246 41.533333 3.000000 240 135 23 320 180 33 125 286715 524962 811677 2293.720 4199.696 6493.416 7125.400 7890 55.226003 101.116276 156.342279 257.964761 343.953014 0 0

View File

@@ -0,0 +1,50 @@
Lab027E. Операторское preview при playback 0.5x
Результаты ручной оценки Lab027D:
- 3 fps достаточно на исходном быстром видео;
- Q20/Q30 приемлем;
- Q23/Q33 приемлем;
- разница Q23/Q33 и Q25/Q35 практически отсутствует.
Предварительно выбран профиль Q23/Q33.
От Q25/Q35 предварительно отказались, поскольку визуальный выигрыш почти отсутствует.
Профиль не считается окончательно утверждённым до ручного просмотра этого preview.
Исходная сцена замедлена для имитации более медленного движения ровера и оценки удобства управления.
Коэффициент playback: 0.500x.
Предупреждение: реальная скорость исходного автомобиля неизвестна.
Исходное видео:
- путь: data\raw\lab026_rover_source.mp4;
- разрешение: 1280x720;
- FPS: 30.000000;
- кадров: 623;
- длительность: 20.766667 с.
Выходное preview:
- разрешение: 1280x720;
- FPS: 30.000000;
- кадров: 1246;
- длительность: 41.533333 с;
- composite FPS: 3.000000.
Профиль:
- BASE 240x135 Q23;
- ROI 320x180 Q33;
- составных обновлений: 125.
Фактические скорости:
- BASE: 55.226003 kbit/s;
- ROI: 101.116276 kbit/s;
- total payload: 156.342279 kbit/s;
- channel rate FEC 2/3: 257.964761 kbit/s;
- channel rate FEC 1/2: 343.953014 kbit/s.
Оценки канальной скорости иллюстративны и не являются окончательной архитектурой радиоканала.
Mismatch-проверка:
- timestamp mismatch: 0;
- frame ID mismatch: 0.
Preview: data\raw\lab027e_previews\lab027e_operator_view_0_5x.mp4
Формат: MP4/mp4v.
Следующий шаг: ручная оценка удобства управления пользователем.

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -0,0 +1,6 @@
max_payload_bytes,composite_frames,mean_base_packets_per_frame,mean_roi_packets_per_frame,mean_total_packets_per_frame,max_total_packets_per_frame,packets_per_second,jpeg_payload_bytes,jpeg_payload_bitrate_kbps,header_bytes_per_second,header_bitrate_kbps,wire_bytes,wire_bitrate_kbps,service_data_percent,efficiency_percent,mean_wire_packet_bytes,p95_wire_packet_bytes,max_wire_packet_bytes
64,63,36.428571,66.174603,102.603175,117,311.268058,409544,157.769759,9960.577849,79.684623,616392,237.454382,33.557866,66.442134,95.357673,96.000000,96
128,63,18.428571,33.269841,51.698413,59,156.837881,409544,157.769759,5018.812199,40.150498,513768,197.920257,20.286199,79.713801,157.742708,160.000000,160
256,63,9.428571,16.920635,26.349206,30,79.935795,409544,157.769759,2557.945425,20.463563,462664,178.233323,11.481334,88.518666,278.713253,288.000000,288
512,63,5.000000,8.682540,13.682540,15,41.508828,409544,157.769759,1328.282504,10.626260,437128,168.396019,6.310280,93.689720,507.109049,544.000000,544
1024,63,3.000000,4.587302,7.587302,8,23.017657,409544,157.769759,736.565008,5.892520,424840,163.662279,3.600414,96.399586,888.786611,1056.000000,1056
1 max_payload_bytes composite_frames mean_base_packets_per_frame mean_roi_packets_per_frame mean_total_packets_per_frame max_total_packets_per_frame packets_per_second jpeg_payload_bytes jpeg_payload_bitrate_kbps header_bytes_per_second header_bitrate_kbps wire_bytes wire_bitrate_kbps service_data_percent efficiency_percent mean_wire_packet_bytes p95_wire_packet_bytes max_wire_packet_bytes
2 64 63 36.428571 66.174603 102.603175 117 311.268058 409544 157.769759 9960.577849 79.684623 616392 237.454382 33.557866 66.442134 95.357673 96.000000 96
3 128 63 18.428571 33.269841 51.698413 59 156.837881 409544 157.769759 5018.812199 40.150498 513768 197.920257 20.286199 79.713801 157.742708 160.000000 160
4 256 63 9.428571 16.920635 26.349206 30 79.935795 409544 157.769759 2557.945425 20.463563 462664 178.233323 11.481334 88.518666 278.713253 288.000000 288
5 512 63 5.000000 8.682540 13.682540 15 41.508828 409544 157.769759 1328.282504 10.626260 437128 168.396019 6.310280 93.689720 507.109049 544.000000 544
6 1024 63 3.000000 4.587302 7.587302 8 23.017657 409544 157.769759 736.565008 5.892520 424840 163.662279 3.600414 96.399586 888.786611 1056.000000 1056

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

@@ -0,0 +1,52 @@
Lab028. Пакетирование синхронного BASE + ROI
Профиль и исходные данные
- Видео: data\raw\lab026_rover_source.mp4
- Источник: 1280x720, 30.000000 fps, 623 кадров, 20.766667 с.
- ROI: x=0.20...0.80, y=0.42...1.00; пиксели x=256...1024, y=302...720.
- Синхронные составные кадры: 63 при 3.000 fps.
- BASE: 240x135, grayscale JPEG Q23; средний размер 2296.016 B, min/max 2122/2476 B.
- ROI: 320x180, grayscale JPEG Q33; средний размер 4204.683 B, min/max 3457/4938 B.
- BASE и ROI формируются из одного source frame и имеют общий composite_frame_id.
Бинарный заголовок
- struct format: !4sBBHIHHHHIII
- Размер: 32 байта; network byte order; padding нет.
- Layout: magic[4] @0, version:u8 @4, object_type:u8 @5, header_size:u16 @6, composite_frame_id:u32 @8, fragment_index:u16 @12, fragment_count:u16 @14, payload_length:u16 @16, flags:u16 @18, jpeg_size:u32 @20, object_crc32:u32 @24, packet_crc32:u32 @28.
- object_type: 1=BASE, 2=ROI; flags зарезервирован и равен 0.
CRC32
- object_crc32 = zlib.crc32(полный JPEG) & 0xFFFFFFFF; значение помещается во все фрагменты объекта и проверяется после полной сборки.
- packet_crc32: сначала поле packet_crc32 заголовка обнуляется, затем CRC считается как zlib.crc32(header_with_zero_crc + payload) & 0xFFFFFFFF.
- Таким образом packet CRC защищает все поля заголовка и payload.
Функциональные проверки
- PASS header_serialization_round_trip: fixed 32-byte header round trip is exact
- PASS ordered_lossless_transfer: BASE and ROI match original JPEG bytes
- PASS random_packet_order: arbitrary packet order reconstructed correctly
- PASS exact_duplicate_packets: 2 exact duplicates ignored
- PASS packet_crc_corruption: payload bit flip rejected; composite not emitted
- PASS missing_fragment: ROI fragment 10 reported missing
- PASS object_crc_corruption: valid packet CRCs still failed full-object CRC
- PASS adjacent_frame_isolation: two interleaved frame IDs remained independent
- PASS base_without_roi_atomicity: complete BASE retained while composite stayed unpublished
Результаты размеров packet payload
payload | BASE pkt/frame | ROI pkt/frame | all pkt/frame | max pkt/frame | pkt/s | JPEG kbit/s | headers B/s | wire kbit/s | service % | efficiency % | packet mean/p95/max
-------:|---------------:|--------------:|--------------:|--------------:|------:|------------:|------------:|------------:|----------:|-------------:|--------------------:
64 | 36.429 | 66.175 | 102.603 | 117 | 311.268 | 157.770 | 9960.578 | 237.454 | 33.558 | 66.442 | 95.4/96.0/96
128 | 18.429 | 33.270 | 51.698 | 59 | 156.838 | 157.770 | 5018.812 | 197.920 | 20.286 | 79.714 | 157.7/160.0/160
256 | 9.429 | 16.921 | 26.349 | 30 | 79.936 | 157.770 | 2557.945 | 178.233 | 11.481 | 88.519 | 278.7/288.0/288
512 | 5.000 | 8.683 | 13.683 | 15 | 41.509 | 157.770 | 1328.283 | 168.396 | 6.310 | 93.690 | 507.1/544.0/544
1024 | 3.000 | 4.587 | 7.587 | 8 | 23.018 | 157.770 | 736.565 | 163.662 | 3.600 | 96.400 | 888.8/1056.0/1056
JPEG payload bitrate одинаков для всех строк, потому что исходные JPEG не меняются при выборе размера фрагмента.
Wire bitrate включает только JPEG payload и 32-байтные заголовки каждого пакета.
Wire bitrate пока НЕ включает FEC, преамбулу, синхронизацию, модуляцию, интервалы, повторные передачи, команды управления и телеметрию.
Лучший размер packet payload автоматически не выбирается: таблица показывает только транспортный компромисс.
Артефакты
- CSV: data\processed\lab028\lab028_packet_payload_results.csv
- Overhead/efficiency: data\processed\lab028\lab028_overhead_efficiency.png
- Packet count/wire bitrate: data\processed\lab028\lab028_packets_wire_bitrate.png
- Промежуточные JPEG и пакеты сохранялись только в памяти; бинарные дампы не создавались.

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -0,0 +1,95 @@
Lab029. Прохождение видеопакетов через канал с потерями и ошибками
Исходные данные и неизменный транспорт Lab028
- Видео: data\raw\lab026_rover_source.mp4
- Источник: 1280x720, 30.000000 fps, 623 кадров, 20.766667 с.
- Реальных синхронных JPEG-пар: 63; BASE 240x135 grayscale Q23, ROI 320x180 grayscale Q33, 3 composite fps.
- Использован protocol/video_packet.py без изменения: 32-byte header, packet CRC32, object CRC32, отдельные BASE/ROI и атомарная выдача CompositeReassembler.
- Payload: 256, 512, 1024 байт.
- Пакетов в одном проходе: 256 B=1660, 512 B=862, 1024 B=478.
Методика Monte Carlo
- Повторов на каждую строку: 200.
- Master seed: 29029; independent seeds 29029...29034; BER seeds 30029...30034; burst seeds 31029...31031.
- Для одинакового параметра один seed повторно используется для payload 256/512/1024, чтобы сравнение было коррелированным и воспроизводимым.
- packet_delivery_rate = (received - CRC rejected) / transmitted.
- effective delivered JPEG bitrate учитывает BASE+ROI bytes только атомарно выданных составных кадров и полное симулированное время.
- Потерянный фрагмент — физически потерянный пакет или пакет, отклонённый проверкой транспорта.
- FEC, ARQ, повторные передачи и интерливинг не применяются.
Модели канала
- Independent loss: каждый пакет теряется независимо с заданной вероятностью.
- BER: число независимых битовых ошибок выбирается binomial по полной длине пакета в битах, включая 32-byte header; выбранные биты физически инвертируются перед reassembler.
- Gilbert-Elliott: Good доставляет все пакеты, Bad теряет все. Начальное состояние выбирается из стационарного распределения.
- В Lab029 длительность состояния Bad и серии потерь задаётся количеством пакетов, а не физическим временем.
- Серия из одинакового количества пакетов имеет разную физическую длительность для payload 256, 512 и 1024 байта, поскольку различается время передачи пакета.
- Доля успешно восстановленных кадров не показывает длительность непрерывного отсутствия нового изображения.
- Поэтому burst-loss результаты Lab029 не являются окончательным сравнением размеров payload; для временного сравнения предназначена Lab029B.
- short: короткие серии потерь; P(G->B)=0.010204082, P(B->G)=0.500000000, stationary loss=2.000%, expected mean burst=2.0.
- medium: средние серии потерь; P(G->B)=0.004081633, P(B->G)=0.200000000, stationary loss=2.000%, expected mean burst=5.0.
- long: длинные серии потерь; P(G->B)=0.001020408, P(B->G)=0.050000000, stationary loss=2.000%, expected mean burst=20.0.
Функциональные проверки
- PASS zero_impairment_100_percent: all payloads delivered 100% packets and composite frames
- PASS packet_crc_rejects_bit_error: payload bit flip was rejected by packet CRC32
- PASS adjacent_frame_isolation: two interleaved neighboring frames remained independent
- PASS atomic_incomplete_frame: missing ROI fragment prevented atomic publication
- PASS fixed_seed_reproducibility: identical seed produced byte-for-byte equal result fields
1. Independent packet loss — atomic composite success
parameter | payload 256 | payload 512 | payload 1024
---------:|------------:|------------:|-------------:
0.0% | 100.000% | 100.000% | 100.000%
0.1% | 97.397% | 98.651% | 99.214%
0.5% | 87.294% | 93.357% | 96.254%
1.0% | 76.405% | 87.008% | 92.206%
2.0% | 58.937% | 76.516% | 86.286%
5.0% | 25.698% | 48.738% | 67.198%
2. BER — atomic composite success
parameter | payload 256 | payload 512 | payload 1024
---------:|------------:|------------:|-------------:
0 | 100.000% | 100.000% | 100.000%
1e-07 | 99.413% | 99.524% | 99.357%
3e-07 | 98.222% | 98.476% | 98.492%
1e-06 | 94.111% | 94.714% | 94.754%
3e-06 | 83.905% | 84.373% | 85.397%
1e-05 | 55.357% | 56.722% | 57.770%
3. Burst-loss
scenario | payload | expected loss | observed loss | mean/max burst | composite success | burst distribution
--------:|--------:|--------------:|--------------:|---------------:|------------------:|:------------------
short | 256 | 2.000% | 1.932% | 1.972/12 | 76.111% | 1:1628;2:822;3-4:635;5-8:155;9-16:12;17-32:0;33+:0
short | 512 | 2.000% | 1.853% | 1.903/11 | 86.484% | 1:861;2:429;3-4:318;5-8:67;9-16:3;17-32:0;33+:0
short | 1024 | 2.000% | 1.891% | 1.899/8 | 91.714% | 1:475;2:263;3-4:171;5-8:43;9-16:0;17-32:0;33+:0
medium | 256 | 2.000% | 2.007% | 4.991/30 | 88.333% | 1:258;2:226;3-4:324;5-8:306;9-16:180;17-32:41;33+:0
medium | 512 | 2.000% | 1.909% | 4.890/27 | 93.317% | 1:124;2:121;3-4:178;5-8:142;9-16:87;17-32:21;33+:0
medium | 1024 | 2.000% | 2.016% | 5.084/27 | 95.357% | 1:77;2:57;3-4:100;5-8:77;9-16:53;17-32:15;33+:0
long | 256 | 2.000% | 1.975% | 19.061/116 | 95.405% | 1:22;2:10;3-4:22;5-8:58;9-16:84;17-32:83;33+:65
long | 512 | 2.000% | 1.983% | 19.311/124 | 96.762% | 1:14;2:4;3-4:13;5-8:32;9-16:39;17-32:40;33+:35
long | 1024 | 2.000% | 2.192% | 20.350/124 | 97.198% | 1:12;2:1;3-4:8;5-8:15;9-16:24;17-32:21;33+:22
4. Сравнение payload 256/512/1024
payload | loss 1% success | BER 1e-6 success | medium burst success | Lab028 wire kbit/s
-------:|----------------:|-----------------:|---------------------:|--------------------:
256 | 76.405% | 94.111% | 88.333% | 178.233
512 | 87.008% | 94.714% | 93.317% | 168.396
1024 | 92.206% | 94.754% | 95.357% | 163.662
Интерпретация
- При фиксированной вероятности потери пакета крупный payload уменьшает число обязательных фрагментов. Поскольку потеря любого фрагмента делает объект неполным, меньшее число пакетов обычно повышает шанс полного кадра.
- При фиксированном BER длинный отдельный пакет чаще повреждается: P(error)=1-(1-BER)^(packet_bits). Одновременно крупный payload уменьшает число 32-byte headers и общую длину wire-потока, поэтому итоговый composite success определяется обоими эффектами.
- Атомарная сборка требует одновременной готовности BASE и ROI. Даже полностью собранный BASE не даёт полезного составного кадра без ROI, поэтому composite success ниже успеха каждого объекта отдельно.
- Burst-loss особенно опасен без интерливинга: соседние фрагменты и иногда соседние кадры теряются одной серией, а CRC только обнаруживает ошибку и не восстанавливает данные.
- Payload 256 B даёт наименьшую длину отдельного пакета и наименьшую вероятность BER-повреждения одного пакета, но требует больше всего фрагментов и headers.
- Payload 512 B остаётся умеренным рабочим кандидатом между packet count и длиной отдельного пакета.
- Payload 1024 B даёт минимум пакетов и header overhead в этих моделях, но каждый пакет длиннее и при его потере пропадает более крупный фрагмент JPEG.
- Окончательный packet payload автоматически не выбирается; для решения нужны Lab029 и последующие данные реального радиоканала, FEC/ARQ и задержек.
Артефакты
- CSV: data\processed\lab029\lab029_results.csv
- Independent loss plot: data\processed\lab029\lab029_independent_loss_success.png
- BER plot: data\processed\lab029\lab029_ber_success.png
- Burst plot: data\processed\lab029\lab029_burst_loss_results.png
- Payload comparison: data\processed\lab029\lab029_payload_comparison.png
- JPEG, пакеты и бинарные дампы на диск не сохранялись.

View File

@@ -0,0 +1,46 @@
model,parameter_name,parameter_value,scenario,payload_size,monte_carlo_repetitions,seed,good_to_bad_probability,bad_to_good_probability,expected_loss_probability,expected_mean_loss_burst,observed_loss_probability,transmitted_packets,received_packets,lost_packets,crc_rejected_packets,packet_delivery_rate,base_objects_completed,roi_objects_completed,atomic_composite_frames_completed,base_only_frames,roi_only_frames,incomplete_frames,composite_success_rate,effective_delivered_jpeg_bitrate_kbps,mean_lost_fragments_per_frame,p95_lost_fragments_per_frame,mean_loss_burst_length,max_loss_burst_length,loss_burst_distribution
independent_loss,packet_loss_probability,0,,256,200,29029,0,0,0,0,0,332000,332000,0,0,1,12600,12600,12600,0,0,0,1,157.76975923,0,0,0,0,1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0,,512,200,29029,0,0,0,0,0,172400,172400,0,0,1,12600,12600,12600,0,0,0,1,157.76975923,0,0,0,0,1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0,,1024,200,29029,0,0,0,0,0,95600,95600,0,0,1,12600,12600,12600,0,0,0,1,157.76975923,0,0,0,0,1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.001,,256,200,29030,0,0,0.001,1.001001001,0.00101807228916,332000,331662,338,0,0.998981927711,12468,12398,12272,196,126,328,0.973968253968,153.639124238,0.0268253968254,0,1,1,1:338;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.001,,512,200,29030,0,0,0.001,1.001001001,0.000991879350348,172400,172229,171,0,0.99900812065,12530,12499,12430,100,69,170,0.986507936508,155.629063242,0.0135714285714,0,1,1,1:171;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.001,,1024,200,29030,0,0,0.001,1.001001001,0.00103556485356,95600,95501,99,0,0.998964435146,12563,12538,12501,62,37,99,0.992142857143,156.519451685,0.00785714285714,0,1,1,1:99;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.005,,256,200,29031,0,0,0.005,1.00502512563,0.00515361445783,332000,330289,1711,0,0.994846385542,11987,11558,10999,988,559,1601,0.872936507937,137.693897913,0.135793650794,1,1.00765606596,2,1:1685;2:13;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.005,,512,200,29031,0,0,0.005,1.00502512563,0.00505220417633,172400,171529,871,0,0.994947795824,12302,12046,11763,539,283,837,0.933571428571,147.277529374,0.069126984127,1,1.01044083527,2,1:853;2:9;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.005,,1024,200,29031,0,0,0.005,1.00502512563,0.00503138075314,95600,95119,481,0,0.994968619247,12408,12317,12128,280,189,472,0.96253968254,151.818947673,0.0381746031746,0,1.01050420168,2,1:471;2:5;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.01,,256,200,29032,0,0,0.01,1.0101010101,0.0101746987952,332000,328622,3378,0,0.989825301205,11449,10592,9627,1822,965,2973,0.764047619048,120.432163724,0.268095238095,1,1.00775656325,2,1:3326;2:26;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.01,,512,200,29032,0,0,0.01,1.0101010101,0.0100928074246,172400,170660,1740,0,0.989907192575,11993,11526,10963,1030,563,1637,0.870079365079,137.210552167,0.138095238095,1,1.00752750434,2,1:1714;2:13;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.01,,1024,200,29032,0,0,0.01,1.0101010101,0.0105962343096,95600,94587,1013,0,0.98940376569,12198,12003,11618,580,385,982,0.922063492063,145.437291814,0.0803968253968,1,1.007960199,2,1:997;2:8;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.02,,256,200,29033,0,0,0.02,1.02040816327,0.0198795180723,332000,325400,6600,0,0.980120481928,10436,8989,7426,3010,1563,5174,0.589365079365,92.8966767255,0.52380952381,2,1.01946246525,3,1:6350;2:122;3-4:2;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.02,,512,200,29033,0,0,0.02,1.02040816327,0.0195649651972,172400,169027,3373,0,0.980435034803,11432,10607,9641,1791,966,2959,0.765158730159,120.639628892,0.267698412698,1,1.0178032589,3,1:3256;2:57;3-4:1;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.02,,1024,200,29033,0,0,0.02,1.02040816327,0.0192573221757,95600,93759,1841,0,0.980742677824,11880,11536,10872,1008,664,1728,0.862857142857,136.121568539,0.146111111111,1,1.01712707182,3,1:1780;2:29;3-4:1;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.05,,256,200,29034,0,0,0.05,1.05263157895,0.0503072289157,332000,315298,16702,0,0.949692771084,7774,5198,3238,4536,1960,9362,0.256984126984,40.4080507223,1.32555555556,3,1.05189570475,4,1:15094;2:746;3-4:38;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.05,,512,200,29034,0,0,0.05,1.05263157895,0.0510266821346,172400,163603,8797,0,0.948973317865,9647,8012,6141,3506,1871,6459,0.487380952381,76.7984243981,0.698174603175,2,1.05139237481,4,1:7961;2:383;3-4:23;5-8:0;9-16:0;17-32:0;33+:0
independent_loss,packet_loss_probability,0.05,,1024,200,29034,0,0,0.05,1.05263157895,0.0507949790795,95600,90744,4856,0,0.949205020921,10780,9911,8467,2313,1444,4133,0.671984126984,105.919342536,0.385396825397,2,1.0492653414,4,1:4415;2:199;3-4:14;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,0,,256,200,30029,0,0,0,0,0,332000,332000,0,0,1,12600,12600,12600,0,0,0,1,157.76975923,0,0,0,0,1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,0,,512,200,30029,0,0,0,0,0,172400,172400,0,0,1,12600,12600,12600,0,0,0,1,157.76975923,0,0,0,0,1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,0,,1024,200,30029,0,0,0,0,0,95600,95600,0,0,1,12600,12600,12600,0,0,0,1,157.76975923,0,0,0,0,1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-07,,256,200,30030,0,0,0,0,0.000225903614458,332000,332000,0,75,0.999774096386,12570,12556,12526,44,30,74,0.994126984127,156.829585233,0.00595238095238,0,1,1,1:75;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-07,,512,200,30030,0,0,0,0,0.000348027842227,172400,172400,0,60,0.999651972158,12578,12562,12540,38,22,60,0.995238095238,157.006054575,0.0047619047619,0,1,1,1:60;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-07,,1024,200,30030,0,0,0,0,0.000847280334728,95600,95600,0,81,0.999152719665,12569,12550,12519,50,31,81,0.993571428571,156.742861637,0.00642857142857,0,1,1,1:81;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,3e-07,,256,200,30031,0,0,0,0,0.000680722891566,332000,332000,0,226,0.999319277108,12514,12461,12376,138,85,224,0.982222222222,154.967524238,0.0179365079365,0,1,1,1:226;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,3e-07,,512,200,30031,0,0,0,0,0.00111368909513,172400,172400,0,192,0.998886310905,12530,12478,12408,122,70,192,0.984761904762,155.35917496,0.0152380952381,0,1,1,1:192;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,3e-07,,1024,200,30031,0,0,0,0,0.00199790794979,95600,95600,0,191,0.99800209205,12532,12478,12410,122,68,190,0.984920634921,155.39185618,0.0151587301587,0,1,1,1:191;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-06,,256,200,30032,0,0,0,0,0.00229819277108,332000,332000,0,763,0.997701807229,12337,12111,11858,479,253,742,0.941111111111,148.434593258,0.0605555555556,1,1.00131233596,2,1:761;2:1;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-06,,512,200,30032,0,0,0,0,0.00396171693735,172400,172400,0,683,0.996038283063,12345,12182,11934,411,248,666,0.947142857143,149.411587801,0.0542063492063,1,1.0058910162,2,1:675;2:4;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-06,,1024,200,30032,0,0,0,0,0.00713389121339,95600,95600,0,682,0.992866108787,12371,12157,11939,432,218,661,0.94753968254,149.447597432,0.054126984127,1,1.0118694362,3,1:667;2:6;3-4:1;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,3e-06,,256,200,30033,0,0,0,0,0.00661445783133,332000,332000,0,2196,0.993385542169,11810,11280,10572,1238,708,2028,0.839047619048,132.241321348,0.174285714286,1,1.00687757909,2,1:2166;2:15;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,3e-06,,512,200,30033,0,0,0,0,0.0122563805104,172400,172400,0,2113,0.98774361949,11848,11321,10631,1217,690,1969,0.84373015873,133.045201926,0.167698412698,1,1.0114887506,2,1:2065;2:24;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,3e-06,,1024,200,30033,0,0,0,0,0.0204916317992,95600,95600,0,1959,0.979508368201,11923,11387,10760,1163,627,1840,0.853968253968,134.696365329,0.155476190476,1,1.02404600105,3,1:1868;2:44;3-4:1;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-05,,256,200,30034,0,0,0,0,0.0222018072289,332000,332000,0,7371,0.977798192771,10234,8590,6975,3259,1615,5625,0.553571428571,87.1395390048,0.585,2,1.01950207469,4,1:7095;2:130;3-4:5;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-05,,512,200,30034,0,0,0,0,0.0407192575406,172400,172400,0,7020,0.959280742459,10313,8706,7147,3166,1559,5453,0.567222222222,89.3745245586,0.557142857143,2,1.03984594875,4,1:6492;2:250;3-4:9;5-8:0;9-16:0;17-32:0;33+:0
ber,bit_error_rate,1e-05,,1024,200,30034,0,0,0,0,0.0692573221757,95600,95600,0,6621,0.930742677824,10300,8931,7279,3021,1652,5321,0.577698412698,91.0087704655,0.525476190476,2,1.07066623545,4,1:5779;2:376;3-4:29;5-8:0;9-16:0;17-32:0;33+:0
burst,gilbert_elliott_scenario,0,short,256,200,31029,0.0102040816327,0.5,0.02,2,0.0193162650602,332000,325587,6413,0,0.98068373494,11365,10541,9590,1775,951,3010,0.761111111111,119.954532905,0.508968253968,3,1.97201722017,12,1:1628;2:822;3-4:635;5-8:155;9-16:12;17-32:0;33+:0
burst,gilbert_elliott_scenario,0,short,512,200,31029,0.0102040816327,0.5,0.02,2,0.0185266821346,172400,169206,3194,0,0.981473317865,11907,11463,10897,1010,566,1703,0.864841269841,136.370440449,0.253492063492,2,1.90345649583,11,1:861;2:429;3-4:318;5-8:67;9-16:3;17-32:0;33+:0
burst,gilbert_elliott_scenario,0,short,1024,200,31029,0.0102040816327,0.5,0.02,2,0.0189121338912,95600,93792,1808,0,0.981087866109,12097,11940,11556,541,384,1044,0.917142857143,144.700911717,0.143492063492,1,1.89915966387,8,1:475;2:263;3-4:171;5-8:43;9-16:0;17-32:0;33+:0
burst,gilbert_elliott_scenario,1,medium,256,200,31030,0.00408163265306,0.2,0.02,5,0.0200692771084,332000,325337,6663,0,0.979930722892,11962,11552,11130,832,422,1470,0.883333333333,139.320930337,0.52880952381,4,4.99101123596,30,1:258;2:226;3-4:324;5-8:306;9-16:180;17-32:41;33+:0
burst,gilbert_elliott_scenario,1,medium,512,200,31030,0.00408163265306,0.2,0.02,5,0.0190893271462,172400,169109,3291,0,0.980910672854,12172,11987,11758,414,229,842,0.933174603175,147.194698555,0.26119047619,2,4.89004457652,27,1:124;2:121;3-4:178;5-8:142;9-16:87;17-32:21;33+:0
burst,gilbert_elliott_scenario,1,medium,1024,200,31030,0.00408163265306,0.2,0.02,5,0.0201569037657,95600,93673,1927,0,0.979843096234,12256,12154,12015,241,139,585,0.953571428571,150.407112039,0.152936507937,0,5.08443271768,27,1:77;2:57;3-4:100;5-8:77;9-16:53;17-32:15;33+:0
burst,gilbert_elliott_scenario,2,long,256,200,31031,0.00102040816327,0.05,0.02,20,0.01975,332000,325443,6557,0,0.98025,12247,12146,12021,226,125,579,0.954047619048,150.526746067,0.520396825397,0,19.0610465116,116,1:22;2:10;3-4:22;5-8:58;9-16:84;17-32:83;33+:65
burst,gilbert_elliott_scenario,2,long,512,200,31031,0.00102040816327,0.05,0.02,20,0.0198259860789,172400,168982,3418,0,0.980174013921,12301,12253,12192,109,61,408,0.967619047619,152.666767897,0.27126984127,0,19.3107344633,124,1:14;2:4;3-4:13;5-8:32;9-16:39;17-32:40;33+:35
burst,gilbert_elliott_scenario,2,long,1024,200,31031,0.00102040816327,0.05,0.02,20,0.0219246861925,95600,93504,2096,0,0.978075313808,12305,12279,12247,58,32,353,0.971984126984,153.307654575,0.166349206349,0,20.3495145631,124,1:12;2:1;3-4:8;5-8:15;9-16:24;17-32:21;33+:22
1 model parameter_name parameter_value scenario payload_size monte_carlo_repetitions seed good_to_bad_probability bad_to_good_probability expected_loss_probability expected_mean_loss_burst observed_loss_probability transmitted_packets received_packets lost_packets crc_rejected_packets packet_delivery_rate base_objects_completed roi_objects_completed atomic_composite_frames_completed base_only_frames roi_only_frames incomplete_frames composite_success_rate effective_delivered_jpeg_bitrate_kbps mean_lost_fragments_per_frame p95_lost_fragments_per_frame mean_loss_burst_length max_loss_burst_length loss_burst_distribution
2 independent_loss packet_loss_probability 0 256 200 29029 0 0 0 0 0 332000 332000 0 0 1 12600 12600 12600 0 0 0 1 157.76975923 0 0 0 0 1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
3 independent_loss packet_loss_probability 0 512 200 29029 0 0 0 0 0 172400 172400 0 0 1 12600 12600 12600 0 0 0 1 157.76975923 0 0 0 0 1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
4 independent_loss packet_loss_probability 0 1024 200 29029 0 0 0 0 0 95600 95600 0 0 1 12600 12600 12600 0 0 0 1 157.76975923 0 0 0 0 1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
5 independent_loss packet_loss_probability 0.001 256 200 29030 0 0 0.001 1.001001001 0.00101807228916 332000 331662 338 0 0.998981927711 12468 12398 12272 196 126 328 0.973968253968 153.639124238 0.0268253968254 0 1 1 1:338;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
6 independent_loss packet_loss_probability 0.001 512 200 29030 0 0 0.001 1.001001001 0.000991879350348 172400 172229 171 0 0.99900812065 12530 12499 12430 100 69 170 0.986507936508 155.629063242 0.0135714285714 0 1 1 1:171;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
7 independent_loss packet_loss_probability 0.001 1024 200 29030 0 0 0.001 1.001001001 0.00103556485356 95600 95501 99 0 0.998964435146 12563 12538 12501 62 37 99 0.992142857143 156.519451685 0.00785714285714 0 1 1 1:99;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
8 independent_loss packet_loss_probability 0.005 256 200 29031 0 0 0.005 1.00502512563 0.00515361445783 332000 330289 1711 0 0.994846385542 11987 11558 10999 988 559 1601 0.872936507937 137.693897913 0.135793650794 1 1.00765606596 2 1:1685;2:13;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
9 independent_loss packet_loss_probability 0.005 512 200 29031 0 0 0.005 1.00502512563 0.00505220417633 172400 171529 871 0 0.994947795824 12302 12046 11763 539 283 837 0.933571428571 147.277529374 0.069126984127 1 1.01044083527 2 1:853;2:9;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
10 independent_loss packet_loss_probability 0.005 1024 200 29031 0 0 0.005 1.00502512563 0.00503138075314 95600 95119 481 0 0.994968619247 12408 12317 12128 280 189 472 0.96253968254 151.818947673 0.0381746031746 0 1.01050420168 2 1:471;2:5;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
11 independent_loss packet_loss_probability 0.01 256 200 29032 0 0 0.01 1.0101010101 0.0101746987952 332000 328622 3378 0 0.989825301205 11449 10592 9627 1822 965 2973 0.764047619048 120.432163724 0.268095238095 1 1.00775656325 2 1:3326;2:26;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
12 independent_loss packet_loss_probability 0.01 512 200 29032 0 0 0.01 1.0101010101 0.0100928074246 172400 170660 1740 0 0.989907192575 11993 11526 10963 1030 563 1637 0.870079365079 137.210552167 0.138095238095 1 1.00752750434 2 1:1714;2:13;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
13 independent_loss packet_loss_probability 0.01 1024 200 29032 0 0 0.01 1.0101010101 0.0105962343096 95600 94587 1013 0 0.98940376569 12198 12003 11618 580 385 982 0.922063492063 145.437291814 0.0803968253968 1 1.007960199 2 1:997;2:8;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
14 independent_loss packet_loss_probability 0.02 256 200 29033 0 0 0.02 1.02040816327 0.0198795180723 332000 325400 6600 0 0.980120481928 10436 8989 7426 3010 1563 5174 0.589365079365 92.8966767255 0.52380952381 2 1.01946246525 3 1:6350;2:122;3-4:2;5-8:0;9-16:0;17-32:0;33+:0
15 independent_loss packet_loss_probability 0.02 512 200 29033 0 0 0.02 1.02040816327 0.0195649651972 172400 169027 3373 0 0.980435034803 11432 10607 9641 1791 966 2959 0.765158730159 120.639628892 0.267698412698 1 1.0178032589 3 1:3256;2:57;3-4:1;5-8:0;9-16:0;17-32:0;33+:0
16 independent_loss packet_loss_probability 0.02 1024 200 29033 0 0 0.02 1.02040816327 0.0192573221757 95600 93759 1841 0 0.980742677824 11880 11536 10872 1008 664 1728 0.862857142857 136.121568539 0.146111111111 1 1.01712707182 3 1:1780;2:29;3-4:1;5-8:0;9-16:0;17-32:0;33+:0
17 independent_loss packet_loss_probability 0.05 256 200 29034 0 0 0.05 1.05263157895 0.0503072289157 332000 315298 16702 0 0.949692771084 7774 5198 3238 4536 1960 9362 0.256984126984 40.4080507223 1.32555555556 3 1.05189570475 4 1:15094;2:746;3-4:38;5-8:0;9-16:0;17-32:0;33+:0
18 independent_loss packet_loss_probability 0.05 512 200 29034 0 0 0.05 1.05263157895 0.0510266821346 172400 163603 8797 0 0.948973317865 9647 8012 6141 3506 1871 6459 0.487380952381 76.7984243981 0.698174603175 2 1.05139237481 4 1:7961;2:383;3-4:23;5-8:0;9-16:0;17-32:0;33+:0
19 independent_loss packet_loss_probability 0.05 1024 200 29034 0 0 0.05 1.05263157895 0.0507949790795 95600 90744 4856 0 0.949205020921 10780 9911 8467 2313 1444 4133 0.671984126984 105.919342536 0.385396825397 2 1.0492653414 4 1:4415;2:199;3-4:14;5-8:0;9-16:0;17-32:0;33+:0
20 ber bit_error_rate 0 256 200 30029 0 0 0 0 0 332000 332000 0 0 1 12600 12600 12600 0 0 0 1 157.76975923 0 0 0 0 1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
21 ber bit_error_rate 0 512 200 30029 0 0 0 0 0 172400 172400 0 0 1 12600 12600 12600 0 0 0 1 157.76975923 0 0 0 0 1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
22 ber bit_error_rate 0 1024 200 30029 0 0 0 0 0 95600 95600 0 0 1 12600 12600 12600 0 0 0 1 157.76975923 0 0 0 0 1:0;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
23 ber bit_error_rate 1e-07 256 200 30030 0 0 0 0 0.000225903614458 332000 332000 0 75 0.999774096386 12570 12556 12526 44 30 74 0.994126984127 156.829585233 0.00595238095238 0 1 1 1:75;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
24 ber bit_error_rate 1e-07 512 200 30030 0 0 0 0 0.000348027842227 172400 172400 0 60 0.999651972158 12578 12562 12540 38 22 60 0.995238095238 157.006054575 0.0047619047619 0 1 1 1:60;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
25 ber bit_error_rate 1e-07 1024 200 30030 0 0 0 0 0.000847280334728 95600 95600 0 81 0.999152719665 12569 12550 12519 50 31 81 0.993571428571 156.742861637 0.00642857142857 0 1 1 1:81;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
26 ber bit_error_rate 3e-07 256 200 30031 0 0 0 0 0.000680722891566 332000 332000 0 226 0.999319277108 12514 12461 12376 138 85 224 0.982222222222 154.967524238 0.0179365079365 0 1 1 1:226;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
27 ber bit_error_rate 3e-07 512 200 30031 0 0 0 0 0.00111368909513 172400 172400 0 192 0.998886310905 12530 12478 12408 122 70 192 0.984761904762 155.35917496 0.0152380952381 0 1 1 1:192;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
28 ber bit_error_rate 3e-07 1024 200 30031 0 0 0 0 0.00199790794979 95600 95600 0 191 0.99800209205 12532 12478 12410 122 68 190 0.984920634921 155.39185618 0.0151587301587 0 1 1 1:191;2:0;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
29 ber bit_error_rate 1e-06 256 200 30032 0 0 0 0 0.00229819277108 332000 332000 0 763 0.997701807229 12337 12111 11858 479 253 742 0.941111111111 148.434593258 0.0605555555556 1 1.00131233596 2 1:761;2:1;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
30 ber bit_error_rate 1e-06 512 200 30032 0 0 0 0 0.00396171693735 172400 172400 0 683 0.996038283063 12345 12182 11934 411 248 666 0.947142857143 149.411587801 0.0542063492063 1 1.0058910162 2 1:675;2:4;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
31 ber bit_error_rate 1e-06 1024 200 30032 0 0 0 0 0.00713389121339 95600 95600 0 682 0.992866108787 12371 12157 11939 432 218 661 0.94753968254 149.447597432 0.054126984127 1 1.0118694362 3 1:667;2:6;3-4:1;5-8:0;9-16:0;17-32:0;33+:0
32 ber bit_error_rate 3e-06 256 200 30033 0 0 0 0 0.00661445783133 332000 332000 0 2196 0.993385542169 11810 11280 10572 1238 708 2028 0.839047619048 132.241321348 0.174285714286 1 1.00687757909 2 1:2166;2:15;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
33 ber bit_error_rate 3e-06 512 200 30033 0 0 0 0 0.0122563805104 172400 172400 0 2113 0.98774361949 11848 11321 10631 1217 690 1969 0.84373015873 133.045201926 0.167698412698 1 1.0114887506 2 1:2065;2:24;3-4:0;5-8:0;9-16:0;17-32:0;33+:0
34 ber bit_error_rate 3e-06 1024 200 30033 0 0 0 0 0.0204916317992 95600 95600 0 1959 0.979508368201 11923 11387 10760 1163 627 1840 0.853968253968 134.696365329 0.155476190476 1 1.02404600105 3 1:1868;2:44;3-4:1;5-8:0;9-16:0;17-32:0;33+:0
35 ber bit_error_rate 1e-05 256 200 30034 0 0 0 0 0.0222018072289 332000 332000 0 7371 0.977798192771 10234 8590 6975 3259 1615 5625 0.553571428571 87.1395390048 0.585 2 1.01950207469 4 1:7095;2:130;3-4:5;5-8:0;9-16:0;17-32:0;33+:0
36 ber bit_error_rate 1e-05 512 200 30034 0 0 0 0 0.0407192575406 172400 172400 0 7020 0.959280742459 10313 8706 7147 3166 1559 5453 0.567222222222 89.3745245586 0.557142857143 2 1.03984594875 4 1:6492;2:250;3-4:9;5-8:0;9-16:0;17-32:0;33+:0
37 ber bit_error_rate 1e-05 1024 200 30034 0 0 0 0 0.0692573221757 95600 95600 0 6621 0.930742677824 10300 8931 7279 3021 1652 5321 0.577698412698 91.0087704655 0.525476190476 2 1.07066623545 4 1:5779;2:376;3-4:29;5-8:0;9-16:0;17-32:0;33+:0
38 burst gilbert_elliott_scenario 0 short 256 200 31029 0.0102040816327 0.5 0.02 2 0.0193162650602 332000 325587 6413 0 0.98068373494 11365 10541 9590 1775 951 3010 0.761111111111 119.954532905 0.508968253968 3 1.97201722017 12 1:1628;2:822;3-4:635;5-8:155;9-16:12;17-32:0;33+:0
39 burst gilbert_elliott_scenario 0 short 512 200 31029 0.0102040816327 0.5 0.02 2 0.0185266821346 172400 169206 3194 0 0.981473317865 11907 11463 10897 1010 566 1703 0.864841269841 136.370440449 0.253492063492 2 1.90345649583 11 1:861;2:429;3-4:318;5-8:67;9-16:3;17-32:0;33+:0
40 burst gilbert_elliott_scenario 0 short 1024 200 31029 0.0102040816327 0.5 0.02 2 0.0189121338912 95600 93792 1808 0 0.981087866109 12097 11940 11556 541 384 1044 0.917142857143 144.700911717 0.143492063492 1 1.89915966387 8 1:475;2:263;3-4:171;5-8:43;9-16:0;17-32:0;33+:0
41 burst gilbert_elliott_scenario 1 medium 256 200 31030 0.00408163265306 0.2 0.02 5 0.0200692771084 332000 325337 6663 0 0.979930722892 11962 11552 11130 832 422 1470 0.883333333333 139.320930337 0.52880952381 4 4.99101123596 30 1:258;2:226;3-4:324;5-8:306;9-16:180;17-32:41;33+:0
42 burst gilbert_elliott_scenario 1 medium 512 200 31030 0.00408163265306 0.2 0.02 5 0.0190893271462 172400 169109 3291 0 0.980910672854 12172 11987 11758 414 229 842 0.933174603175 147.194698555 0.26119047619 2 4.89004457652 27 1:124;2:121;3-4:178;5-8:142;9-16:87;17-32:21;33+:0
43 burst gilbert_elliott_scenario 1 medium 1024 200 31030 0.00408163265306 0.2 0.02 5 0.0201569037657 95600 93673 1927 0 0.979843096234 12256 12154 12015 241 139 585 0.953571428571 150.407112039 0.152936507937 0 5.08443271768 27 1:77;2:57;3-4:100;5-8:77;9-16:53;17-32:15;33+:0
44 burst gilbert_elliott_scenario 2 long 256 200 31031 0.00102040816327 0.05 0.02 20 0.01975 332000 325443 6557 0 0.98025 12247 12146 12021 226 125 579 0.954047619048 150.526746067 0.520396825397 0 19.0610465116 116 1:22;2:10;3-4:22;5-8:58;9-16:84;17-32:83;33+:65
45 burst gilbert_elliott_scenario 2 long 512 200 31031 0.00102040816327 0.05 0.02 20 0.0198259860789 172400 168982 3418 0 0.980174013921 12301 12253 12192 109 61 408 0.967619047619 152.666767897 0.27126984127 0 19.3107344633 124 1:14;2:4;3-4:13;5-8:32;9-16:39;17-32:40;33+:35
46 burst gilbert_elliott_scenario 2 long 1024 200 31031 0.00102040816327 0.05 0.02 20 0.0219246861925 95600 93504 2096 0 0.978075313808 12305 12279 12247 58 32 353 0.971984126984 153.307654575 0.166349206349 0 20.3495145631 124 1:12;2:1;3-4:8;5-8:15;9-16:24;17-32:21;33+:22

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -0,0 +1,74 @@
Lab029B. Временная модель серийных потерь видеопакетов
Исходные данные и транспорт
- Видео: data\raw\lab026_rover_source.mp4
- Источник: 1280x720, 30.000000 fps, 623 кадров, 20.766667 с.
- Использованы все 63 реальные пары: BASE 240x135 grayscale JPEG Q23, ROI 320x180 grayscale JPEG Q33, 3 составных кадра/с.
- Формат Lab028 не изменён: заголовок 32 байта, packet CRC32, object CRC32, отдельные BASE/ROI, атомарный CompositeReassembler.
- Порядок передачи внутри кадра: сначала все BASE-фрагменты, затем все ROI-фрагменты. Поэтому длительная помеха может затрагивать объекты несимметрично.
Временная модель передачи
- Контрольная скорость: 300 кбит/с. Это параметр лабораторной, а не выбранная скорость радиоканала.
- Длительность пакета = фактическая длина (32-byte header + фактический payload) × 8 / 300000.
- Кадр доступен в момент frame_id / 3. Пакеты BASE и ROI передаются подряд; искусственных межпакетных интервалов нет. Остаток периода до следующего кадра является естественным idle.
- Payload 256: packets=1660, timeline=20.881627 с, packet duration min/max=0.986667/7.680000 мс.
- Payload 512: packets=862, timeline=20.869680 с, packet duration min/max=1.093333/14.506667 мс.
- Payload 1024: packets=478, timeline=20.863707 с, packet duration min/max=1.093333/28.160000 мс.
Временная модель канала
- Good пропускает пакеты, Bad теряет пакеты. Длительности состояний независимы и экспоненциально распределены.
- Целевая стационарная доля Bad: 2.0%.
- mean Good = mean Bad × (1-0.02)/0.02 = 49 × mean Bad.
- Консервативное допущение: пакет считается потерянным, если хотя бы часть его передачи пересекается с Bad.
- Monte Carlo: 200 повторов на условие; master seed=290290; seeds 290290...290293.
- Один seed для одинаковой длительности повторно используется для payload 256/512/1024.
Параметры состояний
mean Bad | mean Good | target Bad
--------:|----------:|----------:
10 мс | 490 мс | 2.0%
50 мс | 2450 мс | 2.0%
200 мс | 9800 мс | 2.0%
1000 мс | 49000 мс | 2.0%
Функциональные проверки
- PASS zero_bad_state_100_percent: all 63 composite frames restored for all payloads
- PASS fixed_seed_reproducibility: identical seed produced identical aggregate fields
- PASS adjacent_frame_isolation: two interleaved neighboring frames remained independent
- PASS atomic_incomplete_frame: missing ROI fragment prevented atomic publication
- PASS stationary_bad_fraction: all observed Bad fractions are within 0.323 percentage points of 2%
- PASS longer_bad_longer_outage: mean held-image interval increased from 0.819350 to 1.295846 s
- PASS actual_packet_transmission_time: duration equals actual wire bits / 300000 for full and short final packets
Полная сравнительная таблица
Bad ms | payload | Bad actual | tx/rx/lost packets | packet delivery | BASE | ROI | composite | BASE-only | ROI-only | incomplete | lost burst mean/p95/max | incomplete run mean/p95/max | no image mean/p95/max s | recovery mean/p95/max s | video kbit/s
------:|--------:|-----------:|-------------------:|----------------:|-----:|----:|----------:|----------:|---------:|-----------:|-----------------------:|----------------------------:|-------------------------:|------------------------:|------------:
10 | 256 | 2.016% | 332000/320339/11661 | 96.488% | 84.611% | 75.659% | 65.357% | 2426 | 1298 | 4365 | 2.27/5.0/13 | 1.52/3.0/10 | 0.831/1.350/3.650 | 0.547/1.180/3.364 | 102.487
10 | 512 | 2.008% | 172400/164214/8186 | 95.252% | 85.183% | 77.008% | 66.968% | 2295 | 1265 | 4162 | 1.72/3.0/8 | 1.48/3.0/10 | 0.815/1.343/3.651 | 0.521/1.131/3.353 | 105.043
10 | 1024 | 2.022% | 95600/89121/6479 | 93.223% | 85.595% | 76.984% | 67.397% | 2293 | 1208 | 4108 | 1.43/3.0/6 | 1.47/3.0/10 | 0.812/1.339/3.651 | 0.513/1.115/3.348 | 105.783
50 | 256 | 2.041% | 332000/324191/7809 | 97.648% | 95.333% | 92.960% | 90.405% | 621 | 322 | 1209 | 6.43/17.3/37 | 1.10/2.0/3 | 0.694/1.001/1.348 | 0.441/0.727/1.207 | 141.796
50 | 512 | 2.083% | 172400/167870/4530 | 97.372% | 95.492% | 93.198% | 90.889% | 580 | 291 | 1148 | 3.94/10.0/19 | 1.10/2.0/3 | 0.693/1.000/1.348 | 0.428/0.714/1.196 | 142.643
50 | 1024 | 2.046% | 95600/92757/2843 | 97.026% | 95.619% | 93.421% | 91.095% | 570 | 293 | 1122 | 2.55/6.0/12 | 1.10/2.0/3 | 0.691/1.000/1.348 | 0.422/0.702/1.191 | 143.006
200 | 256 | 1.854% | 332000/325460/6540 | 98.030% | 97.540% | 96.762% | 96.230% | 165 | 67 | 475 | 17.82/49.0/80 | 1.32/3.0/4 | 0.765/1.312/1.657 | 0.547/0.970/1.468 | 150.968
200 | 512 | 1.854% | 172400/168900/3500 | 97.970% | 97.579% | 96.857% | 96.333% | 157 | 66 | 462 | 9.72/26.0/41 | 1.31/3.0/4 | 0.761/1.158/1.657 | 0.536/0.959/1.456 | 151.215
200 | 1024 | 1.854% | 95600/93582/2018 | 97.889% | 97.627% | 96.905% | 96.381% | 157 | 66 | 456 | 5.70/15.0/24 | 1.31/3.0/4 | 0.762/1.228/1.658 | 0.531/0.954/1.451 | 151.334
1000 | 256 | 1.678% | 332000/326429/5571 | 98.322% | 98.143% | 98.008% | 97.802% | 43 | 26 | 277 | 59.27/172.4/403 | 2.98/7.4/16 | 1.302/2.809/5.665 | 1.087/2.487/5.585 | 153.470
1000 | 512 | 1.678% | 172400/169489/2911 | 98.311% | 98.143% | 98.048% | 97.841% | 38 | 26 | 272 | 31.30/91.6/210 | 2.96/7.5/16 | 1.295/2.826/5.665 | 1.077/2.476/5.576 | 153.618
1000 | 1024 | 1.677% | 95600/93965/1635 | 98.290% | 98.143% | 98.079% | 97.873% | 34 | 26 | 268 | 17.77/50.9/116 | 2.95/7.5/16 | 1.291/2.843/5.665 | 1.071/2.471/5.571 | 153.712
Допущения и ограничения
- Не моделируются FEC, интерливинг, ARQ, повторные передачи, искусственные межпакетные интервалы, преамбула физического уровня, управление и телеметрия.
- Bad-интервалы не зависят от границ пакетов; любое частичное пересечение уничтожает пакет целиком.
- no-new-image duration для серии невосстановленных кадров измеряется от публикации предыдущего полного кадра до публикации следующего; при краевых сериях используются начало и конец временной шкалы.
- interference-to-next-frame измеряется от начала каждого Bad-интервала до первого следующего опубликованного составного кадра или до конца шкалы.
- Эффективный видеопоток учитывает JPEG bytes только атомарно восстановленных BASE+ROI и полную длительность расписания.
- Результаты зависят от порядка BASE затем ROI и от контрольной скорости 300 кбит/с.
- Окончательный размер payload автоматически не выбирается.
Артефакты
- CSV: data\processed\lab029b\lab029b_results.csv
- Composite success: data\processed\lab029b\lab029b_composite_success.png
- No-new-image duration: data\processed\lab029b\lab029b_no_image_duration.png
- Missing frame runs: data\processed\lab029b\lab029b_missing_frame_runs.png
- Payload comparison: data\processed\lab029b\lab029b_payload_comparison.png
- JPEG, пакеты и бинарные дампы не сохранялись.

View File

@@ -0,0 +1,13 @@
payload_size,mean_bad_duration_ms,mean_good_duration_ms,target_bad_time_fraction,actual_bad_time_fraction,control_stream_bitrate_kbps,schedule_duration_seconds,monte_carlo_repetitions,seed,transmitted_packets,received_packets,lost_packets,packet_delivery_rate,base_objects_completed,base_object_success_rate,roi_objects_completed,roi_object_success_rate,atomic_composite_frames_completed,composite_success_rate,base_only_frames,roi_only_frames,incomplete_frames,mean_lost_packet_burst,p95_lost_packet_burst,max_lost_packet_burst,mean_consecutive_incomplete_frames,p95_consecutive_incomplete_frames,max_consecutive_incomplete_frames,mean_no_new_image_duration_seconds,p95_no_new_image_duration_seconds,max_no_new_image_duration_seconds,mean_interference_to_next_frame_seconds,p95_interference_to_next_frame_seconds,max_interference_to_next_frame_seconds,effective_delivered_video_bitrate_kbps,bad_interval_count,actual_mean_bad_duration_ms,actual_p95_bad_duration_ms,actual_max_bad_duration_ms
256,10,490,0.02,0.0201609958077,300,20.8816266667,200,290290,332000,320339,11661,0.964876506024,10661,0.846111111111,9533,0.756587301587,8235,0.653571428571,2426,1298,4365,2.27442949093,5,13,1.52409217877,3,10,0.831002299814,1.35024,3.64970666667,0.546677484673,1.18029690393,3.36407888773,102.486509991,8442,9.97380686292,29.8125428395,83.5331876125
512,10,490,0.02,0.0200817045481,300,20.86968,200,290290,172400,164214,8186,0.952517401392,10733,0.851825396825,9703,0.770079365079,8438,0.669682539683,2295,1265,4162,1.72409435552,3,8,1.47903340441,3,10,0.814651021085,1.34314,3.65056,0.521191488299,1.13097049803,3.3529855544,105.043418011,8411,9.96549156518,29.9160688622,83.5331876125
1024,10,490,0.02,0.0202168068758,300,20.8637066667,200,290290,95600,89121,6479,0.932228033473,10785,0.855952380952,9700,0.769841269841,8492,0.673968253968,2293,1208,4108,1.43467670505,3,6,1.46976744186,3,10,0.812397042338,1.33936,3.65141333333,0.512839823089,1.11539721678,3.3478655544,105.78281392,8446,9.98810154849,29.7582896487,83.5331876125
256,50,2450,0.02,0.0204084786408,300,20.8816266667,200,290291,332000,324191,7809,0.976478915663,12012,0.953333333333,11713,0.929603174603,11391,0.904047619048,621,322,1209,6.42716049383,17.3,37,1.10209662716,2,3,0.693585900942,1.00062933333,1.34818666667,0.440632357759,0.727111920855,1.20734749202,141.795746436,1677,50.8243568053,152.864106144,405.431274995
512,50,2450,0.02,0.0208318699816,300,20.86968,200,290291,172400,167870,4530,0.973723897912,12032,0.954920634921,11743,0.931984126984,11452,0.908888888889,580,291,1148,3.93913043478,10,19,1.1027857829,2,3,0.693375395453,1.00016,1.34818666667,0.427559832342,0.714012825361,1.19625415869,142.643151213,1691,51.4198060694,156.002187328,405.431274995
1024,50,2450,0.02,0.0204619230445,300,20.8637066667,200,290291,95600,92757,2843,0.970261506276,12048,0.95619047619,11771,0.934206349206,11478,0.910952380952,570,293,1122,2.54749103943,6,12,1.095703125,2,3,0.691450052083,1.00014,1.34818666667,0.422249750197,0.702414015204,1.19113415869,143.006280124,1677,50.913722151,152.938028086,405.431274995
256,200,9800,0.02,0.0185410363364,300,20.8816266667,200,290292,332000,325460,6540,0.980301204819,12290,0.975396825397,12192,0.967619047619,12125,0.962301587302,165,67,475,17.8201634877,49,80,1.32311977716,3,4,0.765005088208,1.312048,1.65677333333,0.546872959401,0.96963489665,1.46756878424,150.967631513,414,187.037197483,563.305764922,989.194024493
512,200,9800,0.02,0.0185430633718,300,20.86968,200,290292,172400,168900,3500,0.97969837587,12295,0.975793650794,12204,0.968571428571,12138,0.963333333333,157,66,462,9.72222222222,26,41,1.3125,3,4,0.761154924242,1.15764533333,1.65677333333,0.536053764553,0.95939489665,1.45647545091,151.21462907,414,186.950627434,563.305764922,989.194024493
1024,200,9800,0.02,0.01854407776,300,20.8637066667,200,290292,95600,93582,2018,0.978891213389,12301,0.97626984127,12210,0.969047619048,12144,0.96380952381,157,66,456,5.70056497175,15,24,1.31412103746,3,4,0.761923535062,1.227696,1.65762666667,0.530838949739,0.95427489665,1.45135545091,151.334042912,414,186.90734241,563.305764922,989.194024493
256,1000,49000,0.02,0.0167841318375,300,20.8816266667,200,290293,332000,326429,5571,0.983219879518,12366,0.981428571429,12349,0.980079365079,12323,0.978015873016,43,26,277,59.2659574468,172.45,403,2.97849462366,7.4,16,1.30231827957,2.80936533333,5.66493333333,1.08734051838,2.48701382037,5.58511553493,153.469720111,97,722.639123618,2207.25170213,5246.24764036
512,1000,49000,0.02,0.0167765665288,300,20.86968,200,290293,172400,169489,2911,0.983114849188,12366,0.981428571429,12354,0.980476190476,12328,0.978412698413,38,26,272,31.3010752688,91.6,210,2.95652173913,7.45,16,1.29471797101,2.82593466667,5.66493333333,1.07655508883,2.47643248703,5.57572886827,153.618205933,97,721.900154546,2207.25170213,5246.24764036
1024,1000,49000,0.02,0.0167727806255,300,20.8637066667,200,290293,95600,93965,1635,0.98289748954,12366,0.981428571429,12358,0.980793650794,12332,0.97873015873,34,26,268,17.7717391304,50.85,116,2.94505494505,7.5,16,1.2905010989,2.84318666667,5.66493333333,1.07132952182,2.47131248703,5.57060886827,153.711503485,97,721.53067001,2207.25170213,5246.24764036
1 payload_size mean_bad_duration_ms mean_good_duration_ms target_bad_time_fraction actual_bad_time_fraction control_stream_bitrate_kbps schedule_duration_seconds monte_carlo_repetitions seed transmitted_packets received_packets lost_packets packet_delivery_rate base_objects_completed base_object_success_rate roi_objects_completed roi_object_success_rate atomic_composite_frames_completed composite_success_rate base_only_frames roi_only_frames incomplete_frames mean_lost_packet_burst p95_lost_packet_burst max_lost_packet_burst mean_consecutive_incomplete_frames p95_consecutive_incomplete_frames max_consecutive_incomplete_frames mean_no_new_image_duration_seconds p95_no_new_image_duration_seconds max_no_new_image_duration_seconds mean_interference_to_next_frame_seconds p95_interference_to_next_frame_seconds max_interference_to_next_frame_seconds effective_delivered_video_bitrate_kbps bad_interval_count actual_mean_bad_duration_ms actual_p95_bad_duration_ms actual_max_bad_duration_ms
2 256 10 490 0.02 0.0201609958077 300 20.8816266667 200 290290 332000 320339 11661 0.964876506024 10661 0.846111111111 9533 0.756587301587 8235 0.653571428571 2426 1298 4365 2.27442949093 5 13 1.52409217877 3 10 0.831002299814 1.35024 3.64970666667 0.546677484673 1.18029690393 3.36407888773 102.486509991 8442 9.97380686292 29.8125428395 83.5331876125
3 512 10 490 0.02 0.0200817045481 300 20.86968 200 290290 172400 164214 8186 0.952517401392 10733 0.851825396825 9703 0.770079365079 8438 0.669682539683 2295 1265 4162 1.72409435552 3 8 1.47903340441 3 10 0.814651021085 1.34314 3.65056 0.521191488299 1.13097049803 3.3529855544 105.043418011 8411 9.96549156518 29.9160688622 83.5331876125
4 1024 10 490 0.02 0.0202168068758 300 20.8637066667 200 290290 95600 89121 6479 0.932228033473 10785 0.855952380952 9700 0.769841269841 8492 0.673968253968 2293 1208 4108 1.43467670505 3 6 1.46976744186 3 10 0.812397042338 1.33936 3.65141333333 0.512839823089 1.11539721678 3.3478655544 105.78281392 8446 9.98810154849 29.7582896487 83.5331876125
5 256 50 2450 0.02 0.0204084786408 300 20.8816266667 200 290291 332000 324191 7809 0.976478915663 12012 0.953333333333 11713 0.929603174603 11391 0.904047619048 621 322 1209 6.42716049383 17.3 37 1.10209662716 2 3 0.693585900942 1.00062933333 1.34818666667 0.440632357759 0.727111920855 1.20734749202 141.795746436 1677 50.8243568053 152.864106144 405.431274995
6 512 50 2450 0.02 0.0208318699816 300 20.86968 200 290291 172400 167870 4530 0.973723897912 12032 0.954920634921 11743 0.931984126984 11452 0.908888888889 580 291 1148 3.93913043478 10 19 1.1027857829 2 3 0.693375395453 1.00016 1.34818666667 0.427559832342 0.714012825361 1.19625415869 142.643151213 1691 51.4198060694 156.002187328 405.431274995
7 1024 50 2450 0.02 0.0204619230445 300 20.8637066667 200 290291 95600 92757 2843 0.970261506276 12048 0.95619047619 11771 0.934206349206 11478 0.910952380952 570 293 1122 2.54749103943 6 12 1.095703125 2 3 0.691450052083 1.00014 1.34818666667 0.422249750197 0.702414015204 1.19113415869 143.006280124 1677 50.913722151 152.938028086 405.431274995
8 256 200 9800 0.02 0.0185410363364 300 20.8816266667 200 290292 332000 325460 6540 0.980301204819 12290 0.975396825397 12192 0.967619047619 12125 0.962301587302 165 67 475 17.8201634877 49 80 1.32311977716 3 4 0.765005088208 1.312048 1.65677333333 0.546872959401 0.96963489665 1.46756878424 150.967631513 414 187.037197483 563.305764922 989.194024493
9 512 200 9800 0.02 0.0185430633718 300 20.86968 200 290292 172400 168900 3500 0.97969837587 12295 0.975793650794 12204 0.968571428571 12138 0.963333333333 157 66 462 9.72222222222 26 41 1.3125 3 4 0.761154924242 1.15764533333 1.65677333333 0.536053764553 0.95939489665 1.45647545091 151.21462907 414 186.950627434 563.305764922 989.194024493
10 1024 200 9800 0.02 0.01854407776 300 20.8637066667 200 290292 95600 93582 2018 0.978891213389 12301 0.97626984127 12210 0.969047619048 12144 0.96380952381 157 66 456 5.70056497175 15 24 1.31412103746 3 4 0.761923535062 1.227696 1.65762666667 0.530838949739 0.95427489665 1.45135545091 151.334042912 414 186.90734241 563.305764922 989.194024493
11 256 1000 49000 0.02 0.0167841318375 300 20.8816266667 200 290293 332000 326429 5571 0.983219879518 12366 0.981428571429 12349 0.980079365079 12323 0.978015873016 43 26 277 59.2659574468 172.45 403 2.97849462366 7.4 16 1.30231827957 2.80936533333 5.66493333333 1.08734051838 2.48701382037 5.58511553493 153.469720111 97 722.639123618 2207.25170213 5246.24764036
12 512 1000 49000 0.02 0.0167765665288 300 20.86968 200 290293 172400 169489 2911 0.983114849188 12366 0.981428571429 12354 0.980476190476 12328 0.978412698413 38 26 272 31.3010752688 91.6 210 2.95652173913 7.45 16 1.29471797101 2.82593466667 5.66493333333 1.07655508883 2.47643248703 5.57572886827 153.618205933 97 721.900154546 2207.25170213 5246.24764036
13 1024 1000 49000 0.02 0.0167727806255 300 20.8637066667 200 290293 95600 93965 1635 0.98289748954 12366 0.981428571429 12358 0.980793650794 12332 0.97873015873 34 26 268 17.7717391304 50.85 116 2.94505494505 7.5 16 1.2905010989 2.84318666667 5.66493333333 1.07132952182 2.47131248703 5.57060886827 153.711503485 97 721.53067001 2207.25170213 5246.24764036

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

@@ -0,0 +1,87 @@
Lab030. Пакетное избыточное кодирование стираний
Исходный профиль и неизменный внутренний транспорт
- Видео: data\raw\lab026_rover_source.mp4
- 63 реальных пар BASE/ROI, 3 fps; BASE 240x135 grayscale JPEG Q23, ROI 320x180 grayscale JPEG Q33.
- Внутренний Lab028 packet не изменён: payload 512 байт, 32-byte header, packet CRC32 и object CRC32.
GF(256) и блочный код
- Примитивный полином: 0x11D (x^8+x^4+x^3+x^2+1).
- Матрица Вандермонда n×k умножается на обратную верхнюю k×k матрицу и становится систематической.
- Любые k доступных строк систематической генераторной матрицы восстанавливают k исходных символов.
- Нулевое дополнение используется только в математике; восстановленный внутренний пакет обрезается по payload_length Lab028 и проходит собственный CRC.
Внешний пакет FEC
- struct: !4sBBHIHHHHHHII
- Размер: 32 байта, network byte order, padding отсутствует.
- Layout: magic[4]@0, version:u8@4, flags:u8@5, header_size:u16@6, block_id:u32@8, symbol_index:u16@12, k:u16@14, r:u16@16, symbol_size:u16@18, data_length:u16@20, reserved16:u16@22, reserved32:u32@24, outer_crc32:u32@28.
- flags bit0: parity. CRC32 вычисляется по заголовку с нулевым outer_crc32 и данным внешнего символа.
Формирование блоков и передача
- Последовательный поток внутренних пакетов BASE→ROI делится на k=8; блок может пересекать границу кадра.
- Сначала передаются systematic symbols, затем parity symbols этого блока; перемежение отсутствует.
- Последний блок содержит 6 исходных пакетов. Для него r_last=max(1, ceil(k_last*r/8)): режимы 8+1, 8+2, 8+4 получают соответственно 1, 2 и 3 parity.
- Режим Без FEC передаёт исходные Lab028 packets без внешней обёртки; остальные режимы используют внешний заголовок.
- FIFO учитывает время генерации кадра, все внешние пакеты, фактический размер и скорость 300 кбит/с. Очередь не сбрасывается на границах кадров.
Скорость, избыточность и очередь
mode | source packets | parity packets | last block k+r | JPEG kbit/s | inner kbit/s | outer kbit/s | overhead | queue mean/max | timeline s
----:|---------------:|---------------:|---------------:|------------:|-------------:|-------------:|---------:|---------------:|----------:
Без FEC | 862 | 0 | none | 157.770 | 168.396 | 168.396 | 6.310% | 13.717/15 | 20.869680
8+1 | 862 | 108 | 6+1 | 157.770 | 168.396 | 202.987 | 22.276% | 15.452/18 | 20.928560
8+2 | 862 | 216 | 6+2 | 157.770 | 168.396 | 226.951 | 30.483% | 17.210/21 | 20.974640
8+4 | 862 | 431 | 6+3 | 157.770 | 168.396 | 274.659 | 42.558% | 20.859/26 | 21.051440
Временная модель
- Экспоненциальные Good/Bad интервалы Lab029B, Bad≈2%, mean Bad 10/50/200/1000 мс, 200 повторов, fixed seeds 300300...300303.
- Пакет теряется при любом пересечении его передачи с Bad.
- FEC исправляет стирания; CRC обнаруживает повреждения, но битовые ошибки отдельно не добавляются.
Функциональные проверки
- PASS gf256_arithmetic: inverse, division, and distributivity passed
- PASS fec_without_loss: systematic 8+4 block is byte-exact without loss
- PASS recover_any_r_erasures: all 549 exact-r erasure combinations recovered
- PASS r_plus_one_not_guaranteed: 8+2 correctly rejected seven available symbols
- PASS restored_inner_packet_and_crc: restored Lab028 packets are byte-exact and CRC-valid
- PASS outer_crc_detection: outer payload bit flip rejected by outer CRC32
- PASS zero_bad_100_percent: all modes restored all 63 frames without Bad
- PASS fixed_seed_reproducibility: identical seed produced identical result fields
- PASS atomic_incomplete_composite: missing ROI fragment prevented atomic publication
- PASS queue_counts_parity: 431 parity packets included in FIFO timing and queue metrics
Результаты Monte Carlo
Bad ms | mode | Bad actual | lost src/parity | recovered pkt | blocks recovered/failed | block recovery | composite | BASE-only/ROI-only | no image mean/p95/max s | delay mean/p95/max s | video kbit/s
------:|-----:|-----------:|----------------:|--------------:|------------------------:|---------------:|----------:|------------------:|-------------------------:|----------------------:|------------:
10 | Без FEC | 2.024% | 8130/0 | 0 | 0/0 | 0.000% | 66.960% | 2341/1207 | 0.814/1.346/3.008 | 0.185/0.203/0.210 | 105.091
10 | 8+1 | 2.038% | 8457/1121 | 2390 | 2390/2725 | 46.725% | 78.873% | 1471/776 | 0.767/1.317/2.360 | 0.231/0.364/0.451 | 123.422
10 | 8+2 | 2.055% | 8451/2229 | 5560 | 4070/1028 | 79.835% | 91.286% | 600/295 | 0.731/1.017/1.798 | 0.260/0.395/0.466 | 142.607
10 | 8+4 | 1.990% | 8364/4311 | 7797 | 4860/144 | 97.122% | 98.698% | 84/36 | 0.710/1.017/1.069 | 0.308/0.410/0.496 | 153.620
50 | Без FEC | 1.914% | 4062/0 | 0 | 0/0 | 0.000% | 91.452% | 529/296 | 0.693/0.998/1.687 | 0.185/0.203/0.210 | 143.553
50 | 8+1 | 1.929% | 4255/562 | 325 | 325/1216 | 21.090% | 91.762% | 542/263 | 0.709/1.004/1.994 | 0.223/0.245/0.451 | 143.615
50 | 8+2 | 1.995% | 4326/1104 | 971 | 658/905 | 42.099% | 93.333% | 423/214 | 0.713/1.010/1.632 | 0.248/0.275/0.465 | 145.767
50 | 8+4 | 2.035% | 4506/2275 | 2062 | 979/520 | 65.310% | 95.532% | 261/141 | 0.749/1.057/1.406 | 0.298/0.339/0.495 | 148.638
200 | Без FEC | 2.117% | 3877/0 | 0 | 0/0 | 0.000% | 96.071% | 146/83 | 0.786/1.325/2.333 | 0.185/0.203/0.210 | 150.881
200 | 8+1 | 2.169% | 3983/513 | 74 | 74/734 | 9.158% | 95.865% | 162/91 | 0.810/1.332/2.334 | 0.221/0.244/0.448 | 150.129
200 | 8+2 | 1.945% | 3573/908 | 144 | 101/602 | 14.367% | 96.302% | 149/80 | 0.837/1.339/2.334 | 0.246/0.275/0.467 | 150.483
200 | 8+4 | 1.940% | 3550/1777 | 375 | 160/522 | 23.460% | 96.310% | 153/90 | 0.900/1.348/2.334 | 0.296/0.337/0.466 | 149.944
1000 | Без FEC | 1.722% | 3014/0 | 0 | 0/0 | 0.000% | 97.976% | 27/10 | 1.403/3.050/4.327 | 0.185/0.203/0.210 | 153.809
1000 | 8+1 | 1.720% | 3003/374 | 13 | 13/423 | 2.982% | 97.921% | 33/13 | 1.437/3.040/4.311 | 0.221/0.244/0.250 | 153.287
1000 | 8+2 | 1.763% | 3079/781 | 25 | 16/427 | 3.612% | 97.833% | 39/15 | 1.466/3.048/4.295 | 0.246/0.275/0.450 | 152.807
1000 | 8+4 | 1.719% | 3004/1509 | 64 | 27/400 | 6.323% | 97.817% | 47/21 | 1.533/3.095/4.275 | 0.296/0.337/0.465 | 152.233
Допущения и ограничения
- Не реализованы перемежение, ARQ, повторные передачи, команды управления, телеметрия и реальный SDR.
- Любое частичное пересечение Bad уничтожает весь внешний или базовый внутренний пакет.
- Принятые systematic packets немедленно поступают reassembler; восстановленные стирания становятся доступны при получении k символов блока.
- Publication delay измеряется от frame_id/3 до атомарной выдачи BASE+ROI.
- Queue length измеряется в моменты генерации пакетов и включает ожидающие и обслуживаемый пакет.
- Окончательный режим FEC автоматически не выбирается.
Артефакты
- CSV: data\processed\lab030\lab030_results.csv
- Composite success: data\processed\lab030\lab030_composite_success.png
- No-image duration: data\processed\lab030\lab030_no_image_duration.png
- Stream rate/overhead: data\processed\lab030\lab030_stream_rate_overhead.png
- Delay/queue: data\processed\lab030\lab030_delay_queue.png
- Mode comparison: data\processed\lab030\lab030_mode_comparison.png
- JPEG, внутренние/внешние packets и бинарные дампы не сохранялись.

View File

@@ -0,0 +1,17 @@
mode,source_block_size,nominal_parity_count,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,mean_queue_length_packets,max_queue_length_packets,mean_publication_delay_seconds,p95_publication_delay_seconds,max_publication_delay_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,base_objects_completed,roi_objects_completed,atomic_composite_frames_completed,composite_success_rate,base_only_frames,roi_only_frames,incomplete_frames,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,effective_delivered_video_bitrate_kbps
none,8,0,10,490,0.02,0.0202372337783,200,300300,157.76975923,168.396019262,168.396019262,6.3102798265,300,20.86968,13.716937355,15,0.184972089605,0.203013333333,0.20968,172400,0,8130,0,0,0,0,0,10778,9644,8437,0.669603174603,2341,1207,4163,0.813657881797,1.34557333333,3.0084,1.47624113475,3,8,105.090548585
8+1,8,1,10,490,0.02,0.0203834086527,200,300300,157.76975923,168.396019262,202.986837881,22.2758673043,300,20.92856,15.4515463918,18,0.2311155162,0.364053333333,0.451386666667,172400,21600,8457,1121,2390,2390,2725,0.467253176931,11409,10714,9938,0.78873015873,1471,776,2662,0.766680350008,1.31661333333,2.35997333333,1.31847449232,3,6,123.421642005
8+2,8,2,10,490,0.02,0.0205493425986,200,300300,157.76975923,168.396019262,226.951396469,30.4830189704,300,20.97464,17.2096474954,21,0.260180715238,0.394773333333,0.4656,172400,43200,8451,2229,5560,4070,1028,0.798352295018,12102,11797,11502,0.912857142857,600,295,1098,0.730752592593,1.01705733333,1.7976,1.19607843137,2,4,142.607264773
8+4,8,4,10,490,0.02,0.0199022658407,200,300300,157.76975923,168.396019262,274.658619583,42.55787076,300,21.05144,20.8592420727,26,0.308434444087,0.410133333333,0.49632,172400,86200,8364,4311,7797,4860,144,0.971223021583,12520,12472,12436,0.986984126984,84,36,164,0.709739906103,1.01696933333,1.06861333333,1.15492957746,2,2,153.619731477
none,8,0,50,2450,0.02,0.0191374257321,200,300301,157.76975923,168.396019262,168.396019262,6.3102798265,300,20.86968,13.716937355,15,0.185003224855,0.203013333333,0.20968,172400,0,4062,0,0,0,0,0,12052,11819,11523,0.914523809524,529,296,1077,0.69345654043,0.998314666667,1.68717333333,1.10235414534,2,4,143.552817293
8+1,8,1,50,2450,0.02,0.0192899572498,200,300301,157.76975923,168.396019262,202.986837881,22.2758673043,300,20.92856,15.4515463918,18,0.222813291818,0.244506666667,0.451386666667,172400,21600,4255,562,325,325,1216,0.210902011681,12104,11825,11562,0.917619047619,542,263,1038,0.709203642987,1.00418666667,1.99370666667,1.13442622951,2,5,143.614717878
8+2,8,2,50,2450,0.02,0.0199477213011,200,300301,157.76975923,168.396019262,226.951396469,30.4830189704,300,20.97464,17.2096474954,21,0.248295249433,0.275226666667,0.465306666667,172400,43200,4326,1104,971,658,905,0.420985284709,12183,11974,11760,0.933333333333,423,214,840,0.712576776557,1.009596,1.63154666667,1.15384615385,2,4,145.767170259
8+4,8,4,50,2450,0.02,0.0203533945389,200,300301,157.76975923,168.396019262,274.658619583,42.55787076,300,21.05144,20.8592420727,26,0.298285623771,0.338693333333,0.49544,172400,86200,4506,2275,2062,979,520,0.653102068045,12298,12178,12037,0.955317460317,261,141,563,0.749229398664,1.05712,1.40586666667,1.25389755011,2,3,148.638096016
none,8,0,200,9800,0.02,0.0211716551168,200,300302,157.76975923,168.396019262,168.396019262,6.3102798265,300,20.86968,13.716937355,15,0.18509811593,0.203013333333,0.20968,172400,0,3877,0,0,0,0,0,12251,12188,12105,0.960714285714,146,83,495,0.786258898226,1.325184,2.33330666667,1.38655462185,3,6,150.881316819
8+1,8,1,200,9800,0.02,0.0216871677039,200,300302,157.76975923,168.396019262,202.986837881,22.2758673043,300,20.92856,15.4515463918,18,0.221480990148,0.244346666667,0.448133333333,172400,21600,3983,513,74,74,734,0.0915841584158,12241,12170,12079,0.958650793651,162,91,521,0.809597474466,1.332496,2.33416,1.45125348189,3,6,150.12864908
8+2,8,2,200,9800,0.02,0.0194531290427,200,300302,157.76975923,168.396019262,226.951396469,30.4830189704,300,20.97464,17.2096474954,21,0.246329619252,0.275066666667,0.466746666667,172400,43200,3573,908,144,101,602,0.143669985775,12283,12214,12134,0.963015873016,149,80,466,0.837464218579,1.33874666667,2.33416,1.52786885246,3,6,150.482540821
8+4,8,4,200,9800,0.02,0.0194004010436,200,300302,157.76975923,168.396019262,274.658619583,42.55787076,300,21.05144,20.8592420727,26,0.295920402143,0.336666666667,0.465946666667,172400,86200,3550,1777,375,160,522,0.234604105572,12288,12225,12135,0.963095238095,153,90,465,0.899563467643,1.34797333333,2.33416,1.7032967033,3,6,149.943889824
none,8,0,1000,49000,0.02,0.0172219900037,200,300303,157.76975923,168.396019262,168.396019262,6.3102798265,300,20.86968,13.716937355,15,0.185021764277,0.203013333333,0.20968,172400,0,3014,0,0,0,0,0,12372,12355,12345,0.979761904762,27,10,255,1.40302564103,3.049944,4.32696,3.26923076923,8.15,12,153.808757968
8+1,8,1,1000,49000,0.02,0.0172016717987,200,300303,157.76975923,168.396019262,202.986837881,22.2758673043,300,20.92856,15.4515463918,18,0.221316092289,0.244346666667,0.250373333333,172400,21600,3003,374,13,13,423,0.0298165137615,12371,12351,12338,0.979206349206,33,13,262,1.43732205128,3.039692,4.31074666667,3.35897435897,8.15,12,153.287364252
8+2,8,2,1000,49000,0.02,0.0176312789901,200,300303,157.76975923,168.396019262,226.951396469,30.4830189704,300,20.97464,17.2096474954,21,0.24594955031,0.275066666667,0.449946666667,172400,43200,3079,781,25,16,427,0.0361173814898,12366,12342,12327,0.978333333333,39,15,273,1.46630616034,3.04793866667,4.29538666667,3.45569620253,8.1,12,152.806923027
8+4,8,4,1000,49000,0.02,0.0171897343344,200,300303,157.76975923,168.396019262,274.658619583,42.55787076,300,21.05144,20.8592420727,26,0.295510529817,0.336506666667,0.464693333333,172400,86200,3004,1509,64,27,400,0.0632318501171,12372,12346,12325,0.978174603175,47,21,275,1.53289614035,3.09500666667,4.27541333333,3.61842105263,8.25,12,152.233086193
1 mode source_block_size nominal_parity_count 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 mean_queue_length_packets max_queue_length_packets mean_publication_delay_seconds p95_publication_delay_seconds max_publication_delay_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 base_objects_completed roi_objects_completed atomic_composite_frames_completed composite_success_rate base_only_frames roi_only_frames incomplete_frames 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 effective_delivered_video_bitrate_kbps
2 none 8 0 10 490 0.02 0.0202372337783 200 300300 157.76975923 168.396019262 168.396019262 6.3102798265 300 20.86968 13.716937355 15 0.184972089605 0.203013333333 0.20968 172400 0 8130 0 0 0 0 0 10778 9644 8437 0.669603174603 2341 1207 4163 0.813657881797 1.34557333333 3.0084 1.47624113475 3 8 105.090548585
3 8+1 8 1 10 490 0.02 0.0203834086527 200 300300 157.76975923 168.396019262 202.986837881 22.2758673043 300 20.92856 15.4515463918 18 0.2311155162 0.364053333333 0.451386666667 172400 21600 8457 1121 2390 2390 2725 0.467253176931 11409 10714 9938 0.78873015873 1471 776 2662 0.766680350008 1.31661333333 2.35997333333 1.31847449232 3 6 123.421642005
4 8+2 8 2 10 490 0.02 0.0205493425986 200 300300 157.76975923 168.396019262 226.951396469 30.4830189704 300 20.97464 17.2096474954 21 0.260180715238 0.394773333333 0.4656 172400 43200 8451 2229 5560 4070 1028 0.798352295018 12102 11797 11502 0.912857142857 600 295 1098 0.730752592593 1.01705733333 1.7976 1.19607843137 2 4 142.607264773
5 8+4 8 4 10 490 0.02 0.0199022658407 200 300300 157.76975923 168.396019262 274.658619583 42.55787076 300 21.05144 20.8592420727 26 0.308434444087 0.410133333333 0.49632 172400 86200 8364 4311 7797 4860 144 0.971223021583 12520 12472 12436 0.986984126984 84 36 164 0.709739906103 1.01696933333 1.06861333333 1.15492957746 2 2 153.619731477
6 none 8 0 50 2450 0.02 0.0191374257321 200 300301 157.76975923 168.396019262 168.396019262 6.3102798265 300 20.86968 13.716937355 15 0.185003224855 0.203013333333 0.20968 172400 0 4062 0 0 0 0 0 12052 11819 11523 0.914523809524 529 296 1077 0.69345654043 0.998314666667 1.68717333333 1.10235414534 2 4 143.552817293
7 8+1 8 1 50 2450 0.02 0.0192899572498 200 300301 157.76975923 168.396019262 202.986837881 22.2758673043 300 20.92856 15.4515463918 18 0.222813291818 0.244506666667 0.451386666667 172400 21600 4255 562 325 325 1216 0.210902011681 12104 11825 11562 0.917619047619 542 263 1038 0.709203642987 1.00418666667 1.99370666667 1.13442622951 2 5 143.614717878
8 8+2 8 2 50 2450 0.02 0.0199477213011 200 300301 157.76975923 168.396019262 226.951396469 30.4830189704 300 20.97464 17.2096474954 21 0.248295249433 0.275226666667 0.465306666667 172400 43200 4326 1104 971 658 905 0.420985284709 12183 11974 11760 0.933333333333 423 214 840 0.712576776557 1.009596 1.63154666667 1.15384615385 2 4 145.767170259
9 8+4 8 4 50 2450 0.02 0.0203533945389 200 300301 157.76975923 168.396019262 274.658619583 42.55787076 300 21.05144 20.8592420727 26 0.298285623771 0.338693333333 0.49544 172400 86200 4506 2275 2062 979 520 0.653102068045 12298 12178 12037 0.955317460317 261 141 563 0.749229398664 1.05712 1.40586666667 1.25389755011 2 3 148.638096016
10 none 8 0 200 9800 0.02 0.0211716551168 200 300302 157.76975923 168.396019262 168.396019262 6.3102798265 300 20.86968 13.716937355 15 0.18509811593 0.203013333333 0.20968 172400 0 3877 0 0 0 0 0 12251 12188 12105 0.960714285714 146 83 495 0.786258898226 1.325184 2.33330666667 1.38655462185 3 6 150.881316819
11 8+1 8 1 200 9800 0.02 0.0216871677039 200 300302 157.76975923 168.396019262 202.986837881 22.2758673043 300 20.92856 15.4515463918 18 0.221480990148 0.244346666667 0.448133333333 172400 21600 3983 513 74 74 734 0.0915841584158 12241 12170 12079 0.958650793651 162 91 521 0.809597474466 1.332496 2.33416 1.45125348189 3 6 150.12864908
12 8+2 8 2 200 9800 0.02 0.0194531290427 200 300302 157.76975923 168.396019262 226.951396469 30.4830189704 300 20.97464 17.2096474954 21 0.246329619252 0.275066666667 0.466746666667 172400 43200 3573 908 144 101 602 0.143669985775 12283 12214 12134 0.963015873016 149 80 466 0.837464218579 1.33874666667 2.33416 1.52786885246 3 6 150.482540821
13 8+4 8 4 200 9800 0.02 0.0194004010436 200 300302 157.76975923 168.396019262 274.658619583 42.55787076 300 21.05144 20.8592420727 26 0.295920402143 0.336666666667 0.465946666667 172400 86200 3550 1777 375 160 522 0.234604105572 12288 12225 12135 0.963095238095 153 90 465 0.899563467643 1.34797333333 2.33416 1.7032967033 3 6 149.943889824
14 none 8 0 1000 49000 0.02 0.0172219900037 200 300303 157.76975923 168.396019262 168.396019262 6.3102798265 300 20.86968 13.716937355 15 0.185021764277 0.203013333333 0.20968 172400 0 3014 0 0 0 0 0 12372 12355 12345 0.979761904762 27 10 255 1.40302564103 3.049944 4.32696 3.26923076923 8.15 12 153.808757968
15 8+1 8 1 1000 49000 0.02 0.0172016717987 200 300303 157.76975923 168.396019262 202.986837881 22.2758673043 300 20.92856 15.4515463918 18 0.221316092289 0.244346666667 0.250373333333 172400 21600 3003 374 13 13 423 0.0298165137615 12371 12351 12338 0.979206349206 33 13 262 1.43732205128 3.039692 4.31074666667 3.35897435897 8.15 12 153.287364252
16 8+2 8 2 1000 49000 0.02 0.0176312789901 200 300303 157.76975923 168.396019262 226.951396469 30.4830189704 300 20.97464 17.2096474954 21 0.24594955031 0.275066666667 0.449946666667 172400 43200 3079 781 25 16 427 0.0361173814898 12366 12342 12327 0.978333333333 39 15 273 1.46630616034 3.04793866667 4.29538666667 3.45569620253 8.1 12 152.806923027
17 8+4 8 4 1000 49000 0.02 0.0171897343344 200 300303 157.76975923 168.396019262 274.658619583 42.55787076 300 21.05144 20.8592420727 26 0.295510529817 0.336506666667 0.464693333333 172400 86200 3004 1509 64 27 400 0.0632318501171 12372 12346 12325 0.978174603175 47 21 275 1.53289614035 3.09500666667 4.27541333333 3.61842105263 8.25 12 152.233086193

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View 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, внешние пакеты и бинарные дампы на диск не сохранялись.

View 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
1 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
2 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
3 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
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
5 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
6 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
7 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 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
9 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
10 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
11 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
12 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
13 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
14 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
15 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
16 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
17 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
18 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
19 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
20 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
21 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
22 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
23 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
24 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
25 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
26 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
27 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
28 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
29 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

View File

@@ -0,0 +1,101 @@
Lab032. Подбор параметров блочного исправления потерь
Исходный профиль и неизменные слои
- Видео: data\raw\lab026_rover_source.mp4
- 63 реальных пар BASE/ROI, 3 fps; длительность 20.766667 с.
- BASE 240x135 grayscale JPEG Q23; ROI 320x180 grayscale JPEG Q33.
- Внутренний Lab028 packet: payload 512 байт; внешний формат и GF(256) Lab030 не изменены.
- Глубина D=1: systematic symbols блока передаются первыми, затем parity; перемежение отсутствует.
- Блоки формируются из непрерывного потока внутренних пакетов и могут пересекать composite_frame_id.
Последний неполный блок
- Используется единое правило:
r_last = max(1, ceil(k_last × r / k)).
- Нулевое дополнение существует только внутри математики GF(256); внешние пакеты синтетически не добавляются.
Сравнительная таблица восьми режимов
mode | rate | outer/margin kbit/s | composite 10/50/200/1000 ms | pub p95 200 ms s | no-image p95 200 ms s | block mean/max ms | decode mean ms | queue mean/max
----:|-----:|----------------------:|----------------------------:|-------------------:|------------------------:|------------------:|---------------:|---------------:
Без FEC | 1.000000 | 168.396/131.604 | 0.669603/0.914524/0.960714/0.979762 | 0.203013 | 1.325184 | 0.000/0.000 | 0.000 | 13.717/15
4+1 | 0.800000 | 226.951/73.049 | 0.791429/0.909048/0.959683/0.978175 | 0.274880 | 1.337167 | 92.966/189.840 | 77.606 | 17.171/20
8+2 | 0.800000 | 226.951/73.049 | 0.912857/0.933333/0.963016/0.978333 | 0.275067 | 1.338747 | 189.723/266.720 | 159.003 | 17.210/21
12+3 | 0.800000 | 226.951/73.049 | 0.951984/0.951190/0.965714/0.978492 | 0.288773 | 1.339135 | 288.795/337.173 | 242.715 | 17.219/21
6+2 | 0.750000 | 242.928/57.072 | 0.920873/0.930317/0.961270/0.978254 | 0.294080 | 1.333927 | 142.659/214.293 | 111.939 | 18.337/21
8+3 | 0.727273 | 250.916/49.084 | 0.963413/0.948810/0.962540/0.978175 | 0.305947 | 1.339067 | 191.857/266.720 | 145.777 | 18.985/24
4+2 | 0.666667 | 274.659/25.341 | 0.924762/0.924127/0.959048/0.977143 | 0.336320 | 1.349667 | 96.393/159.120 | 65.744 | 20.698/24
8+4 | 0.666667 | 274.659/25.341 | 0.986984/0.955317/0.963095/0.978175 | 0.336667 | 1.347973 | 193.876/266.720 | 132.578 | 20.859/26
Подробные результаты при средней Bad 200 мс
mode | BASE/ROI/composite | blocks ok/fail | restored packets | delivered kbit/s | publication mean/p95/max s | no-image mean/p95/max s | incomplete mean/p95/max
----:|-------------------:|---------------:|-----------------:|-----------------:|--------------------------:|-----------------------:|------------------------:
Без FEC | 0.972302/0.967302/0.960714 | 0.000000/0.000000 | 0 | 150.881 | 0.185098/0.203013/0.209680 | 0.786259/1.325184/2.333307 | 1.387/3.000/6
4+1 | 0.973175/0.966905/0.959683 | 0.975972/0.024028 | 92 | 150.067 | 0.246589/0.274880/0.394773 | 0.823033/1.337167/2.349520 | 1.494/3.000/6
8+2 | 0.974841/0.969365/0.963016 | 0.972130/0.027870 | 144 | 150.483 | 0.246330/0.275067/0.466747 | 0.837464/1.338747/2.334160 | 1.528/3.000/6
12+3 | 0.975794/0.971270/0.965714 | 0.968403/0.031597 | 260 | 150.899 | 0.246565/0.288773/0.522907 | 0.841596/1.339135/2.380240 | 1.543/3.000/6
6+2 | 0.973651/0.968571/0.961270 | 0.975243/0.024757 | 188 | 150.202 | 0.262330/0.294080/0.425493 | 0.839718/1.333927/2.364880 | 1.544/3.000/6
8+3 | 0.974603/0.969524/0.962540 | 0.973981/0.026019 | 249 | 150.081 | 0.271028/0.305947/0.466747 | 0.861515/1.339067/2.334160 | 1.589/3.000/6
4+2 | 0.973095/0.966429/0.959048 | 0.978287/0.021713 | 236 | 149.535 | 0.296583/0.336320/0.394773 | 0.865525/1.349667/2.364880 | 1.613/3.000/6
8+4 | 0.975238/0.970238/0.963095 | 0.975833/0.024167 | 375 | 149.944 | 0.295920/0.336667/0.465947 | 0.899563/1.347973/2.334160 | 1.703/3.000/6
Временная модель и очередь
- Непрерывные чередующиеся экспоненциальные Good/Bad интервалы Lab029B, средняя доля Bad около 2%.
- Средние Bad 10, 50, 200 и 1000 мс; 200 повторов; fixed seeds 300300...300303.
- Пакет теряется при любом пересечении передачи с Bad. FIFO учитывает фактическую длину каждого внешнего пакета и скорость 300 кбит/с.
- Все исследованные режимы остаются ниже 300 кбит/с; положительный запас показан в таблице. Отдельная функциональная проверка ускоряет поток 8+4 вдвое и подтверждает реальное накопление очереди при перегрузке.
- Block duration измеряется от начала первого до конца последнего символа. Decode-ready без потерь — от начала первого до конца k-го systematic symbol.
1. Одинаковая кодовая скорость 0.8: 4+1, 8+2 и 12+3
- 4+1: outer 226.951 кбит/с, block mean 92.966 мс, decode-ready 77.606 мс, composite@200 0.959683.
- 8+2: outer 226.951 кбит/с, block mean 189.723 мс, decode-ready 159.003 мс, composite@200 0.963016.
- 12+3: outer 226.951 кбит/с, block mean 288.795 мс, decode-ready 242.715 мс, composite@200 0.965714.
- При одинаковой номинальной code rate длина блока меняет временное окно, в котором одна помеха может собрать несколько стираний. Короткий блок раньше получает k systematic symbols и быстрее допускает декодирование.
- Длинный блок дольше остаётся открытым и может включить больше потерянных пакетов одной длительной помехи; при этом его больший абсолютный r иногда полезен для рассеянных стираний.
2. Одинаковая code rate 2/3: 4+2 и 8+4
- 4+2: outer 274.659 кбит/с, composite@200 0.959048, publication P95 0.336320 с, no-image P95 1.349667 с.
- 8+4: outer 274.659 кбит/с, composite@200 0.963095, publication P95 0.336667 с, no-image P95 1.347973 с.
- Сравнение изолирует влияние длины блока при одинаковой сильной избыточности: короткий 4+2 быстрее закрывается, длинный 8+4 имеет больше абсолютных parity symbols, но дольше накапливает стирания.
3. Влияние увеличения r
- Большее r позволяет исправить больше стираний, но увеличивает внешний поток, служебную долю, время передачи блока и публикационную задержку.
- 8+3: outer 250.916 кбит/с (8+2 226.951, 8+4 274.659); composite@200 0.962540 (8+2 0.963016, 8+4 0.963095); P95 delay 0.305947 с (8+2 0.275067, 8+4 0.336667).
- Поэтому 8+3 оценивается по фактическому положению между 8+2 и 8+4 сразу по скорости, устойчивости и задержке, без автоматического назначения рабочим режимом.
4. Практическая граница без автоматического выбора
- Минимальный поток: Без FEC, 168.396 кбит/с.
- Максимальная composite-устойчивость при Bad 200 мс: 12+3, 0.965714.
- Минимальная P95-задержка среди защищённых режимов: 4+1, 0.274880 с.
- Недоминируемые по outer bitrate↓, publication P95↓ и composite success↑ режимы при Bad 200 мс: Без FEC, 8+2, 12+3.
- Это набор компромиссов, а не автоматический выбор единственного режима.
Функциональные проверки
- PASS all_k_r_supported: GF(256) generated every requested k+r matrix
- PASS recover_any_r_erasures: recovered all 1208 exact-r erasure patterns
- PASS restored_inner_byte_exact: restored Lab028 packets are byte-exact
- PASS inner_outer_crc: outer and recovered Lab028 CRC32 checks passed
- PASS final_partial_block_scaling: final blocks: 4+1:2+1, 8+2:6+2, 12+3:10+3, 6+2:4+2, 8+3:6+3, 4+2:2+1, 8+4:6+3
- PASS zero_bad_100_percent: all eight modes restored 100% of frames without Bad
- PASS fixed_seed_reproducibility: identical seed produced identical result fields
- PASS queue_counts_parity: every parity packet is included in FIFO timing
- PASS overload_grows_queue: 549.317 kbit/s produced queue mean/max 301.733/589
- PASS atomic_incomplete_composite: missing final ROI fragment prevented publication
- PASS lab030_8_2_reproduction: 8+2 exactly reproduced Lab030 order and four rows
Допущения модели
- JPEG кодируются один раз в памяти; вычислительная задержка GF(256) считается нулевой.
- Стирается весь внешний пакет; отдельные битовые ошибки не моделируются, но оба уровня CRC проверяются.
- Publication delay считается от frame_id/3 до конца пакета, завершившего атомарную сборку BASE+ROI.
- No-image заканчивается публикацией следующего полного кадра или концом расписания; неполный кадр не публикуется.
- ARQ, повторы, глубокое перемежение, команды, телеметрия, модуляция и реальный SDR отсутствуют.
Артефакты
- Полный CSV: data\processed\lab032\lab032_results.csv
- Сводный CSV: data\processed\lab032\lab032_summary.csv
- Отчёт: data\processed\lab032\lab032_report.txt
- Доля восстановленных кадров: data\processed\lab032\lab032_composite_success.png
- Скорость и избыточность: data\processed\lab032\lab032_stream_overhead.png
- Задержка публикации: data\processed\lab032\lab032_publication_delay.png
- Отсутствие изображения: data\processed\lab032\lab032_no_image_duration.png
- Влияние размера блока: data\processed\lab032\lab032_block_size_effect.png
- Практическая граница: data\processed\lab032\lab032_practical_frontier.png
- JPEG, пакеты и бинарные дампы не сохранялись.

View File

@@ -0,0 +1,33 @@
mode,label,source_block_size,nominal_parity_count,code_rate,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,margin_to_control_bitrate_kbps,service_and_parity_percent,control_stream_bitrate_kbps,schedule_duration_seconds,fec_block_count,final_block_source_count,final_block_parity_count,mean_block_duration_seconds,max_block_duration_seconds,mean_decode_ready_duration_seconds,mean_queue_length_packets,max_queue_length_packets,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,base_success_rate,roi_objects_completed,roi_success_rate,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,0,0,1.0,10.0,490.0,0.02,0.020237233778310743,200,300300,157.76975922953451,168.39601926163724,168.39601926163724,131.60398073836276,6.3102798265039075,300.0,20.869679999999992,0,0,0,0.0,0.0,0.0,13.7169373549884,15,172400,0,8130,0,0,0,0,0.0,0.0,0.0,10778,0.8553968253968254,9644,0.7653968253968254,8437,0.6696031746031746,2341,1207,4163,105.09054858531616,0.18497208960530362,0.20301333333332394,0.20967999999999998,0.8136578817966899,1.3455733333333306,3.0084000000000004,1.476241134751773,3.0,8
4+1,4+1,4,1,0.8,10.0,490.0,0.02,0.020205583457443846,200,300300,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.95928000000002,216,2,1,0.09296604938271637,0.18984000000000556,0.07760604938271627,17.17068645640074,20,172400,43200,8454,2166,2948,2948,2885,0.5054003085890623,0.9332175925925926,0.0667824074074074,11517,0.914047619047619,10717,0.8505555555555555,9972,0.7914285714285715,1545,745,2628,123.60095384955959,0.25078923118064045,0.277253333333352,0.3947733333333403,0.7504291108955716,1.0431573333333346,2.687546666666666,1.274490785645005,2.0,7
8+2,8+2,8,2,0.8,10.0,490.0,0.02,0.02054934259858452,200,300300,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.974640000000022,108,6,2,0.18972345679012387,0.2667200000000012,0.15900345679012368,17.209647495361782,21,172400,43200,8451,2229,5560,4070,1028,0.798352295017654,0.9524074074074074,0.047592592592592596,12102,0.9604761904761905,11797,0.9362698412698413,11502,0.9128571428571428,600,295,1098,142.6072647730782,0.2601807152379309,0.39477333333332965,0.46559999999999846,0.7307525925925931,1.0170573333333313,1.7975999999999885,1.196078431372549,2.0,4
12+3,12+3,12,3,0.8,10.0,490.0,0.02,0.02054934259858452,200,300300,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.974640000000022,72,10,3,0.2887951851851859,0.33717333333333244,0.24271518518518562,17.21892393320965,21,172400,43200,8382,2249,6633,4195,481,0.8971343028229256,0.9665972222222222,0.03340277777777778,12298,0.976031746031746,12141,0.9635714285714285,11995,0.9519841269841269,303,146,605,148.739525445967,0.27203066166458373,0.43695999999999735,0.5433600000000043,0.7779739823008857,1.130100000000001,1.8652533333333245,1.3384955752212389,2.0,4
6+2,6+2,6,2,0.75,10.0,490.0,0.02,0.02054934259858452,200,300300,157.76975922953451,168.39601926163724,242.92776886035313,57.072231139646874,35.05486837932128,300.0,20.974640000000022,144,4,2,0.14265870370370404,0.21429333333333744,0.11193870370370387,18.337391304347825,21,172400,57600,8406,2992,5902,4396,959,0.8209150326797385,0.9667013888888889,0.03329861111111111,12165,0.9654761904761905,11882,0.943015873015873,11603,0.9208730158730158,562,279,997,143.8502954043548,0.27183035421873797,0.3794133333333327,0.4374400000000094,0.7170305679592641,1.015386666666668,1.4916266666666544,1.171562867215041,2.0,3
8+3,8+3,8,3,0.7272727272727273,10.0,490.0,0.02,0.020402467996494884,200,300300,157.76975922953451,168.39601926163724,250.91595505617977,49.08404494382023,37.12246828058022,300.0,21.020720000000026,108,6,3,0.19185679012345724,0.2667200000000012,0.145776790123457,18.984822934232714,24,172400,64800,8524,3269,7148,4741,412,0.9200465748107899,0.980925925925926,0.019074074074074073,12377,0.9823015873015873,12259,0.972936507936508,12139,0.9634126984126984,238,120,461,150.1392511769338,0.28472546338248755,0.410133333333329,0.48210666666667734,0.7119441206030163,1.0108000000000015,1.6533066666666691,1.1582914572864322,2.0,4
4+2,4+2,4,2,0.6666666666666666,10.0,490.0,0.02,0.020402467996494884,200,300300,157.76975922953451,168.39601926163724,274.6586195826645,25.341380417335472,42.55787075997801,300.0,21.020720000000026,216,2,1,0.09639320987654372,0.1591200000000068,0.06574432098765466,20.698375870069604,24,172400,86200,8475,4327,6317,4860,936,0.8385093167701864,0.9783333333333334,0.021666666666666667,12181,0.9667460317460318,11940,0.9476190476190476,11652,0.9247619047619048,529,288,948,144.11669438534915,0.30090820688866216,0.34253333333332137,0.41933333333331824,0.6944152068696341,1.0002666666666684,1.6533066666666691,1.1100702576112411,2.0,4
8+4,8+4,8,4,0.6666666666666666,10.0,490.0,0.02,0.019902265840707405,200,300300,157.76975922953451,168.39601926163724,274.6586195826645,25.341380417335472,42.55787075997801,300.0,21.051440000000028,108,6,3,0.1938755555555563,0.2667200000000012,0.13257777777777818,20.85924207269915,26,172400,86200,8364,4311,7797,4860,144,0.9712230215827338,0.9933333333333333,0.006666666666666667,12520,0.9936507936507937,12472,0.9898412698412699,12436,0.986984126984127,84,36,164,153.61973147680135,0.3084344440870609,0.4101333333333308,0.4963199999999981,0.7097399061032867,1.0169693333333332,1.0686133333333285,1.1549295774647887,2.0,2
none,Без FEC,0,0,1.0,50.0,2450.0,0.02,0.019137425732142044,200,300301,157.76975922953451,168.39601926163724,168.39601926163724,131.60398073836276,6.3102798265039075,300.0,20.869679999999992,0,0,0,0.0,0.0,0.0,13.7169373549884,15,172400,0,4062,0,0,0,0,0.0,0.0,0.0,12052,0.9565079365079365,11819,0.938015873015873,11523,0.9145238095238095,529,296,1077,143.55281729283826,0.18500322485463208,0.20301333333332394,0.20967999999999998,0.6934565404298871,0.9983146666666661,1.6871733333333334,1.1023541453428864,2.0,4
4+1,4+1,4,1,0.8,50.0,2450.0,0.02,0.020366888699952315,200,300301,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.95928000000002,216,2,1,0.09296604938271637,0.18984000000000556,0.07760604938271627,17.17068645640074,20,172400,43200,4404,1111,435,435,1555,0.2185929648241206,0.9640046296296296,0.03599537037037037,12072,0.9580952380952381,11759,0.9332539682539682,11454,0.909047619047619,618,305,1146,142.09415018073125,0.2470573493975917,0.27522666666668627,0.394773333333335,0.714345825703629,1.0041866666666657,1.993706666666668,1.165818921668362,2.0,5
8+2,8+2,8,2,0.8,50.0,2450.0,0.02,0.019947721301082785,200,300301,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.974640000000022,108,6,2,0.18972345679012387,0.2667200000000012,0.15900345679012368,17.209647495361782,21,172400,43200,4326,1104,971,658,905,0.4209852847088932,0.9581018518518518,0.04189814814814815,12183,0.9669047619047619,11974,0.9503174603174603,11760,0.9333333333333333,423,214,840,145.76717025894112,0.24829524943310788,0.27522666666668627,0.46530666666666143,0.7125767765567773,1.009596,1.6315466666666705,1.1538461538461537,2.0,4
12+3,12+3,12,3,0.8,50.0,2450.0,0.02,0.019947721301082785,200,300301,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.974640000000022,72,10,3,0.2887951851851859,0.33717333333333244,0.24271518518518562,17.21892393320965,21,172400,43200,4368,1082,1492,799,598,0.5719398711524696,0.9584722222222222,0.041527777777777775,12273,0.974047619047619,12114,0.9614285714285714,11985,0.9511904761904761,288,129,615,148.55436660653038,0.25108506744541914,0.2925866666666561,0.5421066666666583,0.7189982697201026,1.0041866666666657,1.993706666666668,1.1736641221374047,2.0,5
6+2,6+2,6,2,0.75,50.0,2450.0,0.02,0.019947721301082785,200,300301,157.76975922953451,168.39601926163724,242.92776886035313,57.072231139646874,35.05486837932128,300.0,20.974640000000022,144,4,2,0.14265870370370404,0.21429333333333744,0.11193870370370387,18.337391304347825,21,172400,57600,4368,1480,994,687,973,0.413855421686747,0.9662152777777778,0.03378472222222222,12172,0.966031746031746,11935,0.9472222222222222,11722,0.9303174603174603,450,213,878,145.30510368711916,0.2636889040550546,0.2962933333333524,0.4374400000000094,0.7177993752788941,1.0114399999999997,1.993706666666668,1.1753681392235609,2.0,5
8+3,8+3,8,3,0.7272727272727273,50.0,2450.0,0.02,0.019374042379375574,200,300301,157.76975922953451,168.39601926163724,250.91595505617977,49.08404494382023,37.12246828058022,300.0,21.020720000000026,108,6,3,0.19185679012345724,0.2667200000000012,0.145776790123457,18.984822934232714,24,172400,64800,4293,1651,1567,863,658,0.5673898750821827,0.9695370370370371,0.030462962962962963,12280,0.9746031746031746,12107,0.9608730158730159,11955,0.9488095238095238,325,152,645,147.8507529713538,0.2735714953297101,0.3079733333333543,0.4809599999999983,0.7145212903225816,1.0080079999999976,1.3905066666666706,1.1559139784946237,2.0,3
4+2,4+2,4,2,0.6666666666666666,50.0,2450.0,0.02,0.019374042379375574,200,300301,157.76975922953451,168.39601926163724,274.6586195826645,25.341380417335472,42.55787075997801,300.0,21.020720000000026,216,2,1,0.09639320987654372,0.1591200000000068,0.06574432098765466,20.698375870069604,24,172400,86200,4328,2165,1095,760,1111,0.4061998931052913,0.9742824074074075,0.025717592592592594,12133,0.962936507936508,11923,0.9462698412698413,11644,0.9241269841269841,489,279,956,144.01249053315,0.2971720302301636,0.3366666666666909,0.41933333333331824,0.7232546932006642,1.0119066666666576,1.7137333333333764,1.1890547263681592,2.0,4
8+4,8+4,8,4,0.6666666666666666,50.0,2450.0,0.02,0.0203533945388834,200,300301,157.76975922953451,168.39601926163724,274.6586195826645,25.341380417335472,42.55787075997801,300.0,21.051440000000028,108,6,3,0.1938755555555563,0.2667200000000012,0.13257777777777818,20.85924207269915,26,172400,86200,4506,2275,2062,979,520,0.6531020680453635,0.975925925925926,0.024074074074074074,12298,0.976031746031746,12178,0.9665079365079365,12037,0.9553174603174603,261,141,563,148.6380960162343,0.29828562377115203,0.3386933333333566,0.49543999999999855,0.7492293986636983,1.0571200000000047,1.4058666666666717,1.2538975501113585,2.0,3
none,Без FEC,0,0,1.0,200.0,9800.0,0.02,0.02117165511678711,200,300302,157.76975922953451,168.39601926163724,168.39601926163724,131.60398073836276,6.3102798265039075,300.0,20.869679999999992,0,0,0,0.0,0.0,0.0,13.7169373549884,15,172400,0,3877,0,0,0,0,0.0,0.0,0.0,12251,0.9723015873015873,12188,0.9673015873015873,12105,0.9607142857142857,146,83,495,150.88131681942423,0.18509811593005004,0.20301333333332394,0.20967999999999998,0.7862588982259566,1.3251839999999993,2.333306666666667,1.3865546218487395,3.0,6
4+1,4+1,4,1,0.8,200.0,9800.0,0.02,0.01946372101257088,200,300302,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.95928000000002,216,2,1,0.09296604938271637,0.18984000000000556,0.07760604938271627,17.17068645640074,20,172400,43200,3597,915,92,92,1038,0.08141592920353982,0.9759722222222222,0.024027777777777776,12262,0.9731746031746031,12183,0.9669047619047619,12092,0.9596825396825397,170,91,508,150.0674164379691,0.24658850369390367,0.27488000000001733,0.394773333333335,0.8230332549019609,1.3371666666666668,2.34952,1.4941176470588236,3.0,6
8+2,8+2,8,2,0.8,200.0,9800.0,0.02,0.01945312904270856,200,300302,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.974640000000022,108,6,2,0.18972345679012387,0.2667200000000012,0.15900345679012368,17.209647495361782,21,172400,43200,3573,908,144,101,602,0.14366998577524892,0.9721296296296297,0.027870370370370372,12283,0.9748412698412698,12214,0.9693650793650793,12134,0.963015873015873,149,80,466,150.4825408207243,0.2463296192516908,0.27506666666666346,0.4667466666666762,0.8374642185792353,1.3387466666666654,2.3341600000000007,1.5278688524590165,3.0,6
12+3,12+3,12,3,0.8,200.0,9800.0,0.02,0.01945312904270856,200,300302,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.974640000000022,72,10,3,0.2887951851851859,0.33717333333333244,0.24271518518518562,17.21892393320965,21,172400,43200,3579,903,260,131,455,0.2235494880546075,0.9684027777777777,0.03159722222222222,12295,0.9757936507936508,12238,0.9712698412698413,12168,0.9657142857142857,127,70,432,150.89903235526316,0.2465654372123616,0.2887733333333302,0.5229066666666595,0.8415958095238097,1.3391346666666688,2.380239999999999,1.542857142857143,3.0,6
6+2,6+2,6,2,0.75,200.0,9800.0,0.02,0.01945312904270856,200,300302,157.76975922953451,168.39601926163724,242.92776886035313,57.072231139646874,35.05486837932128,300.0,20.974640000000022,144,4,2,0.14265870370370404,0.21429333333333744,0.11193870370370387,18.337391304347825,21,172400,57600,3609,1180,188,127,713,0.15119047619047618,0.9752430555555556,0.024756944444444446,12268,0.9736507936507937,12204,0.9685714285714285,12112,0.9612698412698413,156,92,488,150.2020516204329,0.2623295794804066,0.29408000000000545,0.42549333333333905,0.8397175527426163,1.3339266666666698,2.3648799999999994,1.5443037974683544,3.0,6
8+3,8+3,8,3,0.7272727272727273,200.0,9800.0,0.02,0.01942144600871695,200,300302,157.76975922953451,168.39601926163724,250.91595505617977,49.08404494382023,37.12246828058022,300.0,21.020720000000026,108,6,3,0.19185679012345724,0.2667200000000012,0.145776790123457,18.984822934232714,24,172400,64800,3566,1346,249,130,562,0.18786127167630057,0.9739814814814814,0.026018518518518517,12280,0.9746031746031746,12216,0.9695238095238096,12128,0.9625396825396826,152,88,472,150.08097914819265,0.2710280233069496,0.30594666666668857,0.4667466666666762,0.8615145230078568,1.3390666666666675,2.3341600000000007,1.5892255892255893,3.0,6
4+2,4+2,4,2,0.6666666666666666,200.0,9800.0,0.02,0.01942144600871695,200,300302,157.76975922953451,168.39601926163724,274.6586195826645,25.341380417335472,42.55787075997801,300.0,21.020720000000026,216,2,1,0.09639320987654372,0.1591200000000068,0.06574432098765466,20.698375870069604,24,172400,86200,3572,1806,236,159,938,0.14494074749316319,0.978287037037037,0.02171296296296296,12261,0.9730952380952381,12177,0.9664285714285714,12084,0.959047619047619,177,93,516,149.53471051419723,0.29658307403729667,0.33632000000002193,0.39477333333332965,0.8655246666666663,1.349666666666665,2.3648799999999994,1.6125,3.0,6
8+4,8+4,8,4,0.6666666666666666,200.0,9800.0,0.02,0.019400401043555997,200,300302,157.76975922953451,168.39601926163724,274.6586195826645,25.341380417335472,42.55787075997801,300.0,21.051440000000028,108,6,3,0.1938755555555563,0.2667200000000012,0.13257777777777818,20.85924207269915,26,172400,86200,3550,1777,375,160,522,0.23460410557184752,0.9758333333333333,0.024166666666666666,12288,0.9752380952380952,12225,0.9702380952380952,12135,0.9630952380952381,153,90,465,149.94388982416385,0.2959204021425649,0.3366666666666909,0.46594666666666207,0.8995634676434676,1.347973333333331,2.3341600000000007,1.7032967032967032,3.0,6
none,Без FEC,0,0,1.0,1000.0,49000.0,0.02,0.017221990003688604,200,300303,157.76975922953451,168.39601926163724,168.39601926163724,131.60398073836276,6.3102798265039075,300.0,20.869679999999992,0,0,0,0.0,0.0,0.0,13.7169373549884,15,172400,0,3014,0,0,0,0,0.0,0.0,0.0,12372,0.981904761904762,12355,0.9805555555555555,12345,0.9797619047619047,27,10,255,153.8087579684979,0.1850217642770288,0.20301333333332394,0.20967999999999998,1.4030256410256405,3.0499439999999973,4.3269600000000015,3.269230769230769,8.149999999999991,12
4+1,4+1,4,1,0.8,1000.0,49000.0,0.02,0.01762954307387838,200,300303,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.95928000000002,216,2,1,0.09296604938271637,0.18984000000000556,0.07760604938271627,17.17068645640074,20,172400,43200,3089,774,18,18,806,0.021844660194174758,0.9813425925925926,0.018657407407407407,12362,0.9811111111111112,12340,0.9793650793650793,12325,0.9781746031746031,37,15,275,152.8935249684148,0.24643575388776331,0.27488000000001733,0.37941333333333027,1.444222551440331,3.016560000000001,4.3107466666666685,3.3950617283950617,8.0,12
8+2,8+2,8,2,0.8,1000.0,49000.0,0.02,0.017631278990127012,200,300303,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.974640000000022,108,6,2,0.18972345679012387,0.2667200000000012,0.15900345679012368,17.209647495361782,21,172400,43200,3079,781,25,16,427,0.03611738148984198,0.9802314814814815,0.01976851851851852,12366,0.9814285714285714,12342,0.9795238095238096,12327,0.9783333333333334,39,15,273,152.80692302704583,0.24594955030961974,0.27506666666666346,0.44994666666666205,1.466306160337555,3.0479386666666684,4.295386666666669,3.4556962025316458,8.099999999999994,12
12+3,12+3,12,3,0.8,1000.0,49000.0,0.02,0.017631278990127012,200,300303,157.76975922953451,168.39601926163724,226.95139646869984,73.04860353130016,30.4830189704105,300.0,20.974640000000022,72,10,3,0.2887951851851859,0.33717333333333244,0.24271518518518562,17.21892393320965,21,172400,43200,3090,775,34,18,304,0.055900621118012424,0.9788888888888889,0.021111111111111112,12367,0.9815079365079366,12343,0.9796031746031746,12329,0.9784920634920635,38,14,271,152.83293157832492,0.24574732095060553,0.2850666666666548,0.5122933333333357,1.5037301754385983,3.0950066666666745,4.3368533333333215,3.5657894736842106,8.25,12
6+2,6+2,6,2,0.75,1000.0,49000.0,0.02,0.017631278990127012,200,300303,157.76975922953451,168.39601926163724,242.92776886035313,57.072231139646874,35.05486837932128,300.0,20.974640000000022,144,4,2,0.14265870370370404,0.21429333333333744,0.11193870370370387,18.337391304347825,21,172400,57600,3092,1033,40,25,547,0.043706293706293704,0.9810069444444445,0.018993055555555555,12366,0.9814285714285714,12338,0.9792063492063492,12326,0.9782539682539683,40,12,274,152.79328179172546,0.26206411812429153,0.29408000000000545,0.4192266666666633,1.4673545991561199,3.047938666666669,4.336853333333321,3.4683544303797467,8.099999999999994,12
8+3,8+3,8,3,0.7272727272727273,1000.0,49000.0,0.02,0.017636471517506424,200,300303,157.76975922953451,168.39601926163724,250.91595505617977,49.08404494382023,37.12246828058022,300.0,21.020720000000026,108,6,3,0.19185679012345724,0.2667200000000012,0.145776790123457,18.984822934232714,24,172400,64800,3080,1165,48,25,418,0.056433408577878104,0.9806481481481482,0.019351851851851853,12368,0.9815873015873016,12340,0.9793650793650793,12325,0.9781746031746031,43,15,275,152.44826628203012,0.27059416362407174,0.3057866666666631,0.44994666666666205,1.508938181818184,3.079317333333341,4.290773333333321,3.5714285714285716,8.200000000000003,12
4+2,4+2,4,2,0.6666666666666666,1000.0,49000.0,0.02,0.017636471517506424,200,300303,157.76975922953451,168.39601926163724,274.6586195826645,25.341380417335472,42.55787075997801,300.0,21.020720000000026,216,2,1,0.09639320987654372,0.1591200000000068,0.06574432098765466,20.698375870069604,24,172400,86200,3094,1545,55,36,784,0.04390243902439024,0.9818518518518519,0.01814814814814815,12362,0.9811111111111112,12331,0.9786507936507937,12312,0.9771428571428571,50,19,288,152.2895466948799,0.2964339592809204,0.33632000000002193,0.39477333333333053,1.5150906666666693,3.0350866666667184,4.336853333333319,3.6,8.049999999999997,12
8+4,8+4,8,4,0.6666666666666666,1000.0,49000.0,0.02,0.017189734334432376,200,300303,157.76975922953451,168.39601926163724,274.6586195826645,25.341380417335472,42.55787075997801,300.0,21.051440000000028,108,6,3,0.1938755555555563,0.2667200000000012,0.13257777777777818,20.85924207269915,26,172400,86200,3004,1509,64,27,400,0.06323185011709602,0.9814814814814815,0.018518518518518517,12372,0.981904761904762,12346,0.9798412698412698,12325,0.9781746031746031,47,21,275,152.2330861926783,0.29551052981744624,0.33650666666666273,0.46469333333333185,1.5328961403508796,3.0950066666666753,4.2754133333333195,3.6184210526315788,8.25,12
1 mode label source_block_size nominal_parity_count code_rate 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 margin_to_control_bitrate_kbps service_and_parity_percent control_stream_bitrate_kbps schedule_duration_seconds fec_block_count final_block_source_count final_block_parity_count mean_block_duration_seconds max_block_duration_seconds mean_decode_ready_duration_seconds mean_queue_length_packets max_queue_length_packets 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 base_success_rate roi_objects_completed roi_success_rate 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
2 none Без FEC 0 0 1.0 10.0 490.0 0.02 0.020237233778310743 200 300300 157.76975922953451 168.39601926163724 168.39601926163724 131.60398073836276 6.3102798265039075 300.0 20.869679999999992 0 0 0 0.0 0.0 0.0 13.7169373549884 15 172400 0 8130 0 0 0 0 0.0 0.0 0.0 10778 0.8553968253968254 9644 0.7653968253968254 8437 0.6696031746031746 2341 1207 4163 105.09054858531616 0.18497208960530362 0.20301333333332394 0.20967999999999998 0.8136578817966899 1.3455733333333306 3.0084000000000004 1.476241134751773 3.0 8
3 4+1 4+1 4 1 0.8 10.0 490.0 0.02 0.020205583457443846 200 300300 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.95928000000002 216 2 1 0.09296604938271637 0.18984000000000556 0.07760604938271627 17.17068645640074 20 172400 43200 8454 2166 2948 2948 2885 0.5054003085890623 0.9332175925925926 0.0667824074074074 11517 0.914047619047619 10717 0.8505555555555555 9972 0.7914285714285715 1545 745 2628 123.60095384955959 0.25078923118064045 0.277253333333352 0.3947733333333403 0.7504291108955716 1.0431573333333346 2.687546666666666 1.274490785645005 2.0 7
4 8+2 8+2 8 2 0.8 10.0 490.0 0.02 0.02054934259858452 200 300300 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.974640000000022 108 6 2 0.18972345679012387 0.2667200000000012 0.15900345679012368 17.209647495361782 21 172400 43200 8451 2229 5560 4070 1028 0.798352295017654 0.9524074074074074 0.047592592592592596 12102 0.9604761904761905 11797 0.9362698412698413 11502 0.9128571428571428 600 295 1098 142.6072647730782 0.2601807152379309 0.39477333333332965 0.46559999999999846 0.7307525925925931 1.0170573333333313 1.7975999999999885 1.196078431372549 2.0 4
5 12+3 12+3 12 3 0.8 10.0 490.0 0.02 0.02054934259858452 200 300300 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.974640000000022 72 10 3 0.2887951851851859 0.33717333333333244 0.24271518518518562 17.21892393320965 21 172400 43200 8382 2249 6633 4195 481 0.8971343028229256 0.9665972222222222 0.03340277777777778 12298 0.976031746031746 12141 0.9635714285714285 11995 0.9519841269841269 303 146 605 148.739525445967 0.27203066166458373 0.43695999999999735 0.5433600000000043 0.7779739823008857 1.130100000000001 1.8652533333333245 1.3384955752212389 2.0 4
6 6+2 6+2 6 2 0.75 10.0 490.0 0.02 0.02054934259858452 200 300300 157.76975922953451 168.39601926163724 242.92776886035313 57.072231139646874 35.05486837932128 300.0 20.974640000000022 144 4 2 0.14265870370370404 0.21429333333333744 0.11193870370370387 18.337391304347825 21 172400 57600 8406 2992 5902 4396 959 0.8209150326797385 0.9667013888888889 0.03329861111111111 12165 0.9654761904761905 11882 0.943015873015873 11603 0.9208730158730158 562 279 997 143.8502954043548 0.27183035421873797 0.3794133333333327 0.4374400000000094 0.7170305679592641 1.015386666666668 1.4916266666666544 1.171562867215041 2.0 3
7 8+3 8+3 8 3 0.7272727272727273 10.0 490.0 0.02 0.020402467996494884 200 300300 157.76975922953451 168.39601926163724 250.91595505617977 49.08404494382023 37.12246828058022 300.0 21.020720000000026 108 6 3 0.19185679012345724 0.2667200000000012 0.145776790123457 18.984822934232714 24 172400 64800 8524 3269 7148 4741 412 0.9200465748107899 0.980925925925926 0.019074074074074073 12377 0.9823015873015873 12259 0.972936507936508 12139 0.9634126984126984 238 120 461 150.1392511769338 0.28472546338248755 0.410133333333329 0.48210666666667734 0.7119441206030163 1.0108000000000015 1.6533066666666691 1.1582914572864322 2.0 4
8 4+2 4+2 4 2 0.6666666666666666 10.0 490.0 0.02 0.020402467996494884 200 300300 157.76975922953451 168.39601926163724 274.6586195826645 25.341380417335472 42.55787075997801 300.0 21.020720000000026 216 2 1 0.09639320987654372 0.1591200000000068 0.06574432098765466 20.698375870069604 24 172400 86200 8475 4327 6317 4860 936 0.8385093167701864 0.9783333333333334 0.021666666666666667 12181 0.9667460317460318 11940 0.9476190476190476 11652 0.9247619047619048 529 288 948 144.11669438534915 0.30090820688866216 0.34253333333332137 0.41933333333331824 0.6944152068696341 1.0002666666666684 1.6533066666666691 1.1100702576112411 2.0 4
9 8+4 8+4 8 4 0.6666666666666666 10.0 490.0 0.02 0.019902265840707405 200 300300 157.76975922953451 168.39601926163724 274.6586195826645 25.341380417335472 42.55787075997801 300.0 21.051440000000028 108 6 3 0.1938755555555563 0.2667200000000012 0.13257777777777818 20.85924207269915 26 172400 86200 8364 4311 7797 4860 144 0.9712230215827338 0.9933333333333333 0.006666666666666667 12520 0.9936507936507937 12472 0.9898412698412699 12436 0.986984126984127 84 36 164 153.61973147680135 0.3084344440870609 0.4101333333333308 0.4963199999999981 0.7097399061032867 1.0169693333333332 1.0686133333333285 1.1549295774647887 2.0 2
10 none Без FEC 0 0 1.0 50.0 2450.0 0.02 0.019137425732142044 200 300301 157.76975922953451 168.39601926163724 168.39601926163724 131.60398073836276 6.3102798265039075 300.0 20.869679999999992 0 0 0 0.0 0.0 0.0 13.7169373549884 15 172400 0 4062 0 0 0 0 0.0 0.0 0.0 12052 0.9565079365079365 11819 0.938015873015873 11523 0.9145238095238095 529 296 1077 143.55281729283826 0.18500322485463208 0.20301333333332394 0.20967999999999998 0.6934565404298871 0.9983146666666661 1.6871733333333334 1.1023541453428864 2.0 4
11 4+1 4+1 4 1 0.8 50.0 2450.0 0.02 0.020366888699952315 200 300301 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.95928000000002 216 2 1 0.09296604938271637 0.18984000000000556 0.07760604938271627 17.17068645640074 20 172400 43200 4404 1111 435 435 1555 0.2185929648241206 0.9640046296296296 0.03599537037037037 12072 0.9580952380952381 11759 0.9332539682539682 11454 0.909047619047619 618 305 1146 142.09415018073125 0.2470573493975917 0.27522666666668627 0.394773333333335 0.714345825703629 1.0041866666666657 1.993706666666668 1.165818921668362 2.0 5
12 8+2 8+2 8 2 0.8 50.0 2450.0 0.02 0.019947721301082785 200 300301 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.974640000000022 108 6 2 0.18972345679012387 0.2667200000000012 0.15900345679012368 17.209647495361782 21 172400 43200 4326 1104 971 658 905 0.4209852847088932 0.9581018518518518 0.04189814814814815 12183 0.9669047619047619 11974 0.9503174603174603 11760 0.9333333333333333 423 214 840 145.76717025894112 0.24829524943310788 0.27522666666668627 0.46530666666666143 0.7125767765567773 1.009596 1.6315466666666705 1.1538461538461537 2.0 4
13 12+3 12+3 12 3 0.8 50.0 2450.0 0.02 0.019947721301082785 200 300301 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.974640000000022 72 10 3 0.2887951851851859 0.33717333333333244 0.24271518518518562 17.21892393320965 21 172400 43200 4368 1082 1492 799 598 0.5719398711524696 0.9584722222222222 0.041527777777777775 12273 0.974047619047619 12114 0.9614285714285714 11985 0.9511904761904761 288 129 615 148.55436660653038 0.25108506744541914 0.2925866666666561 0.5421066666666583 0.7189982697201026 1.0041866666666657 1.993706666666668 1.1736641221374047 2.0 5
14 6+2 6+2 6 2 0.75 50.0 2450.0 0.02 0.019947721301082785 200 300301 157.76975922953451 168.39601926163724 242.92776886035313 57.072231139646874 35.05486837932128 300.0 20.974640000000022 144 4 2 0.14265870370370404 0.21429333333333744 0.11193870370370387 18.337391304347825 21 172400 57600 4368 1480 994 687 973 0.413855421686747 0.9662152777777778 0.03378472222222222 12172 0.966031746031746 11935 0.9472222222222222 11722 0.9303174603174603 450 213 878 145.30510368711916 0.2636889040550546 0.2962933333333524 0.4374400000000094 0.7177993752788941 1.0114399999999997 1.993706666666668 1.1753681392235609 2.0 5
15 8+3 8+3 8 3 0.7272727272727273 50.0 2450.0 0.02 0.019374042379375574 200 300301 157.76975922953451 168.39601926163724 250.91595505617977 49.08404494382023 37.12246828058022 300.0 21.020720000000026 108 6 3 0.19185679012345724 0.2667200000000012 0.145776790123457 18.984822934232714 24 172400 64800 4293 1651 1567 863 658 0.5673898750821827 0.9695370370370371 0.030462962962962963 12280 0.9746031746031746 12107 0.9608730158730159 11955 0.9488095238095238 325 152 645 147.8507529713538 0.2735714953297101 0.3079733333333543 0.4809599999999983 0.7145212903225816 1.0080079999999976 1.3905066666666706 1.1559139784946237 2.0 3
16 4+2 4+2 4 2 0.6666666666666666 50.0 2450.0 0.02 0.019374042379375574 200 300301 157.76975922953451 168.39601926163724 274.6586195826645 25.341380417335472 42.55787075997801 300.0 21.020720000000026 216 2 1 0.09639320987654372 0.1591200000000068 0.06574432098765466 20.698375870069604 24 172400 86200 4328 2165 1095 760 1111 0.4061998931052913 0.9742824074074075 0.025717592592592594 12133 0.962936507936508 11923 0.9462698412698413 11644 0.9241269841269841 489 279 956 144.01249053315 0.2971720302301636 0.3366666666666909 0.41933333333331824 0.7232546932006642 1.0119066666666576 1.7137333333333764 1.1890547263681592 2.0 4
17 8+4 8+4 8 4 0.6666666666666666 50.0 2450.0 0.02 0.0203533945388834 200 300301 157.76975922953451 168.39601926163724 274.6586195826645 25.341380417335472 42.55787075997801 300.0 21.051440000000028 108 6 3 0.1938755555555563 0.2667200000000012 0.13257777777777818 20.85924207269915 26 172400 86200 4506 2275 2062 979 520 0.6531020680453635 0.975925925925926 0.024074074074074074 12298 0.976031746031746 12178 0.9665079365079365 12037 0.9553174603174603 261 141 563 148.6380960162343 0.29828562377115203 0.3386933333333566 0.49543999999999855 0.7492293986636983 1.0571200000000047 1.4058666666666717 1.2538975501113585 2.0 3
18 none Без FEC 0 0 1.0 200.0 9800.0 0.02 0.02117165511678711 200 300302 157.76975922953451 168.39601926163724 168.39601926163724 131.60398073836276 6.3102798265039075 300.0 20.869679999999992 0 0 0 0.0 0.0 0.0 13.7169373549884 15 172400 0 3877 0 0 0 0 0.0 0.0 0.0 12251 0.9723015873015873 12188 0.9673015873015873 12105 0.9607142857142857 146 83 495 150.88131681942423 0.18509811593005004 0.20301333333332394 0.20967999999999998 0.7862588982259566 1.3251839999999993 2.333306666666667 1.3865546218487395 3.0 6
19 4+1 4+1 4 1 0.8 200.0 9800.0 0.02 0.01946372101257088 200 300302 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.95928000000002 216 2 1 0.09296604938271637 0.18984000000000556 0.07760604938271627 17.17068645640074 20 172400 43200 3597 915 92 92 1038 0.08141592920353982 0.9759722222222222 0.024027777777777776 12262 0.9731746031746031 12183 0.9669047619047619 12092 0.9596825396825397 170 91 508 150.0674164379691 0.24658850369390367 0.27488000000001733 0.394773333333335 0.8230332549019609 1.3371666666666668 2.34952 1.4941176470588236 3.0 6
20 8+2 8+2 8 2 0.8 200.0 9800.0 0.02 0.01945312904270856 200 300302 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.974640000000022 108 6 2 0.18972345679012387 0.2667200000000012 0.15900345679012368 17.209647495361782 21 172400 43200 3573 908 144 101 602 0.14366998577524892 0.9721296296296297 0.027870370370370372 12283 0.9748412698412698 12214 0.9693650793650793 12134 0.963015873015873 149 80 466 150.4825408207243 0.2463296192516908 0.27506666666666346 0.4667466666666762 0.8374642185792353 1.3387466666666654 2.3341600000000007 1.5278688524590165 3.0 6
21 12+3 12+3 12 3 0.8 200.0 9800.0 0.02 0.01945312904270856 200 300302 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.974640000000022 72 10 3 0.2887951851851859 0.33717333333333244 0.24271518518518562 17.21892393320965 21 172400 43200 3579 903 260 131 455 0.2235494880546075 0.9684027777777777 0.03159722222222222 12295 0.9757936507936508 12238 0.9712698412698413 12168 0.9657142857142857 127 70 432 150.89903235526316 0.2465654372123616 0.2887733333333302 0.5229066666666595 0.8415958095238097 1.3391346666666688 2.380239999999999 1.542857142857143 3.0 6
22 6+2 6+2 6 2 0.75 200.0 9800.0 0.02 0.01945312904270856 200 300302 157.76975922953451 168.39601926163724 242.92776886035313 57.072231139646874 35.05486837932128 300.0 20.974640000000022 144 4 2 0.14265870370370404 0.21429333333333744 0.11193870370370387 18.337391304347825 21 172400 57600 3609 1180 188 127 713 0.15119047619047618 0.9752430555555556 0.024756944444444446 12268 0.9736507936507937 12204 0.9685714285714285 12112 0.9612698412698413 156 92 488 150.2020516204329 0.2623295794804066 0.29408000000000545 0.42549333333333905 0.8397175527426163 1.3339266666666698 2.3648799999999994 1.5443037974683544 3.0 6
23 8+3 8+3 8 3 0.7272727272727273 200.0 9800.0 0.02 0.01942144600871695 200 300302 157.76975922953451 168.39601926163724 250.91595505617977 49.08404494382023 37.12246828058022 300.0 21.020720000000026 108 6 3 0.19185679012345724 0.2667200000000012 0.145776790123457 18.984822934232714 24 172400 64800 3566 1346 249 130 562 0.18786127167630057 0.9739814814814814 0.026018518518518517 12280 0.9746031746031746 12216 0.9695238095238096 12128 0.9625396825396826 152 88 472 150.08097914819265 0.2710280233069496 0.30594666666668857 0.4667466666666762 0.8615145230078568 1.3390666666666675 2.3341600000000007 1.5892255892255893 3.0 6
24 4+2 4+2 4 2 0.6666666666666666 200.0 9800.0 0.02 0.01942144600871695 200 300302 157.76975922953451 168.39601926163724 274.6586195826645 25.341380417335472 42.55787075997801 300.0 21.020720000000026 216 2 1 0.09639320987654372 0.1591200000000068 0.06574432098765466 20.698375870069604 24 172400 86200 3572 1806 236 159 938 0.14494074749316319 0.978287037037037 0.02171296296296296 12261 0.9730952380952381 12177 0.9664285714285714 12084 0.959047619047619 177 93 516 149.53471051419723 0.29658307403729667 0.33632000000002193 0.39477333333332965 0.8655246666666663 1.349666666666665 2.3648799999999994 1.6125 3.0 6
25 8+4 8+4 8 4 0.6666666666666666 200.0 9800.0 0.02 0.019400401043555997 200 300302 157.76975922953451 168.39601926163724 274.6586195826645 25.341380417335472 42.55787075997801 300.0 21.051440000000028 108 6 3 0.1938755555555563 0.2667200000000012 0.13257777777777818 20.85924207269915 26 172400 86200 3550 1777 375 160 522 0.23460410557184752 0.9758333333333333 0.024166666666666666 12288 0.9752380952380952 12225 0.9702380952380952 12135 0.9630952380952381 153 90 465 149.94388982416385 0.2959204021425649 0.3366666666666909 0.46594666666666207 0.8995634676434676 1.347973333333331 2.3341600000000007 1.7032967032967032 3.0 6
26 none Без FEC 0 0 1.0 1000.0 49000.0 0.02 0.017221990003688604 200 300303 157.76975922953451 168.39601926163724 168.39601926163724 131.60398073836276 6.3102798265039075 300.0 20.869679999999992 0 0 0 0.0 0.0 0.0 13.7169373549884 15 172400 0 3014 0 0 0 0 0.0 0.0 0.0 12372 0.981904761904762 12355 0.9805555555555555 12345 0.9797619047619047 27 10 255 153.8087579684979 0.1850217642770288 0.20301333333332394 0.20967999999999998 1.4030256410256405 3.0499439999999973 4.3269600000000015 3.269230769230769 8.149999999999991 12
27 4+1 4+1 4 1 0.8 1000.0 49000.0 0.02 0.01762954307387838 200 300303 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.95928000000002 216 2 1 0.09296604938271637 0.18984000000000556 0.07760604938271627 17.17068645640074 20 172400 43200 3089 774 18 18 806 0.021844660194174758 0.9813425925925926 0.018657407407407407 12362 0.9811111111111112 12340 0.9793650793650793 12325 0.9781746031746031 37 15 275 152.8935249684148 0.24643575388776331 0.27488000000001733 0.37941333333333027 1.444222551440331 3.016560000000001 4.3107466666666685 3.3950617283950617 8.0 12
28 8+2 8+2 8 2 0.8 1000.0 49000.0 0.02 0.017631278990127012 200 300303 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.974640000000022 108 6 2 0.18972345679012387 0.2667200000000012 0.15900345679012368 17.209647495361782 21 172400 43200 3079 781 25 16 427 0.03611738148984198 0.9802314814814815 0.01976851851851852 12366 0.9814285714285714 12342 0.9795238095238096 12327 0.9783333333333334 39 15 273 152.80692302704583 0.24594955030961974 0.27506666666666346 0.44994666666666205 1.466306160337555 3.0479386666666684 4.295386666666669 3.4556962025316458 8.099999999999994 12
29 12+3 12+3 12 3 0.8 1000.0 49000.0 0.02 0.017631278990127012 200 300303 157.76975922953451 168.39601926163724 226.95139646869984 73.04860353130016 30.4830189704105 300.0 20.974640000000022 72 10 3 0.2887951851851859 0.33717333333333244 0.24271518518518562 17.21892393320965 21 172400 43200 3090 775 34 18 304 0.055900621118012424 0.9788888888888889 0.021111111111111112 12367 0.9815079365079366 12343 0.9796031746031746 12329 0.9784920634920635 38 14 271 152.83293157832492 0.24574732095060553 0.2850666666666548 0.5122933333333357 1.5037301754385983 3.0950066666666745 4.3368533333333215 3.5657894736842106 8.25 12
30 6+2 6+2 6 2 0.75 1000.0 49000.0 0.02 0.017631278990127012 200 300303 157.76975922953451 168.39601926163724 242.92776886035313 57.072231139646874 35.05486837932128 300.0 20.974640000000022 144 4 2 0.14265870370370404 0.21429333333333744 0.11193870370370387 18.337391304347825 21 172400 57600 3092 1033 40 25 547 0.043706293706293704 0.9810069444444445 0.018993055555555555 12366 0.9814285714285714 12338 0.9792063492063492 12326 0.9782539682539683 40 12 274 152.79328179172546 0.26206411812429153 0.29408000000000545 0.4192266666666633 1.4673545991561199 3.047938666666669 4.336853333333321 3.4683544303797467 8.099999999999994 12
31 8+3 8+3 8 3 0.7272727272727273 1000.0 49000.0 0.02 0.017636471517506424 200 300303 157.76975922953451 168.39601926163724 250.91595505617977 49.08404494382023 37.12246828058022 300.0 21.020720000000026 108 6 3 0.19185679012345724 0.2667200000000012 0.145776790123457 18.984822934232714 24 172400 64800 3080 1165 48 25 418 0.056433408577878104 0.9806481481481482 0.019351851851851853 12368 0.9815873015873016 12340 0.9793650793650793 12325 0.9781746031746031 43 15 275 152.44826628203012 0.27059416362407174 0.3057866666666631 0.44994666666666205 1.508938181818184 3.079317333333341 4.290773333333321 3.5714285714285716 8.200000000000003 12
32 4+2 4+2 4 2 0.6666666666666666 1000.0 49000.0 0.02 0.017636471517506424 200 300303 157.76975922953451 168.39601926163724 274.6586195826645 25.341380417335472 42.55787075997801 300.0 21.020720000000026 216 2 1 0.09639320987654372 0.1591200000000068 0.06574432098765466 20.698375870069604 24 172400 86200 3094 1545 55 36 784 0.04390243902439024 0.9818518518518519 0.01814814814814815 12362 0.9811111111111112 12331 0.9786507936507937 12312 0.9771428571428571 50 19 288 152.2895466948799 0.2964339592809204 0.33632000000002193 0.39477333333333053 1.5150906666666693 3.0350866666667184 4.336853333333319 3.6 8.049999999999997 12
33 8+4 8+4 8 4 0.6666666666666666 1000.0 49000.0 0.02 0.017189734334432376 200 300303 157.76975922953451 168.39601926163724 274.6586195826645 25.341380417335472 42.55787075997801 300.0 21.051440000000028 108 6 3 0.1938755555555563 0.2667200000000012 0.13257777777777818 20.85924207269915 26 172400 86200 3004 1509 64 27 400 0.06323185011709602 0.9814814814814815 0.018518518518518517 12372 0.981904761904762 12346 0.9798412698412698 12325 0.9781746031746031 47 21 275 152.2330861926783 0.29551052981744624 0.33650666666666273 0.46469333333333185 1.5328961403508796 3.0950066666666753 4.2754133333333195 3.6184210526315788 8.25 12

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -0,0 +1,9 @@
mode,label,source_block_size,nominal_parity_count,code_rate,outer_fec_stream_bitrate_kbps,margin_to_control_bitrate_kbps,service_and_parity_percent,fec_block_count,mean_block_duration_seconds,max_block_duration_seconds,mean_decode_ready_duration_seconds,mean_queue_length_packets,max_queue_length_packets,composite_success_10ms,p95_publication_delay_10ms_seconds,p95_no_new_image_10ms_seconds,composite_success_50ms,p95_publication_delay_50ms_seconds,p95_no_new_image_50ms_seconds,composite_success_200ms,p95_publication_delay_200ms_seconds,p95_no_new_image_200ms_seconds,composite_success_1000ms,p95_publication_delay_1000ms_seconds,p95_no_new_image_1000ms_seconds
none,Без FEC,0,0,1.0,168.39601926163724,131.60398073836276,6.3102798265039075,0,0.0,0.0,0.0,13.7169373549884,15,0.6696031746031746,0.20301333333332394,1.3455733333333306,0.9145238095238095,0.20301333333332394,0.9983146666666661,0.9607142857142857,0.20301333333332394,1.3251839999999993,0.9797619047619047,0.20301333333332394,3.0499439999999973
4+1,4+1,4,1,0.8,226.95139646869984,73.04860353130016,30.4830189704105,216,0.09296604938271637,0.18984000000000556,0.07760604938271627,17.17068645640074,20,0.7914285714285715,0.277253333333352,1.0431573333333346,0.909047619047619,0.27522666666668627,1.0041866666666657,0.9596825396825397,0.27488000000001733,1.3371666666666668,0.9781746031746031,0.27488000000001733,3.016560000000001
8+2,8+2,8,2,0.8,226.95139646869984,73.04860353130016,30.4830189704105,108,0.18972345679012387,0.2667200000000012,0.15900345679012368,17.209647495361782,21,0.9128571428571428,0.39477333333332965,1.0170573333333313,0.9333333333333333,0.27522666666668627,1.009596,0.963015873015873,0.27506666666666346,1.3387466666666654,0.9783333333333334,0.27506666666666346,3.0479386666666684
12+3,12+3,12,3,0.8,226.95139646869984,73.04860353130016,30.4830189704105,72,0.2887951851851859,0.33717333333333244,0.24271518518518562,17.21892393320965,21,0.9519841269841269,0.43695999999999735,1.130100000000001,0.9511904761904761,0.2925866666666561,1.0041866666666657,0.9657142857142857,0.2887733333333302,1.3391346666666688,0.9784920634920635,0.2850666666666548,3.0950066666666745
6+2,6+2,6,2,0.75,242.92776886035313,57.072231139646874,35.05486837932128,144,0.14265870370370404,0.21429333333333744,0.11193870370370387,18.337391304347825,21,0.9208730158730158,0.3794133333333327,1.015386666666668,0.9303174603174603,0.2962933333333524,1.0114399999999997,0.9612698412698413,0.29408000000000545,1.3339266666666698,0.9782539682539683,0.29408000000000545,3.047938666666669
8+3,8+3,8,3,0.7272727272727273,250.91595505617977,49.08404494382023,37.12246828058022,108,0.19185679012345724,0.2667200000000012,0.145776790123457,18.984822934232714,24,0.9634126984126984,0.410133333333329,1.0108000000000015,0.9488095238095238,0.3079733333333543,1.0080079999999976,0.9625396825396826,0.30594666666668857,1.3390666666666675,0.9781746031746031,0.3057866666666631,3.079317333333341
4+2,4+2,4,2,0.6666666666666666,274.6586195826645,25.341380417335472,42.55787075997801,216,0.09639320987654372,0.1591200000000068,0.06574432098765466,20.698375870069604,24,0.9247619047619048,0.34253333333332137,1.0002666666666684,0.9241269841269841,0.3366666666666909,1.0119066666666576,0.959047619047619,0.33632000000002193,1.349666666666665,0.9771428571428571,0.33632000000002193,3.0350866666667184
8+4,8+4,8,4,0.6666666666666666,274.6586195826645,25.341380417335472,42.55787075997801,108,0.1938755555555563,0.2667200000000012,0.13257777777777818,20.85924207269915,26,0.986984126984127,0.4101333333333308,1.0169693333333332,0.9553174603174603,0.3386933333333566,1.0571200000000047,0.9630952380952381,0.3366666666666909,1.347973333333331,0.9781746031746031,0.33650666666666273,3.0950066666666753
1 mode label source_block_size nominal_parity_count code_rate outer_fec_stream_bitrate_kbps margin_to_control_bitrate_kbps service_and_parity_percent fec_block_count mean_block_duration_seconds max_block_duration_seconds mean_decode_ready_duration_seconds mean_queue_length_packets max_queue_length_packets composite_success_10ms p95_publication_delay_10ms_seconds p95_no_new_image_10ms_seconds composite_success_50ms p95_publication_delay_50ms_seconds p95_no_new_image_50ms_seconds composite_success_200ms p95_publication_delay_200ms_seconds p95_no_new_image_200ms_seconds composite_success_1000ms p95_publication_delay_1000ms_seconds p95_no_new_image_1000ms_seconds
2 none Без FEC 0 0 1.0 168.39601926163724 131.60398073836276 6.3102798265039075 0 0.0 0.0 0.0 13.7169373549884 15 0.6696031746031746 0.20301333333332394 1.3455733333333306 0.9145238095238095 0.20301333333332394 0.9983146666666661 0.9607142857142857 0.20301333333332394 1.3251839999999993 0.9797619047619047 0.20301333333332394 3.0499439999999973
3 4+1 4+1 4 1 0.8 226.95139646869984 73.04860353130016 30.4830189704105 216 0.09296604938271637 0.18984000000000556 0.07760604938271627 17.17068645640074 20 0.7914285714285715 0.277253333333352 1.0431573333333346 0.909047619047619 0.27522666666668627 1.0041866666666657 0.9596825396825397 0.27488000000001733 1.3371666666666668 0.9781746031746031 0.27488000000001733 3.016560000000001
4 8+2 8+2 8 2 0.8 226.95139646869984 73.04860353130016 30.4830189704105 108 0.18972345679012387 0.2667200000000012 0.15900345679012368 17.209647495361782 21 0.9128571428571428 0.39477333333332965 1.0170573333333313 0.9333333333333333 0.27522666666668627 1.009596 0.963015873015873 0.27506666666666346 1.3387466666666654 0.9783333333333334 0.27506666666666346 3.0479386666666684
5 12+3 12+3 12 3 0.8 226.95139646869984 73.04860353130016 30.4830189704105 72 0.2887951851851859 0.33717333333333244 0.24271518518518562 17.21892393320965 21 0.9519841269841269 0.43695999999999735 1.130100000000001 0.9511904761904761 0.2925866666666561 1.0041866666666657 0.9657142857142857 0.2887733333333302 1.3391346666666688 0.9784920634920635 0.2850666666666548 3.0950066666666745
6 6+2 6+2 6 2 0.75 242.92776886035313 57.072231139646874 35.05486837932128 144 0.14265870370370404 0.21429333333333744 0.11193870370370387 18.337391304347825 21 0.9208730158730158 0.3794133333333327 1.015386666666668 0.9303174603174603 0.2962933333333524 1.0114399999999997 0.9612698412698413 0.29408000000000545 1.3339266666666698 0.9782539682539683 0.29408000000000545 3.047938666666669
7 8+3 8+3 8 3 0.7272727272727273 250.91595505617977 49.08404494382023 37.12246828058022 108 0.19185679012345724 0.2667200000000012 0.145776790123457 18.984822934232714 24 0.9634126984126984 0.410133333333329 1.0108000000000015 0.9488095238095238 0.3079733333333543 1.0080079999999976 0.9625396825396826 0.30594666666668857 1.3390666666666675 0.9781746031746031 0.3057866666666631 3.079317333333341
8 4+2 4+2 4 2 0.6666666666666666 274.6586195826645 25.341380417335472 42.55787075997801 216 0.09639320987654372 0.1591200000000068 0.06574432098765466 20.698375870069604 24 0.9247619047619048 0.34253333333332137 1.0002666666666684 0.9241269841269841 0.3366666666666909 1.0119066666666576 0.959047619047619 0.33632000000002193 1.349666666666665 0.9771428571428571 0.33632000000002193 3.0350866666667184
9 8+4 8+4 8 4 0.6666666666666666 274.6586195826645 25.341380417335472 42.55787075997801 108 0.1938755555555563 0.2667200000000012 0.13257777777777818 20.85924207269915 26 0.986984126984127 0.4101333333333308 1.0169693333333332 0.9553174603174603 0.3386933333333566 1.0571200000000047 0.9630952380952381 0.3366666666666909 1.347973333333331 0.9781746031746031 0.33650666666666273 3.0950066666666753

View File

@@ -0,0 +1,405 @@
# Исследование сжатия видеопотока в Lab026Lab027
## 1. Назначение исследований
Lab026, Lab026B и Lab027 исследуют способы уменьшения полезной нагрузки
видеоканала для системы управления ровером через ретранслятор.
На рассматриваемом этапе измеряется только полезная нагрузка,
формируемая средствами покадрового кодирования изображения. Исследования
не включают радиопередачу и не определяют профиль как автоматически
безопасный для управления.
Последовательность исследований:
```text
Lab026
|
+-- разрешение кадра
+-- частота кадров
+-- color / grayscale
+-- JPEG Quality
|
v
Контрольный профиль: 320x180, grayscale, 2 fps, JPEG Q40
|
+--> Lab026B: 4-битная яркость и индексированный цвет
|
+--> Lab027: раздельная передача общего кадра BASE и области ROI
```
## 2. Исходное видео
Во всех трёх лабораторных использован один файл:
```text
data/raw/lab026_rover_source.mp4
```
| Параметр | Значение |
|---|---:|
| Размер файла | 7 790 985 байт |
| Разрешение | 1280x720 |
| Частота кадров | 30.000000 кадр/с |
| Число кадров | 623 |
| Длительность | 20.766667 с |
| Приблизительный файловый битрейт | 3001.343 кбит/с |
## 3. Метод покадрового JPEG-сжатия
Lab026 и JPEG-режимы последующих лабораторных используют независимое
покадровое сжатие:
```text
исходный кадр
|
+--> изменение разрешения
|
+--> преобразование color / grayscale по параметрам профиля
|
+--> cv2.imencode(..., JPEG Quality)
|
+--> размер JPEG в байтах
|
+--> cv2.imdecode(...)
|
+--> расчёт PSNR
```
JPEG кодируется и декодируется в памяти. Отдельные JPEG-файлы на диск
не сохраняются. Межкадровое предсказание не используется.
Кадры для заданной частоты выбираются по временной шкале. В общем виде:
```text
frame_time = frame_index / source_fps
кадр выбирается, если:
frame_time + 1e-9 >= next_sample_time
после выбора:
next_sample_time += 1 / target_fps
```
## 4. Lab026: разрешение, FPS, grayscale и JPEG Quality
### 4.1. Изменение FPS
Условия серии: 640x360, grayscale, JPEG Q50.
| Целевой FPS | Выбрано кадров | Payload, кбит/с | PSNR, дБ |
|---:|---:|---:|---:|
| 30 | 623 | 3936.913 | 37.350 |
| 10 | 208 | 1402.877 | 36.370 |
| 5 | 104 | 702.043 | 36.353 |
| 2 | 42 | 284.084 | 36.320 |
| 1 | 21 | 142.273 | 36.288 |
| 0.5 | 11 | 73.821 | 36.372 |
| 0.2 | 5 | 35.247 | 35.860 |
### 4.2. Изменение разрешения
Условия серии: 5 кадр/с, grayscale, JPEG Q50.
| Разрешение | Выбрано кадров | Payload, кбит/с | PSNR, дБ |
|---|---:|---:|---:|
| 1280x720 | 104 | 2121.333 | 39.608 |
| 960x540 | 104 | 1314.376 | 38.632 |
| 640x360 | 104 | 702.043 | 36.353 |
| 480x270 | 104 | 431.824 | 36.172 |
| 320x180 | 104 | 227.294 | 35.069 |
| 160x90 | 104 | 80.918 | 33.586 |
### 4.3. Color, grayscale и JPEG Quality
Условия серии: 640x360, 5 кадр/с.
| Режим | JPEG Quality | Payload, кбит/с | PSNR, дБ |
|---|---:|---:|---:|
| color | 90 | 2113.639 | 39.694 |
| color | 70 | 1117.677 | 36.029 |
| color | 50 | 823.307 | 34.439 |
| color | 30 | 605.629 | 32.766 |
| color | 20 | 471.731 | 31.299 |
| grayscale | 90 | 1809.440 | 42.575 |
| grayscale | 70 | 957.219 | 38.032 |
| grayscale | 50 | 702.043 | 36.353 |
| grayscale | 30 | 511.658 | 34.702 |
| grayscale | 20 | 392.150 | 33.304 |
### 4.4. Контрольный профиль
В качестве контрольного профиля принят:
| Параметр | Значение |
|---|---:|
| Разрешение | 320x180 |
| Цветовой режим | grayscale |
| Частота | 2 кадр/с |
| JPEG Quality | 40 |
| Выбрано кадров | 42 |
| Payload bitrate | 80.283660 кбит/с |
| Средний PSNR | 34.362114 дБ |
Этот профиль используется как baseline в Lab026B и как контрольная
точка для Lab027.
## 5. Lab026B: глубина 4 бита на пиксель
### 5.1. Исследованные представления
Под 4-битной яркостью понимается индекс `0...15`, то есть 16 уровней
серого. Восстановленное значение формируется по тому же индексу в
диапазоне `0...255`.
Под 4-битным индексированным цветом понимается один индекс `0...15`
на пиксель и палитра не более 16 RGB-цветов на кадр. Это не RGB444:
RGB444 использует по 4 бита на каждый из трёх каналов, то есть 12 бит
на пиксель.
Исследованы пять режимов:
| Режим | Представление |
|---|---|
| `gray8_jpeg` | Контрольный grayscale JPEG Q40 |
| `gray4_jpeg` | 16 уровней серого, восстановление в `uint8`, JPEG Q40 |
| `gray4_packed_zlib` | Два 4-битных индекса в байте, zlib level 9, заголовок 16 байт |
| `color16_png` | До 16 цветов, без дизеринга, индексированный PNG |
| `color16_packed_zlib` | 4-битные индексы, zlib level 9, заголовок 16 байт, палитра 48 байт |
### 5.2. Результаты при 320x180 и 2 кадр/с
| Режим | Payload, кбит/с | Средний PSNR, дБ |
|---|---:|---:|
| `gray8_jpeg` | 80.283660 | 34.362114 |
| `gray4_jpeg` | 88.417849 | 32.588941 |
| `gray4_packed_zlib` | 169.916148 | 34.397012 |
| `color16_png` | 143.121669 | 25.384724 |
| `color16_packed_zlib` | 140.568347 | 25.384724 |
### 5.3. Зафиксированный отрицательный результат
В Lab026B уменьшение глубины до 4 бит не позволило повысить разрешение
кадра в пределах 100 кбит/с.
До 100 кбит/с прошли только два профиля:
| Профиль | Разрешение | Payload, кбит/с | Средний PSNR, дБ |
|---|---|---:|---:|
| `320x180_gray8_jpeg_2fps` | 320x180 | 80.283660 | 34.362114 |
| `320x180_gray4_jpeg_2fps` | 320x180 | 88.417849 | 32.588941 |
Профилей с разрешением больше 320x180 и payload не более
80.283660 кбит/с не получено. Цветных `color16`-профилей до
100 кбит/с также не получено.
## 6. Lab027: многомасштабная передача BASE + ROI
### 6.1. Принцип
В Lab027 один профиль состоит из двух независимых JPEG-потоков:
```text
исходный полноразмерный кадр
|
+--> BASE
| полный grayscale-кадр
| собственные разрешение, FPS и JPEG Quality
|
+--> ROI
вырезка из исходного кадра
собственные разрешение, FPS и JPEG Quality
приёмная реконструкция 640x360:
декодированный BASE
|
+--> масштабирование до 640x360
|
+--> наложение последнего декодированного ROI
в геометрическое положение области интереса
```
BASE и ROI обновляются независимо по временной шкале. Между
обновлениями удерживается последнее декодированное состояние каждого
потока.
### 6.2. Фиксированная ROI
Нормализованные координаты:
```text
x_min = 0.20
x_max = 0.80
y_min = 0.42
y_max = 1.00
```
Для исходного кадра 1280x720 используются координаты:
```text
x = 256...1024
y = 302...720
```
Область занимает центральные 60% ширины и нижние 58% высоты кадра.
ROI фиксирована и не использует автоматическое распознавание дороги,
нейронные сети или детекторы объектов.
### 6.3. Результаты ROI-профилей
| Профиль | BASE | ROI | BASE, кбит/с | ROI, кбит/с | Total, кбит/с | Full PSNR, дБ | ROI PSNR, дБ |
|---|---|---|---:|---:|---:|---:|---:|
| `base240_1fps_q25_roi320_2fps_q35` | 240x135, 1 FPS, Q25 | 320x180, 2 FPS, Q35 | 19.592167 | 73.683467 | 93.275634 | 19.657187 | 19.574377 |
| `base240_0_5fps_q25_roi320_2fps_q35` | 240x135, 0.5 FPS, Q25 | 320x180, 2 FPS, Q35 | 10.150112 | 73.683467 | 83.833579 | 18.613817 | 19.574377 |
| `base160_1fps_q25_roi320_2fps_q35` | 160x90, 1 FPS, Q25 | 320x180, 2 FPS, Q35 | 11.511525 | 73.683467 | 85.194992 | 19.701304 | 19.574377 |
| `base240_1fps_q25_roi448_1fps_q30` | 240x135, 1 FPS, Q25 | 448x252, 1 FPS, Q30 | 19.592167 | 56.932392 | 76.524559 | 19.098790 | 17.871555 |
| `base240_0_5fps_q25_roi448_1fps_q30` | 240x135, 0.5 FPS, Q25 | 448x252, 1 FPS, Q30 | 10.150112 | 56.932392 | 67.082504 | 18.113877 | 17.871555 |
| `base320_1fps_q30_roi320_1fps_q35` | 320x180, 1 FPS, Q30 | 320x180, 1 FPS, Q35 | 33.862343 | 36.738491 | 70.600835 | 19.121457 | 17.888190 |
| `base240_1fps_q20_roi320_1fps_q30` | 240x135, 1 FPS, Q20 | 320x180, 1 FPS, Q30 | 17.180610 | 33.306453 | 50.487063 | 19.107784 | 17.873870 |
| `base160_0_5fps_q20_roi320_2fps_q30` | 160x90, 0.5 FPS, Q20 | 320x180, 2 FPS, Q30 | 5.323917 | 66.820546 | 72.144462 | 18.664976 | 19.549559 |
Контрольный baseline при повторении в Lab027 составил
80.270177 кбит/с. Контрольное значение из Lab026, используемое для
сравнения, равно 80.283660 кбит/с.
### 6.4. Основной режим
В качестве основного режима в этом описании зафиксирован профиль:
```text
base160_1fps_q25_roi320_2fps_q35
```
| Компонент | Параметры |
|---|---|
| BASE | 160x90, 1 кадр/с, JPEG Q25 |
| ROI | 320x180, 2 кадр/с, JPEG Q35 |
| BASE bitrate | 11.511525 кбит/с |
| ROI bitrate | 73.683467 кбит/с |
| Total payload bitrate | 85.194992 кбит/с |
| Mean reconstructed full PSNR | 19.701304 дБ |
| Mean reconstructed ROI PSNR | 19.574377 дБ |
### 6.5. Аварийный режим
В качестве аварийного режима в этом описании зафиксирован профиль:
```text
base240_1fps_q20_roi320_1fps_q30
```
| Компонент | Параметры |
|---|---|
| BASE | 240x135, 1 кадр/с, JPEG Q20 |
| ROI | 320x180, 1 кадр/с, JPEG Q30 |
| BASE bitrate | 17.180610 кбит/с |
| ROI bitrate | 33.306453 кбит/с |
| Total payload bitrate | 50.487063 кбит/с |
| Mean reconstructed full PSNR | 19.107784 дБ |
| Mean reconstructed ROI PSNR | 17.873870 дБ |
## 7. Расчёт payload bitrate
Для одного JPEG-потока:
```text
total_payload_bytes = сумма размеров выбранных JPEG-кадров
payload_bitrate_bps =
total_payload_bytes * 8 / source_duration_seconds
payload_bitrate_kbps =
payload_bitrate_bps / 1000
```
Для Lab027:
```text
total_payload_bytes =
total_base_bytes + total_roi_bytes
base_bitrate_kbps =
total_base_bytes * 8 / source_duration_seconds / 1000
roi_bitrate_kbps =
total_roi_bytes * 8 / source_duration_seconds / 1000
total_payload_bitrate_kbps =
base_bitrate_kbps + roi_bitrate_kbps
```
Lab026B использует тот же принцип подсчёта полезной нагрузки, но размер
кадра определяется выбранным режимом: JPEG, индексированный PNG либо
упакованные и сжатые zlib индексы вместе с предусмотренными заголовком
и палитрой.
## 8. Неучтённые накладные расходы радиоканала
В приведённые значения payload bitrate пока не включены:
- заголовки радиопакетов и служебные поля радиопротокола;
- преамбула;
- CRC;
- FEC;
- фрагментация кадров по радиопакетам;
- межпакетные интервалы;
- повторные передачи;
- команды управления.
Значения также не включают оценку задержки полного тракта. PSNR и
статические сравнительные изображения не заменяют ручную оценку
пригодности изображения. Фиксированная ROI не гарантирует попадания
препятствия в область интереса.
## 9. Итоговый рабочий видеорежим после Lab027CLab027E
Динамические сравнения Lab027C и Lab027D подтвердили, что раздельное
асинхронное обновление BASE и ROI заметно оператору. Синхронное
формирование обеих частей из одного исходного кадра устранило их
визуальное рассогласование. Частота 2 кадр/с оказалась недостаточной,
а 3 кадр/с по результатам ручной оценки признаны приемлемыми.
В качестве рабочего компромисса выбран следующий профиль:
| Компонент | Рабочие параметры |
|---|---|
| BASE | 240x135, grayscale, JPEG Q23 |
| ROI | 320x180, grayscale, JPEG Q33 |
| Обновление | синхронное и атомарное |
| Частота составного изображения | 3 кадр/с |
| JPEG payload | 156.342279 кбит/с |
| Оценка с 10% overhead и FEC 2/3 | 257.964761 кбит/с |
| Оценка с 10% overhead и FEC 1/2 | 343.953014 кбит/с |
Расчёт иллюстративных канальных скоростей:
```text
channel_rate_fec_2_3_kbps =
payload_kbps * 1.10 / (2 / 3)
channel_rate_fec_1_2_kbps =
payload_kbps * 1.10 / (1 / 2)
```
JPEG Q20 для BASE и Q30 для ROI признаны приемлемыми. Профиль Q23/Q33
выбран как рабочий компромисс качества и потока. Визуальная разница
между Q23/Q33 и Q25/Q35 практически отсутствует, поэтому увеличение
потока для Q25/Q35 не дало заметного преимущества при ручной оценке.
При скорости ровера 25 км/ч линейная скорость равна примерно
6.944 м/с. При трёх составных кадрах в секунду ровер проходит:
```text
6.944 м/с / 3 кадр/с = 2.315 м/кадр
```
То есть между соседними составными изображениями ровер перемещается
примерно на 2.31 м. Эта оценка не включает задержку кодирования,
радиоканала, ретранслятора, декодирования и реакции оператора.
Lab027E дополнительно использовала playback 0.5x для локальной
визуальной имитации более медленного движения сцены. Замедление
применялось только при создании операторского preview и не является
частью передаваемого радиоканального формата. Реальная скорость
автомобиля в исходном видео неизвестна.

178
protocol/fec_interleaver.py Normal file
View 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],)
)

View File

@@ -0,0 +1,613 @@
"""
Systematic packet-erasure FEC over GF(256) for Lab028 wire packets.
The code uses a Vandermonde generator matrix over GF(256), transformed to
systematic form. The primitive polynomial is x^8+x^4+x^3+x^2+1 (0x11D).
Any k available symbols from an n=k+r block reconstruct all k source
symbols.
Each source or parity symbol is carried in a fixed 32-byte outer header::
!4sBBHIHHHHHHII
Offset Size Field
0 4 magic (b"SFE1")
4 1 version
5 1 flags (bit 0: parity)
6 2 header_size
8 4 block_id
12 2 symbol_index
14 2 source_count (k)
16 2 parity_count (r)
18 2 symbol_size
20 2 data_length
22 2 reserved16 (zero)
24 4 reserved32 (zero)
28 4 outer_crc32
Source symbols carry the original serialized Lab028 packet without padding.
Parity symbols carry symbol_size bytes. Zero padding is applied only during
GF(256) mathematics. A recovered source symbol is trimmed from the Lab028
payload_length field and must pass the original Lab028 packet CRC32.
"""
from __future__ import annotations
from dataclasses import dataclass
from functools import lru_cache
import struct
import zlib
from protocol.video_packet import (
HEADER_FORMAT as INNER_HEADER_FORMAT,
HEADER_SIZE as INNER_HEADER_SIZE,
MAGIC as INNER_MAGIC,
VERSION as INNER_VERSION,
decode_packet as decode_inner_packet,
)
GF_PRIMITIVE_POLYNOMIAL = 0x11D
GF_FIELD_SIZE = 256
GF_ORDER = 255
OUTER_MAGIC = b"SFE1"
OUTER_VERSION = 1
OUTER_FLAG_PARITY = 0x01
OUTER_HEADER_FORMAT = "!4sBBHIHHHHHHII"
OUTER_HEADER_SIZE = struct.calcsize(OUTER_HEADER_FORMAT)
MAX_SYMBOL_SIZE = 0xFFFF
MAX_BLOCK_SYMBOLS = 0xFF
class FECError(ValueError):
"""Base class for outer packets and erasure-code failures."""
class OuterPacketCRCError(FECError):
"""The outer packet failed its CRC32 check."""
class InsufficientSymbolsError(FECError):
"""Fewer than k unique symbols are available."""
class MatrixSingularError(FECError):
"""A GF(256) matrix has no inverse."""
@dataclass(frozen=True)
class OuterSymbol:
"""Decoded source or parity symbol after outer CRC validation."""
block_id: int
symbol_index: int
source_count: int
parity_count: int
symbol_size: int
data: bytes
is_parity: bool
outer_crc32: int = 0
@dataclass(frozen=True)
class DecodedFECBlock:
"""All reconstructed Lab028 packets from one FEC block."""
block_id: int
source_packets: tuple[bytes, ...]
recovered_indices: tuple[int, ...]
def _build_gf_tables() -> tuple[
tuple[int, ...],
tuple[int, ...],
]:
exponent = [0] * (GF_ORDER * 2)
logarithm = [0] * GF_FIELD_SIZE
value = 1
for index in range(GF_ORDER):
exponent[index] = value
logarithm[value] = index
value <<= 1
if value & GF_FIELD_SIZE:
value ^= GF_PRIMITIVE_POLYNOMIAL
for index in range(GF_ORDER, GF_ORDER * 2):
exponent[index] = exponent[index - GF_ORDER]
return tuple(exponent), tuple(logarithm)
GF_EXP, GF_LOG = _build_gf_tables()
def gf_add(left: int, right: int) -> int:
"""Addition/subtraction in GF(256)."""
return left ^ right
def gf_mul(left: int, right: int) -> int:
"""Multiplication in GF(256)."""
if left == 0 or right == 0:
return 0
return GF_EXP[GF_LOG[left] + GF_LOG[right]]
def gf_div(dividend: int, divisor: int) -> int:
"""Division in GF(256)."""
if divisor == 0:
raise ZeroDivisionError("GF(256) division by zero")
if dividend == 0:
return 0
return GF_EXP[
(GF_LOG[dividend] - GF_LOG[divisor]) % GF_ORDER
]
def gf_inverse(value: int) -> int:
"""Multiplicative inverse in GF(256)."""
if value == 0:
raise ZeroDivisionError("zero has no GF(256) inverse")
return GF_EXP[GF_ORDER - GF_LOG[value]]
def gf_pow(value: int, exponent: int) -> int:
"""Non-negative integer power in GF(256)."""
if exponent < 0:
raise ValueError("negative GF exponent is unsupported")
if exponent == 0:
return 1
if value == 0:
return 0
return GF_EXP[(GF_LOG[value] * exponent) % GF_ORDER]
GF_MUL_TRANSLATIONS = tuple(
bytes(gf_mul(coefficient, value) for value in range(256))
for coefficient in range(256)
)
def matrix_multiply(
left: tuple[tuple[int, ...], ...],
right: tuple[tuple[int, ...], ...],
) -> tuple[tuple[int, ...], ...]:
"""Multiply two small matrices over GF(256)."""
if not left or not right:
raise ValueError("matrices must not be empty")
inner_size = len(left[0])
if inner_size != len(right):
raise ValueError("matrix dimensions do not match")
column_count = len(right[0])
result = []
for row in left:
if len(row) != inner_size:
raise ValueError("left matrix is ragged")
result_row = []
for column_index in range(column_count):
value = 0
for inner_index in range(inner_size):
value ^= gf_mul(
row[inner_index],
right[inner_index][column_index],
)
result_row.append(value)
result.append(tuple(result_row))
return tuple(result)
def matrix_inverse(
matrix: tuple[tuple[int, ...], ...],
) -> tuple[tuple[int, ...], ...]:
"""Invert a square matrix using GF(256) Gauss-Jordan elimination."""
size = len(matrix)
if size == 0 or any(len(row) != size for row in matrix):
raise ValueError("matrix must be non-empty and square")
augmented = [
list(row)
+ [1 if row_index == column_index else 0
for column_index in range(size)]
for row_index, row in enumerate(matrix)
]
for pivot_column in range(size):
pivot_row = next(
(
row_index
for row_index in range(pivot_column, size)
if augmented[row_index][pivot_column] != 0
),
None,
)
if pivot_row is None:
raise MatrixSingularError("GF(256) matrix is singular")
if pivot_row != pivot_column:
augmented[pivot_column], augmented[pivot_row] = (
augmented[pivot_row],
augmented[pivot_column],
)
pivot_inverse = gf_inverse(
augmented[pivot_column][pivot_column]
)
augmented[pivot_column] = [
gf_mul(value, pivot_inverse)
for value in augmented[pivot_column]
]
for row_index in range(size):
if row_index == pivot_column:
continue
factor = augmented[row_index][pivot_column]
if factor == 0:
continue
augmented[row_index] = [
value ^ gf_mul(factor, pivot_value)
for value, pivot_value in zip(
augmented[row_index],
augmented[pivot_column],
)
]
return tuple(
tuple(row[size:]) for row in augmented
)
@lru_cache(maxsize=None)
def systematic_generator_matrix(
source_count: int,
parity_count: int,
) -> tuple[tuple[int, ...], ...]:
"""Return an n×k systematic Vandermonde generator matrix."""
if not 1 <= source_count <= MAX_BLOCK_SYMBOLS:
raise ValueError("source_count is outside 1...255")
if not 0 <= parity_count <= (
MAX_BLOCK_SYMBOLS - source_count
):
raise ValueError("source_count + parity_count exceeds 255")
total_count = source_count + parity_count
vandermonde = tuple(
tuple(
gf_pow(row_index + 1, column_index)
for column_index in range(source_count)
)
for row_index in range(total_count)
)
top_inverse = matrix_inverse(
vandermonde[:source_count]
)
generator = matrix_multiply(vandermonde, top_inverse)
identity = tuple(
tuple(
1 if row_index == column_index else 0
for column_index in range(source_count)
)
for row_index in range(source_count)
)
if generator[:source_count] != identity:
raise RuntimeError("generator matrix is not systematic")
return generator
def _linear_combine(
coefficients: tuple[int, ...],
symbols: tuple[bytes, ...],
symbol_size: int,
) -> bytes:
"""Combine equal-size byte strings over GF(256), using C-level helpers."""
accumulator = 0
for coefficient, symbol in zip(coefficients, symbols):
if coefficient == 0:
continue
translated = symbol.translate(
GF_MUL_TRANSLATIONS[coefficient]
)
accumulator ^= int.from_bytes(translated, "little")
return accumulator.to_bytes(symbol_size, "little")
def encode_parity_symbols(
source_symbols: tuple[bytes, ...],
parity_count: int,
) -> tuple[bytes, ...]:
"""Encode zero-padded source symbols into parity symbols."""
if not source_symbols:
raise ValueError("source symbol list is empty")
symbol_size = len(source_symbols[0])
if symbol_size == 0:
raise ValueError("symbol size is zero")
if any(len(symbol) != symbol_size for symbol in source_symbols):
raise ValueError("source symbols must have equal size")
generator = systematic_generator_matrix(
len(source_symbols), parity_count
)
return tuple(
_linear_combine(row, source_symbols, symbol_size)
for row in generator[len(source_symbols):]
)
def outer_crc32(data: bytes) -> int:
return zlib.crc32(data) & 0xFFFFFFFF
def _validate_outer_symbol(symbol: OuterSymbol) -> None:
total_count = symbol.source_count + symbol.parity_count
if not 0 <= symbol.block_id <= 0xFFFFFFFF:
raise FECError("block_id is outside uint32")
if not 1 <= symbol.source_count <= MAX_BLOCK_SYMBOLS:
raise FECError("source_count is outside 1...255")
if not 0 <= symbol.parity_count <= (
MAX_BLOCK_SYMBOLS - symbol.source_count
):
raise FECError("invalid parity_count")
if not 0 <= symbol.symbol_index < total_count:
raise FECError("symbol_index is outside the block")
if not 1 <= symbol.symbol_size <= MAX_SYMBOL_SIZE:
raise FECError("symbol_size is outside uint16")
if not 1 <= len(symbol.data) <= symbol.symbol_size:
raise FECError("data length is outside symbol_size")
expected_parity = symbol.symbol_index >= symbol.source_count
if symbol.is_parity != expected_parity:
raise FECError("parity flag conflicts with symbol_index")
if symbol.is_parity and len(symbol.data) != symbol.symbol_size:
raise FECError("parity data must equal symbol_size")
def _pack_outer_header(
symbol: OuterSymbol,
crc_value: int,
) -> bytes:
return struct.pack(
OUTER_HEADER_FORMAT,
OUTER_MAGIC,
OUTER_VERSION,
OUTER_FLAG_PARITY if symbol.is_parity else 0,
OUTER_HEADER_SIZE,
symbol.block_id,
symbol.symbol_index,
symbol.source_count,
symbol.parity_count,
symbol.symbol_size,
len(symbol.data),
0,
0,
crc_value,
)
def encode_outer_symbol(symbol: OuterSymbol) -> bytes:
"""Serialize one source/parity symbol and calculate outer CRC32."""
if not isinstance(symbol, OuterSymbol):
raise TypeError("symbol must be OuterSymbol")
_validate_outer_symbol(symbol)
header_without_crc = _pack_outer_header(symbol, 0)
crc_value = outer_crc32(header_without_crc + symbol.data)
return _pack_outer_header(symbol, crc_value) + symbol.data
def decode_outer_symbol(wire_packet: bytes) -> OuterSymbol:
"""Deserialize and validate one outer FEC packet."""
if not isinstance(wire_packet, (bytes, bytearray)):
raise TypeError("wire_packet must be bytes or bytearray")
wire_packet = bytes(wire_packet)
if len(wire_packet) < OUTER_HEADER_SIZE + 1:
raise FECError("outer packet is too short")
(
magic,
version,
flags,
header_size,
block_id,
symbol_index,
source_count,
parity_count,
symbol_size,
data_length,
reserved16,
reserved32,
received_crc,
) = struct.unpack(
OUTER_HEADER_FORMAT,
wire_packet[:OUTER_HEADER_SIZE],
)
if magic != OUTER_MAGIC:
raise FECError("invalid outer magic")
if version != OUTER_VERSION:
raise FECError("unsupported outer version")
if flags & ~OUTER_FLAG_PARITY:
raise FECError("unsupported outer flags")
if header_size != OUTER_HEADER_SIZE:
raise FECError("invalid outer header size")
if reserved16 != 0 or reserved32 != 0:
raise FECError("reserved outer fields must be zero")
if len(wire_packet) != OUTER_HEADER_SIZE + data_length:
raise FECError("outer data_length does not match packet length")
symbol = OuterSymbol(
block_id=block_id,
symbol_index=symbol_index,
source_count=source_count,
parity_count=parity_count,
symbol_size=symbol_size,
data=wire_packet[OUTER_HEADER_SIZE:],
is_parity=bool(flags & OUTER_FLAG_PARITY),
outer_crc32=received_crc,
)
_validate_outer_symbol(symbol)
calculated_crc = outer_crc32(
_pack_outer_header(symbol, 0) + symbol.data
)
if calculated_crc != received_crc:
raise OuterPacketCRCError(
"outer CRC mismatch: "
f"received 0x{received_crc:08X}, "
f"calculated 0x{calculated_crc:08X}"
)
return symbol
def encode_fec_block(
inner_packets: tuple[bytes, ...],
block_id: int,
parity_count: int,
) -> tuple[bytes, ...]:
"""Wrap systematic Lab028 packets and append parity packets."""
if not inner_packets:
raise ValueError("inner packet block is empty")
if len(inner_packets) + parity_count > MAX_BLOCK_SYMBOLS:
raise ValueError("FEC block has more than 255 symbols")
validated_packets = []
for packet in inner_packets:
packet_bytes = bytes(packet)
decode_inner_packet(packet_bytes)
validated_packets.append(packet_bytes)
symbol_size = max(len(packet) for packet in validated_packets)
if symbol_size > MAX_SYMBOL_SIZE:
raise ValueError("inner packet is too large for outer symbol_size")
padded_sources = tuple(
packet + bytes(symbol_size - len(packet))
for packet in validated_packets
)
parity_symbols = encode_parity_symbols(
padded_sources, parity_count
)
source_count = len(validated_packets)
outer_packets = [
encode_outer_symbol(
OuterSymbol(
block_id=block_id,
symbol_index=index,
source_count=source_count,
parity_count=parity_count,
symbol_size=symbol_size,
data=packet,
is_parity=False,
)
)
for index, packet in enumerate(validated_packets)
]
outer_packets.extend(
encode_outer_symbol(
OuterSymbol(
block_id=block_id,
symbol_index=source_count + parity_index,
source_count=source_count,
parity_count=parity_count,
symbol_size=symbol_size,
data=parity,
is_parity=True,
)
)
for parity_index, parity in enumerate(parity_symbols)
)
return tuple(outer_packets)
def _padded_symbol(symbol: OuterSymbol) -> bytes:
return symbol.data + bytes(symbol.symbol_size - len(symbol.data))
def trim_recovered_inner_packet(padded_packet: bytes) -> bytes:
"""Trim GF padding using the recovered Lab028 header and validate CRC."""
if len(padded_packet) < INNER_HEADER_SIZE:
raise FECError("recovered symbol is shorter than Lab028 header")
unpacked = struct.unpack(
INNER_HEADER_FORMAT,
padded_packet[:INNER_HEADER_SIZE],
)
magic = unpacked[0]
version = unpacked[1]
payload_length = unpacked[7]
if magic != INNER_MAGIC or version != INNER_VERSION:
raise FECError("recovered Lab028 magic/version is invalid")
packet_length = INNER_HEADER_SIZE + payload_length
if packet_length > len(padded_packet):
raise FECError("recovered Lab028 length exceeds symbol_size")
inner_packet = padded_packet[:packet_length]
decode_inner_packet(inner_packet)
return inner_packet
def decode_fec_block(
wire_symbols: tuple[bytes, ...],
) -> DecodedFECBlock:
"""Recover all source Lab028 packets from any k valid outer symbols."""
if not wire_symbols:
raise InsufficientSymbolsError("no outer symbols received")
symbols_by_index: dict[int, OuterSymbol] = {}
metadata = None
for wire_symbol in wire_symbols:
symbol = decode_outer_symbol(wire_symbol)
current_metadata = (
symbol.block_id,
symbol.source_count,
symbol.parity_count,
symbol.symbol_size,
)
if metadata is None:
metadata = current_metadata
elif current_metadata != metadata:
raise FECError("outer symbols belong to different blocks")
existing = symbols_by_index.get(symbol.symbol_index)
if existing is not None:
if existing != symbol:
raise FECError("conflicting duplicate outer symbol")
continue
symbols_by_index[symbol.symbol_index] = symbol
assert metadata is not None
block_id, source_count, parity_count, symbol_size = metadata
if len(symbols_by_index) < source_count:
raise InsufficientSymbolsError(
f"need {source_count} symbols, got {len(symbols_by_index)}"
)
selected_indices = tuple(sorted(symbols_by_index)[:source_count])
generator = systematic_generator_matrix(
source_count, parity_count
)
decode_matrix = matrix_inverse(
tuple(generator[index] for index in selected_indices)
)
selected_symbols = tuple(
_padded_symbol(symbols_by_index[index])
for index in selected_indices
)
source_packets = []
recovered_indices = []
for source_index in range(source_count):
received_source = symbols_by_index.get(source_index)
if received_source is not None:
inner_packet = received_source.data
decode_inner_packet(inner_packet)
else:
padded_packet = _linear_combine(
decode_matrix[source_index],
selected_symbols,
symbol_size,
)
inner_packet = trim_recovered_inner_packet(padded_packet)
recovered_indices.append(source_index)
source_packets.append(inner_packet)
return DecodedFECBlock(
block_id=block_id,
source_packets=tuple(source_packets),
recovered_indices=tuple(recovered_indices),
)

416
protocol/video_packet.py Normal file
View File

@@ -0,0 +1,416 @@
"""
Transport packets for synchronous BASE + ROI JPEG composite frames.
The wire header has a fixed 32-byte, padding-free network-byte-order layout::
!4sBBHIHHHHIII
Offset Size Field
0 4 magic (b"SRV1")
4 1 version
5 1 object_type (1=BASE, 2=ROI)
6 2 header_size
8 4 composite_frame_id
12 2 fragment_index
14 2 fragment_count
16 2 payload_length
18 2 flags (reserved, must be zero)
20 4 jpeg_size
24 4 object_crc32
28 4 packet_crc32
packet_crc32 is calculated over the complete header with packet_crc32 set to
zero, followed by the packet payload. object_crc32 is calculated over the
complete JPEG before fragmentation and checked after reassembly.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from enum import IntEnum
import struct
import zlib
MAGIC = b"SRV1"
VERSION = 1
HEADER_FORMAT = "!4sBBHIHHHHIII"
HEADER_SIZE = struct.calcsize(HEADER_FORMAT)
MAX_PAYLOAD_LENGTH = 0xFFFF
MAX_FRAGMENT_COUNT = 0xFFFF
MAX_JPEG_SIZE = 0xFFFFFFFF
class ObjectType(IntEnum):
"""JPEG object carried by a packet."""
BASE = 1
ROI = 2
class VideoPacketError(ValueError):
"""Base class for video transport validation errors."""
class PacketCRCError(VideoPacketError):
"""The packet header or payload failed its CRC32 check."""
class ObjectCRCError(VideoPacketError):
"""A completely reassembled JPEG failed its CRC32 check."""
class ObjectConsistencyError(VideoPacketError):
"""Fragments for one object contain inconsistent metadata or data."""
@dataclass(frozen=True)
class VideoPacket:
"""Decoded and CRC-checked transport packet."""
composite_frame_id: int
object_type: ObjectType
fragment_index: int
fragment_count: int
jpeg_size: int
object_crc32: int
payload: bytes
packet_crc32: int = 0
@dataclass(frozen=True)
class CompositeFrame:
"""Atomically reassembled BASE and ROI JPEGs for one source update."""
composite_frame_id: int
base_jpeg: bytes
roi_jpeg: bytes
def crc32(data: bytes) -> int:
"""Return an unsigned IEEE CRC32."""
return zlib.crc32(data) & 0xFFFFFFFF
def _validate_packet_fields(packet: VideoPacket) -> None:
if not 0 <= packet.composite_frame_id <= 0xFFFFFFFF:
raise VideoPacketError("composite_frame_id is outside uint32")
if packet.object_type not in (ObjectType.BASE, ObjectType.ROI):
raise VideoPacketError("unsupported object_type")
if not 1 <= packet.fragment_count <= MAX_FRAGMENT_COUNT:
raise VideoPacketError("fragment_count is outside uint16")
if not 0 <= packet.fragment_index < packet.fragment_count:
raise VideoPacketError("fragment_index is outside fragment_count")
if not 1 <= len(packet.payload) <= MAX_PAYLOAD_LENGTH:
raise VideoPacketError("payload length is outside uint16")
if not 1 <= packet.jpeg_size <= MAX_JPEG_SIZE:
raise VideoPacketError("jpeg_size is outside uint32")
if len(packet.payload) > packet.jpeg_size:
raise VideoPacketError("payload is larger than the JPEG object")
if not 0 <= packet.object_crc32 <= 0xFFFFFFFF:
raise VideoPacketError("object_crc32 is outside uint32")
def _pack_header(packet: VideoPacket, packet_crc32: int) -> bytes:
return struct.pack(
HEADER_FORMAT,
MAGIC,
VERSION,
int(packet.object_type),
HEADER_SIZE,
packet.composite_frame_id,
packet.fragment_index,
packet.fragment_count,
len(packet.payload),
0,
packet.jpeg_size,
packet.object_crc32,
packet_crc32,
)
def encode_packet(packet: VideoPacket) -> bytes:
"""Serialize a packet and calculate its packet CRC32."""
if not isinstance(packet, VideoPacket):
raise TypeError("packet must be VideoPacket")
_validate_packet_fields(packet)
header_with_zero_crc = _pack_header(packet, 0)
packet_crc32 = crc32(header_with_zero_crc + packet.payload)
return _pack_header(packet, packet_crc32) + packet.payload
def decode_packet(wire_packet: bytes) -> VideoPacket:
"""Deserialize a packet and validate its fixed header and packet CRC32."""
if not isinstance(wire_packet, (bytes, bytearray)):
raise TypeError("wire_packet must be bytes or bytearray")
wire_packet = bytes(wire_packet)
if len(wire_packet) < HEADER_SIZE + 1:
raise VideoPacketError("packet is shorter than header plus payload")
(
magic,
version,
object_type_value,
header_size,
composite_frame_id,
fragment_index,
fragment_count,
payload_length,
flags,
jpeg_size,
object_crc32,
received_packet_crc32,
) = struct.unpack(HEADER_FORMAT, wire_packet[:HEADER_SIZE])
if magic != MAGIC:
raise VideoPacketError("invalid packet magic")
if version != VERSION:
raise VideoPacketError("unsupported packet version")
if header_size != HEADER_SIZE:
raise VideoPacketError("invalid fixed header size")
if flags != 0:
raise VideoPacketError("reserved flags must be zero")
try:
object_type = ObjectType(object_type_value)
except ValueError as error:
raise VideoPacketError("unsupported object_type") from error
if len(wire_packet) != HEADER_SIZE + payload_length:
raise VideoPacketError("packet length does not match payload_length")
packet = VideoPacket(
composite_frame_id=composite_frame_id,
object_type=object_type,
fragment_index=fragment_index,
fragment_count=fragment_count,
jpeg_size=jpeg_size,
object_crc32=object_crc32,
payload=wire_packet[HEADER_SIZE:],
packet_crc32=received_packet_crc32,
)
_validate_packet_fields(packet)
calculated_packet_crc32 = crc32(
_pack_header(packet, 0) + packet.payload
)
if calculated_packet_crc32 != received_packet_crc32:
raise PacketCRCError(
"packet CRC mismatch: "
f"received 0x{received_packet_crc32:08X}, "
f"calculated 0x{calculated_packet_crc32:08X}"
)
return packet
def packetize_jpeg(
jpeg: bytes,
composite_frame_id: int,
object_type: ObjectType,
max_payload_length: int,
) -> list[bytes]:
"""Split one non-empty JPEG object into serialized packets."""
if not isinstance(jpeg, (bytes, bytearray)):
raise TypeError("jpeg must be bytes or bytearray")
jpeg = bytes(jpeg)
if not jpeg:
raise ValueError("JPEG object must not be empty")
if len(jpeg) > MAX_JPEG_SIZE:
raise ValueError("JPEG object is larger than uint32")
if not 1 <= max_payload_length <= MAX_PAYLOAD_LENGTH:
raise ValueError("max_payload_length is outside uint16")
if not 0 <= composite_frame_id <= 0xFFFFFFFF:
raise ValueError("composite_frame_id is outside uint32")
try:
object_type = ObjectType(object_type)
except ValueError as error:
raise ValueError("unsupported object_type") from error
fragment_count = (
len(jpeg) + max_payload_length - 1
) // max_payload_length
if fragment_count > MAX_FRAGMENT_COUNT:
raise ValueError("JPEG needs more than 65535 fragments")
object_crc32 = crc32(jpeg)
packets = []
for fragment_index in range(fragment_count):
start = fragment_index * max_payload_length
payload = jpeg[start:start + max_payload_length]
packets.append(
encode_packet(
VideoPacket(
composite_frame_id=composite_frame_id,
object_type=object_type,
fragment_index=fragment_index,
fragment_count=fragment_count,
jpeg_size=len(jpeg),
object_crc32=object_crc32,
payload=payload,
)
)
)
return packets
@dataclass
class _ObjectAssembly:
composite_frame_id: int
object_type: ObjectType
fragment_count: int
jpeg_size: int
object_crc32: int
fragments: dict[int, bytes] = field(default_factory=dict)
@classmethod
def from_packet(cls, packet: VideoPacket) -> "_ObjectAssembly":
return cls(
composite_frame_id=packet.composite_frame_id,
object_type=packet.object_type,
fragment_count=packet.fragment_count,
jpeg_size=packet.jpeg_size,
object_crc32=packet.object_crc32,
)
def add(self, packet: VideoPacket) -> bool:
metadata = (
packet.composite_frame_id,
packet.object_type,
packet.fragment_count,
packet.jpeg_size,
packet.object_crc32,
)
expected = (
self.composite_frame_id,
self.object_type,
self.fragment_count,
self.jpeg_size,
self.object_crc32,
)
if metadata != expected:
raise ObjectConsistencyError(
"fragment metadata conflicts with object assembly"
)
existing = self.fragments.get(packet.fragment_index)
if existing is not None:
if existing != packet.payload:
raise ObjectConsistencyError(
"different payload for an existing fragment index"
)
return False
self.fragments[packet.fragment_index] = packet.payload
return True
def missing_fragments(self) -> tuple[int, ...]:
return tuple(
index
for index in range(self.fragment_count)
if index not in self.fragments
)
def assemble_if_complete(self) -> bytes | None:
if self.missing_fragments():
return None
jpeg = b"".join(
self.fragments[index]
for index in range(self.fragment_count)
)
if len(jpeg) != self.jpeg_size:
raise ObjectConsistencyError(
"reassembled JPEG length does not match jpeg_size"
)
calculated_object_crc32 = crc32(jpeg)
if calculated_object_crc32 != self.object_crc32:
raise ObjectCRCError(
"object CRC mismatch: "
f"received 0x{self.object_crc32:08X}, "
f"calculated 0x{calculated_object_crc32:08X}"
)
return jpeg
class CompositeReassembler:
"""Reassemble interleaved BASE/ROI packets and publish atomic frames."""
def __init__(self) -> None:
self._objects: dict[
tuple[int, ObjectType], _ObjectAssembly
] = {}
self._completed: dict[
int, dict[ObjectType, bytes]
] = {}
self._finalized_frame_ids: set[int] = set()
self.duplicate_packets = 0
def ingest(self, wire_packet: bytes) -> CompositeFrame | None:
"""Accept one packet and return a frame only when BASE and ROI exist."""
packet = decode_packet(wire_packet)
if packet.composite_frame_id in self._finalized_frame_ids:
self.duplicate_packets += 1
return None
key = (packet.composite_frame_id, packet.object_type)
assembly = self._objects.get(key)
if assembly is None:
assembly = _ObjectAssembly.from_packet(packet)
self._objects[key] = assembly
if not assembly.add(packet):
self.duplicate_packets += 1
return None
jpeg = assembly.assemble_if_complete()
if jpeg is None:
return None
frame_parts = self._completed.setdefault(
packet.composite_frame_id, {}
)
frame_parts[packet.object_type] = jpeg
if not all(
object_type in frame_parts
for object_type in (ObjectType.BASE, ObjectType.ROI)
):
return None
frame = CompositeFrame(
composite_frame_id=packet.composite_frame_id,
base_jpeg=frame_parts[ObjectType.BASE],
roi_jpeg=frame_parts[ObjectType.ROI],
)
self._finalized_frame_ids.add(packet.composite_frame_id)
self._completed.pop(packet.composite_frame_id, None)
for object_type in (ObjectType.BASE, ObjectType.ROI):
self._objects.pop(
(packet.composite_frame_id, object_type), None
)
return frame
def missing_fragments(
self,
composite_frame_id: int,
object_type: ObjectType,
) -> tuple[int, ...] | None:
"""Return missing indexes, or None if this object has not started."""
assembly = self._objects.get(
(composite_frame_id, ObjectType(object_type))
)
if assembly is None:
return None
return assembly.missing_fragments()
def object_is_complete(
self,
composite_frame_id: int,
object_type: ObjectType,
) -> bool:
"""Report whether one CRC-validated object awaits its counterpart."""
return ObjectType(object_type) in self._completed.get(
composite_frame_id, {}
)

View File

@@ -0,0 +1,875 @@
"""
Lab025. Приём и программная WFM-демодуляция FM-радиостанции.
Схема подключения:
антенна 40860 МГц -> RX1
Используется только приёмный канал RX1. Передатчики TX1 и TX2
не используются. Необработанные IQ-сэмплы на диск не сохраняются.
"""
from pathlib import Path
import adi
import matplotlib
import numpy as np
from scipy import signal
from scipy.io import wavfile
# Для лабораторной графики сохраняется в файлы без блокирующих окон.
matplotlib.use("Agg")
import matplotlib.pyplot as plt
# ---------------------------------------------------------------------
# Параметры приёмника Pluto+
# ---------------------------------------------------------------------
PLUTO_URI = "ip:192.168.2.1"
STATION_FREQUENCY_HZ = 100_100_000
LO_OFFSET_HZ = 250_000
RX_LO_FREQUENCY_HZ = (
STATION_FREQUENCY_HZ + LO_OFFSET_HZ
)
SAMPLE_RATE_HZ = 2_400_000
RX_BANDWIDTH_HZ = 1_500_000
RX_BUFFER_SIZE = 65_536
DISCARD_BUFFER_COUNT = 3
CAPTURE_BUFFER_COUNT = 128
# ---------------------------------------------------------------------
# Параметры обработки сигнала
# ---------------------------------------------------------------------
CHANNEL_DECIMATION = 10
CHANNEL_SAMPLE_RATE_HZ = 240_000
AUDIO_CUTOFF_HZ = 15_000
AUDIO_SAMPLE_RATE_HZ = 48_000
DEEMPHASIS_TIME_CONSTANT_SECONDS = 50e-6
AUDIO_TRANSIENT_DURATION_SECONDS = 0.05
AUDIO_REFERENCE_PERCENTILE = 99.5
AUDIO_TARGET_LEVEL = 0.85
MINIMUM_AUDIO_REFERENCE_PEAK = 1e-12
RF_WELCH_MAXIMUM_SAMPLE_COUNT = 1_048_576
RF_WELCH_SEGMENT_LENGTH = 8_192
RF_WELCH_OVERLAP_LENGTH = 4_096
AUDIO_WELCH_SEGMENT_LENGTH = 8_192
# ---------------------------------------------------------------------
# Выходные файлы
# ---------------------------------------------------------------------
OUTPUT_DIRECTORY = Path("data/processed/lab025")
WAV_FILE_PATH = (
OUTPUT_DIRECTORY / "lab025_wfm_audio_100_1mhz.wav"
)
RF_SPECTRUM_FILE_PATH = (
OUTPUT_DIRECTORY / "lab025_rf_spectrum.png"
)
AUDIO_WAVEFORM_FILE_PATH = (
OUTPUT_DIRECTORY / "lab025_audio_waveform.png"
)
AUDIO_SPECTRUM_FILE_PATH = (
OUTPUT_DIRECTORY / "lab025_audio_spectrum.png"
)
REPORT_FILE_PATH = OUTPUT_DIRECTORY / "lab025_report.txt"
def configure_receiver() -> adi.Pluto:
"""
Подключается к Pluto+ и настраивает только приёмный канал RX1.
Частота гетеродина смещена на 250 кГц выше частоты станции.
Благодаря этому полезный сигнал не совпадает с аппаратным DC-пиком
в центре комплексной полосы приёмника.
"""
print("Подключение к Pluto+...")
sdr = adi.Pluto(uri=PLUTO_URI)
# Используем только первый приёмный канал RX1.
sdr.rx_enabled_channels = [0]
sdr.sample_rate = SAMPLE_RATE_HZ
sdr.rx_lo = RX_LO_FREQUENCY_HZ
sdr.rx_rf_bandwidth = RX_BANDWIDTH_HZ
# Медленная АРУ подходит для приёма вещательной FM-станции.
sdr.gain_control_mode_chan0 = "slow_attack"
sdr.rx_buffer_size = RX_BUFFER_SIZE
return sdr
def receive_samples(sdr: adi.Pluto) -> np.ndarray:
"""
Получает последовательность комплексных IQ-буферов.
Первые буферы отбрасываются, поскольку после настройки приёмника
в них могут присутствовать переходные процессы АРУ и фильтров.
Рабочие буферы объединяются только в оперативной памяти.
"""
print()
print(
"Отбрасывание переходных буферов: "
f"{DISCARD_BUFFER_COUNT}..."
)
for _ in range(DISCARD_BUFFER_COUNT):
_ = sdr.rx()
print("Получение рабочих IQ-буферов...")
received_buffers: list[np.ndarray] = []
for buffer_number in range(1, CAPTURE_BUFFER_COUNT + 1):
received_buffer = np.asarray(
sdr.rx(),
dtype=np.complex64,
)
if received_buffer.size == 0:
raise RuntimeError(
"Pluto+ вернул пустой рабочий IQ-буфер."
)
received_buffers.append(received_buffer)
if (
buffer_number % 16 == 0
or buffer_number == CAPTURE_BUFFER_COUNT
):
print(
f" Принято {buffer_number:3d}/"
f"{CAPTURE_BUFFER_COUNT} буферов"
)
if not received_buffers:
raise RuntimeError("Pluto+ не вернул IQ-сэмплы.")
combined_samples = np.concatenate(received_buffers)
if combined_samples.size == 0:
raise RuntimeError("После объединения получен пустой IQ-массив.")
if not np.all(np.isfinite(combined_samples)):
raise RuntimeError("В IQ-сэмплах обнаружены NaN или Inf.")
return np.asarray(combined_samples, dtype=np.complex64)
def shift_station_to_baseband(
samples: np.ndarray,
sample_rate_hz: float,
frequency_shift_hz: float,
) -> np.ndarray:
"""
Переносит выбранную станцию в центр цифровой полосы.
При положительном смещении комплексный генератор переносит сигнал,
расположенный на отрицательной относительной частоте, к 0 Гц.
"""
if samples.size == 0:
raise RuntimeError(
"Невозможно выполнить цифровой перенос пустого IQ-массива."
)
sample_indices = np.arange(
len(samples),
dtype=np.float64,
)
digital_oscillator = np.exp(
1j
* 2.0
* np.pi
* frequency_shift_hz
* sample_indices
/ sample_rate_hz
).astype(np.complex64)
centered_samples = samples * digital_oscillator
if not np.all(np.isfinite(centered_samples)):
raise RuntimeError(
"После цифрового переноса обнаружены NaN или Inf."
)
return np.asarray(centered_samples, dtype=np.complex64)
def extract_wfm_channel(
centered_samples: np.ndarray,
) -> np.ndarray:
"""
Фильтрует WFM-канал и понижает частоту до 240 кГц.
Полигармоническая передискретизация одновременно выполняет
низкочастотную фильтрацию и децимацию в десять раз.
"""
calculated_sample_rate_hz = (
SAMPLE_RATE_HZ / CHANNEL_DECIMATION
)
if not np.isclose(
calculated_sample_rate_hz,
CHANNEL_SAMPLE_RATE_HZ,
):
raise RuntimeError(
"Частота канального сигнала после децимации "
"не равна 240 кГц."
)
channel_samples = signal.resample_poly(
centered_samples,
up=1,
down=CHANNEL_DECIMATION,
window=("kaiser", 8.0),
)
if channel_samples.size == 0:
raise RuntimeError("После выделения WFM-канала массив пуст.")
if not np.all(np.isfinite(channel_samples)):
raise RuntimeError(
"После выделения WFM-канала обнаружены NaN или Inf."
)
return np.asarray(channel_samples, dtype=np.complex64)
def demodulate_fm(
channel_samples: np.ndarray,
) -> np.ndarray:
"""
Выполняет частотную демодуляцию по фазовой разности отсчётов.
Результат представляет монофонический композитный FM-сигнал
до звуковой фильтрации и коррекции предыскажений.
"""
if channel_samples.size < 2:
raise RuntimeError(
"Недостаточно канальных отсчётов для FM-демодуляции."
)
phase_difference = np.angle(
channel_samples[1:]
* np.conj(channel_samples[:-1])
).astype(np.float64)
demodulated = phase_difference - np.mean(phase_difference)
if demodulated.size == 0:
raise RuntimeError("FM-дискриминатор вернул пустой массив.")
if not np.all(np.isfinite(demodulated)):
raise RuntimeError(
"После FM-демодуляции обнаружены NaN или Inf."
)
return demodulated
def lowpass_audio(
demodulated_samples: np.ndarray,
sample_rate_hz: float,
) -> np.ndarray:
"""
Выделяет монофонический звук L+R в полосе до 15 кГц.
Фильтр подавляет стереопилот 19 кГц, стереоразностную часть,
RDS и внеполосный высокочастотный шум.
"""
audio_sos = signal.butter(
6,
AUDIO_CUTOFF_HZ,
btype="lowpass",
fs=sample_rate_hz,
output="sos",
)
filtered_audio = signal.sosfiltfilt(
audio_sos,
demodulated_samples,
)
if filtered_audio.size == 0:
raise RuntimeError("Звуковой фильтр вернул пустой массив.")
if not np.all(np.isfinite(filtered_audio)):
raise RuntimeError(
"После звукового фильтра обнаружены NaN или Inf."
)
return np.asarray(filtered_audio, dtype=np.float64)
def apply_deemphasis(
audio_samples: np.ndarray,
sample_rate_hz: float,
time_constant_seconds: float,
) -> np.ndarray:
"""
Выполняет европейскую FM-коррекцию предыскажений 50 мкс.
Используется устойчивый однополюсный рекурсивный фильтр,
реализованный функцией scipy.signal.lfilter.
"""
alpha = np.exp(
-1.0
/ (
sample_rate_hz
* time_constant_seconds
)
)
deemphasized = signal.lfilter(
[1.0 - alpha],
[1.0, -alpha],
audio_samples,
)
deemphasized = deemphasized - np.mean(deemphasized)
if deemphasized.size == 0:
raise RuntimeError("De-emphasis вернул пустой массив.")
if not np.all(np.isfinite(deemphasized)):
raise RuntimeError(
"После de-emphasis обнаружены NaN или Inf."
)
return np.asarray(deemphasized, dtype=np.float64)
def resample_audio_to_output_rate(
audio_samples: np.ndarray,
) -> np.ndarray:
"""
Преобразует звуковой сигнал с 240 кГц в выходные 48 кГц.
"""
output_decimation = 5
calculated_output_rate_hz = (
CHANNEL_SAMPLE_RATE_HZ / output_decimation
)
if not np.isclose(
calculated_output_rate_hz,
AUDIO_SAMPLE_RATE_HZ,
):
raise RuntimeError(
"Рассчитанная частота WAV не равна 48 кГц."
)
output_audio = signal.resample_poly(
audio_samples,
up=1,
down=output_decimation,
)
if output_audio.size == 0:
raise RuntimeError(
"После преобразования в 48 кГц получен пустой массив."
)
if not np.all(np.isfinite(output_audio)):
raise RuntimeError(
"После преобразования звука обнаружены NaN или Inf."
)
return np.asarray(output_audio, dtype=np.float64)
def convert_audio_to_pcm16(
audio_samples: np.ndarray,
) -> np.ndarray:
"""
Удаляет переходный участок, нормализует звук и создаёт PCM16.
Опорный уровень определяется по 99,5-му процентилю модуля,
поэтому единичный выброс не делает весь WAV слишком тихим.
"""
if audio_samples.size == 0:
raise RuntimeError("Невозможно нормализовать пустой звук.")
centered_audio = audio_samples - np.mean(audio_samples)
transient_sample_count = int(
round(
AUDIO_TRANSIENT_DURATION_SECONDS
* AUDIO_SAMPLE_RATE_HZ
)
)
if centered_audio.size <= transient_sample_count:
raise RuntimeError(
"Звуковой массив короче переходного участка 0,05 с."
)
centered_audio = centered_audio[transient_sample_count:]
reference_peak = float(
np.percentile(
np.abs(centered_audio),
AUDIO_REFERENCE_PERCENTILE,
)
)
if (
not np.isfinite(reference_peak)
or reference_peak <= MINIMUM_AUDIO_REFERENCE_PEAK
):
raise RuntimeError(
"Сигнал слишком мал для безопасной нормализации PCM16."
)
normalized_audio = (
centered_audio
/ reference_peak
* AUDIO_TARGET_LEVEL
)
normalized_audio = np.clip(
normalized_audio,
-1.0,
1.0,
)
pcm16_audio = np.round(
normalized_audio * np.iinfo(np.int16).max
).astype(np.int16)
if pcm16_audio.size == 0:
raise RuntimeError("После преобразования PCM16 массив пуст.")
return pcm16_audio
def calculate_rf_spectrum(
samples: np.ndarray,
) -> tuple[np.ndarray, np.ndarray]:
"""
Рассчитывает ограниченный спектр исходного IQ методом Уэлча.
Для графика используется не более 1 048 576 отсчётов, поэтому
полная восьмимиллионная запись не передаётся в одну большую FFT.
"""
analysis_sample_count = min(
len(samples),
RF_WELCH_MAXIMUM_SAMPLE_COUNT,
)
analysis_samples = samples[:analysis_sample_count]
relative_frequencies_hz, power_density = signal.welch(
analysis_samples,
fs=SAMPLE_RATE_HZ,
window="hann",
nperseg=RF_WELCH_SEGMENT_LENGTH,
noverlap=RF_WELCH_OVERLAP_LENGTH,
detrend=False,
return_onesided=False,
scaling="density",
)
relative_frequencies_hz = np.fft.fftshift(
relative_frequencies_hz
)
power_density = np.fft.fftshift(power_density)
minimum_positive_value = np.finfo(np.float64).tiny
power_db = 10.0 * np.log10(
power_density + minimum_positive_value
)
power_db -= np.max(power_db)
return relative_frequencies_hz, power_db
def create_rf_spectrum_graph(samples: np.ndarray) -> None:
"""
Сохраняет спектр до цифрового переноса станции в центр.
"""
frequencies_hz, power_db = calculate_rf_spectrum(samples)
figure, axes = plt.subplots(figsize=(13, 7))
axes.plot(
frequencies_hz / 1e3,
power_db,
linewidth=0.8,
)
expected_station_offset_hz = -LO_OFFSET_HZ
axes.axvline(
expected_station_offset_hz / 1e3,
color="tab:red",
linestyle="--",
linewidth=1.4,
label=(
"Ожидаемая станция 100,100 МГц "
"(-250 кГц)"
),
)
axes.set_title(
"Lab025. Спектр принятого IQ до цифрового переноса\n"
"RX LO = 100,350 МГц; станция = 100,100 МГц"
)
axes.set_xlabel("Относительная частота относительно RX LO, кГц")
axes.set_ylabel("Относительная мощность, дБ")
axes.set_ylim(-90, 5)
axes.grid(True)
axes.legend()
figure.tight_layout()
figure.savefig(RF_SPECTRUM_FILE_PATH, dpi=160)
plt.close(figure)
def create_audio_waveform_graph(pcm16_audio: np.ndarray) -> None:
"""
Сохраняет первые 0,1 секунды нормированного звука.
"""
displayed_sample_count = min(
len(pcm16_audio),
int(round(0.1 * AUDIO_SAMPLE_RATE_HZ)),
)
displayed_audio = (
pcm16_audio[:displayed_sample_count].astype(np.float64)
/ np.iinfo(np.int16).max
)
time_seconds = (
np.arange(displayed_sample_count, dtype=np.float64)
/ AUDIO_SAMPLE_RATE_HZ
)
figure, axes = plt.subplots(figsize=(12, 5))
axes.plot(time_seconds, displayed_audio, linewidth=0.8)
axes.set_title("Lab025. Первые 0,1 секунды демодулированного звука")
axes.set_xlabel("Время, с")
axes.set_ylabel("Нормированная амплитуда")
axes.set_ylim(-1.05, 1.05)
axes.grid(True)
figure.tight_layout()
figure.savefig(AUDIO_WAVEFORM_FILE_PATH, dpi=160)
plt.close(figure)
def create_audio_spectrum_graph(pcm16_audio: np.ndarray) -> None:
"""
Рассчитывает методом Уэлча и сохраняет односторонний спектр WAV.
"""
normalized_audio = (
pcm16_audio.astype(np.float64)
/ np.iinfo(np.int16).max
)
segment_length = min(
AUDIO_WELCH_SEGMENT_LENGTH,
len(normalized_audio),
)
frequencies_hz, power_density = signal.welch(
normalized_audio,
fs=AUDIO_SAMPLE_RATE_HZ,
window="hann",
nperseg=segment_length,
noverlap=segment_length // 2,
detrend="constant",
return_onesided=True,
scaling="density",
)
minimum_positive_value = np.finfo(np.float64).tiny
power_db = 10.0 * np.log10(
power_density + minimum_positive_value
)
power_db -= np.max(power_db)
figure, axes = plt.subplots(figsize=(12, 6))
axes.plot(frequencies_hz / 1e3, power_db, linewidth=0.9)
axes.set_xlim(0, 20)
axes.set_ylim(-100, 5)
axes.set_title("Lab025. Спектр демодулированного монофонического звука")
axes.set_xlabel("Частота, кГц")
axes.set_ylabel("Относительная спектральная плотность, дБ")
axes.grid(True)
figure.tight_layout()
figure.savefig(AUDIO_SPECTRUM_FILE_PATH, dpi=160)
plt.close(figure)
def calculate_audio_statistics(
pcm16_audio: np.ndarray,
) -> tuple[float, float, float]:
"""
Возвращает нормированные RMS, пик и процент предельных отсчётов.
"""
normalized_audio = (
pcm16_audio.astype(np.float64)
/ np.iinfo(np.int16).max
)
rms_value = float(
np.sqrt(np.mean(normalized_audio ** 2))
)
peak_value = float(np.max(np.abs(normalized_audio)))
clipped_sample_count = int(
np.count_nonzero(
(pcm16_audio == np.iinfo(np.int16).min)
| (pcm16_audio == np.iinfo(np.int16).max)
)
)
clipping_percentage = (
100.0
* clipped_sample_count
/ len(pcm16_audio)
)
return rms_value, peak_value, clipping_percentage
def save_report(
iq_sample_count: int,
iq_duration_seconds: float,
pcm16_audio: np.ndarray,
audio_rms: float,
audio_peak: float,
clipping_percentage: float,
) -> None:
"""
Создаёт текстовый отчёт с параметрами приёма и WAV-файла.
"""
wav_duration_seconds = (
len(pcm16_audio) / AUDIO_SAMPLE_RATE_HZ
)
report_lines = [
"Lab025. Приём и программная WFM-демодуляция",
"",
f"URI Pluto+: {PLUTO_URI}",
f"Частота станции: {STATION_FREQUENCY_HZ} Гц",
f"RX LO: {RX_LO_FREQUENCY_HZ} Гц",
f"Цифровое смещение: +{LO_OFFSET_HZ} Гц",
f"Частота дискретизации RX: {SAMPLE_RATE_HZ} Гц",
f"Полоса RX: {RX_BANDWIDTH_HZ} Гц",
f"Количество рабочих буферов: {CAPTURE_BUFFER_COUNT}",
f"Количество IQ-сэмплов: {iq_sample_count}",
f"Длительность IQ-записи: {iq_duration_seconds:.6f} с",
(
"Частота канального сигнала после децимации: "
f"{CHANNEL_SAMPLE_RATE_HZ} Гц"
),
f"Длительность итогового WAV: {wav_duration_seconds:.6f} с",
f"Частота WAV: {AUDIO_SAMPLE_RATE_HZ} Гц",
"Тип PCM: signed PCM16, mono",
f"RMS итогового аудио: {audio_rms:.6f}",
f"Пиковая амплитуда: {audio_peak:.6f}",
f"Отсчёты на границе PCM16: {clipping_percentage:.6f} %",
"",
"Выходные файлы:",
f"WAV: {WAV_FILE_PATH}",
f"Радиоспектр: {RF_SPECTRUM_FILE_PATH}",
f"Звуковая волна: {AUDIO_WAVEFORM_FILE_PATH}",
f"Спектр звука: {AUDIO_SPECTRUM_FILE_PATH}",
f"Отчёт: {REPORT_FILE_PATH}",
"",
"Использован только приёмный канал RX1.",
"Передатчики TX1 и TX2 не использовались.",
"Необработанные IQ-сэмплы на диск не сохранялись.",
]
REPORT_FILE_PATH.write_text(
"\n".join(report_lines),
encoding="utf-8",
)
def main() -> None:
"""
Выполняет полный цикл приёма, WFM-демодуляции и сохранения WAV.
"""
OUTPUT_DIRECTORY.mkdir(parents=True, exist_ok=True)
sdr = None
try:
sdr = configure_receiver()
print()
print("Параметры RX:")
print(f" URI: {PLUTO_URI}")
print(
f" Станция: "
f"{STATION_FREQUENCY_HZ / 1e6:.3f} МГц"
)
print(
f" RX LO: "
f"{sdr.rx_lo / 1e6:.3f} МГц"
)
print(
f" Частота дискретизации: "
f"{sdr.sample_rate / 1e6:.3f} Мвыб/с"
)
print(
f" Полоса RX: "
f"{sdr.rx_rf_bandwidth / 1e6:.3f} МГц"
)
print(
f" Режим усиления: "
f"{sdr.gain_control_mode_chan0}"
)
print(f" Размер буфера: {sdr.rx_buffer_size}")
print(" Активный канал: RX1")
samples = receive_samples(sdr)
iq_sample_count = len(samples)
iq_duration_seconds = iq_sample_count / SAMPLE_RATE_HZ
print()
print(f"Количество IQ-сэмплов: {iq_sample_count}")
print(f"Длительность записи: {iq_duration_seconds:.3f} с")
# Удаляем остаточную комплексную постоянную составляющую.
samples = samples - np.mean(samples)
print()
print("Цифровой перенос станции в центр полосы...")
centered_samples = shift_station_to_baseband(
samples=samples,
sample_rate_hz=SAMPLE_RATE_HZ,
frequency_shift_hz=LO_OFFSET_HZ,
)
print("Фильтрация WFM-канала и децимация до 240 кГц...")
channel_samples = extract_wfm_channel(centered_samples)
print("FM-демодуляция...")
demodulated_samples = demodulate_fm(channel_samples)
print("Звуковой low-pass фильтр 015 кГц...")
filtered_audio = lowpass_audio(
demodulated_samples=demodulated_samples,
sample_rate_hz=CHANNEL_SAMPLE_RATE_HZ,
)
print("De-emphasis 50 мкс...")
deemphasized_audio = apply_deemphasis(
audio_samples=filtered_audio,
sample_rate_hz=CHANNEL_SAMPLE_RATE_HZ,
time_constant_seconds=(
DEEMPHASIS_TIME_CONSTANT_SECONDS
),
)
print("Преобразование звука в 48 кГц...")
output_audio = resample_audio_to_output_rate(
deemphasized_audio
)
pcm16_audio = convert_audio_to_pcm16(output_audio)
audio_rms, audio_peak, clipping_percentage = (
calculate_audio_statistics(pcm16_audio)
)
print("Сохранение WAV...")
wavfile.write(
WAV_FILE_PATH,
AUDIO_SAMPLE_RATE_HZ,
pcm16_audio,
)
if not WAV_FILE_PATH.is_file():
raise RuntimeError("Выходной WAV-файл не создан.")
print("Сохранение графиков...")
create_rf_spectrum_graph(samples)
create_audio_waveform_graph(pcm16_audio)
create_audio_spectrum_graph(pcm16_audio)
print("Создание текстового отчёта...")
save_report(
iq_sample_count=iq_sample_count,
iq_duration_seconds=iq_duration_seconds,
pcm16_audio=pcm16_audio,
audio_rms=audio_rms,
audio_peak=audio_peak,
clipping_percentage=clipping_percentage,
)
print()
print("Созданы файлы:")
print(f" WAV: {WAV_FILE_PATH}")
print(f" Радиоспектр: {RF_SPECTRUM_FILE_PATH}")
print(f" Звуковая волна: {AUDIO_WAVEFORM_FILE_PATH}")
print(f" Спектр звука: {AUDIO_SPECTRUM_FILE_PATH}")
print(f" Отчёт: {REPORT_FILE_PATH}")
print()
print(f"RMS аудио: {audio_rms:.6f}")
print(f"Пиковая амплитуда: {audio_peak:.6f}")
print(
f"Отсчёты на границе PCM: "
f"{clipping_percentage:.6f} %"
)
print()
print("Lab025 выполнена успешно.")
print()
print("Для прослушивания откройте:")
print(WAV_FILE_PATH)
finally:
if sdr is not None:
destroy_buffer = getattr(
sdr,
"rx_destroy_buffer",
None,
)
if callable(destroy_buffer):
try:
destroy_buffer()
except Exception as cleanup_error:
print(
"Предупреждение: не удалось освободить "
f"RX-буфер: {cleanup_error}"
)
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,925 @@
"""
Lab027. Динамическое превью временного обновления BASE и ROI.
Скрипт не повторяет расчёт benchmark Lab027 и не изменяет его
результаты. Он создаёт одно игнорируемое Git preview-видео с четырьмя
фиксированными профилями. Для каждого профиля независимо удерживаются
последние декодированные JPEG-состояния BASE и ROI.
Отдельные JPEG-файлы не сохраняются: кодирование и декодирование
выполняются только в памяти средствами OpenCV.
"""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
import cv2
import numpy as np
SOURCE_VIDEO_PATH = Path("data/raw/lab026_rover_source.mp4")
PREVIEW_DIRECTORY = Path("data/raw/lab027_previews")
MP4_PREVIEW_PATH = (
PREVIEW_DIRECTORY / "lab027_roi_temporal_preview.mp4"
)
AVI_PREVIEW_PATH = (
PREVIEW_DIRECTORY / "lab027_roi_temporal_preview.avi"
)
OUTPUT_FPS = 30.0
PANEL_WIDTH = 640
PANEL_HEIGHT = 360
OUTPUT_WIDTH = PANEL_WIDTH * 2
OUTPUT_HEIGHT = PANEL_HEIGHT * 2
ROI_X_MIN = 0.20
ROI_X_MAX = 0.80
ROI_Y_MIN = 0.42
ROI_Y_MAX = 1.00
FRAME_TIME_EPSILON_SECONDS = 1e-9
NEW_UPDATE_LABEL_SECONDS = 0.15
@dataclass(frozen=True)
class PreviewProfile:
"""
Описывает один из четырёх фиксированных preview-профилей.
"""
name: str
base_width: int
base_height: int
base_fps: float
base_quality: int
roi_enabled: bool
roi_width: int
roi_height: int
roi_fps: float
roi_quality: int
measured_payload_kbps: float
@dataclass
class ProfileState:
"""
Хранит независимое временное состояние BASE и ROI профиля.
"""
latest_base: np.ndarray | None = None
latest_roi: np.ndarray | None = None
next_base_time: float = 0.0
next_roi_time: float = 0.0
last_base_update_time: float = 0.0
last_roi_update_time: float = 0.0
base_update_count: int = 0
roi_update_count: int = 0
def read_video_metadata(
source_path: Path,
) -> tuple[int, int, float, int, float]:
"""
Читает и проверяет параметры исходного видео.
"""
if not source_path.exists():
raise RuntimeError(
f"Исходный видеофайл отсутствует: {source_path}"
)
capture = cv2.VideoCapture(str(source_path))
if not capture.isOpened():
raise RuntimeError(
f"OpenCV не смог открыть видео: {source_path}"
)
try:
width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = float(capture.get(cv2.CAP_PROP_FPS))
frame_count = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
finally:
capture.release()
if width <= 0 or height <= 0:
raise RuntimeError(
"OpenCV вернул некорректное разрешение видео."
)
if fps <= 0.0:
raise RuntimeError("FPS исходного видео равен нулю.")
if frame_count <= 0:
raise RuntimeError("Число кадров исходного видео равно нулю.")
duration_seconds = frame_count / fps
return width, height, fps, frame_count, duration_seconds
def build_profiles() -> list[PreviewProfile]:
"""
Создаёт ровно четыре согласованных preview-профиля.
"""
profiles = [
PreviewProfile(
name="baseline",
base_width=320,
base_height=180,
base_fps=2.0,
base_quality=40,
roi_enabled=False,
roi_width=0,
roi_height=0,
roi_fps=0.0,
roi_quality=0,
measured_payload_kbps=80.27,
),
PreviewProfile(
name="ROI normal",
base_width=240,
base_height=135,
base_fps=1.0,
base_quality=25,
roi_enabled=True,
roi_width=320,
roi_height=180,
roi_fps=2.0,
roi_quality=35,
measured_payload_kbps=93.28,
),
PreviewProfile(
name="ROI economy",
base_width=160,
base_height=90,
base_fps=1.0,
base_quality=25,
roi_enabled=True,
roi_width=320,
roi_height=180,
roi_fps=2.0,
roi_quality=35,
measured_payload_kbps=85.19,
),
PreviewProfile(
name="ROI degraded channel",
base_width=240,
base_height=135,
base_fps=1.0,
base_quality=20,
roi_enabled=True,
roi_width=320,
roi_height=180,
roi_fps=1.0,
roi_quality=30,
measured_payload_kbps=50.49,
),
]
if len(profiles) != 4:
raise RuntimeError(
"Preview Lab027 должно содержать ровно четыре профиля."
)
return profiles
def normalized_roi_to_pixels(
width: int,
height: int,
) -> tuple[int, int, int, int]:
"""
Переводит фиксированные нормализованные координаты ROI в пиксели.
Результат задаёт полуоткрытый прямоугольник:
x_min, y_min, x_max, y_max.
"""
if width <= 0 or height <= 0:
raise ValueError("Размер кадра должен быть положительным.")
x_min = int(round(width * ROI_X_MIN))
x_max = int(round(width * ROI_X_MAX))
y_min = int(round(height * ROI_Y_MIN))
y_max = int(round(height * ROI_Y_MAX))
x_min = min(max(x_min, 0), width - 1)
x_max = min(max(x_max, x_min + 1), width)
y_min = min(max(y_min, 0), height - 1)
y_max = min(max(y_max, y_min + 1), height)
return x_min, y_min, x_max, y_max
def should_update(
current_time: float,
next_update_time: float,
epsilon_seconds: float = FRAME_TIME_EPSILON_SECONDS,
) -> bool:
"""
Проверяет наступление времени очередного обновления потока.
"""
return (
current_time + epsilon_seconds
>= next_update_time
)
def encode_decode_grayscale_jpeg(
gray_frame: np.ndarray,
jpeg_quality: int,
) -> np.ndarray:
"""
Кодирует grayscale JPEG в памяти и декодирует его обратно.
"""
if gray_frame.ndim != 2:
raise RuntimeError(
"JPEG preview должен получать grayscale-кадр."
)
encoding_ok, encoded = cv2.imencode(
".jpg",
gray_frame,
[cv2.IMWRITE_JPEG_QUALITY, jpeg_quality],
)
if not encoding_ok or encoded is None or encoded.size == 0:
raise RuntimeError("OpenCV не смог закодировать JPEG.")
decoded = cv2.imdecode(
encoded,
cv2.IMREAD_GRAYSCALE,
)
if decoded is None or decoded.shape != gray_frame.shape:
raise RuntimeError(
"Декодированный JPEG имеет некорректный размер."
)
return decoded
def encode_decode_base(
source_frame: np.ndarray,
profile: PreviewProfile,
) -> np.ndarray:
"""
Формирует очередное декодированное состояние BASE.
"""
source_gray = cv2.cvtColor(
source_frame,
cv2.COLOR_BGR2GRAY,
)
resized_base = cv2.resize(
source_gray,
(profile.base_width, profile.base_height),
interpolation=cv2.INTER_AREA,
)
return encode_decode_grayscale_jpeg(
resized_base,
profile.base_quality,
)
def encode_decode_roi(
source_frame: np.ndarray,
source_roi: tuple[int, int, int, int],
profile: PreviewProfile,
) -> np.ndarray:
"""
Вырезает ROI исходного BGR-кадра и формирует JPEG-состояние.
"""
if not profile.roi_enabled:
raise RuntimeError(
"Нельзя кодировать ROI для отключённого ROI-профиля."
)
x_min, y_min, x_max, y_max = source_roi
roi_bgr = source_frame[y_min:y_max, x_min:x_max]
if roi_bgr.size == 0:
raise RuntimeError("Вырезана пустая область ROI.")
roi_gray = cv2.cvtColor(
roi_bgr,
cv2.COLOR_BGR2GRAY,
)
resized_roi = cv2.resize(
roi_gray,
(profile.roi_width, profile.roi_height),
interpolation=cv2.INTER_AREA,
)
return encode_decode_grayscale_jpeg(
resized_roi,
profile.roi_quality,
)
def reconstruct_panel(
profile: PreviewProfile,
state: ProfileState,
panel_roi: tuple[int, int, int, int],
) -> np.ndarray:
"""
Восстанавливает одну grayscale-панель размером 640x360.
"""
if state.latest_base is None:
raise RuntimeError("BASE-состояние ещё не создано.")
reconstructed = cv2.resize(
state.latest_base,
(PANEL_WIDTH, PANEL_HEIGHT),
interpolation=cv2.INTER_LINEAR,
)
if profile.roi_enabled:
if state.latest_roi is None:
raise RuntimeError("ROI-состояние ещё не создано.")
x_min, y_min, x_max, y_max = panel_roi
resized_roi = cv2.resize(
state.latest_roi,
(x_max - x_min, y_max - y_min),
interpolation=cv2.INTER_LINEAR,
)
reconstructed[y_min:y_max, x_min:x_max] = resized_roi
return reconstructed
def draw_text_line(
image: np.ndarray,
text: str,
y_position: int,
text_color: tuple[int, int, int] = (255, 255, 255),
) -> None:
"""
Рисует одну ASCII-строку служебной информации OpenCV.
"""
cv2.putText(
image,
text,
(10, y_position),
cv2.FONT_HERSHEY_SIMPLEX,
0.46,
text_color,
1,
cv2.LINE_AA,
)
def draw_panel_information(
reconstructed_gray: np.ndarray,
profile: PreviewProfile,
state: ProfileState,
current_time: float,
panel_roi: tuple[int, int, int, int],
) -> np.ndarray:
"""
Добавляет рамку ROI, параметры и индикаторы обновления панели.
"""
panel = cv2.cvtColor(
reconstructed_gray,
cv2.COLOR_GRAY2BGR,
)
if profile.roi_enabled:
cv2.rectangle(
panel,
(panel_roi[0], panel_roi[1]),
(panel_roi[2] - 1, panel_roi[3] - 1),
(0, 255, 255),
2,
)
overlay = panel.copy()
cv2.rectangle(
overlay,
(0, 0),
(PANEL_WIDTH - 1, 142),
(0, 0, 0),
thickness=-1,
)
cv2.addWeighted(
overlay,
0.72,
panel,
0.28,
0.0,
panel,
)
base_age = max(
0.0,
current_time - state.last_base_update_time,
)
roi_age = max(
0.0,
current_time - state.last_roi_update_time,
)
base_is_new = (
base_age <= NEW_UPDATE_LABEL_SECONDS
)
roi_is_new = (
profile.roi_enabled
and roi_age <= NEW_UPDATE_LABEL_SECONDS
)
draw_text_line(panel, profile.name, 20)
draw_text_line(
panel,
(
f"BASE: {profile.base_width}x{profile.base_height}, "
f"{profile.base_fps:g} fps, Q{profile.base_quality}"
),
41,
)
if profile.roi_enabled:
roi_text = (
f"ROI: {profile.roi_width}x{profile.roi_height}, "
f"{profile.roi_fps:g} fps, Q{profile.roi_quality}"
)
roi_age_text = f"{roi_age:.3f} s"
else:
roi_text = "ROI: disabled"
roi_age_text = "disabled"
draw_text_line(panel, roi_text, 62)
draw_text_line(
panel,
(
f"payload={profile.measured_payload_kbps:.2f} kbps, "
f"source time={current_time:.3f} s"
),
83,
)
draw_text_line(
panel,
(
f"since BASE={base_age:.3f} s, "
f"since ROI={roi_age_text}"
),
104,
)
update_labels: list[str] = []
if base_is_new:
update_labels.append("NEW BASE")
if roi_is_new:
update_labels.append("NEW ROI")
if update_labels:
draw_text_line(
panel,
" | ".join(update_labels),
130,
text_color=(0, 255, 0),
)
return panel
def compose_grid(panels: list[np.ndarray]) -> np.ndarray:
"""
Объединяет четыре панели в сетку 2x2 размером 1280x720.
"""
if len(panels) != 4:
raise RuntimeError(
"Для сетки preview требуется ровно четыре панели."
)
for panel in panels:
if panel.shape != (PANEL_HEIGHT, PANEL_WIDTH, 3):
raise RuntimeError(
f"Некорректный размер панели: {panel.shape}"
)
top_row = np.hstack((panels[0], panels[1]))
bottom_row = np.hstack((panels[2], panels[3]))
grid = np.vstack((top_row, bottom_row))
if grid.shape != (OUTPUT_HEIGHT, OUTPUT_WIDTH, 3):
raise RuntimeError(
f"Некорректный размер сетки: {grid.shape}"
)
return grid
def open_preview_writer() -> tuple[cv2.VideoWriter, Path, bool]:
"""
Открывает MP4 writer либо разрешённый fallback AVI/MJPG.
"""
mp4_writer = cv2.VideoWriter(
str(MP4_PREVIEW_PATH),
cv2.VideoWriter_fourcc(*"mp4v"),
OUTPUT_FPS,
(OUTPUT_WIDTH, OUTPUT_HEIGHT),
True,
)
if mp4_writer.isOpened():
return mp4_writer, MP4_PREVIEW_PATH, False
mp4_writer.release()
if MP4_PREVIEW_PATH.exists():
MP4_PREVIEW_PATH.unlink()
avi_writer = cv2.VideoWriter(
str(AVI_PREVIEW_PATH),
cv2.VideoWriter_fourcc(*"MJPG"),
OUTPUT_FPS,
(OUTPUT_WIDTH, OUTPUT_HEIGHT),
True,
)
if not avi_writer.isOpened():
avi_writer.release()
if AVI_PREVIEW_PATH.exists():
AVI_PREVIEW_PATH.unlink()
raise RuntimeError(
"OpenCV не смог открыть ни MP4, ни AVI writer."
)
return avi_writer, AVI_PREVIEW_PATH, True
def create_preview(
source_path: Path,
profiles: list[PreviewProfile],
source_width: int,
source_height: int,
source_fps: float,
expected_frame_count: int,
) -> tuple[Path, bool, int, list[ProfileState]]:
"""
Создаёт preview-видео с одним выходным кадром на исходный кадр.
"""
if len(profiles) != 4:
raise RuntimeError(
"Ожидалось ровно четыре preview-профиля."
)
PREVIEW_DIRECTORY.mkdir(
parents=True,
exist_ok=True,
)
capture = cv2.VideoCapture(str(source_path))
if not capture.isOpened():
raise RuntimeError(
f"OpenCV не смог открыть видео: {source_path}"
)
writer, preview_path, fallback_used = open_preview_writer()
source_roi = normalized_roi_to_pixels(
source_width,
source_height,
)
panel_roi = normalized_roi_to_pixels(
PANEL_WIDTH,
PANEL_HEIGHT,
)
states = [
ProfileState()
for _ in profiles
]
frame_index = 0
try:
while True:
frame_read, source_frame = capture.read()
if not frame_read:
break
if source_frame is None:
raise RuntimeError(
f"Получен пустой кадр {frame_index}."
)
if (
source_frame.shape[1] != source_width
or source_frame.shape[0] != source_height
):
raise RuntimeError(
"Размер кадра отличается от метаданных."
)
current_time = frame_index / source_fps
panels: list[np.ndarray] = []
for profile, state in zip(profiles, states):
if should_update(
current_time,
state.next_base_time,
):
state.latest_base = encode_decode_base(
source_frame,
profile,
)
state.last_base_update_time = current_time
state.next_base_time += 1.0 / profile.base_fps
state.base_update_count += 1
if (
profile.roi_enabled
and should_update(
current_time,
state.next_roi_time,
)
):
state.latest_roi = encode_decode_roi(
source_frame,
source_roi,
profile,
)
state.last_roi_update_time = current_time
state.next_roi_time += 1.0 / profile.roi_fps
state.roi_update_count += 1
reconstructed = reconstruct_panel(
profile,
state,
panel_roi,
)
panels.append(
draw_panel_information(
reconstructed,
profile,
state,
current_time,
panel_roi,
)
)
writer.write(compose_grid(panels))
frame_index += 1
if (
frame_index % 100 == 0
or frame_index == expected_frame_count
):
print(
f" Written frames: "
f"{frame_index}/{expected_frame_count}"
)
except Exception:
capture.release()
writer.release()
if preview_path.exists():
preview_path.unlink()
raise
finally:
capture.release()
writer.release()
if frame_index != expected_frame_count:
if preview_path.exists():
preview_path.unlink()
raise RuntimeError(
"Число записанных кадров не совпало с исходным: "
f"{frame_index} != {expected_frame_count}."
)
return (
preview_path,
fallback_used,
frame_index,
states,
)
def read_frame_at(
capture: cv2.VideoCapture,
frame_index: int,
) -> tuple[bool, tuple[int, ...] | None]:
"""
Читает один кадр preview по индексу для итоговой проверки.
"""
capture.set(
cv2.CAP_PROP_POS_FRAMES,
frame_index,
)
frame_read, frame = capture.read()
if not frame_read or frame is None:
return False, None
return True, frame.shape
def verify_preview(
preview_path: Path,
source_frame_count: int,
source_duration_seconds: float,
) -> tuple[
int,
int,
float,
int,
float,
tuple[bool, tuple[int, ...] | None],
tuple[bool, tuple[int, ...] | None],
tuple[bool, tuple[int, ...] | None],
]:
"""
Проверяет контейнер, геометрию, FPS, длительность и три кадра.
"""
if not preview_path.exists():
raise RuntimeError(
f"Preview отсутствует: {preview_path}"
)
if preview_path.stat().st_size <= 0:
raise RuntimeError("Preview имеет нулевой размер.")
capture = cv2.VideoCapture(str(preview_path))
if not capture.isOpened():
raise RuntimeError(
f"OpenCV не смог открыть preview: {preview_path}"
)
try:
width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = float(capture.get(cv2.CAP_PROP_FPS))
frame_count = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
if fps <= 0.0:
raise RuntimeError("FPS preview равен нулю.")
duration_seconds = frame_count / fps
first_frame = read_frame_at(capture, 0)
middle_frame = read_frame_at(
capture,
frame_count // 2,
)
last_frame = read_frame_at(
capture,
frame_count - 1,
)
finally:
capture.release()
if width != OUTPUT_WIDTH or height != OUTPUT_HEIGHT:
raise RuntimeError(
f"Некорректное разрешение preview: {width}x{height}."
)
if frame_count != source_frame_count:
raise RuntimeError(
"Число кадров preview не совпало с исходным."
)
allowed_duration_difference = (
1.0 / fps + FRAME_TIME_EPSILON_SECONDS
)
if (
abs(duration_seconds - source_duration_seconds)
> allowed_duration_difference
):
raise RuntimeError(
"Длительность preview отличается более чем на один кадр."
)
for label, frame_result in [
("первый", first_frame),
("средний", middle_frame),
("последний", last_frame),
]:
if not frame_result[0]:
raise RuntimeError(
f"Не удалось прочитать {label} кадр preview."
)
return (
width,
height,
fps,
frame_count,
duration_seconds,
first_frame,
middle_frame,
last_frame,
)
def main() -> None:
"""
Создаёт и проверяет динамическое preview Lab027.
"""
print("Reading source video metadata...")
(
source_width,
source_height,
source_fps,
source_frame_count,
source_duration_seconds,
) = read_video_metadata(SOURCE_VIDEO_PATH)
print(f" Source: {SOURCE_VIDEO_PATH}")
print(f" Resolution: {source_width}x{source_height}")
print(f" FPS: {source_fps:.6f}")
print(f" Frames: {source_frame_count}")
print(f" Duration: {source_duration_seconds:.6f} s")
profiles = build_profiles()
print("Creating dynamic preview...")
(
preview_path,
fallback_used,
written_frame_count,
states,
) = create_preview(
source_path=SOURCE_VIDEO_PATH,
profiles=profiles,
source_width=source_width,
source_height=source_height,
source_fps=source_fps,
expected_frame_count=source_frame_count,
)
print("Verifying preview...")
(
preview_width,
preview_height,
preview_fps,
preview_frame_count,
preview_duration_seconds,
first_frame,
middle_frame,
last_frame,
) = verify_preview(
preview_path,
source_frame_count,
source_duration_seconds,
)
print("")
print(f"Preview path: {preview_path}")
print(f"Fallback used: {fallback_used}")
print(f"File size: {preview_path.stat().st_size} bytes")
print(
f"Preview resolution: "
f"{preview_width}x{preview_height}"
)
print(f"Preview FPS: {preview_fps:.6f}")
print(f"Written frames: {written_frame_count}")
print(f"Verified frames: {preview_frame_count}")
print(
f"Preview duration: "
f"{preview_duration_seconds:.6f} s"
)
print(f"First frame: {first_frame}")
print(f"Middle frame: {middle_frame}")
print(f"Last frame: {last_frame}")
print("")
print("Profile update counts:")
for profile, state in zip(profiles, states):
print(
f" {profile.name}: "
f"BASE={state.base_update_count}, "
f"ROI={state.roi_update_count}"
)
print("")
print("Lab027 temporal preview completed successfully.")
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,869 @@
"""
Lab028. Packetization of synchronous BASE + ROI JPEG video objects.
The laboratory forms the selected Lab027E profile directly from the source
video, keeps every JPEG and packet in memory, verifies the transport layer,
and writes only aggregate CSV/report/plot artifacts.
"""
from __future__ import annotations
import csv
from dataclasses import dataclass
from pathlib import Path
import random
from typing import Callable
import cv2
import matplotlib
import numpy as np
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from protocol.video_packet import (
CompositeFrame,
CompositeReassembler,
HEADER_FORMAT,
HEADER_SIZE,
ObjectCRCError,
ObjectType,
PacketCRCError,
VideoPacket,
decode_packet,
encode_packet,
packetize_jpeg,
)
SOURCE_VIDEO_PATH = Path("data/raw/lab026_rover_source.mp4")
OUTPUT_DIRECTORY = Path("data/processed/lab028")
CSV_PATH = OUTPUT_DIRECTORY / "lab028_packet_payload_results.csv"
REPORT_PATH = OUTPUT_DIRECTORY / "lab028_report.txt"
OVERHEAD_PLOT_PATH = (
OUTPUT_DIRECTORY / "lab028_overhead_efficiency.png"
)
TRAFFIC_PLOT_PATH = (
OUTPUT_DIRECTORY / "lab028_packets_wire_bitrate.png"
)
COMPOSITE_FPS = 3.0
BASE_WIDTH = 240
BASE_HEIGHT = 135
BASE_QUALITY = 23
ROI_WIDTH = 320
ROI_HEIGHT = 180
ROI_QUALITY = 33
ROI_X_MIN = 0.20
ROI_X_MAX = 0.80
ROI_Y_MIN = 0.42
ROI_Y_MAX = 1.00
PAYLOAD_LENGTHS = (64, 128, 256, 512, 1024)
FRAME_TIME_EPSILON_SECONDS = 1e-9
CSV_FIELDS = [
"max_payload_bytes",
"composite_frames",
"mean_base_packets_per_frame",
"mean_roi_packets_per_frame",
"mean_total_packets_per_frame",
"max_total_packets_per_frame",
"packets_per_second",
"jpeg_payload_bytes",
"jpeg_payload_bitrate_kbps",
"header_bytes_per_second",
"header_bitrate_kbps",
"wire_bytes",
"wire_bitrate_kbps",
"service_data_percent",
"efficiency_percent",
"mean_wire_packet_bytes",
"p95_wire_packet_bytes",
"max_wire_packet_bytes",
]
@dataclass(frozen=True)
class VideoMetadata:
width: int
height: int
fps: float
frame_count: int
duration_seconds: float
@dataclass(frozen=True)
class EncodedComposite:
composite_frame_id: int
source_frame_index: int
base_jpeg: bytes
roi_jpeg: bytes
@dataclass(frozen=True)
class PayloadMetrics:
max_payload_bytes: int
composite_frames: int
mean_base_packets_per_frame: float
mean_roi_packets_per_frame: float
mean_total_packets_per_frame: float
max_total_packets_per_frame: int
packets_per_second: float
jpeg_payload_bytes: int
jpeg_payload_bitrate_kbps: float
header_bytes_per_second: float
header_bitrate_kbps: float
wire_bytes: int
wire_bitrate_kbps: float
service_data_percent: float
efficiency_percent: float
mean_wire_packet_bytes: float
p95_wire_packet_bytes: float
max_wire_packet_bytes: int
@dataclass(frozen=True)
class TestResult:
name: str
passed: bool
detail: str
def normalized_roi_to_pixels(
width: int,
height: int,
) -> tuple[int, int, int, int]:
"""Use the normalized ROI coordinates from Lab027 through Lab027E."""
coordinates = (
int(round(width * ROI_X_MIN)),
int(round(height * ROI_Y_MIN)),
int(round(width * ROI_X_MAX)),
int(round(height * ROI_Y_MAX)),
)
x_min, y_min, x_max, y_max = coordinates
if not (
0 <= x_min < x_max <= width
and 0 <= y_min < y_max <= height
):
raise RuntimeError("calculated ROI is outside the source frame")
return coordinates
def encode_grayscale_jpeg(image: np.ndarray, quality: int) -> bytes:
"""Encode one grayscale image to an in-memory JPEG."""
encoded, buffer = cv2.imencode(
".jpg",
image,
[int(cv2.IMWRITE_JPEG_QUALITY), int(quality)],
)
if not encoded:
raise RuntimeError("OpenCV could not encode JPEG")
jpeg = buffer.tobytes()
if not jpeg:
raise RuntimeError("OpenCV produced an empty JPEG")
return jpeg
def encode_composite(
source_frame: np.ndarray,
source_roi: tuple[int, int, int, int],
composite_frame_id: int,
source_frame_index: int,
) -> EncodedComposite:
"""Form synchronous BASE and ROI JPEGs from exactly one source frame."""
grayscale = cv2.cvtColor(source_frame, cv2.COLOR_BGR2GRAY)
base = cv2.resize(
grayscale,
(BASE_WIDTH, BASE_HEIGHT),
interpolation=cv2.INTER_AREA,
)
x_min, y_min, x_max, y_max = source_roi
roi = grayscale[y_min:y_max, x_min:x_max]
if roi.size == 0:
raise RuntimeError("source ROI is empty")
roi = cv2.resize(
roi,
(ROI_WIDTH, ROI_HEIGHT),
interpolation=cv2.INTER_AREA,
)
return EncodedComposite(
composite_frame_id=composite_frame_id,
source_frame_index=source_frame_index,
base_jpeg=encode_grayscale_jpeg(base, BASE_QUALITY),
roi_jpeg=encode_grayscale_jpeg(roi, ROI_QUALITY),
)
def load_video_profile(
source_path: Path,
) -> tuple[VideoMetadata, list[EncodedComposite]]:
"""Read the video sequentially and select synchronous updates at 3 fps."""
if not source_path.exists():
raise FileNotFoundError(f"source video is missing: {source_path}")
capture = cv2.VideoCapture(str(source_path))
if not capture.isOpened():
raise RuntimeError(f"OpenCV could not open {source_path}")
width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = float(capture.get(cv2.CAP_PROP_FPS))
declared_frame_count = int(
capture.get(cv2.CAP_PROP_FRAME_COUNT)
)
if width <= 0 or height <= 0 or fps <= 0.0:
capture.release()
raise RuntimeError("invalid source video metadata")
source_roi = normalized_roi_to_pixels(width, height)
selected: list[EncodedComposite] = []
source_frame_index = 0
next_composite_time = 0.0
try:
while True:
frame_read, source_frame = capture.read()
if not frame_read or source_frame is None:
break
source_time = source_frame_index / fps
if (
source_time + FRAME_TIME_EPSILON_SECONDS
>= next_composite_time
):
selected.append(
encode_composite(
source_frame,
source_roi,
len(selected),
source_frame_index,
)
)
next_composite_time += 1.0 / COMPOSITE_FPS
source_frame_index += 1
finally:
capture.release()
if source_frame_index <= 0 or not selected:
raise RuntimeError("source video did not yield frames")
if (
declared_frame_count > 0
and source_frame_index != declared_frame_count
):
raise RuntimeError(
"decoded frame count differs from video metadata: "
f"{source_frame_index} != {declared_frame_count}"
)
metadata = VideoMetadata(
width=width,
height=height,
fps=fps,
frame_count=source_frame_index,
duration_seconds=source_frame_index / fps,
)
return metadata, selected
def packets_for_composite(
composite: EncodedComposite,
max_payload_bytes: int,
) -> tuple[list[bytes], list[bytes]]:
"""Packetize BASE and ROI separately with one composite frame ID."""
base_packets = packetize_jpeg(
composite.base_jpeg,
composite.composite_frame_id,
ObjectType.BASE,
max_payload_bytes,
)
roi_packets = packetize_jpeg(
composite.roi_jpeg,
composite.composite_frame_id,
ObjectType.ROI,
max_payload_bytes,
)
return base_packets, roi_packets
def calculate_payload_metrics(
composites: list[EncodedComposite],
duration_seconds: float,
max_payload_bytes: int,
) -> PayloadMetrics:
"""Calculate actual packet and bitrate statistics for one payload limit."""
base_counts: list[int] = []
roi_counts: list[int] = []
total_counts: list[int] = []
wire_packet_sizes: list[int] = []
for composite in composites:
base_packets, roi_packets = packets_for_composite(
composite, max_payload_bytes
)
base_counts.append(len(base_packets))
roi_counts.append(len(roi_packets))
total_counts.append(len(base_packets) + len(roi_packets))
wire_packet_sizes.extend(
len(packet) for packet in base_packets + roi_packets
)
jpeg_payload_bytes = sum(
len(composite.base_jpeg) + len(composite.roi_jpeg)
for composite in composites
)
packet_count = len(wire_packet_sizes)
header_bytes = packet_count * HEADER_SIZE
wire_bytes = jpeg_payload_bytes + header_bytes
return PayloadMetrics(
max_payload_bytes=max_payload_bytes,
composite_frames=len(composites),
mean_base_packets_per_frame=float(np.mean(base_counts)),
mean_roi_packets_per_frame=float(np.mean(roi_counts)),
mean_total_packets_per_frame=float(np.mean(total_counts)),
max_total_packets_per_frame=max(total_counts),
packets_per_second=packet_count / duration_seconds,
jpeg_payload_bytes=jpeg_payload_bytes,
jpeg_payload_bitrate_kbps=(
jpeg_payload_bytes * 8.0 / duration_seconds / 1000.0
),
header_bytes_per_second=header_bytes / duration_seconds,
header_bitrate_kbps=(
header_bytes * 8.0 / duration_seconds / 1000.0
),
wire_bytes=wire_bytes,
wire_bitrate_kbps=(
wire_bytes * 8.0 / duration_seconds / 1000.0
),
service_data_percent=header_bytes / wire_bytes * 100.0,
efficiency_percent=jpeg_payload_bytes / wire_bytes * 100.0,
mean_wire_packet_bytes=float(np.mean(wire_packet_sizes)),
p95_wire_packet_bytes=float(
np.percentile(wire_packet_sizes, 95)
),
max_wire_packet_bytes=max(wire_packet_sizes),
)
def feed_packets(
packets: list[bytes],
reassembler: CompositeReassembler | None = None,
) -> tuple[list[CompositeFrame], CompositeReassembler]:
"""Feed packets and collect every atomically published frame."""
receiver = reassembler or CompositeReassembler()
completed = []
for packet in packets:
frame = receiver.ingest(packet)
if frame is not None:
completed.append(frame)
return completed, receiver
def assert_frame_matches(
frame: CompositeFrame,
expected: EncodedComposite,
) -> None:
if frame.composite_frame_id != expected.composite_frame_id:
raise AssertionError("composite frame ID differs")
if frame.base_jpeg != expected.base_jpeg:
raise AssertionError("BASE JPEG differs byte-for-byte")
if frame.roi_jpeg != expected.roi_jpeg:
raise AssertionError("ROI JPEG differs byte-for-byte")
def run_functional_tests(
composites: list[EncodedComposite],
) -> list[TestResult]:
"""Run header and all mandatory Lab028 transport checks."""
if len(composites) < 2:
raise RuntimeError("functional checks need two video frames")
first = composites[0]
second = composites[1]
base_packets, roi_packets = packets_for_composite(first, 256)
all_packets = base_packets + roi_packets
tests: list[tuple[str, Callable[[], str]]] = []
def header_round_trip() -> str:
parsed = decode_packet(all_packets[0])
rebuilt = encode_packet(
VideoPacket(
composite_frame_id=parsed.composite_frame_id,
object_type=parsed.object_type,
fragment_index=parsed.fragment_index,
fragment_count=parsed.fragment_count,
jpeg_size=parsed.jpeg_size,
object_crc32=parsed.object_crc32,
payload=parsed.payload,
)
)
if rebuilt != all_packets[0]:
raise AssertionError("serialized bytes changed after round trip")
return f"fixed {HEADER_SIZE}-byte header round trip is exact"
def ordered_lossless() -> str:
frames, _ = feed_packets(all_packets)
if len(frames) != 1:
raise AssertionError("ordered transfer did not emit one frame")
assert_frame_matches(frames[0], first)
return "BASE and ROI match original JPEG bytes"
def shuffled_packets() -> str:
shuffled = list(all_packets)
random.Random(28001).shuffle(shuffled)
frames, _ = feed_packets(shuffled)
if len(frames) != 1:
raise AssertionError("shuffled transfer did not emit one frame")
assert_frame_matches(frames[0], first)
return "arbitrary packet order reconstructed correctly"
def duplicate_packets() -> str:
duplicated = list(all_packets)
duplicated.extend(
[all_packets[0], all_packets[len(base_packets)]]
)
random.Random(28002).shuffle(duplicated)
frames, receiver = feed_packets(duplicated)
if len(frames) != 1:
raise AssertionError("duplicates changed publication count")
assert_frame_matches(frames[0], first)
if receiver.duplicate_packets < 2:
raise AssertionError("exact duplicates were not counted")
return f"{receiver.duplicate_packets} exact duplicates ignored"
def packet_crc_corruption() -> str:
corrupted = bytearray(all_packets[0])
corrupted[-1] ^= 0x01
receiver = CompositeReassembler()
try:
receiver.ingest(bytes(corrupted))
except PacketCRCError:
pass
else:
raise AssertionError("corrupted packet passed packet CRC")
frames, _ = feed_packets(all_packets[1:], receiver)
if frames:
raise AssertionError("frame emitted despite rejected packet")
return "payload bit flip rejected; composite not emitted"
def missing_fragment() -> str:
missing_packet = roi_packets[len(roi_packets) // 2]
missing_index = decode_packet(missing_packet).fragment_index
remaining = [
packet
for packet in all_packets
if packet is not missing_packet
]
frames, receiver = feed_packets(remaining)
if frames:
raise AssertionError("frame emitted with a missing fragment")
missing = receiver.missing_fragments(
first.composite_frame_id, ObjectType.ROI
)
if missing is None or missing_index not in missing:
raise AssertionError("missing fragment was not reported")
return f"ROI fragment {missing_index} reported missing"
def object_crc_corruption() -> str:
target_position = len(base_packets)
parsed = decode_packet(all_packets[target_position])
changed_payload = bytearray(parsed.payload)
changed_payload[0] ^= 0x01
altered = encode_packet(
VideoPacket(
composite_frame_id=parsed.composite_frame_id,
object_type=parsed.object_type,
fragment_index=parsed.fragment_index,
fragment_count=parsed.fragment_count,
jpeg_size=parsed.jpeg_size,
object_crc32=parsed.object_crc32,
payload=bytes(changed_payload),
)
)
formally_valid = list(all_packets)
formally_valid[target_position] = altered
receiver = CompositeReassembler()
emitted = []
object_error_seen = False
for packet in formally_valid:
try:
frame = receiver.ingest(packet)
except ObjectCRCError:
object_error_seen = True
continue
if frame is not None:
emitted.append(frame)
if not object_error_seen:
raise AssertionError("object CRC did not detect changed JPEG")
if emitted:
raise AssertionError("frame emitted after object CRC failure")
return "valid packet CRCs still failed full-object CRC"
def adjacent_frames_do_not_mix() -> str:
first_packets = sum(packets_for_composite(first, 256), [])
second_packets = sum(packets_for_composite(second, 256), [])
interleaved = first_packets + second_packets
random.Random(28003).shuffle(interleaved)
frames, _ = feed_packets(interleaved)
by_id = {frame.composite_frame_id: frame for frame in frames}
if set(by_id) != {
first.composite_frame_id,
second.composite_frame_id,
}:
raise AssertionError("adjacent frames were lost or mixed")
assert_frame_matches(by_id[first.composite_frame_id], first)
assert_frame_matches(by_id[second.composite_frame_id], second)
return "two interleaved frame IDs remained independent"
def base_only_is_not_atomic() -> str:
frames, receiver = feed_packets(base_packets)
if frames:
raise AssertionError("BASE-only input emitted a composite")
if not receiver.object_is_complete(
first.composite_frame_id, ObjectType.BASE
):
raise AssertionError("complete BASE object was not retained")
return "complete BASE retained while composite stayed unpublished"
tests.extend(
[
("header_serialization_round_trip", header_round_trip),
("ordered_lossless_transfer", ordered_lossless),
("random_packet_order", shuffled_packets),
("exact_duplicate_packets", duplicate_packets),
("packet_crc_corruption", packet_crc_corruption),
("missing_fragment", missing_fragment),
("object_crc_corruption", object_crc_corruption),
("adjacent_frame_isolation", adjacent_frames_do_not_mix),
("base_without_roi_atomicity", base_only_is_not_atomic),
]
)
results = []
for name, test in tests:
try:
detail = test()
except Exception as error:
results.append(TestResult(name, False, str(error)))
else:
results.append(TestResult(name, True, detail))
failed = [result for result in results if not result.passed]
if failed:
details = "; ".join(
f"{result.name}: {result.detail}" for result in failed
)
raise RuntimeError(f"functional transport tests failed: {details}")
return results
def save_csv(metrics: list[PayloadMetrics]) -> None:
OUTPUT_DIRECTORY.mkdir(parents=True, exist_ok=True)
with CSV_PATH.open("w", encoding="utf-8", newline="") as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=CSV_FIELDS)
writer.writeheader()
for item in metrics:
row = {}
for field_name in CSV_FIELDS:
value = getattr(item, field_name)
row[field_name] = (
f"{value:.6f}"
if isinstance(value, float)
else value
)
writer.writerow(row)
def save_plots(metrics: list[PayloadMetrics]) -> None:
payloads = [item.max_payload_bytes for item in metrics]
figure, axis = plt.subplots(figsize=(9, 5.5))
axis.plot(
payloads,
[item.service_data_percent for item in metrics],
marker="o",
linewidth=2,
label="Service data (header / wire)",
)
axis.plot(
payloads,
[item.efficiency_percent for item in metrics],
marker="s",
linewidth=2,
label="Efficiency (JPEG / wire)",
)
axis.set_xscale("log", base=2)
axis.set_xticks(payloads)
axis.set_xticklabels([str(value) for value in payloads])
axis.set_xlabel("Maximum packet payload, bytes")
axis.set_ylabel("Share, %")
axis.set_title("Lab028 packet overhead and efficiency")
axis.grid(True, alpha=0.3)
axis.legend()
figure.tight_layout()
figure.savefig(OVERHEAD_PLOT_PATH, dpi=160)
plt.close(figure)
figure, packet_axis = plt.subplots(figsize=(9, 5.5))
bitrate_axis = packet_axis.twinx()
packet_line = packet_axis.plot(
payloads,
[item.packets_per_second for item in metrics],
color="tab:blue",
marker="o",
linewidth=2,
label="Packets/s",
)
bitrate_lines = bitrate_axis.plot(
payloads,
[item.wire_bitrate_kbps for item in metrics],
color="tab:red",
marker="s",
linewidth=2,
label="Wire bitrate",
)
bitrate_axis.plot(
payloads,
[item.jpeg_payload_bitrate_kbps for item in metrics],
color="tab:green",
linestyle="--",
linewidth=2,
label="JPEG payload bitrate",
)
packet_axis.set_xscale("log", base=2)
packet_axis.set_xticks(payloads)
packet_axis.set_xticklabels([str(value) for value in payloads])
packet_axis.set_xlabel("Maximum packet payload, bytes")
packet_axis.set_ylabel("Packets per second", color="tab:blue")
bitrate_axis.set_ylabel("Bitrate, kbit/s", color="tab:red")
packet_axis.set_title("Lab028 packet rate and wire bitrate")
packet_axis.grid(True, alpha=0.3)
lines = packet_line + bitrate_lines + bitrate_axis.lines[1:]
packet_axis.legend(
lines,
[line.get_label() for line in lines],
loc="best",
)
figure.tight_layout()
figure.savefig(TRAFFIC_PLOT_PATH, dpi=160)
plt.close(figure)
def metrics_table(metrics: list[PayloadMetrics]) -> list[str]:
lines = [
(
"payload | BASE pkt/frame | ROI pkt/frame | all pkt/frame | "
"max pkt/frame | pkt/s | JPEG kbit/s | headers B/s | "
"wire kbit/s | service % | efficiency % | packet mean/p95/max"
),
(
"-------:|---------------:|--------------:|--------------:|"
"--------------:|------:|------------:|------------:|"
"------------:|----------:|-------------:|--------------------:"
),
]
for item in metrics:
lines.append(
f"{item.max_payload_bytes} | "
f"{item.mean_base_packets_per_frame:.3f} | "
f"{item.mean_roi_packets_per_frame:.3f} | "
f"{item.mean_total_packets_per_frame:.3f} | "
f"{item.max_total_packets_per_frame} | "
f"{item.packets_per_second:.3f} | "
f"{item.jpeg_payload_bitrate_kbps:.3f} | "
f"{item.header_bytes_per_second:.3f} | "
f"{item.wire_bitrate_kbps:.3f} | "
f"{item.service_data_percent:.3f} | "
f"{item.efficiency_percent:.3f} | "
f"{item.mean_wire_packet_bytes:.1f}/"
f"{item.p95_wire_packet_bytes:.1f}/"
f"{item.max_wire_packet_bytes}"
)
return lines
def write_report(
metadata: VideoMetadata,
composites: list[EncodedComposite],
metrics: list[PayloadMetrics],
test_results: list[TestResult],
) -> None:
source_roi = normalized_roi_to_pixels(
metadata.width, metadata.height
)
base_sizes = [len(item.base_jpeg) for item in composites]
roi_sizes = [len(item.roi_jpeg) for item in composites]
lines = [
"Lab028. Пакетирование синхронного BASE + ROI",
"",
"Профиль и исходные данные",
f"- Видео: {SOURCE_VIDEO_PATH}",
(
f"- Источник: {metadata.width}x{metadata.height}, "
f"{metadata.fps:.6f} fps, {metadata.frame_count} кадров, "
f"{metadata.duration_seconds:.6f} с."
),
(
f"- ROI: x={ROI_X_MIN:.2f}...{ROI_X_MAX:.2f}, "
f"y={ROI_Y_MIN:.2f}...{ROI_Y_MAX:.2f}; "
f"пиксели x={source_roi[0]}...{source_roi[2]}, "
f"y={source_roi[1]}...{source_roi[3]}."
),
(
f"- Синхронные составные кадры: {len(composites)} "
f"при {COMPOSITE_FPS:.3f} fps."
),
(
f"- BASE: {BASE_WIDTH}x{BASE_HEIGHT}, grayscale JPEG Q"
f"{BASE_QUALITY}; средний размер {np.mean(base_sizes):.3f} B, "
f"min/max {min(base_sizes)}/{max(base_sizes)} B."
),
(
f"- ROI: {ROI_WIDTH}x{ROI_HEIGHT}, grayscale JPEG Q"
f"{ROI_QUALITY}; средний размер {np.mean(roi_sizes):.3f} B, "
f"min/max {min(roi_sizes)}/{max(roi_sizes)} B."
),
(
"- BASE и ROI формируются из одного source frame и имеют "
"общий composite_frame_id."
),
"",
"Бинарный заголовок",
f"- struct format: {HEADER_FORMAT}",
f"- Размер: {HEADER_SIZE} байта; network byte order; padding нет.",
(
"- Layout: magic[4] @0, version:u8 @4, object_type:u8 @5, "
"header_size:u16 @6, composite_frame_id:u32 @8, "
"fragment_index:u16 @12, fragment_count:u16 @14, "
"payload_length:u16 @16, flags:u16 @18, jpeg_size:u32 @20, "
"object_crc32:u32 @24, packet_crc32:u32 @28."
),
"- object_type: 1=BASE, 2=ROI; flags зарезервирован и равен 0.",
"",
"CRC32",
(
"- object_crc32 = zlib.crc32(полный JPEG) & 0xFFFFFFFF; "
"значение помещается во все фрагменты объекта и проверяется "
"после полной сборки."
),
(
"- packet_crc32: сначала поле packet_crc32 заголовка "
"обнуляется, затем CRC считается как "
"zlib.crc32(header_with_zero_crc + payload) & 0xFFFFFFFF."
),
"- Таким образом packet CRC защищает все поля заголовка и payload.",
"",
"Функциональные проверки",
]
lines.extend(
f"- {'PASS' if item.passed else 'FAIL'} {item.name}: {item.detail}"
for item in test_results
)
lines.extend(
[
"",
"Результаты размеров packet payload",
*metrics_table(metrics),
"",
(
"JPEG payload bitrate одинаков для всех строк, потому что "
"исходные JPEG не меняются при выборе размера фрагмента."
),
(
"Wire bitrate включает только JPEG payload и 32-байтные "
"заголовки каждого пакета."
),
(
"Wire bitrate пока НЕ включает FEC, преамбулу, "
"синхронизацию, модуляцию, интервалы, повторные передачи, "
"команды управления и телеметрию."
),
(
"Лучший размер packet payload автоматически не выбирается: "
"таблица показывает только транспортный компромисс."
),
"",
"Артефакты",
f"- CSV: {CSV_PATH}",
f"- Overhead/efficiency: {OVERHEAD_PLOT_PATH}",
f"- Packet count/wire bitrate: {TRAFFIC_PLOT_PATH}",
(
"- Промежуточные JPEG и пакеты сохранялись только в памяти; "
"бинарные дампы не создавались."
),
"",
]
)
REPORT_PATH.write_text("\n".join(lines), encoding="utf-8")
def validate_outputs(metrics: list[PayloadMetrics]) -> None:
if len(metrics) != len(PAYLOAD_LENGTHS):
raise RuntimeError("not all payload sizes were measured")
if [item.max_payload_bytes for item in metrics] != list(
PAYLOAD_LENGTHS
):
raise RuntimeError("payload result order differs")
if any(
abs(
item.service_data_percent
+ item.efficiency_percent
- 100.0
) > 1e-9
for item in metrics
):
raise RuntimeError("overhead and efficiency do not sum to 100%")
for path in (
CSV_PATH,
REPORT_PATH,
OVERHEAD_PLOT_PATH,
TRAFFIC_PLOT_PATH,
):
if not path.exists() or path.stat().st_size <= 0:
raise RuntimeError(f"missing or empty output: {path}")
def main() -> None:
print("Lab028: loading and JPEG-encoding the Lab027E profile...")
metadata, composites = load_video_profile(SOURCE_VIDEO_PATH)
print(
f" source={metadata.width}x{metadata.height}, "
f"{metadata.fps:.3f} fps, frames={metadata.frame_count}"
)
print(f" synchronous composite frames={len(composites)}")
print("Running functional transport checks...")
test_results = run_functional_tests(composites)
for result in test_results:
print(f" PASS {result.name}: {result.detail}")
print("Measuring packet payload sizes...")
metrics = [
calculate_payload_metrics(
composites,
metadata.duration_seconds,
payload_length,
)
for payload_length in PAYLOAD_LENGTHS
]
for item in metrics:
print(
f" payload={item.max_payload_bytes:4d} B: "
f"{item.packets_per_second:.3f} packet/s, "
f"wire={item.wire_bitrate_kbps:.3f} kbit/s, "
f"service={item.service_data_percent:.3f}%"
)
OUTPUT_DIRECTORY.mkdir(parents=True, exist_ok=True)
save_csv(metrics)
save_plots(metrics)
write_report(metadata, composites, metrics, test_results)
validate_outputs(metrics)
print(f"CSV: {CSV_PATH}")
print(f"Report: {REPORT_PATH}")
print(f"Plots: {OVERHEAD_PLOT_PATH}, {TRAFFIC_PLOT_PATH}")
print("Lab028 completed successfully.")
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff