New hang on startup for omxh264enc

Graham Leggett minfrin at sharp.fm
Thu Dec 8 13:58:06 UTC 2016


On 08 Dec 2016, at 12:05 PM, Sebastian Dröge <sebastian at centricular.com> wrote:

>> Does gst-omx support dynamic resolution changes?
>> 
>> It appears that the hang is occurring just as the graphics card
>> reports a resolution change, as follows:
>> [...]
> 
> It does support that, and that worked at some point in the past at
> least. However there might be special behaviour on the RPi, or a bug.

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. I suspect the error checking is naive here, the real error is discarded and we’re assuming we always fail for the same reason.

The second problem is that after failing, we plow on regardless with the card in a disabled state, which then causes our hang further down the line.

Does this make sense?

Regards,
Graham
—

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3240 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20161208/0cba8890/attachment.bin>


More information about the gstreamer-devel mailing list