perf: reduce NV12 per-frame copies from 5 to 2 via single from_buffer_copy + byref offset

This commit is contained in:
Matteo Benedetto
2026-03-24 00:47:32 +01:00
parent ecdbf5eb04
commit a201594a90
2 changed files with 44 additions and 31 deletions
+11 -6
View File
@@ -11,7 +11,11 @@ mppvideodec auto-selected) and reports:
• A/V sync drift (video PTS vs pipeline clock position)
• from_buffer_copy() time per frame (CPU copy cost)
Run on device:
Run on device (must use same env as the app):
export LD_LIBRARY_PATH=/home/ark/miniconda3/envs/r36s-dlna-browser/lib
export GST_PLUGIN_PATH=/usr/lib/aarch64-linux-gnu/gstreamer-1.0
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgomp.so.1
export PYTHONPATH=/home/ark/R36SHack/src
/home/ark/miniconda3/envs/r36s-dlna-browser/bin/python \\
/home/ark/R36SHack/tests/benchmark_nv12_decode.py [URL]
@@ -186,12 +190,13 @@ def _on_sample(sink) -> Gst.FlowReturn:
if fmt_str == "NV12":
y_size = int(info.stride[0]) * int(info.height)
uv_size = int(info.stride[1]) * (int(info.height) // 2)
# Simulate named c_ubyte array creation (the actual upload path)
# Simulate the single from_buffer_copy the app now does:
# ONE copy of the full Y+UV buffer, then ctypes.byref for the UV offset.
t1 = time.monotonic()
y_arr = (ctypes.c_ubyte * len(raw[:y_size])).from_buffer_copy(raw[:y_size])
uv_arr = (ctypes.c_ubyte * len(raw[y_size:y_size+uv_size])).from_buffer_copy(raw[y_size:y_size+uv_size])
copy_us = (time.monotonic() - t1) * 1e6 # override with NV12-specific copy
arr = (ctypes.c_ubyte * len(raw)).from_buffer_copy(raw)
y_ptr = ctypes.cast(arr, ctypes.POINTER(ctypes.c_ubyte))
uv_ptr = ctypes.cast(ctypes.byref(arr, y_size), ctypes.POINTER(ctypes.c_ubyte))
copy_us = (time.monotonic() - t1) * 1e6
with stats.lock:
stats.total_frames += 1