Lab034: evaluate stale video frame dropping

This commit is contained in:
LittleSam129
2026-08-03 13:17:55 +03:00
parent 21751f41dd
commit b63e36abdb
14 changed files with 1415 additions and 0 deletions

View File

@@ -188,3 +188,28 @@ git version 2.51.1.windows.1
- Итоговое восстановление всех кадров после освобождения очереди не означает работу видео в реальном времени. - Итоговое восстановление всех кадров после освобождения очереди не означает работу видео в реальном времени.
- Расчёты и графики выполнены с Matplotlib 3.11.1. - Расчёты и графики выполнены с Matplotlib 3.11.1.
- Следующий этап посвящён отбрасыванию устаревших видеокадров. - Следующий этап посвящён отбрасыванию устаревших видеокадров.
---
# Запись 009
## Дата
3 августа 2026 года
## Тема
Завершение Lab034: реактивное отбрасывание устаревших видеокадров.
## Выполнено
- Сравнены непрерывные FEC-блоки и блоки, выровненные по составным кадрам.
- Выравнивание увеличивает видеопоток на 5,975 кбит/с, или на 2,633%.
- При 300 кбит/с удаление кадров не требуется.
- При 260 кбит/с ограничения 1000 и 1500 мс не срабатывают, а ограничение 500 мс уже чрезмерно.
- При 230 кбит/с реактивное удаление устаревших кадров уменьшает очередь, но резко снижает частоту обновления.
- Ограничение 500 мс оставляет только 3 из 63 кадров.
- Ограничение 1500 мс оставляет 27 из 63 кадров.
- Подтверждено, что короткая очередь сама по себе не означает свежее изображение.
- Текущая реактивная политика не принята.
- Следующий этап посвящён упреждающему допуску кадров и обслуживанию видео целыми кадрами.

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,16 @@
channel_kbps,policy,control_mean_age_ms,control_p95_age_ms,control_max_age_ms,control_deadline_misses,control_max_receive_gap_ms,control_replaced,emergency_total_delay_ms,emergency_deadline_met,emergency_blocker_class,emergency_blocker_size_bytes,emergency_blocker_sequence,emergency_blocking_delay_ms,telemetry_mean_age_ms,telemetry_p95_age_ms,telemetry_max_age_ms,telemetry_deadline_misses,telemetry_replaced
300.0,continuous_no_drop,9.439928685896334,17.46633333333346,17.813000000000745,0,65.7596666666671,0,1.7066666666671892,True,none,0,-1,0.0,12.424120192306697,20.10688333333437,20.37300000000064,0,0
300.0,aligned_no_drop,10.09563301281934,17.46633333333314,17.78700000000022,0,65.7596666666671,0,1.7066666666671892,True,none,0,-1,0.0,12.858206730768112,19.573666666667933,20.160000000000622,0,0
300.0,aligned_1500ms,10.09563301281934,17.46633333333314,17.78700000000022,0,65.7596666666671,0,1.7066666666671892,True,none,0,-1,0.0,12.858206730768112,19.573666666667933,20.160000000000622,0,0
300.0,aligned_1000ms,10.09563301281934,17.46633333333314,17.78700000000022,0,65.7596666666671,0,1.7066666666671892,True,none,0,-1,0.0,12.858206730768112,19.573666666667933,20.160000000000622,0,0
300.0,aligned_500ms,10.09563301281934,17.46633333333314,17.78700000000022,0,65.7596666666671,0,1.7066666666671892,True,none,0,-1,0.0,12.858206730768112,19.573666666667933,20.160000000000622,0,0
260.0,continuous_no_drop,10.282265902386632,18.753596153843198,20.66700000000843,0,63.476923076922546,0,1.969230769230279,True,none,0,-1,0.0,13.863505177534366,22.44779230770204,23.620846153853847,0,0
260.0,aligned_no_drop,10.671617788489147,18.907692307691043,20.492307692309808,0,67.81538461538617,0,1.969230769230279,True,none,0,-1,0.0,13.490528846181197,21.89960384616611,23.323076923056796,0,0
260.0,aligned_1500ms,10.671617788489147,18.907692307691043,20.492307692309808,0,67.81538461538617,0,1.969230769230279,True,none,0,-1,0.0,13.490528846181197,21.89960384616611,23.323076923056796,0,0
260.0,aligned_1000ms,10.671617788489147,18.907692307691043,20.492307692309808,0,67.81538461538617,0,1.969230769230279,True,none,0,-1,0.0,13.490528846181197,21.89960384616611,23.323076923056796,0,0
260.0,aligned_500ms,10.71385151629976,18.907692307691043,20.492307692309808,0,67.81538461538617,0,1.969230769230279,True,none,0,-1,0.0,13.61641642014566,22.039999999996684,23.323076923056796,0,0
230.0,continuous_no_drop,12.250334448143445,21.84782608690261,23.33913043477409,0,69.00869565217427,0,11.547826086889756,True,video,608,458,9.32173913036749,15.51421404680579,25.111304347813142,26.678260869555714,0,0
230.0,aligned_no_drop,12.729598662164767,22.499999999942013,24.556521739064863,0,69.00869565217427,0,22.330434782542596,True,video,608,463,20.10434782602033,15.594983277549522,25.377391304327652,27.895652173848262,0,0
230.0,aligned_1500ms,12.613043478216982,22.460869565154475,24.556521739064863,0,69.00869565217427,0,22.330434782542596,True,video,608,463,20.10434782602033,15.613377926377664,25.426086956510073,27.895652173848262,0,0
230.0,aligned_1000ms,12.76596989961911,22.578260869525746,23.356521739078318,0,69.00869565217427,0,11.652173912974462,True,video,608,484,9.426086956452195,15.511371237411904,25.37739130434555,26.608695652086567,0,0
230.0,aligned_500ms,12.377759197289913,22.230434782573028,23.339130434790967,0,69.00869565217427,0,3.6869565216850475,True,video,608,511,1.4608695651627812,15.598996655484031,24.913043478221116,26.678260869573478,0,0
1 channel_kbps policy control_mean_age_ms control_p95_age_ms control_max_age_ms control_deadline_misses control_max_receive_gap_ms control_replaced emergency_total_delay_ms emergency_deadline_met emergency_blocker_class emergency_blocker_size_bytes emergency_blocker_sequence emergency_blocking_delay_ms telemetry_mean_age_ms telemetry_p95_age_ms telemetry_max_age_ms telemetry_deadline_misses telemetry_replaced
2 300.0 continuous_no_drop 9.439928685896334 17.46633333333346 17.813000000000745 0 65.7596666666671 0 1.7066666666671892 True none 0 -1 0.0 12.424120192306697 20.10688333333437 20.37300000000064 0 0
3 300.0 aligned_no_drop 10.09563301281934 17.46633333333314 17.78700000000022 0 65.7596666666671 0 1.7066666666671892 True none 0 -1 0.0 12.858206730768112 19.573666666667933 20.160000000000622 0 0
4 300.0 aligned_1500ms 10.09563301281934 17.46633333333314 17.78700000000022 0 65.7596666666671 0 1.7066666666671892 True none 0 -1 0.0 12.858206730768112 19.573666666667933 20.160000000000622 0 0
5 300.0 aligned_1000ms 10.09563301281934 17.46633333333314 17.78700000000022 0 65.7596666666671 0 1.7066666666671892 True none 0 -1 0.0 12.858206730768112 19.573666666667933 20.160000000000622 0 0
6 300.0 aligned_500ms 10.09563301281934 17.46633333333314 17.78700000000022 0 65.7596666666671 0 1.7066666666671892 True none 0 -1 0.0 12.858206730768112 19.573666666667933 20.160000000000622 0 0
7 260.0 continuous_no_drop 10.282265902386632 18.753596153843198 20.66700000000843 0 63.476923076922546 0 1.969230769230279 True none 0 -1 0.0 13.863505177534366 22.44779230770204 23.620846153853847 0 0
8 260.0 aligned_no_drop 10.671617788489147 18.907692307691043 20.492307692309808 0 67.81538461538617 0 1.969230769230279 True none 0 -1 0.0 13.490528846181197 21.89960384616611 23.323076923056796 0 0
9 260.0 aligned_1500ms 10.671617788489147 18.907692307691043 20.492307692309808 0 67.81538461538617 0 1.969230769230279 True none 0 -1 0.0 13.490528846181197 21.89960384616611 23.323076923056796 0 0
10 260.0 aligned_1000ms 10.671617788489147 18.907692307691043 20.492307692309808 0 67.81538461538617 0 1.969230769230279 True none 0 -1 0.0 13.490528846181197 21.89960384616611 23.323076923056796 0 0
11 260.0 aligned_500ms 10.71385151629976 18.907692307691043 20.492307692309808 0 67.81538461538617 0 1.969230769230279 True none 0 -1 0.0 13.61641642014566 22.039999999996684 23.323076923056796 0 0
12 230.0 continuous_no_drop 12.250334448143445 21.84782608690261 23.33913043477409 0 69.00869565217427 0 11.547826086889756 True video 608 458 9.32173913036749 15.51421404680579 25.111304347813142 26.678260869555714 0 0
13 230.0 aligned_no_drop 12.729598662164767 22.499999999942013 24.556521739064863 0 69.00869565217427 0 22.330434782542596 True video 608 463 20.10434782602033 15.594983277549522 25.377391304327652 27.895652173848262 0 0
14 230.0 aligned_1500ms 12.613043478216982 22.460869565154475 24.556521739064863 0 69.00869565217427 0 22.330434782542596 True video 608 463 20.10434782602033 15.613377926377664 25.426086956510073 27.895652173848262 0 0
15 230.0 aligned_1000ms 12.76596989961911 22.578260869525746 23.356521739078318 0 69.00869565217427 0 11.652173912974462 True video 608 484 9.426086956452195 15.511371237411904 25.37739130434555 26.608695652086567 0 0
16 230.0 aligned_500ms 12.377759197289913 22.230434782573028 23.339130434790967 0 69.00869565217427 0 3.6869565216850475 True video 608 511 1.4608695651627812 15.598996655484031 24.913043478221116 26.678260869573478 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -0,0 +1,98 @@
Lab034. Ограничение возраста видеоданных и отбрасывание устаревших кадров
1. Исходное состояние
- Commit Lab033: 21751f41dd0af022fc1f935c67e795e3ae4257c5.
- Перед Lab034 рабочее дерево было чистым; main опережала origin/main на один commit.
- Lab028-Lab033 и их результаты не изменяются.
2. Формирование FEC-блоков
layout | source | parity | blocks | partial | cross-frame | frames/block mean/max | before/after Lab033 kbps
Непрерывные | 862 | 216 | 72 | 1 | 58 | 1.806/2 | 226.951/240.240
По кадрам | 862 | 251 | 125 | 62 | 0 | 1.000/1 | 232.926/246.647
- Дополнительная избыточность выравнивания: 5.975 кбит/с (2.633%).
- Средняя эквивалентная группа кадра: непрерывные 17.111 пакета / 263.968 мс; выровненные 17.667 пакета / 271.007 мс при 300 кбит/с.
3. Пятнадцать сочетаний
speed | policy | offered/capacity | published/drop/partial | update fps | age P95 ms | control P95 ms | emergency ms | queue max/end | drain s | wasted bytes
300 | Непрерывные, без отбрасывания | 0.8607 | 63/0/0 | 2.986 | 593.333 | 17.466 | 1.707 | 22/15 | 0.231867 | 0
300 | По кадрам, без отбрасывания | 0.8821 | 63/0/0 | 2.986 | 590.000 | 17.466 | 1.707 | 21/13 | 0.199440 | 0
300 | По кадрам, 1500 мс | 0.8821 | 63/0/0 | 2.986 | 590.000 | 17.466 | 1.707 | 21/13 | 0.199440 | 0
300 | По кадрам, 1000 мс | 0.8821 | 63/0/0 | 2.986 | 590.000 | 17.466 | 1.707 | 21/13 | 0.199440 | 0
300 | По кадрам, 500 мс | 0.8821 | 63/0/0 | 2.986 | 590.000 | 17.466 | 1.707 | 21/13 | 0.199440 | 0
260 | Непрерывные, без отбрасывания | 0.9931 | 63/0/0 | 2.937 | 690.000 | 18.754 | 1.969 | 28/23 | 0.399200 | 0
260 | По кадрам, без отбрасывания | 1.0178 | 63/0/0 | 2.937 | 773.833 | 18.908 | 1.969 | 37/30 | 0.539293 | 0
260 | По кадрам, 1500 мс | 1.0178 | 63/0/0 | 2.937 | 773.833 | 18.908 | 1.969 | 37/30 | 0.539293 | 0
260 | По кадрам, 1000 мс | 1.0178 | 63/0/0 | 2.937 | 773.833 | 18.908 | 1.969 | 37/30 | 0.539293 | 0
260 | По кадрам, 500 мс | 1.0178 | 56/7/7 | 2.648 | 1053.833 | 18.908 | 1.969 | 31/24 | 0.403939 | 69597
230 | Непрерывные, без отбрасывания | 1.1227 | 63/0/0 | 2.697 | 2443.833 | 21.848 | 11.548 | 132/127 | 2.547420 | 0
230 | По кадрам, без отбрасывания | 1.1505 | 63/0/0 | 2.600 | 2913.333 | 22.500 | 22.330 | 160/155 | 3.125855 | 0
230 | По кадрам, 1500 мс | 1.1505 | 27/36/36 | 1.300 | 11064.833 | 22.461 | 22.330 | 87/81 | 1.418064 | 321929
230 | По кадрам, 1000 мс | 1.1505 | 14/49/49 | 0.674 | 11731.500 | 22.578 | 11.652 | 63/53 | 0.904881 | 434885
230 | По кадрам, 500 мс | 1.1505 | 3/60/60 | 0.144 | 11731.500 | 22.230 | 3.687 | 32/27 | 0.419072 | 532167
4. Практический смысл ограничений возраста
- При 300 кбит/с очередь обслуживается достаточно быстро: ограничения 500, 1000 и 1500 мс не срабатывают и не дают выигрыша.
- При 260 кбит/с пределы 1000 и 1500 мс также не срабатывают; предел 500 мс публикует 56 из 63 кадров и отбрасывает 7, поэтому он уже чрезмерно жёсткий для части кадров.
- При 230 кбит/с предел 1500 мс сохраняет 27 кадров, 1000 мс — 14, 500 мс — только 3; более строгий предел лучше ограничивает очередь, но резко уменьшает частоту обновления.
- В исследованной перегрузке 1500 мс является наиболее мягким из конечных ограничений; 1000 мс сильнее улучшает свежесть ценой обновлений, а 500 мс чрезмерно жёсток.
5. Интерпретация
- Произвольное удаление символа из непрерывного FEC-блока опасно: блок может содержать соседние кадры, и нехватка символов затрагивает их совместное декодирование.
- Выравнивание изолирует кадр в собственных блоках, поэтому все ожидающие символы устаревшего кадра можно удалить без повреждения соседей.
- Цена изоляции — 5.975 кбит/с дополнительного внешнего потока из-за большего числа неполных блоков.
- Полная доставка после освобождения очереди не является целью операторского видео: поздний полный кадр уже не описывает текущее состояние ровера.
- При перегрузке отбрасывание старого кадра освобождает ресурс для более свежего изображения и не затрагивает команды.
- При 230 кбит/с выравнивание меняет фазу активного видеопакета около 10,0 с; фактическая задержка аварийной команды может отличаться от Lab033, но отбрасывание её не увеличивает, а непереключаемая верхняя граница остаётся прежней, поскольку максимальный размер пакета не изменён.
- Слишком малый возраст может отменять кадры быстрее их полной передачи и снижать фактическую частоту обновления.
- Поэтому возраст изображения оценивается вместе с частотой обновления: хорошее значение одного показателя не гарантирует полезный видеопоток.
- Замена команд допустима только для текущего состояния (скорость, поворот, торможение, телеметрия). Дискретные события заменять нельзя; в Lab034 они не моделируются.
6. Допущения
- Один общий абстрактный ресурс, одна скорость для обоих направлений, без времени переключения и без выбора физического duplex/TDD/FDD.
- Ошибки и помехи отсутствуют; начатый пакет не прерывается; форматы Lab028, Lab030 и Lab033 неизменны.
- Возраст считается от формирования составного кадра по generation_time_us; служебные frame_id и состояние отмены не сериализуются.
- Видеокадр с удалёнными пакетами очищается в приёмнике и никогда не публикуется.
- Допустимые возраста 500, 1000 и 1500 мс заданы явно и автоматически не выбираются.
7. Функциональные проверки
- PASS 01_continuous_matches_lab033: PASS
- PASS 02_aligned_blocks_one_frame: PASS
- PASS 03_aligned_no_drop_recovers_all: PASS
- PASS 04_whole_frame_drop_isolated: PASS
- PASS 05_only_waiting_video_removed: PASS
- PASS 06_active_packet_not_preempted: PASS
- PASS 07_partial_cancel_not_published: PASS
- PASS 08_age_uses_frame_generation: PASS
- PASS 09_receiver_cleans_stale_state: PASS
- PASS 10_emergency_never_deleted: PASS
- PASS 11_high_priority_before_video: PASS
- PASS 12_230kbps_finite_age_bounds_queue: PASS
- PASS 13_packet_accounting: PASS
- PASS 14_byte_accounting: PASS
- PASS 15_all_crc_layers_pass: PASS
- PASS 16_incomplete_frame_never_published: PASS
- PASS 17_reproducible: PASS
- PASS 18_drop_does_not_worsen_emergency: PASS
8. Созданные файлы
- protocol/video_age_policy.py
- tests/lab034_stale_video_drop.py
- data/processed/lab034/lab034_summary.csv
- data/processed/lab034/lab034_video_metrics.csv
- data/processed/lab034/lab034_control_metrics.csv
- data/processed/lab034/lab034_report.txt
- data/processed/lab034/lab034_image_age.png
- data/processed/lab034/lab034_frame_outcomes.png
- data/processed/lab034/lab034_queue_size.png
- data/processed/lab034/lab034_control_delay.png
- data/processed/lab034/lab034_update_rate.png
- data/processed/lab034/lab034_fec_alignment_overhead.png
- data/processed/lab034/lab034_policy_comparison.png
9. Итоговый Git status
- Lab034 не добавлена в индекс и не закоммичена.
## main...origin/main [ahead 1]
?? data/processed/lab034/
?? protocol/video_age_policy.py
?? tests/lab034_stale_video_drop.py

View File

@@ -0,0 +1,16 @@
channel_kbps,policy,layout,max_video_age_ms,offered_load_kbps,offered_to_capacity_ratio,transmitted_packets,transmitted_bytes,dropped_packets,dropped_bytes,wasted_transmitted_bytes,mean_queue_packets,max_queue_packets,mean_queue_bytes,max_queue_bytes,queue_at_source_end_packets,additional_drain_seconds,channel_utilization_fraction
300.0,continuous_no_drop,continuous,-1,258.21380417335473,0.8607126805778491,1703,670280,0,0,0,8.05016637239154,22,4452.387224542477,12221,15,0.23186699999999405,0.8512086423304386
300.0,aligned_no_drop,aligned,-1,264.62022471910115,0.8820674157303372,1738,686910,0,0,0,8.518393226324118,21,4685.69717834665,11415,13,0.1994403333333281,0.8724635473515175
300.0,aligned_1500ms,aligned,1500,264.62022471910115,0.8820674157303372,1738,686910,0,0,0,8.518393226324118,21,4685.69717834665,11415,13,0.1994403333333281,0.8724635473515175
300.0,aligned_1000ms,aligned,1000,264.62022471910115,0.8820674157303372,1738,686910,0,0,0,8.518393226324118,21,4685.69717834665,11415,13,0.1994403333333281,0.8724635473515175
300.0,aligned_500ms,aligned,500,264.62022471910115,0.8820674157303372,1738,686910,0,0,0,8.518393226324118,21,4685.69717834665,11415,13,0.1994403333333281,0.8724635473515175
260.0,continuous_no_drop,continuous,-1,258.21380417335473,0.9931300160513643,1703,670280,0,0,0,10.783079034450305,28,6010.224630522928,16384,23,0.39920033333350347,0.9743990170589202
260.0,aligned_no_drop,aligned,-1,264.62022471910115,1.017770095073466,1738,686910,0,0,0,13.695290291396285,37,7655.6639836816,21131,30,0.5392926410258561,0.991800947030499
260.0,aligned_1500ms,aligned,1500,264.62022471910115,1.017770095073466,1738,686910,0,0,0,13.695290291396285,37,7655.6639836816,21131,30,0.5392926410258561,0.991800947030499
260.0,aligned_1000ms,aligned,1000,264.62022471910115,1.017770095073466,1738,686910,0,0,0,13.695290291396285,37,7655.6639836816,21131,30,0.5392926410258561,0.991800947030499
260.0,aligned_500ms,aligned,500,264.62022471910115,1.017770095073466,1730,682511,8,4399,69597,13.261018996174682,31,7402.747049027978,16992,24,0.4039387948720048,0.991800947030499
230.0,continuous_no_drop,continuous,-1,258.21380417335473,1.1226687137971945,1703,670280,0,0,0,59.749842696627866,132,34307.118394888734,75969,127,2.547420289855012,1.0
230.0,aligned_no_drop,aligned,-1,264.62022471910115,1.1505227161700051,1738,686910,0,0,0,76.17493190801534,160,43586.68565075366,92568,155,3.1258550724636294,1.0
230.0,aligned_1500ms,aligned,1500,264.62022471910115,1.1505227161700051,1641,637811,97,49099,321929,59.44779896084508,87,33911.67327808277,50035,81,1.4180637681158217,1.0
230.0,aligned_1000ms,aligned,1000,264.62022471910115,1.1505227161700051,1609,623057,129,63853,434885,42.60156656500422,63,24223.970784957004,35495,53,0.9048811594201744,1.0
230.0,aligned_500ms,aligned,500,264.62022471910115,1.1505227161700051,1580,609090,158,77820,532167,20.03526158908224,32,11270.42233914812,18208,27,0.41907246376802476,0.9999999999999993
1 channel_kbps policy layout max_video_age_ms offered_load_kbps offered_to_capacity_ratio transmitted_packets transmitted_bytes dropped_packets dropped_bytes wasted_transmitted_bytes mean_queue_packets max_queue_packets mean_queue_bytes max_queue_bytes queue_at_source_end_packets additional_drain_seconds channel_utilization_fraction
2 300.0 continuous_no_drop continuous -1 258.21380417335473 0.8607126805778491 1703 670280 0 0 0 8.05016637239154 22 4452.387224542477 12221 15 0.23186699999999405 0.8512086423304386
3 300.0 aligned_no_drop aligned -1 264.62022471910115 0.8820674157303372 1738 686910 0 0 0 8.518393226324118 21 4685.69717834665 11415 13 0.1994403333333281 0.8724635473515175
4 300.0 aligned_1500ms aligned 1500 264.62022471910115 0.8820674157303372 1738 686910 0 0 0 8.518393226324118 21 4685.69717834665 11415 13 0.1994403333333281 0.8724635473515175
5 300.0 aligned_1000ms aligned 1000 264.62022471910115 0.8820674157303372 1738 686910 0 0 0 8.518393226324118 21 4685.69717834665 11415 13 0.1994403333333281 0.8724635473515175
6 300.0 aligned_500ms aligned 500 264.62022471910115 0.8820674157303372 1738 686910 0 0 0 8.518393226324118 21 4685.69717834665 11415 13 0.1994403333333281 0.8724635473515175
7 260.0 continuous_no_drop continuous -1 258.21380417335473 0.9931300160513643 1703 670280 0 0 0 10.783079034450305 28 6010.224630522928 16384 23 0.39920033333350347 0.9743990170589202
8 260.0 aligned_no_drop aligned -1 264.62022471910115 1.017770095073466 1738 686910 0 0 0 13.695290291396285 37 7655.6639836816 21131 30 0.5392926410258561 0.991800947030499
9 260.0 aligned_1500ms aligned 1500 264.62022471910115 1.017770095073466 1738 686910 0 0 0 13.695290291396285 37 7655.6639836816 21131 30 0.5392926410258561 0.991800947030499
10 260.0 aligned_1000ms aligned 1000 264.62022471910115 1.017770095073466 1738 686910 0 0 0 13.695290291396285 37 7655.6639836816 21131 30 0.5392926410258561 0.991800947030499
11 260.0 aligned_500ms aligned 500 264.62022471910115 1.017770095073466 1730 682511 8 4399 69597 13.261018996174682 31 7402.747049027978 16992 24 0.4039387948720048 0.991800947030499
12 230.0 continuous_no_drop continuous -1 258.21380417335473 1.1226687137971945 1703 670280 0 0 0 59.749842696627866 132 34307.118394888734 75969 127 2.547420289855012 1.0
13 230.0 aligned_no_drop aligned -1 264.62022471910115 1.1505227161700051 1738 686910 0 0 0 76.17493190801534 160 43586.68565075366 92568 155 3.1258550724636294 1.0
14 230.0 aligned_1500ms aligned 1500 264.62022471910115 1.1505227161700051 1641 637811 97 49099 321929 59.44779896084508 87 33911.67327808277 50035 81 1.4180637681158217 1.0
15 230.0 aligned_1000ms aligned 1000 264.62022471910115 1.1505227161700051 1609 623057 129 63853 434885 42.60156656500422 63 24223.970784957004 35495 53 0.9048811594201744 1.0
16 230.0 aligned_500ms aligned 500 264.62022471910115 1.1505227161700051 1580 609090 158 77820 532167 20.03526158908224 32 11270.42233914812 18208 27 0.41907246376802476 0.9999999999999993

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,16 @@
channel_kbps,policy,created_frames,published_frames,intentionally_dropped_frames,partially_transmitted_cancelled_frames,published_after_deadline_frames,published_fraction,actual_update_fps,mean_publication_delay_ms,p95_publication_delay_ms,max_publication_delay_ms,mean_display_age_ms,p95_display_age_ms,max_display_age_ms,display_age_over_500ms_fraction,display_age_over_1000ms_fraction,mean_no_update_duration_ms,p95_no_update_duration_ms,max_no_update_duration_ms,mean_missing_run_frames,p95_missing_run_frames,max_missing_run_frames,delivered_useful_video_kbps,wasted_transmitted_video_bytes,receiver_cleared_frames
300.0,continuous_no_drop,63,63,0,0,0,1.0,2.985553772070626,276.3369365079338,322.0720000000001,330.77299999999,437.2938723131218,593.3333333333333,660.0000000000001,0.3142444658325313,0.0,329.6296296296296,388.9899000000025,397.1729999999969,0.0,0.0,0,157.76975922953451,0,0
300.0,aligned_no_drop,63,63,0,0,0,1.0,2.985553772070626,272.2167195767169,293.13066666666225,301.84000000000003,433.2836060314408,589.9999999999999,623.3333333333348,0.30221366698748797,0.0,329.6296296296296,355.05666666666684,406.506333333331,0.0,0.0,0,157.76975922953451,0,0
300.0,aligned_1500ms,63,63,0,0,0,1.0,2.985553772070626,272.2167195767169,293.13066666666225,301.84000000000003,433.2836060314408,589.9999999999999,623.3333333333348,0.30221366698748797,0.0,329.6296296296296,355.05666666666684,406.506333333331,0.0,0.0,0,157.76975922953451,0,0
300.0,aligned_1000ms,63,63,0,0,0,1.0,2.985553772070626,272.2167195767169,293.13066666666225,301.84000000000003,433.2836060314408,589.9999999999999,623.3333333333348,0.30221366698748797,0.0,329.6296296296296,355.05666666666684,406.506333333331,0.0,0.0,0,157.76975922953451,0,0
300.0,aligned_500ms,63,63,0,0,0,1.0,2.985553772070626,272.2167195767169,293.13066666666225,301.84000000000003,433.2836060314408,589.9999999999999,623.3333333333348,0.30221366698748797,0.0,329.6296296296296,355.05666666666684,406.506333333331,0.0,0.0,0,157.76975922953451,0,0
260.0,continuous_no_drop,63,63,0,0,0,1.0,2.937399678972713,351.2176776557015,445.84648717956554,459.55930769245157,509.63907603464884,690.0000000000005,783.3333333333314,0.5312800769971127,0.0,334.9462365591397,401.4781615384583,411.91761538461515,0.0,0.0,0,157.76975922953451,0,0
260.0,aligned_no_drop,63,63,0,0,0,1.0,2.937399678972713,393.259570207603,579.4598205129968,620.584948718161,546.5335258261151,773.833333333333,943.3333333333316,0.62223291626564,0.0,334.9462365591397,363.58000000001095,417.7637692307723,0.0,0.0,0,157.76975922953451,0,0
260.0,aligned_1500ms,63,63,0,0,0,1.0,2.937399678972713,393.259570207603,579.4598205129968,620.584948718161,546.5335258261151,773.833333333333,943.3333333333316,0.62223291626564,0.0,334.9462365591397,363.58000000001095,417.7637692307723,0.0,0.0,0,157.76975922953451,0,0
260.0,aligned_1000ms,63,63,0,0,0,1.0,2.937399678972713,393.259570207603,579.4598205129968,620.584948718161,546.5335258261151,773.833333333333,943.3333333333316,0.62223291626564,0.0,334.9462365591397,363.58000000001095,417.7637692307723,0.0,0.0,0,157.76975922953451,0,0
260.0,aligned_500ms,63,56,7,7,0,0.8888888888888888,2.648475120385233,367.5917000915918,493.7670000001404,498.6567435899403,584.550850176452,1053.8333333333312,1769.9999999999995,0.6212704523580366,0.060153994225216556,370.8333333333333,664.0000000000219,1270.1227435895887,1.4,2.5999999999999996,3,139.5205136436597,69597,7
230.0,continuous_no_drop,63,63,0,0,0,1.0,2.696629213483146,1445.9947550034299,2505.9953623187953,2583.976811594141,1464.8845043310876,2443.8333333333317,2740.000000000002,0.9716073147256978,0.78055822906641,364.32748538011697,437.67652173912944,464.34782608695,0.0,0.0,0,157.76975922953451,0,0
230.0,aligned_no_drop,63,63,0,0,0,1.0,2.6003210272873196,1777.4951000689596,3067.511884057848,3204.707246376671,1723.7872954764196,2913.333333333334,3206.666666666667,0.9735322425409048,0.8267564966313763,377.57575757575756,412.5426086956473,424.00000000000125,0.0,0.0,0,157.76975922953451,0,0
230.0,aligned_1500ms,63,27,36,36,0,0.42857142857142855,1.3001605136436598,1010.3600644122084,1414.757101449207,1473.0202898550094,4028.4071222329167,11064.833333333332,12103.333333333334,0.9735322425409048,0.8267564966313763,741.6666666666666,416.659130434783,10626.97971014499,36.0,36.0,36,66.39987158908507,321929,36
230.0,aligned_1000ms,63,14,49,49,0,0.2222222222222222,0.6741573033707865,734.7155279503047,977.28927536231,995.617391304334,4667.483156881616,11731.499999999998,12770.0,0.9735322425409048,0.8233878729547642,1384.4444444444443,6308.219130434754,11828.788405797173,24.5,36.65,38,34.951781701444624,434885,49
230.0,aligned_500ms,63,3,60,60,0,0.047619047619047616,0.14446227929373998,429.5149758453909,457.5026086956464,460.9971014492756,5508.034969521976,11731.499999999998,12770.0,0.9696823869104908,0.9076034648700674,5191.666666666666,11634.280579710185,12340.614492753682,30.0,37.2,38,7.567126805778492,532167,60
1 channel_kbps policy created_frames published_frames intentionally_dropped_frames partially_transmitted_cancelled_frames published_after_deadline_frames published_fraction actual_update_fps mean_publication_delay_ms p95_publication_delay_ms max_publication_delay_ms mean_display_age_ms p95_display_age_ms max_display_age_ms display_age_over_500ms_fraction display_age_over_1000ms_fraction mean_no_update_duration_ms p95_no_update_duration_ms max_no_update_duration_ms mean_missing_run_frames p95_missing_run_frames max_missing_run_frames delivered_useful_video_kbps wasted_transmitted_video_bytes receiver_cleared_frames
2 300.0 continuous_no_drop 63 63 0 0 0 1.0 2.985553772070626 276.3369365079338 322.0720000000001 330.77299999999 437.2938723131218 593.3333333333333 660.0000000000001 0.3142444658325313 0.0 329.6296296296296 388.9899000000025 397.1729999999969 0.0 0.0 0 157.76975922953451 0 0
3 300.0 aligned_no_drop 63 63 0 0 0 1.0 2.985553772070626 272.2167195767169 293.13066666666225 301.84000000000003 433.2836060314408 589.9999999999999 623.3333333333348 0.30221366698748797 0.0 329.6296296296296 355.05666666666684 406.506333333331 0.0 0.0 0 157.76975922953451 0 0
4 300.0 aligned_1500ms 63 63 0 0 0 1.0 2.985553772070626 272.2167195767169 293.13066666666225 301.84000000000003 433.2836060314408 589.9999999999999 623.3333333333348 0.30221366698748797 0.0 329.6296296296296 355.05666666666684 406.506333333331 0.0 0.0 0 157.76975922953451 0 0
5 300.0 aligned_1000ms 63 63 0 0 0 1.0 2.985553772070626 272.2167195767169 293.13066666666225 301.84000000000003 433.2836060314408 589.9999999999999 623.3333333333348 0.30221366698748797 0.0 329.6296296296296 355.05666666666684 406.506333333331 0.0 0.0 0 157.76975922953451 0 0
6 300.0 aligned_500ms 63 63 0 0 0 1.0 2.985553772070626 272.2167195767169 293.13066666666225 301.84000000000003 433.2836060314408 589.9999999999999 623.3333333333348 0.30221366698748797 0.0 329.6296296296296 355.05666666666684 406.506333333331 0.0 0.0 0 157.76975922953451 0 0
7 260.0 continuous_no_drop 63 63 0 0 0 1.0 2.937399678972713 351.2176776557015 445.84648717956554 459.55930769245157 509.63907603464884 690.0000000000005 783.3333333333314 0.5312800769971127 0.0 334.9462365591397 401.4781615384583 411.91761538461515 0.0 0.0 0 157.76975922953451 0 0
8 260.0 aligned_no_drop 63 63 0 0 0 1.0 2.937399678972713 393.259570207603 579.4598205129968 620.584948718161 546.5335258261151 773.833333333333 943.3333333333316 0.62223291626564 0.0 334.9462365591397 363.58000000001095 417.7637692307723 0.0 0.0 0 157.76975922953451 0 0
9 260.0 aligned_1500ms 63 63 0 0 0 1.0 2.937399678972713 393.259570207603 579.4598205129968 620.584948718161 546.5335258261151 773.833333333333 943.3333333333316 0.62223291626564 0.0 334.9462365591397 363.58000000001095 417.7637692307723 0.0 0.0 0 157.76975922953451 0 0
10 260.0 aligned_1000ms 63 63 0 0 0 1.0 2.937399678972713 393.259570207603 579.4598205129968 620.584948718161 546.5335258261151 773.833333333333 943.3333333333316 0.62223291626564 0.0 334.9462365591397 363.58000000001095 417.7637692307723 0.0 0.0 0 157.76975922953451 0 0
11 260.0 aligned_500ms 63 56 7 7 0 0.8888888888888888 2.648475120385233 367.5917000915918 493.7670000001404 498.6567435899403 584.550850176452 1053.8333333333312 1769.9999999999995 0.6212704523580366 0.060153994225216556 370.8333333333333 664.0000000000219 1270.1227435895887 1.4 2.5999999999999996 3 139.5205136436597 69597 7
12 230.0 continuous_no_drop 63 63 0 0 0 1.0 2.696629213483146 1445.9947550034299 2505.9953623187953 2583.976811594141 1464.8845043310876 2443.8333333333317 2740.000000000002 0.9716073147256978 0.78055822906641 364.32748538011697 437.67652173912944 464.34782608695 0.0 0.0 0 157.76975922953451 0 0
13 230.0 aligned_no_drop 63 63 0 0 0 1.0 2.6003210272873196 1777.4951000689596 3067.511884057848 3204.707246376671 1723.7872954764196 2913.333333333334 3206.666666666667 0.9735322425409048 0.8267564966313763 377.57575757575756 412.5426086956473 424.00000000000125 0.0 0.0 0 157.76975922953451 0 0
14 230.0 aligned_1500ms 63 27 36 36 0 0.42857142857142855 1.3001605136436598 1010.3600644122084 1414.757101449207 1473.0202898550094 4028.4071222329167 11064.833333333332 12103.333333333334 0.9735322425409048 0.8267564966313763 741.6666666666666 416.659130434783 10626.97971014499 36.0 36.0 36 66.39987158908507 321929 36
15 230.0 aligned_1000ms 63 14 49 49 0 0.2222222222222222 0.6741573033707865 734.7155279503047 977.28927536231 995.617391304334 4667.483156881616 11731.499999999998 12770.0 0.9735322425409048 0.8233878729547642 1384.4444444444443 6308.219130434754 11828.788405797173 24.5 36.65 38 34.951781701444624 434885 49
16 230.0 aligned_500ms 63 3 60 60 0 0.047619047619047616 0.14446227929373998 429.5149758453909 457.5026086956464 460.9971014492756 5508.034969521976 11731.499999999998 12770.0 0.9696823869104908 0.9076034648700674 5191.666666666666 11634.280579710185 12340.614492753682 30.0 37.2 38 7.567126805778492 532167 60

View File

@@ -0,0 +1,224 @@
"""Frame-aware stale-video policy for the Lab034 shared link queue.
The scheduler remains strict-priority, state-replacing, and non-preemptive.
Unlike Lab033, packet availability is separate from the timestamp stored in
the common header. Every aligned video packet therefore carries the source
composite-frame generation time while FEC construction metadata remains local
to the scheduler.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Iterable
from protocol.link_packet import HEADER_SIZE, LinkPacket, TrafficClass, encode_link_packet
from protocol.priority_scheduler import transmission_duration_seconds
TIME_EPSILON_SECONDS = 1e-12
@dataclass(frozen=True)
class AgePolicyPacket:
"""A common packet plus non-serialized availability/frame metadata."""
packet: LinkPacket
arrival_order: int
available_time_us: int
composite_frame_id: int | None = None
@property
def available_time_seconds(self) -> float:
return self.available_time_us / 1_000_000.0
@property
def frame_generation_seconds(self) -> float:
return self.packet.generation_time_us / 1_000_000.0
@property
def wire_size_bytes(self) -> int:
return HEADER_SIZE + len(self.packet.payload)
@dataclass(frozen=True)
class StateReplacement:
removed: AgePolicyPacket
replacement: AgePolicyPacket
time_seconds: float
@dataclass(frozen=True)
class DroppedVideoPacket:
item: AgePolicyPacket
drop_time_seconds: float
@dataclass(frozen=True)
class AgeScheduledPacket:
item: AgePolicyPacket
start_seconds: float
end_seconds: float
blocked_by: AgePolicyPacket | None
blocking_delay_seconds: float
wire_packet: bytes
@dataclass(frozen=True)
class AgeScheduleResult:
channel_bitrate_bps: float
max_video_age_seconds: float | None
transmitted: tuple[AgeScheduledPacket, ...]
dropped_video: tuple[DroppedVideoPacket, ...]
replacements: tuple[StateReplacement, ...]
def _enqueue(
ready: list[AgePolicyPacket],
item: AgePolicyPacket,
replacements: list[StateReplacement],
) -> None:
if item.packet.traffic_class in (TrafficClass.CONTROL, TrafficClass.TELEMETRY):
retained = []
for old in ready:
if (
old.packet.traffic_class == item.packet.traffic_class
and old.packet.stream_id == item.packet.stream_id
):
replacements.append(
StateReplacement(old, item, item.available_time_seconds)
)
else:
retained.append(old)
ready[:] = retained
ready.append(item)
def schedule_with_video_age(
packets: Iterable[AgePolicyPacket],
channel_bitrate_bps: float,
max_video_age_seconds: float | None,
) -> AgeScheduleResult:
"""Run a strict-priority non-preemptive scheduler with frame drops.
At every packet-selection instant all queued packets belonging to a video
frame older than ``max_video_age_seconds`` are removed together. An active
packet has already left the queue and is never interrupted.
"""
if channel_bitrate_bps <= 0.0:
raise ValueError("channel bitrate must be positive")
if max_video_age_seconds is not None and max_video_age_seconds <= 0.0:
raise ValueError("maximum video age must be positive")
arrivals = sorted(
tuple(packets),
key=lambda item: (item.available_time_seconds, item.arrival_order),
)
if len({item.arrival_order for item in arrivals}) != len(arrivals):
raise ValueError("arrival_order values must be unique")
for item in arrivals:
if item.packet.traffic_class is TrafficClass.VIDEO:
if item.composite_frame_id is None:
raise ValueError("video packet lacks composite_frame_id")
elif item.composite_frame_id is not None:
raise ValueError("non-video packet has composite_frame_id")
ready: list[AgePolicyPacket] = []
transmitted: list[AgeScheduledPacket] = []
dropped: list[DroppedVideoPacket] = []
replacements: list[StateReplacement] = []
blocker_by_order: dict[int, tuple[AgePolicyPacket, float]] = {}
dropped_frames: set[int] = set()
arrival_index = 0
cursor = 0.0
def admit_until(limit: float, active: AgePolicyPacket | None = None, active_end: float = 0.0) -> None:
nonlocal arrival_index
while (
arrival_index < len(arrivals)
and arrivals[arrival_index].available_time_seconds
<= limit + TIME_EPSILON_SECONDS
):
item = arrivals[arrival_index]
arrival_index += 1
if (
active is not None
and item.available_time_seconds > cursor + TIME_EPSILON_SECONDS
):
blocker_by_order[item.arrival_order] = (
active,
max(0.0, active_end - item.available_time_seconds),
)
if item.composite_frame_id in dropped_frames:
dropped.append(DroppedVideoPacket(item, limit))
else:
_enqueue(ready, item, replacements)
def expire_video(now: float) -> None:
if max_video_age_seconds is None:
return
expired_frames = {
item.composite_frame_id
for item in ready
if (
item.packet.traffic_class is TrafficClass.VIDEO
and now - item.frame_generation_seconds
> max_video_age_seconds + TIME_EPSILON_SECONDS
)
}
if not expired_frames:
return
retained = []
for item in ready:
if item.composite_frame_id in expired_frames:
dropped.append(DroppedVideoPacket(item, now))
assert item.composite_frame_id is not None
dropped_frames.add(item.composite_frame_id)
else:
retained.append(item)
ready[:] = retained
while arrival_index < len(arrivals) or ready:
if not ready:
cursor = max(cursor, arrivals[arrival_index].available_time_seconds)
admit_until(cursor)
expire_video(cursor)
if not ready:
continue
selected_index = min(
range(len(ready)),
key=lambda index: (
int(ready[index].packet.traffic_class),
ready[index].arrival_order,
),
)
selected = ready.pop(selected_index)
start = max(cursor, selected.available_time_seconds)
wire_packet = encode_link_packet(selected.packet)
end = start + transmission_duration_seconds(
len(wire_packet), channel_bitrate_bps
)
cursor = start
admit_until(end, selected, end)
blocker, blocking_delay = blocker_by_order.get(
selected.arrival_order, (None, 0.0)
)
transmitted.append(
AgeScheduledPacket(
item=selected,
start_seconds=start,
end_seconds=end,
blocked_by=blocker,
blocking_delay_seconds=blocking_delay,
wire_packet=wire_packet,
)
)
cursor = end
return AgeScheduleResult(
channel_bitrate_bps=channel_bitrate_bps,
max_video_age_seconds=max_video_age_seconds,
transmitted=tuple(transmitted),
dropped_video=tuple(dropped),
replacements=tuple(replacements),
)

File diff suppressed because it is too large Load Diff