fix(bench): del ctypes/bytes objects immediately in callback to prevent OOM on 1GB device
This commit is contained in:
@@ -183,20 +183,23 @@ def _on_sample(sink) -> Gst.FlowReturn:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Measure from_buffer_copy() cost (the CPU copy the app does)
|
# Measure extract_dup (GStreamer buf → Python bytes) + from_buffer_copy
|
||||||
|
# (Python bytes → ctypes array for SDL upload). del objects immediately
|
||||||
|
# after timing so CPython's ref-counting frees the 3+ MB allocations at
|
||||||
|
# once rather than letting them accumulate across frames (OOM on 1 GB device).
|
||||||
t0 = time.monotonic()
|
t0 = time.monotonic()
|
||||||
raw = buf.extract_dup(0, buf.get_size())
|
raw = buf.extract_dup(0, buf.get_size())
|
||||||
copy_us = (time.monotonic() - t0) * 1e6
|
extract_us = (time.monotonic() - t0) * 1e6
|
||||||
|
|
||||||
if fmt_str == "NV12":
|
if fmt_str == "NV12":
|
||||||
y_size = int(info.stride[0]) * int(info.height)
|
y_size = int(info.stride[0]) * int(info.height)
|
||||||
# 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()
|
t1 = time.monotonic()
|
||||||
arr = (ctypes.c_ubyte * len(raw)).from_buffer_copy(raw)
|
arr = (ctypes.c_ubyte * len(raw)).from_buffer_copy(raw)
|
||||||
y_ptr = ctypes.cast(arr, ctypes.POINTER(ctypes.c_ubyte))
|
copy_us = extract_us + (time.monotonic() - t1) * 1e6
|
||||||
uv_ptr = ctypes.cast(ctypes.byref(arr, y_size), ctypes.POINTER(ctypes.c_ubyte))
|
del arr # free 3 MB ctypes array immediately
|
||||||
copy_us = (time.monotonic() - t1) * 1e6
|
else:
|
||||||
|
copy_us = extract_us
|
||||||
|
del raw # free 3 MB bytes object immediately
|
||||||
|
|
||||||
with stats.lock:
|
with stats.lock:
|
||||||
stats.total_frames += 1
|
stats.total_frames += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user