Files
SDR-Rover/tools/video_report_table.py

92 lines
5.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Обновить числовую таблицу VIDEO-001 по сохранённым результатам."""
from __future__ import annotations
import argparse
from collections import defaultdict
import json
from pathlib import Path
MATRIX = (((320, 240), (5, 10, 15)), ((640, 360), (5, 10, 15)),
((640, 480), (5, 10)), ((854, 480), (5, 10)), ((1280, 720), (5,)))
# Это качественные оценки контрольных кадров, а не результат автоматической метрики.
QUALITY = {
(320, 240, "jpeg"): "Ближние машины и полоса видны; дальние предметы мелки",
(320, 240, "160k"): "Ближние машины и направление видны; мелкие детали ограничены",
(320, 240, "320k"): "Почти тот же вид, что при 160k",
(640, 360, "jpeg"): "Машины и разметка видны; крупный поток",
(640, 360, "160k"): "Машины видны; текстура дороги размыта при движении",
(640, 360, "320k"): "Машины, полоса и направление различимы",
(640, 480, "jpeg"): "Машины видны; чёрные поля 60 пикселей",
(640, 480, "160k"): "Машины видны; поля и размытие деталей",
(640, 480, "320k"): "Машины видны; полезная область как 640×360",
(854, 480, "jpeg"): "Машины и разметка чётче; крупный поток",
(854, 480, "160k"): "Ближние машины видны; дальние детали размыты",
(854, 480, "320k"): "Машины, полосы и направление хорошо различимы",
(1280, 720, "jpeg"): "Машины и разметка подробны; поток велик",
(1280, 720, "160k"): "Машины видны; разрешение не даёт ожидаемой детализации",
(1280, 720, "320k"): "Машины и разметка видны; дальние надписи не проверены",
}
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--comparison-160k", type=Path, required=True)
parser.add_argument("--comparison-320k", type=Path, required=True)
parser.add_argument("--report", type=Path, required=True)
arguments = parser.parse_args()
datasets = {
code: json.loads(path.read_text(encoding="utf-8"))
for code, path in (("160k", arguments.comparison_160k),
("320k", arguments.comparison_320k))
}
if datasets["160k"]["source_sha256"] != datasets["320k"]["source_sha256"]:
raise ValueError("Наборы сравнения используют разные исходные ролики")
if datasets["160k"]["windows"] != datasets["320k"]["windows"]:
raise ValueError("Наборы сравнения используют разные участки ролика")
cases = defaultdict(list)
for code, dataset in datasets.items():
for case in dataset["cases"]:
key = (tuple(case["resolution"]), case["fps"], case["codec"], code)
cases[key].append(case)
rows = [
"| Разрешение | FPS | Кодек | Средний поток | Пик 1 с | Кодирование | "
"Декодирование | Качество для оператора | FITS CURRENT RADIO BUDGET |",
"|---|---:|---|---:|---:|---:|---:|---|---|",
]
for resolution, rates in MATRIX:
for fps in rates:
for codec, code, label, quality_code in (
("JPEG_INDEPENDENT", "160k", "JPEG q35", "jpeg"),
("H264_LIBX264", "160k", "H.264 160k", "160k"),
("H264_LIBX264", "320k", "H.264 320k", "320k"),
):
pair = cases[(resolution, fps, codec, code)]
if len(pair) != 2:
raise ValueError(f"Ожидались два участка: {resolution}, {fps}, {label}")
average = max(case["average_bitrate_bps"] for case in pair) / 1000
peak = max(case["peak_one_second_bitrate_bps"] for case in pair) / 1000
encode = max(case["encode_time_per_frame_s"]["mean"] for case in pair) * 1000
decode = max(case["decode_time_per_frame_s"]["mean"] for case in pair) * 1000
if any(case["radio_screen"]["fits_current_radio_budget"] !=
"NO_ON_OBSERVED_BURST_SCREEN" for case in pair):
raise ValueError(f"Недостаточно оснований для НЕТ: {resolution}, {fps}, {label}")
quality = QUALITY[(*resolution, quality_code)]
encode_text = f"{encode:.1f}".replace(".", ",")
decode_text = f"{decode:.1f}".replace(".", ",")
rows.append(f"| {resolution[0]}×{resolution[1]} | {fps} | {label} | "
f"{average:.0f} | {peak:.0f} | "
f"{encode_text} | {decode_text} | {quality} | НЕТ |")
report = arguments.report.read_text(encoding="utf-8")
start = report.index("| Разрешение | FPS | Кодек |")
end = report.index("\n\n", start)
arguments.report.write_text(report[:start] + "\n".join(rows) + report[end:],
encoding="utf-8")
print(f"Обновлено строк таблицы: {len(rows) - 2}")
if __name__ == "__main__":
main()