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 767641 - videodecoder: Missing drain vfunc GST_FIXME flood on Raspberry Pi
videodecoder: Missing drain vfunc GST_FIXME flood on Raspberry Pi
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other All
: Normal blocker
: 1.9.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on: 767232
Blocks:
 
 
Reported: 2016-06-14 09:31 UTC by Philippe Normand
Modified: 2016-07-05 16:40 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
sample H264 byte-stream (182.57 KB, application/octet-stream)
2016-06-14 09:31 UTC, Philippe Normand
  Details
264parse:6,baseparse:6,videodecoder:6 log (142.31 KB, application/gzip)
2016-06-14 10:38 UTC, Philippe Normand
  Details
omxvideodec: Implement ::drain() virtual method (2.39 KB, patch)
2016-06-17 08:00 UTC, Sebastian Dröge (slomo)
committed Details | Review
log file (621.42 KB, text/plain)
2016-06-29 13:25 UTC, Philippe Normand
  Details
videodecoder patch (4.52 KB, patch)
2016-06-30 14:42 UTC, Philippe Normand
none Details | Review
updated videodecoder patch (5.24 KB, patch)
2016-07-01 06:56 UTC, Philippe Normand
none Details | Review
videodecoder: Take stream lock one time only on drain (3.93 KB, patch)
2016-07-05 08:09 UTC, Philippe Normand
committed Details | Review

Description Philippe Normand 2016-06-14 09:31:24 UTC
Created attachment 329765 [details]
sample H264 byte-stream

+++ This bug was initially created as a clone of Bug #767232 +++

Since commit eb1ebf226ff8c29ea976169f81135219f1ab412b of gst-plugins-base the decoder will emit GST_FIXME logs:

FIXME           videodecoder gstvideodecoder.c:1057:gst_video_decoder_drain_out:<omxh264dec-omxh264dec0> Sub-class should implement drain()

For every frame handled by the decoder.

The use-case is the following:

GST_DEBUG=3 gst-launch-1.0 filesrc location=raw.h264 ! "video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, level=(string)1.3, profile=(string)main, width=(int)320, height=(int)240, framerat
e=(fraction)2500/83, pixel-aspect-ratio=(fraction)1/1, parsed=(boolean)true" ! decodebin use-buffering=TRUE ! glimagesink
Comment 1 Philippe Normand 2016-06-14 10:38:39 UTC
Created attachment 329773 [details]
264parse:6,baseparse:6,videodecoder:6 log
Comment 2 Sebastian Dröge (slomo) 2016-06-17 08:00:21 UTC
Created attachment 329929 [details] [review]
omxvideodec: Implement ::drain() virtual method
Comment 3 Sebastian Dröge (slomo) 2016-06-17 08:00:48 UTC
Untested patch, please test and let me know :)
Comment 4 Philippe Normand 2016-06-17 10:54:03 UTC
It works fine, thanks!
Comment 5 Sebastian Dröge (slomo) 2016-06-17 11:00:55 UTC
Attachment 329929 [details] pushed as 198e313 - omxvideodec: Implement ::drain() virtual method
Comment 6 Philippe Normand 2016-06-29 11:24:58 UTC
I'm sorry I didn't test this properly. With the patch applied and when the decoder drain is activated it never finishes, the drain_cond isn't signaled.
Comment 7 Philippe Normand 2016-06-29 13:24:16 UTC
The decoder handles the first frame and is in PAUSED state and then a drain is requested but the drain_cond isn't signaled, I'll attach a log file.
Comment 8 Philippe Normand 2016-06-29 13:25:38 UTC
Created attachment 330585 [details]
log file
Comment 9 Philippe Normand 2016-06-30 09:06:03 UTC
There's a deadlock in gst_omx_videodec_dec_reconfigure_output_port() on the video decoder stream lock acquisition:

https://cgit.freedesktop.org/gstreamer/gst-omx/tree/omx/gstomxvideodec.c#n949

Not sure yet what's going on with that rec mutex :(
Comment 10 Philippe Normand 2016-06-30 09:55:46 UTC
The mutex is locked once in gst_video_decoder_chain(), then once in gst_video_decoder_drain_out() and unlocked once only in gst_omx_video_dec_drain().
Comment 11 Sebastian Dröge (slomo) 2016-06-30 10:05:02 UTC
Are all other callers to drain_out() not taking that lock? Sounds like we need a boolean parameter there then to know if it's already taken or not to distinguish these cases. Can you check?
Comment 12 Philippe Normand 2016-06-30 10:20:05 UTC
chain() is the only caller taking the stream lock indeed. Adding the boolean parameter to drain_out() works, the decoder drains and I see the preroll frame on-screen but now there's another deadlock it seems :/
Comment 13 Philippe Normand 2016-06-30 10:33:14 UTC
After the drain gst_omx_port_acquire_buffer() in the loop function returns GST_OMX_ACQUIRE_BUFFER_EOS but it shouldn't! I'll debug this a bit further today.
Comment 14 Philippe Normand 2016-06-30 14:42:06 UTC
Created attachment 330662 [details] [review]
videodecoder patch
Comment 15 Sebastian Dröge (slomo) 2016-06-30 20:32:19 UTC
Comment on attachment 330662 [details] [review]
videodecoder patch

If I'm not mistaken, maybe just require that the stream lock is taken when drain_out() is called? And you just take and release it around the call in the callers that don't have it yet? That seems like a cleaner solution
Comment 16 Philippe Normand 2016-07-01 06:56:34 UTC
Created attachment 330698 [details] [review]
updated videodecoder patch
Comment 17 Sebastian Dröge (slomo) 2016-07-01 09:02:43 UTC
Review of attachment 330698 [details] [review]:

::: gst-libs/gst/video/gstvideodecoder.c
@@ +2194,2 @@
     ret = gst_video_decoder_drain_out (decoder, FALSE);
+    GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

If I'm not missing anything, chain_forward() is always called with that lock taken already: from _chain() which takes it just around, and _flush_parse() is called from _drain_out() (!) for reverse playback and _chain_reverse() which is called with the lock taken in _chain().

@@ +2232,2 @@
       gst_video_decoder_drain_out (decoder, FALSE);
+      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);

Same here
Comment 18 Philippe Normand 2016-07-05 08:09:47 UTC
Created attachment 330889 [details] [review]
videodecoder: Take stream lock one time only on drain

When the drain is triggered from the chain function the lock is already
taken so there is no need to take it one more time.
Comment 19 Sebastian Dröge (slomo) 2016-07-05 16:40:44 UTC
Attachment 330889 [details] pushed as 6338146 - videodecoder: Take stream lock one time only on drain