From 5332ce98802b11d4c068f7da66cbac611aa50b50 Mon Sep 17 00:00:00 2001 From: Matteo Benedetto Date: Tue, 24 Mar 2026 00:31:44 +0100 Subject: [PATCH] fix: use named c_ubyte arrays to prevent dangling pointer segfault in SDL_UpdateNVTexture --- .../player/gstreamer_backend.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/r36s_dlna_browser/player/gstreamer_backend.py b/src/r36s_dlna_browser/player/gstreamer_backend.py index 0bf58bc..30a5247 100644 --- a/src/r36s_dlna_browser/player/gstreamer_backend.py +++ b/src/r36s_dlna_browser/player/gstreamer_backend.py @@ -246,24 +246,22 @@ class GStreamerBackend(PlayerBackend): if frame.pixel_format == "NV12" and frame.uv_pixels is not None: # Zero-copy NV12 path: upload Y and UV planes separately. # SDL_UpdateNVTexture avoids a full BGRA conversion on CPU. - # ctypes.create_string_buffer returns c_char_Array_N; cast to - # LP_c_ubyte which SDL_UpdateNVTexture requires. + # Use named c_ubyte arrays so the buffers stay alive for the + # duration of the C call (ctypes.cast of a temporary would produce + # a dangling pointer after CPython reference-counts the temp away). try: - _ubyte_p = ctypes.POINTER(ctypes.c_ubyte) - y_data = bytes(frame.pixels) - uv_data = bytes(frame.uv_pixels) - y_buf = ctypes.cast(ctypes.create_string_buffer(y_data), _ubyte_p) - uv_buf = ctypes.cast(ctypes.create_string_buffer(uv_data), _ubyte_p) + y_arr = (ctypes.c_ubyte * len(frame.pixels)).from_buffer_copy(frame.pixels) + uv_arr = (ctypes.c_ubyte * len(frame.uv_pixels)).from_buffer_copy(frame.uv_pixels) log.debug( "SDL_UpdateNVTexture: %dx%d y_len=%d uv_len=%d pitch=%d uv_pitch=%d", frame.width, frame.height, - len(y_data), len(uv_data), + len(frame.pixels), len(frame.uv_pixels), frame.pitch, frame.uv_pitch, ) result = sdl2.SDL_UpdateNVTexture( self._texture, None, - y_buf, frame.pitch, - uv_buf, frame.uv_pitch, + y_arr, frame.pitch, + uv_arr, frame.uv_pitch, ) except Exception: log.error(