[Bug 774654] Flushing can hang if output port queue of pending buffers is empty

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Sat Dec 10 12:52:32 UTC 2016


https://bugzilla.gnome.org/show_bug.cgi?id=774654

--- Comment #11 from minfrin at sharp.fm ---
Yes, we do support dynamic resolution changes, although the mechanism currently
doesn't seem to work.

After some more picking apart of the code, it seems we hang because we haven’t
reconfigured the port correctly in response to OMX_EventPortSettingsChanged.

What we’re supposed to do when OMX_EventPortSettingsChanged arrives is disable
the port, reconfigure, then enable the port again.

What we do instead is miss out the disable step - we attempt to reconfigure and
enable only.

The reason we miss out the disable step is because the port reports itself as
already disabled, and so the disable step is skipped.

It appears we might have never been enabled because the following two lines
have appeared:

0:00:26.136954131 16918 0x740c8630 DEBUG            omxvideodec
gstomxvideodec.c:963:gst_omx_video_dec_reconfigure_output_port:<omxh264dec-omxh264dec0>
Failed to negotiate with feature memory:GLMemory
0:00:26.245094851 16918 0x740c8630 ERROR            omxvideodec
gstomxvideodec.c:971:gst_omx_video_dec_reconfigure_output_port:<omxh264dec-omxh264dec0>
Failed to negotiate RGBA for EGLImage

At a glance, these two log statements seem unrelated, however they appear here,
where the second is a fallback after the failure of the first:

     gst_omx_port_get_port_definition (self->dec_out_port, &port_def);
     GST_VIDEO_DECODER_STREAM_LOCK (self);
     state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
         GST_VIDEO_FORMAT_RGBA, port_def.format.video.nFrameWidth,
         port_def.format.video.nFrameHeight, self->input_state);

     /* at this point state->caps is NULL */
     if (state->caps)
       gst_caps_unref (state->caps);
     state->caps = gst_video_info_to_caps (&state->info);
     gst_caps_set_features (state->caps, 0,
         gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, NULL));

     /* try to negotiate with caps feature */
     if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {

       GST_DEBUG_OBJECT (self,
           "Failed to negotiate with feature %s",
           GST_CAPS_FEATURE_MEMORY_GL_MEMORY);

       if (state->caps)
         gst_caps_replace (&state->caps, NULL);

       /* fallback: try to use EGLImage even if it is not in the caps feature
*/
       if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
         gst_video_codec_state_unref (state);
         GST_ERROR_OBJECT (self, "Failed to negotiate RGBA for EGLImage");
         GST_VIDEO_DECODER_STREAM_UNLOCK (self);
         goto no_egl;
       }
     }

This code then follows the no_egl path, which seems to bypass this step:

     err = gst_omx_port_set_enabled (self->dec_out_port, TRUE);
     if (err != OMX_ErrorNone)
       goto no_egl;

The decoder is now running, but in an unexpectedly “disabled” state, which
throws everything off track.

It seems there are two problems, the first being that
gst_video_decoder_negotiate() fails twice in a row.

The first gst_video_decoder_negotiate() fails because the downstream omxh264enc
element does not support GLMemory for some reason. It appears support for this
was added to the decoder, but not the encoder.

The second gst_video_decoder_negotiate() fails because the downstream
omxh264enc element does not support RGBA. It is not clear why RGBA was chosen,
given that it is not a supported input format for much of OMX.

Given that we failed to negotiate twice, we now follow the no_egl path, however
this path doesn't appear to place OMX in a state where it can renegotiate in
future.

It is not yet clear to me what the no_egl path does that is different to the
path that would have been taken if this RPI specific code wasn't there at all.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list