omx: Catch errors when releasing buffers to a port and handle them
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 11 Mar 2013 09:04:10 +0000 (10:04 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 11 Mar 2013 09:04:10 +0000 (10:04 +0100)
omx/gstomxaudioenc.c
omx/gstomxvideodec.c
omx/gstomxvideoenc.c

index e49cc0a..a64450c 100644 (file)
@@ -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");
index b49818a..f9fe327 100644 (file)
@@ -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)) {
index 4ba27cb..138e510 100644 (file)
@@ -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");