qsvh265dec memory leak, bad use of gst_memory_new_wrapped
Describe your issue
A severe memory leak occurs when using qsvh265dec or qsvh264dec, leaking the full incoming bitstream.
Expected Behavior
No memory leak
Observed Behavior
Memory leak equal to bitrate of h265 stream.
Setup
- Operating System: Windows (Linux also impacted)
- Device: Computer
- GStreamer Version: 1.24.2, 1.22
- Command line: gst-launch-1.0 filesrc location=test1.mov ! qtdemux ! h265parse ! qsvh265dec ! autovideosink (or any h265 stream)
Steps to reproduce the bug
- Get a computer with Intel QSV support
- Play a h265 or h264 stream
- Observe memory leak
How reproducible is the bug?
Always, when using qsvh265dec or qsvh264dec
Screenshots if relevant
Solutions you have tried
Replacing nullptr
in gstqsvh265dec.cpp:424 with data
, solved the memory leak. When the reference count of the created GstMemory
becomes zero, g_free(NULL)
is called, instead of g_free(data)
. So data
is not being freed, creating the memory leak.
Related non-duplicate issues
- #3163 (closed)
- !6583 (merged) I suggested in #3163 (closed) that frame objects were leaking, but I spoke too soon. After closer inspection of the debug output, I found that frames were not leaking. The output of gstqsvdecoder.cpp:584 also always prints 0 frames. So !6583 (merged) should be reverted, because it is now just unnecessary code.
Additional Information
With VMMap.exe I traced heap allocations, and saw a lot of allocations from gstqsvh265dec.cpp:419.
So I looked at the code again, and found that GstMemory *gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data, gsize maxsize, gsize offset, gsize size, gpointer user_data, GDestroyNotify notify)
is not used correctly. The author probably assumed notify
would be called as notify(data, user_data)
, but notify is only called with user_data
, which is passed as NULL
instead of data
. After recompiling gst-plugins-bad from source with data
instead of nullptr
, the memory leak was gone.
I looked through the source code to find more bad uses of gst_memory_new_wrapped, and only found one, in gstqsvh264dec.cpp, which seems like just a copy of the h265 implementation (probably the other way around). So qsvh264dec will also leak the input bitstream.