From 65174bbd7fe9d11d751b0133c8eb41e6b99fcea8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 11 Mar 2013 10:04:10 +0100 Subject: [PATCH] omx: Catch errors when releasing buffers to a port and handle them --- omx/gstomxaudioenc.c | 51 ++++++++++++++++++++++++++++++++++++++++-------- omx/gstomxvideodec.c | 55 ++++++++++++++++++++++++++++++++++++++++++---------- omx/gstomxvideoenc.c | 45 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 125 insertions(+), 26 deletions(-) diff --git a/omx/gstomxaudioenc.c b/omx/gstomxaudioenc.c index e49cc0a..a64450c 100644 --- a/omx/gstomxaudioenc.c +++ b/omx/gstomxaudioenc.c @@ -283,6 +283,7 @@ gst_omx_audio_enc_loop (GstOMXAudioEnc * self) GstFlowReturn flow_ret = GST_FLOW_OK; GstOMXAcquireBufferReturn acq_return; gboolean is_eos; + OMX_ERRORTYPE err; klass = GST_OMX_AUDIO_ENC_GET_CLASS (self); @@ -298,7 +299,6 @@ gst_omx_audio_enc_loop (GstOMXAudioEnc * self) GstAudioInfo *info = gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (self)); GstCaps *caps; - OMX_ERRORTYPE err; GST_DEBUG_OBJECT (self, "Port settings have changed, updating caps"); @@ -477,7 +477,9 @@ gst_omx_audio_enc_loop (GstOMXAudioEnc * self) gst_flow_get_name (flow_ret)); } - gst_omx_port_release_buffer (port, buf); + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) + goto release_error; self->downstream_flow_ret = flow_ret; } else { @@ -552,6 +554,18 @@ caps_failed: self->started = FALSE; return; } +release_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to relase output buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); + gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + self->started = FALSE; + GST_AUDIO_ENCODER_STREAM_UNLOCK (self); + return; + } } static gboolean @@ -844,6 +858,7 @@ gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf) gsize size; guint offset = 0; GstClockTime timestamp, duration, timestamp_offset = 0; + OMX_ERRORTYPE err; self = GST_OMX_AUDIO_ENC (encoder); @@ -881,8 +896,6 @@ gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf) GST_AUDIO_ENCODER_STREAM_LOCK (self); goto flushing; } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) { - OMX_ERRORTYPE err; - /* Reallocate all buffers */ err = gst_omx_port_set_enabled (port, FALSE); if (err != OMX_ErrorNone) { @@ -980,7 +993,9 @@ gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf) offset += buf->omx_buf->nFilledLen; self->started = TRUE; - gst_omx_port_release_buffer (port, buf); + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) + goto release_error; } GST_DEBUG_OBJECT (self, "Passed frame to component"); @@ -1014,6 +1029,13 @@ reconfigure_error: ("Unable to reconfigure input port")); return GST_FLOW_ERROR; } +release_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to relase input buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); + return GST_FLOW_ERROR; + } } static gboolean @@ -1021,6 +1043,7 @@ gst_omx_audio_enc_sink_event (GstAudioEncoder * encoder, GstEvent * event) { GstOMXAudioEnc *self; GstOMXAudioEncClass *klass; + OMX_ERRORTYPE err; self = GST_OMX_AUDIO_ENC (encoder); klass = GST_OMX_AUDIO_ENC_GET_CLASS (self); @@ -1067,8 +1090,13 @@ gst_omx_audio_enc_sink_event (GstAudioEncoder * encoder, GstEvent * event) GST_SECOND); buf->omx_buf->nTickCount = 0; buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS; - gst_omx_port_release_buffer (self->enc_in_port, buf); - GST_DEBUG_OBJECT (self, "Sent EOS to the component"); + err = gst_omx_port_release_buffer (self->enc_in_port, buf); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Failed to send EOS to component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + } else { + GST_DEBUG_OBJECT (self, "Sent EOS to the component"); + } } else { GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", acq_ret); } @@ -1087,6 +1115,7 @@ gst_omx_audio_enc_drain (GstOMXAudioEnc * self) GstOMXAudioEncClass *klass; GstOMXBuffer *buf; GstOMXAcquireBufferReturn acq_ret; + OMX_ERRORTYPE err; GST_DEBUG_OBJECT (self, "Draining component"); @@ -1133,7 +1162,13 @@ gst_omx_audio_enc_drain (GstOMXAudioEnc * self) GST_SECOND); buf->omx_buf->nTickCount = 0; buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS; - gst_omx_port_release_buffer (self->enc_in_port, buf); + err = gst_omx_port_release_buffer (self->enc_in_port, buf); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + GST_AUDIO_ENCODER_STREAM_LOCK (self); + return GST_FLOW_ERROR; + } GST_DEBUG_OBJECT (self, "Waiting until component is drained"); g_cond_wait (&self->drain_cond, &self->drain_lock); GST_DEBUG_OBJECT (self, "Drained component"); diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c index b49818a..f9fe327 100644 --- a/omx/gstomxvideodec.c +++ b/omx/gstomxvideodec.c @@ -546,8 +546,9 @@ gst_omx_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer) /* Release back to the port, can be filled again */ err = gst_omx_port_release_buffer (pool->port, omx_buf); if (err != OMX_ErrorNone) { - /* TODO: Do something about this */ - g_assert_not_reached (); + GST_ELEMENT_ERROR (pool->element, LIBRARY, SETTINGS, (NULL), + ("Failed to relase output buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); } } else { /* TODO: Implement. @@ -1360,6 +1361,7 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) GstOMXAcquireBufferReturn acq_return; GstClockTimeDiff deadline; gboolean is_eos; + OMX_ERRORTYPE err; klass = GST_OMX_VIDEO_DEC_GET_CLASS (self); @@ -1372,7 +1374,6 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) if (!gst_pad_has_current_caps (GST_VIDEO_DECODER_SRC_PAD (self)) || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) { - OMX_ERRORTYPE err; GstVideoCodecState *state; OMX_PARAM_PORTDEFINITIONTYPE port_def; GstVideoFormat format; @@ -1614,8 +1615,11 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) gst_flow_get_name (flow_ret)); } - if (buf) - gst_omx_port_release_buffer (port, buf); + if (buf) { + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) + goto release_error; + } self->downstream_flow_ret = flow_ret; } else { @@ -1708,6 +1712,18 @@ caps_failed: self->started = FALSE; return; } +release_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to relase output buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); + gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + self->started = FALSE; + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + return; + } } static gboolean @@ -2172,6 +2188,7 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, GstBuffer *codec_data = NULL; guint offset = 0, size; GstClockTime timestamp, duration, timestamp_offset = 0; + OMX_ERRORTYPE err; self = GST_OMX_VIDEO_DEC (decoder); klass = GST_OMX_VIDEO_DEC_GET_CLASS (self); @@ -2221,8 +2238,6 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, GST_VIDEO_DECODER_STREAM_LOCK (self); goto flushing; } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) { - OMX_ERRORTYPE err; - /* Reallocate all buffers */ err = gst_omx_port_set_enabled (port, FALSE); if (err != OMX_ErrorNone) { @@ -2308,8 +2323,10 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, buf->omx_buf->nFilledLen); self->started = TRUE; - gst_omx_port_release_buffer (port, buf); + err = gst_omx_port_release_buffer (port, buf); gst_buffer_replace (&self->codec_data, NULL); + if (err != OMX_ErrorNone) + goto release_error; /* Acquire new buffer for the actual frame */ continue; } @@ -2362,7 +2379,9 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, offset += buf->omx_buf->nFilledLen; self->started = TRUE; - gst_omx_port_release_buffer (port, buf); + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) + goto release_error; } gst_video_codec_frame_unref (frame); @@ -2420,6 +2439,14 @@ reconfigure_error: ("Unable to reconfigure input port")); return GST_FLOW_ERROR; } +release_error: + { + gst_video_codec_frame_unref (frame); + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to relase input buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); + return GST_FLOW_ERROR; + } } static GstFlowReturn @@ -2438,6 +2465,7 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) GstOMXVideoDecClass *klass; GstOMXBuffer *buf; GstOMXAcquireBufferReturn acq_ret; + OMX_ERRORTYPE err; GST_DEBUG_OBJECT (self, "Draining component"); @@ -2486,7 +2514,14 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) GST_SECOND); buf->omx_buf->nTickCount = 0; buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS; - gst_omx_port_release_buffer (self->dec_in_port, buf); + err = gst_omx_port_release_buffer (self->dec_in_port, buf); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + GST_VIDEO_DECODER_STREAM_LOCK (self); + return GST_FLOW_ERROR; + } + GST_DEBUG_OBJECT (self, "Waiting until component is drained"); if (G_UNLIKELY (self->dec->hacks & GST_OMX_HACK_DRAIN_MAY_NOT_RETURN)) { diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c index 4ba27cb..138e510 100644 --- a/omx/gstomxvideoenc.c +++ b/omx/gstomxvideoenc.c @@ -734,6 +734,7 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self) GstFlowReturn flow_ret = GST_FLOW_OK; GstOMXAcquireBufferReturn acq_return; gboolean is_eos; + OMX_ERRORTYPE err; klass = GST_OMX_VIDEO_ENC_GET_CLASS (self); @@ -748,7 +749,6 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self) || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) { GstCaps *caps; GstVideoCodecState *state; - OMX_ERRORTYPE err; GST_DEBUG_OBJECT (self, "Port settings have changed, updating caps"); @@ -867,7 +867,9 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self) gst_flow_get_name (flow_ret)); } - gst_omx_port_release_buffer (port, buf); + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) + goto release_error; self->downstream_flow_ret = flow_ret; } else { @@ -944,6 +946,18 @@ caps_failed: self->started = FALSE; return; } +release_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to relase output buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); + gst_pad_push_event (GST_VIDEO_ENCODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_VIDEO_ENCODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + self->started = FALSE; + GST_VIDEO_ENCODER_STREAM_UNLOCK (self); + return; + } } static gboolean @@ -1494,6 +1508,7 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, GstOMXVideoEnc *self; GstOMXPort *port; GstOMXBuffer *buf; + OMX_ERRORTYPE err; self = GST_OMX_VIDEO_ENC (encoder); @@ -1529,8 +1544,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, GST_VIDEO_ENCODER_STREAM_LOCK (self); goto flushing; } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) { - OMX_ERRORTYPE err; - /* Reallocate all buffers */ err = gst_omx_port_set_enabled (port, FALSE); if (err != OMX_ErrorNone) { @@ -1602,7 +1615,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, GST_DEBUG_OBJECT (self, "Handling frame"); if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)) { - OMX_ERRORTYPE err; OMX_CONFIG_INTRAREFRESHVOPTYPE config; GST_OMX_INIT_STRUCT (&config); @@ -1646,14 +1658,16 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, (GDestroyNotify) buffer_identification_free); self->started = TRUE; - gst_omx_port_release_buffer (port, buf); + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) + goto release_error; GST_DEBUG_OBJECT (self, "Passed frame to component"); } gst_video_codec_frame_unref (frame); - return self->downstream_flow_ret;; + return self->downstream_flow_ret; full_buffer: { @@ -1700,6 +1714,14 @@ buffer_fill_error: gst_video_codec_frame_unref (frame); return GST_FLOW_ERROR; } +release_error: + { + gst_video_codec_frame_unref (frame); + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to relase input buffer to component: %s (0x%08x)", + gst_omx_error_to_string (err), err)); + return GST_FLOW_ERROR; + } } static GstFlowReturn @@ -1718,6 +1740,7 @@ gst_omx_video_enc_drain (GstOMXVideoEnc * self, gboolean at_eos) GstOMXVideoEncClass *klass; GstOMXBuffer *buf; GstOMXAcquireBufferReturn acq_ret; + OMX_ERRORTYPE err; GST_DEBUG_OBJECT (self, "Draining component"); @@ -1766,7 +1789,13 @@ gst_omx_video_enc_drain (GstOMXVideoEnc * self, gboolean at_eos) GST_SECOND); buf->omx_buf->nTickCount = 0; buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS; - gst_omx_port_release_buffer (self->enc_in_port, buf); + err = gst_omx_port_release_buffer (self->enc_in_port, buf); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)", + gst_omx_error_to_string (err), err); + GST_VIDEO_ENCODER_STREAM_LOCK (self); + return GST_FLOW_ERROR; + } GST_DEBUG_OBJECT (self, "Waiting until component is drained"); g_cond_wait (&self->drain_cond, &self->drain_lock); GST_DEBUG_OBJECT (self, "Drained component"); -- 2.7.4