Complete VIDEO-001 through VIDEO-004 software video studies

This commit is contained in:
LittleSam129
2026-09-16 18:27:35 +03:00
parent af7c05f2da
commit 95f664076a
403 changed files with 392009 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
"""Обновить числовую таблицу 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()