After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 790312 - msdk: memory leak always happen when encoding and decoding
msdk: memory leak always happen when encoding and decoding
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
unspecified
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks: 789886
 
 
Reported: 2017-11-14 05:55 UTC by Hyunjun Ko
Modified: 2017-11-29 23:41 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
msdkenc: fix a frame leak (2.44 KB, patch)
2017-11-14 06:03 UTC, Hyunjun Ko
none Details | Review
msdkenc: fix a frame leak (2.46 KB, patch)
2017-11-14 09:25 UTC, Hyunjun Ko
none Details | Review
msdkenc: handle the MORE_DATA case (2.78 KB, patch)
2017-11-21 06:02 UTC, Hyunjun Ko
none Details | Review
msdkenc: handle the MORE_DATA case (2.84 KB, patch)
2017-11-21 06:16 UTC, Hyunjun Ko
none Details | Review
msdkenc: handle the MORE_DATA case (3.16 KB, patch)
2017-11-21 09:13 UTC, Hyunjun Ko
committed Details | Review
msdkdec: fix buffer leaks during drain and a leak of videobufferpool (2.54 KB, patch)
2017-11-22 03:33 UTC, Hyunjun Ko
committed Details | Review
msdkdec: keep draining even if a finish_task fails (1.13 KB, patch)
2017-11-23 03:44 UTC, Hyunjun Ko
committed Details | Review

Description Hyunjun Ko 2017-11-14 05:55:48 UTC
Reproduce step:

# GST_DEBUG="GST_TRACER:7,GST_CALL_TRACE:7" GST_TRACERS="leaks" gst-launch-1.0 videotestsrc num-buffers=100 ! msdkh264enc ! fakesink


Result:
0:00:00.213422022 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstBuffer, address=(gpointer)0x7fd028241300, description=(string)buffer: 0x7fd028241300, pts 99:99:99.999999999, dts 99:99:99.999999999, dur 99:99:99.999999999, size 115200, offset none, offset_end none, flags 0x0, ref-count=(uint)1, trace=(string);
0:00:00.213449373 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstBuffer, address=(gpointer)0x7fd028241520, description=(string)buffer: 0x7fd028241520, pts 99:99:99.999999999, dts 99:99:99.999999999, dur 99:99:99.999999999, size 115200, offset none, offset_end none, flags 0x0, ref-count=(uint)1, trace=(string);
0:00:00.213480031 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstBuffer, address=(gpointer)0x7fd0282411f0, description=(string)buffer: 0x7fd0282411f0, pts 99:99:99.999999999, dts 99:99:99.999999999, dur 99:99:99.999999999, size 115200, offset none, offset_end none, flags 0x0, ref-count=(uint)1, trace=(string);
0:00:00.213505559 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstBuffer, address=(gpointer)0x7fd028241410, description=(string)buffer: 0x7fd028241410, pts 99:99:99.999999999, dts 99:99:99.999999999, dur 99:99:99.999999999, size 115200, offset none, offset_end none, flags 0x0, ref-count=(uint)1, trace=(string);
0:00:00.213516695 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstBuffer, address=(gpointer)0x7fd0282410e0, description=(string)buffer: 0x7fd0282410e0, pts 0:00:00.000000000, dts 99:99:99.999999999, dur 0:00:00.033333333, size 115200, offset 0, offset_end 1, flags 0x40, ref-count=(uint)1, trace=(string);
0:00:00.213525424 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstCaps, address=(gpointer)0x7fd0280028f0, description=(string)video/x-raw, width=(int)320, height=(int)240, framerate=(fraction)30/1, format=(string)NV12, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, ref-count=(uint)2, trace=(string);
0:00:00.213552458 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstMemory, address=(gpointer)0x7fd0282612a0, description=(string)0x7fd0282612a0, ref-count=(uint)1, trace=(string);
0:00:00.213561953 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstMemory, address=(gpointer)0x7fd028224000, description=(string)0x7fd028224000, ref-count=(uint)1, trace=(string);
0:00:00.213570038 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstMemory, address=(gpointer)0x7fd028245000, description=(string)0x7fd028245000, ref-count=(uint)1, trace=(string);
0:00:00.213577833 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstMemory, address=(gpointer)0x7fd0282997e0, description=(string)0x7fd0282997e0, ref-count=(uint)1, trace=(string);
0:00:00.213585658 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstMemory, address=(gpointer)0x7fd02827d540, description=(string)0x7fd02827d540, ref-count=(uint)1, trace=(string);
0:00:00.213594623 25428       0xa97230 TRACE             GST_TRACER :0:: object-alive, type-name=(string)GstVideoBufferPool, address=(gpointer)0x7fd0282221d0, description=(string)<videobufferpool0>, ref-count=(uint)1, trace=(string);

** (gst-launch-1.0:25428): WARNING **: Leaks detected


Tested on CentOS7
Comment 1 Hyunjun Ko 2017-11-14 06:03:24 UTC
Created attachment 363555 [details] [review]
msdkenc: fix a frame leak

This leak happens at the first frame to encode.
We should release the frame even if we got no sync point from the driver.

Also, a little bit of code clean-up added.
Comment 2 Sebastian Dröge (slomo) 2017-11-14 08:32:56 UTC
Review of attachment 363555 [details] [review]:

Looks good but:

::: sys/msdk/gstmsdkenc.c
@@ +527,3 @@
+    GST_INFO_OBJECT (thiz,
+        "No sync point from the driver, skipping this frame");
+    goto fail;

This is no "fail" really, it's somewhat expected behaviour. Maybe call the label "out", "done", or similar?

Also why would it give no sync point? And will the frame appear decoded at a later time, or is it literally gone?
Comment 3 Hyunjun Ko 2017-11-14 09:14:25 UTC
(In reply to Sebastian Dröge (slomo) from comment #2)
> Review of attachment 363555 [details] [review] [review]:
> 
> Looks good but:
> 
> ::: sys/msdk/gstmsdkenc.c
> @@ +527,3 @@
> +    GST_INFO_OBJECT (thiz,
> +        "No sync point from the driver, skipping this frame");
> +    goto fail;
> 
> This is no "fail" really, it's somewhat expected behaviour. Maybe call the
> label "out", "done", or similar?

That's what I hesitated actually. Probably 'done' would be better.

> 
> Also why would it give no sync point? And will the frame appear decoded at a
> later time, or is it literally gone?

Well, I realized that I misunderstood the situation :(
In this case, the driver returns MORE_DATA, which means that the frame will be decoded later.
And this patch is wrong!

I'll re-propose a patch to handle MORE_DATA.
Comment 4 Hyunjun Ko 2017-11-14 09:25:23 UTC
Created attachment 363565 [details] [review]
msdkenc: fix a frame leak

This leak happens at the first frame to encode.
We should release the frame if we got MFX_ERR_MORE_DATA from the driver.

Also, a little bit of code clean-up added.
Comment 5 Hyunjun Ko 2017-11-16 09:13:35 UTC
Found a problem with filesrc.
I'm re-working on it.
Comment 6 Sebastian Dröge (slomo) 2017-11-16 09:29:01 UTC
Comment on attachment 363565 [details] [review]
msdkenc: fix a frame leak

On MORE_DATA you probably also don't want to finish the frame, but just unref it and retrieve it from the base class again later when you actually got output for it (or it was decided that the frame is to be discarded, do we know about that?).
Comment 7 Hyunjun Ko 2017-11-21 06:02:18 UTC
Created attachment 364093 [details] [review]
msdkenc: handle the MORE_DATA case

If the driver requires more data, just unref the frame at the moment
then retreive/finish the frame after encoding is finished.

This also fixes a memory leak.
Comment 8 Hyunjun Ko 2017-11-21 06:16:21 UTC
Created attachment 364094 [details] [review]
msdkenc: handle the MORE_DATA case

If the driver requires more data, just unref the frame at the moment
then retreive/finish the frame after encoding is finished.

This also fixes a memory leak.
Comment 9 Sebastian Dröge (slomo) 2017-11-21 08:02:42 UTC
Review of attachment 364094 [details] [review]:

::: sys/msdk/gstmsdkenc.c
@@ +643,3 @@
+    GstVideoCodecFrame *frame;
+
+    frame = gst_video_encoder_get_oldest_frame (GST_VIDEO_ENCODER_CAST (thiz));

This is wrong if frame reordering happens. You're getting the oldest frame in PTS order here

Ideally you would carry the system_frame_number of the frame through the MSDK, and then retrieve it here with that number again.

@@ +647,3 @@
+      gst_msdkenc_dequeue_frame (thiz, frame);
+      gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (thiz), frame);
+    }

What if we get here ("more_data") but no frame is pending? Shouldn't that be an error?
Comment 10 Hyunjun Ko 2017-11-21 09:13:22 UTC
Created attachment 364105 [details] [review]
msdkenc: handle the MORE_DATA case

If the driver requires more data, just unref the frame at the moment
then retreive/finish the frame after encoding is finished.

This also fixes a memory leak.
Comment 11 Sebastian Dröge (slomo) 2017-11-21 09:29:27 UTC
Review of attachment 364105 [details] [review]:

Looks good to me, thanks!
Comment 12 Víctor Manuel Jáquez Leal 2017-11-21 10:14:15 UTC
Review of attachment 364105 [details] [review]:

::: sys/msdk/gstmsdkenc.c
@@ +649,3 @@
+      gst_msdkenc_dequeue_frame (thiz, frame);
+      gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (thiz), frame);
+      gst_msdkenc_reset_task (task);

not sure but I feel this line is missing here:

task->more_data = FALSE;
Comment 13 Hyunjun Ko 2017-11-21 10:37:54 UTC
Review of attachment 364105 [details] [review]:

::: sys/msdk/gstmsdkenc.c
@@ +649,3 @@
+      gst_msdkenc_dequeue_frame (thiz, frame);
+      gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (thiz), frame);
+      gst_msdkenc_reset_task (task);

gst_msdkenc_reset_task is doing that.
Comment 14 Víctor Manuel Jáquez Leal 2017-11-21 10:41:57 UTC
Review of attachment 364105 [details] [review]:

::: sys/msdk/gstmsdkenc.c
@@ +649,3 @@
+      gst_msdkenc_dequeue_frame (thiz, frame);
+      gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (thiz), frame);
+      gst_msdkenc_reset_task (task);

Oh. Ok. Sorry for the noise.
Comment 15 Sebastian Dröge (slomo) 2017-11-21 13:50:26 UTC
Probably the same is needed for the decoder also?
Comment 16 Hyunjun Ko 2017-11-22 01:27:24 UTC
(In reply to Sebastian Dröge (slomo) from comment #15)
> Probably the same is needed for the decoder also?

I also found some leaks when decoding, but didn't check if that is similar to this. I'm going to look into this.
Comment 17 Hyunjun Ko 2017-11-22 03:33:42 UTC
Created attachment 364161 [details] [review]
msdkdec: fix buffer leaks during drain and a leak of  videobufferpool
Comment 18 Sebastian Dröge (slomo) 2017-11-22 07:57:44 UTC
Review of attachment 364161 [details] [review]:

::: sys/msdk/gstmsdkdec.c
@@ +703,3 @@
     task = &g_array_index (thiz->tasks, MsdkDecTask, thiz->next_task);
+    if ((flow = gst_msdkdec_finish_task (thiz, task)) != GST_FLOW_OK)
+      return flow;

Should all other tasks not be finished too somehow, so that all pending frames are discarded at least?
Comment 19 Sebastian Dröge (slomo) 2017-11-22 15:30:31 UTC
commit 0933b8b45a5888ad9454be25b3e96a8851e67aea (HEAD -> master)
Author: Hyunjun Ko <zzoon@igalia.com>
Date:   Wed Nov 22 11:33:54 2017 +0900

    msdkdec: fix buffer leaks during drain and a leak of videobufferpool
    
    https://bugzilla.gnome.org/show_bug.cgi?id=790312

commit ddd9355767b03ed48ff180f9e9ab480afa3cf613
Author: Hyunjun Ko <zzoon@igalia.com>
Date:   Tue Nov 21 14:57:03 2017 +0900

    msdkenc: handle the MORE_DATA case
    
    If the driver requires more data, just unref the frame at the moment
    then retreive/finish the frame after encoding is finished.
    
    This also fixes a memory leak.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=790312
Comment 20 Sebastian Dröge (slomo) 2017-11-22 15:31:36 UTC
Keeping the bug open for the remaining patch as mentioned in comment 18.
Comment 21 Hyunjun Ko 2017-11-23 03:44:46 UTC
Created attachment 364255 [details] [review]
msdkdec: keep draining even if a finish_task fails

Should continue draining so that it could try to
discard the rest of pending frames even if a finish_task fails.
Comment 22 Sebastian Dröge (slomo) 2017-11-23 08:08:33 UTC
Attachment 364255 [details] pushed as 3301dd3 - msdkdec: keep draining even if a finish_task fails
Comment 23 Sebastian Dröge (slomo) 2017-11-23 08:09:07 UTC
Let me know if any of the many MSDK changes should be backported to 1.12, thanks :)