Skip to content

Commit 2ea24ca

Browse files
committed
Record and display VMAF runner timing instead of overall task timing
1 parent e27151c commit 2ea24ca

3 files changed

Lines changed: 41 additions & 8 deletions

File tree

changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
**<span style="color:#56adda">0.0.4</span>**
2+
- Record and display VMAF runner timing instead of overall task timing
3+
14
**<span style="color:#56adda">0.0.3</span>**
25
- Added file sampling controls with a two-option dropdown for whole-file analysis or sampled one-minute chunks
36
- Added a conditional sample-count slider to control how many one-minute chunks are compared across the timeline

info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
"render_frontend_panel": 1
1717
},
1818
"tags": "video,plex,dvr,ffmpeg,data panel,test",
19-
"version": "0.0.3"
19+
"version": "0.0.4"
2020
}

plugin.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
PLUGIN_ID = "vmaf_quality_audit"
4747
STATE_KEY_RESULT = "analysis_result"
48+
STATE_KEY_TIMING = "analysis_timing"
4849
DEFAULT_FFMPEG = "/usr/lib/btbn-ffmpeg/bin/ffmpeg"
4950
DEFAULT_FFPROBE = "/usr/lib/btbn-ffmpeg/bin/ffprobe"
5051

@@ -698,7 +699,7 @@ def _run_vmaf_audit_child(
698699
"file_sampling_mode": sampling_mode,
699700
"file_sampling_count": sampling_count,
700701
"file_sampling_windows": sample_windows,
701-
"captured_at": datetime.datetime.utcnow().isoformat() + "Z",
702+
"captured_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
702703
}
703704
_write_json_file(result_path, result_payload)
704705
except Exception as exc:
@@ -722,7 +723,7 @@ def _run_vmaf_audit_child(
722723
_coerce_int(settings_payload.get("file_sampling_count"), 5), 1
723724
),
724725
"file_sampling_windows": [],
725-
"captured_at": datetime.datetime.utcnow().isoformat() + "Z",
726+
"captured_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
726727
}
727728
_write_json_file(result_path, failure_payload)
728729
raise
@@ -1102,17 +1103,31 @@ def _persist_audit_record(task_data_store, data):
11021103

11031104
source_path = _get_abspath(data.get("source_data", {}).get("abspath"))
11041105
destination_files = _build_destination_file_data(_event_destination_files(data))
1106+
analysis_timing = (
1107+
task_data_store.get_task_state(
1108+
STATE_KEY_TIMING, default={}, task_id=data.get("task_id")
1109+
)
1110+
or {}
1111+
)
11051112
finish_time = (
1106-
datetime.datetime.fromtimestamp(data["finish_time"])
1107-
if data.get("finish_time")
1113+
datetime.datetime.fromtimestamp(analysis_timing["finish_time"])
1114+
if analysis_timing.get("finish_time")
11081115
else None
11091116
)
11101117
start_time = (
1111-
datetime.datetime.fromtimestamp(data["start_time"])
1112-
if data.get("start_time")
1118+
datetime.datetime.fromtimestamp(analysis_timing["start_time"])
1119+
if analysis_timing.get("start_time")
11131120
else None
11141121
)
1115-
test_duration_seconds = _duration_seconds(start_time, finish_time)
1122+
test_duration_seconds = _coerce_float(analysis_timing.get("duration_seconds"))
1123+
if test_duration_seconds is None:
1124+
test_duration_seconds = _duration_seconds(start_time, finish_time)
1125+
if start_time is None and data.get("start_time"):
1126+
start_time = datetime.datetime.fromtimestamp(data["start_time"])
1127+
if finish_time is None and data.get("finish_time"):
1128+
finish_time = datetime.datetime.fromtimestamp(data["finish_time"])
1129+
if test_duration_seconds is None:
1130+
test_duration_seconds = _duration_seconds(start_time, finish_time)
11161131

11171132
source_video = analysis.get("source_video") or {}
11181133
output_video = analysis.get("output_video") or {}
@@ -1290,6 +1305,7 @@ def child_work(source_path, log_queue=None, prog_queue=None):
12901305
data.get("worker_log", []).append(f"\n{warning_message}\n")
12911306
if task_data_store is not None:
12921307
task_data_store.set_task_state(STATE_KEY_RESULT, None)
1308+
task_data_store.set_task_state(STATE_KEY_TIMING, None)
12931309
return
12941310

12951311
result = {
@@ -1303,6 +1319,14 @@ def child_work(source_path, log_queue=None, prog_queue=None):
13031319
"vmaf_summary": {},
13041320
"vmaf_frames": [],
13051321
}
1322+
analysis_start_time = datetime.datetime.now(datetime.timezone.utc)
1323+
analysis_timing = {
1324+
"start_time": analysis_start_time.timestamp(),
1325+
"finish_time": None,
1326+
"duration_seconds": None,
1327+
}
1328+
if task_data_store is not None:
1329+
task_data_store.set_task_state(STATE_KEY_TIMING, analysis_timing)
13061330

13071331
try:
13081332
result = _run_vmaf_audit(source_path, encoded_path, plugin_settings, data)
@@ -1315,6 +1339,12 @@ def child_work(source_path, log_queue=None, prog_queue=None):
13151339
raise
13161340
finally:
13171341
if task_data_store is not None:
1342+
analysis_finish_time = datetime.datetime.now(datetime.timezone.utc)
1343+
analysis_timing["finish_time"] = analysis_finish_time.timestamp()
1344+
analysis_timing["duration_seconds"] = round(
1345+
(analysis_finish_time - analysis_start_time).total_seconds(), 3
1346+
)
1347+
task_data_store.set_task_state(STATE_KEY_TIMING, analysis_timing)
13181348
task_data_store.set_task_state(STATE_KEY_RESULT, result)
13191349

13201350

0 commit comments

Comments
 (0)