Pausing video playback causes egl images leak.
Posted: 29 Aug 2024 10:14
Hello,
Appear to have found a bug...
I captured an API trace of vlc.
From the trace, it can be observed that during normal playback, VLC calls eglDestroyImageKHR to destroy the EGL images created for each frame.
However, when playback is paused, VLC does not invoke eglDestroyImageKHR to deallocate the EGL images, which results in leaks of EGL images and significant GPU memory leakage.
I have coded a patch to address this issue, which correctly releases the EGL images upon pausing playback.
Here's a bunch of info:
os: ubuntu
hwdec: vaapi
vlc version: 3.0.20
Appear to have found a bug...
I captured an API trace of vlc.
Code: Select all
apitrace trace -a egl -o vlc.trace vlc h264_4k_60fps.mp4
From the trace, it can be observed that during normal playback, VLC calls eglDestroyImageKHR to destroy the EGL images created for each frame.
Code: Select all
7171 eglMakeCurrent(dpy = 0x7ffa2424aac0, draw = NULL, read = NULL, ctx = NULL) = EGL_TRUE
7172 eglMakeCurrent(dpy = 0x7ffa2424aac0, draw = 0x7ffa243a3ca0, read = 0x7ffa243a3ca0, ctx = 0x7ffa243a4320) = EGL_TRUE
7173 eglCreateImageKHR(dpy = 0x7ffa2424aac0, ctx = NULL, target = EGL_LINUX_DMA_BUF_EXT, buffer = NULL, attrib_list = {EGL_WIDTH, 3840, EGL_HEIGHT, 2160, EGL_LINUX_DRM_FOURCC_EXT, 538982482, EGL_DMA_BUF_PLANE0_FD_EXT, 38, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, 3840, EGL_NONE}) = 0x7ffa24d3f870
7174 glBindTexture(target = GL_TEXTURE_2D, texture = 1)
7175 glEGLImageTargetTexture2DOES(target = GL_TEXTURE_2D, image = 0x7ffa24d3f870)
7176 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_RGBA, width = 3840, height = 2160, border = 0, format = GL_RGBA, type = GL_UNSIGNED_BYTE, pixels = blob(33177600)) // fake
7177 eglCreateImageKHR(dpy = 0x7ffa2424aac0, ctx = NULL, target = EGL_LINUX_DMA_BUF_EXT, buffer = NULL, attrib_list = {EGL_WIDTH, 1920, EGL_HEIGHT, 1080, EGL_LINUX_DRM_FOURCC_EXT, 943215175, EGL_DMA_BUF_PLANE0_FD_EXT, 38, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 8355840, EGL_DMA_BUF_PLANE0_PITCH_EXT, 3840, EGL_NONE}) = 0x7ffa24d33960
7178 glBindTexture(target = GL_TEXTURE_2D, texture = 2)
7179 glEGLImageTargetTexture2DOES(target = GL_TEXTURE_2D, image = 0x7ffa24d33960)
7180 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_RGBA, width = 1920, height = 1080, border = 0, format = GL_RGBA, type = GL_UNSIGNED_BYTE, pixels = blob(8294400)) // fake
7181 eglDestroyImageKHR(dpy = 0x7ffa2424aac0, image = 0x7ffa24d44e00) = EGL_TRUE
7182 eglDestroyImageKHR(dpy = 0x7ffa2424aac0, image = 0x7ffa24a9aca0) = EGL_TRUE
7183 eglMakeCurrent(dpy = 0x7ffa2424aac0, draw = NULL, read = NULL, ctx = NULL) = EGL_TRUE
7184 eglMakeCurrent(dpy = 0x7ffa2424aac0, draw = 0x7ffa243a3ca0, read = 0x7ffa243a3ca0, ctx = 0x7ffa243a4320) = EGL_TRUE
Code: Select all
20228 eglMakeCurrent(dpy = 0x7ffa2424aac0, draw = NULL, read = NULL, ctx = NULL) = EGL_TRUE
20229 eglMakeCurrent(dpy = 0x7ffa2424aac0, draw = 0x7ffa243a3ca0, read = 0x7ffa243a3ca0, ctx = 0x7ffa243a4320) = EGL_TRUE
20230 eglCreateImageKHR(dpy = 0x7ffa2424aac0, ctx = NULL, target = EGL_LINUX_DMA_BUF_EXT, buffer = NULL, attrib_list = {EGL_WIDTH, 3840, EGL_HEIGHT, 2160, EGL_LINUX_DRM_FOURCC_EXT, 538982482, EGL_DMA_BUF_PLANE0_FD_EXT, 38, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, 3840, EGL_NONE}) = 0x7ffa24bbcec0
20231 glBindTexture(target = GL_TEXTURE_2D, texture = 1)
20232 glEGLImageTargetTexture2DOES(target = GL_TEXTURE_2D, image = 0x7ffa24bbcec0)
20233 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_RGBA, width = 3840, height = 2160, border = 0, format = GL_RGBA, type = GL_UNSIGNED_BYTE, pixels = blob(33177600)) // fake
20234 eglCreateImageKHR(dpy = 0x7ffa2424aac0, ctx = NULL, target = EGL_LINUX_DMA_BUF_EXT, buffer = NULL, attrib_list = {EGL_WIDTH, 1920, EGL_HEIGHT, 1080, EGL_LINUX_DRM_FOURCC_EXT, 943215175, EGL_DMA_BUF_PLANE0_FD_EXT, 38, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 8355840, EGL_DMA_BUF_PLANE0_PITCH_EXT, 3840, EGL_NONE}) = 0x7ffa24bb6710
20235 glBindTexture(target = GL_TEXTURE_2D, texture = 2)
20236 glEGLImageTargetTexture2DOES(target = GL_TEXTURE_2D, image = 0x7ffa24bb6710)
20237 glTexImage2D(target = GL_TEXTURE_2D, level = 0, internalformat = GL_RGBA, width = 1920, height = 1080, border = 0, format = GL_RGBA, type = GL_UNSIGNED_BYTE, pixels = blob(8294400)) // fake
20238 eglMakeCurrent(dpy = 0x7ffa2424aac0, draw = NULL, read = NULL, ctx = NULL) = EGL_TRUE
20239 eglMakeCurrent(dpy = 0x7ffa2424aac0, draw = 0x7ffa243a3ca0, read = 0x7ffa243a3ca0, ctx = 0x7ffa243a4320) = EGL_TRUE
Code: Select all
--- modules/video_output/opengl/converter_vaapi.c 2024-08-23 11:31:33.354136404 +0800
+++ modules/video_output/opengl/converter_vaapi.c 2024-08-23 11:31:57.614745863 +0800
@@ -282,6 +282,14 @@
for (unsigned i = 0; i < va_image.num_planes; ++i)
priv->last.egl_images[i] = egl_images[i];
}
+ else
+ {
+ for (unsigned i = 0; i < priv->last.va_image.num_planes; ++i)
+ vaegl_image_destroy(tc, priv->last.egl_images[i]);
+
+ for (unsigned i = 0; i < va_image.num_planes; ++i)
+ priv->last.egl_images[i] = egl_images[i];
+ }
return VLC_SUCCESS;
Here's a bunch of info:
os: ubuntu
hwdec: vaapi
vlc version: 3.0.20