GNOME Bugzilla – Bug 736758
Memory leak when switching between MPEG2 TS streams
Last modified: 2014-11-08 14:10:25 UTC
Created attachment 286309 [details] qmlplayer3 test app I found a memory leak with qt-gstreamer 1.2.0 using the qtquick2videosink. On my laptop and on some i.MX6 board I clearly see that on every "switch" from one MPEG2 TS stream to another main memory is consumed and not freed. I created a test app which reproduces the behaviour. (see qmlplayer3.tar.bz2) This app simulates stream switches using a timer. This means every 3 seconds the pipeline is stopped, the uri is changed and the pipeline is restarted. Two example streams can be found at: https://www.dropbox.com/s/fia0e3ozky5udqr/stream_239.4.1.8_dump.ts?dl=0 https://www.dropbox.com/s/9p8ktvs5dq7wzbw/stream_239.8.1.2_dump.ts?dl=0 With qt-gstreamer and Qt 5.x do: $> tar -xf qmlplayer3.tar.bz2 $> cd qmlplayer3 $> qmake $> make $> ./qmlplayer3 file:///tmp/stream_239.4.1.8_dump.ts file:///tmp/stream_239.8.1.2_dump.ts (click start and see with free -m the memory consumptions raises) I can fix this by changing in the elements/gstqtvideosink/delegates/basedelegate.cpp in the DeactivateEventType case the line g_clear_pointer(&m_buffer, gst_buffer_unref); to gst_buffer_unref(m_buffer); After this change I see that main memory is consumed but also freed after every stream switch.
It seems that I have found the memory leak. There is a missing gst_buffer_unref() in the destructor of VideoMaterial (qtquick2videosink - elements/gstqtvideosink/painters/videomaterial.cpp). After setting the pipeline to state NULL the current VideoMaterial (with the frame data) will be deleted and the QSGMaterial of the current QSGVideoNode is set to QSGFlatColorMaterial. In the process of deleting the VideoMaterial there is still one reference on the GstBuffer frame data. As soon the playback starts again and a new VideoMaterial is created new memory is allocated and the old was not freed. Adding a gst_buffer_ref() ind VideoMaterial::~Videomaterial frees the buffer correctly. B.t.w. the above change from g_clear_pointer() to gst_buffer_unref() in the basedelegate.cpp leads to a synchronization issue when switch between streams and on playback stop the last frame content will be shown instead of the black rectangle. (This was an observation on my i.MX6 hardware)
Created attachment 287351 [details] [review] Unref the buffer with the frame data when removing VideoMaterial instance
commit fe3e8979697773c69d98d172f3eea0bf0dd37287 Author: George Kiagiadakis <george.kiagiadakis@collabora.com> Date: Tue Sep 30 01:11:58 2014 +0300 gstqtvideosink: fix memory leak and synchronization issue related to buffer reference counting https://bugzilla.gnome.org/show_bug.cgi?id=736758