omx: Clean up port settings change handling
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 27 Feb 2013 14:49:56 +0000 (15:49 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 27 Feb 2013 14:50:20 +0000 (15:50 +0100)
omx/gstomx.c
omx/gstomx.h
omx/gstomxaudioenc.c
omx/gstomxvideodec.c
omx/gstomxvideoenc.c

index 442fd99..9cd6454 100644 (file)
@@ -876,7 +876,6 @@ gst_omx_component_add_port (GstOMXComponent * comp, guint32 index)
   g_queue_init (&port->pending_buffers);
   port->flushing = TRUE;
   port->flushed = FALSE;
-  port->settings_changed = FALSE;
   port->enabled_pending = FALSE;
   port->disabled_pending = FALSE;
 
@@ -905,27 +904,6 @@ gst_omx_component_get_port (GstOMXComponent * comp, guint32 index)
   return NULL;
 }
 
-void
-gst_omx_component_trigger_settings_changed (GstOMXComponent * comp,
-    guint32 port_index)
-{
-  g_return_if_fail (comp != NULL);
-
-  /* Reverse hacks */
-  if (port_index == 1
-      && (comp->hacks & GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_PORT_0_TO_1))
-    port_index = 0;
-
-  if (!(comp->hacks &
-          GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_NDATA_PARAMETER_SWAP)) {
-    EventHandler (comp->handle, comp, OMX_EventPortSettingsChanged, port_index,
-        0, NULL);
-  } else {
-    EventHandler (comp->handle, comp, OMX_EventPortSettingsChanged, 0,
-        port_index, NULL);
-  }
-}
-
 /* NOTE: Uses comp->lock and comp->messages_lock */
 void
 gst_omx_component_set_last_error (GstOMXComponent * comp, OMX_ERRORTYPE err)
@@ -1252,7 +1230,6 @@ retry:
      * the caller about it */
     if (port->settings_cookie != port->configured_settings_cookie) {
       ret = GST_OMX_ACQUIRE_BUFFER_RECONFIGURE;
-      port->settings_changed = TRUE;
       goto done;
     }
   }
@@ -1275,15 +1252,6 @@ retry:
     }
 
     ret = GST_OMX_ACQUIRE_BUFFER_RECONFIGURE;
-    port->settings_changed = TRUE;
-    goto done;
-  }
-
-  if (port->settings_changed) {
-    GST_DEBUG_OBJECT (comp->parent,
-        "Port %u has settings changed, need new caps", port->index);
-    ret = GST_OMX_ACQUIRE_BUFFER_RECONFIGURED;
-    port->settings_changed = FALSE;
     goto done;
   }
 
@@ -2207,7 +2175,7 @@ gst_omx_port_is_enabled (GstOMXPort * port)
 
 /* NOTE: Uses comp->lock and comp->messages_lock */
 OMX_ERRORTYPE
-gst_omx_port_reconfigure (GstOMXPort * port)
+gst_omx_port_mark_reconfigured (GstOMXPort * port)
 {
   GstOMXComponent *comp;
   OMX_ERRORTYPE err = OMX_ErrorNone;
@@ -2217,57 +2185,16 @@ gst_omx_port_reconfigure (GstOMXPort * port)
   comp = port->comp;
 
   g_mutex_lock (&comp->lock);
-  GST_DEBUG_OBJECT (comp->parent, "Reconfiguring port %u", port->index);
+  GST_DEBUG_OBJECT (comp->parent, "Marking port %u is reconfigured",
+      port->index);
 
   gst_omx_component_handle_messages (comp);
 
-  if (!port->settings_changed)
-    goto done;
-
   if ((err = comp->last_error) != OMX_ErrorNone)
     goto done;
 
-  /* Disable and enable the port. This already takes
-   * care of deallocating and allocating buffers.
-   */
-  err = gst_omx_port_set_enabled_unlocked (port, FALSE);
-  if (err != OMX_ErrorNone)
-    goto done;
-
-  err = gst_omx_port_wait_buffers_released_unlocked (port, 5 * GST_SECOND);
-  if (err != OMX_ErrorNone)
-    goto done;
-
-  if (!port->tunneled) {
-    err = gst_omx_port_deallocate_buffers_unlocked (port);
-    if (err != OMX_ErrorNone)
-      goto done;
-  }
-
-  err = gst_omx_port_wait_enabled_unlocked (port, 1 * GST_SECOND);
-  if (err != OMX_ErrorNone)
-    goto done;
-
-  err = gst_omx_port_set_enabled_unlocked (port, TRUE);
-  if (err != OMX_ErrorNone)
-    goto done;
-
-  if (!port->tunneled) {
-    err = gst_omx_port_allocate_buffers_unlocked (port);
-    if (err != OMX_ErrorNone)
-      goto done;
-  }
-
-  err = gst_omx_port_wait_enabled_unlocked (port, 5 * GST_SECOND);
-  if (err != OMX_ErrorNone)
-    goto done;
-
   port->configured_settings_cookie = port->settings_cookie;
 
-  /* If this is an output port, notify all input ports
-   * that might wait for us to reconfigure in
-   * acquire_buffer()
-   */
   if (port->port_def.eDir == OMX_DirOutput) {
     GList *l;
 
@@ -2285,71 +2212,7 @@ gst_omx_port_reconfigure (GstOMXPort * port)
 done:
   gst_omx_port_update_port_definition (port, NULL);
 
-  GST_DEBUG_OBJECT (comp->parent, "Reconfigured port %u: %s (0x%08x)",
-      port->index, gst_omx_error_to_string (err), err);
-
-  g_mutex_unlock (&comp->lock);
-
-  return err;
-}
-
-/* NOTE: Uses comp->lock and comp->messages_lock */
-OMX_ERRORTYPE
-gst_omx_port_manual_reconfigure (GstOMXPort * port, gboolean start)
-{
-  GstOMXComponent *comp;
-  OMX_ERRORTYPE err = OMX_ErrorNone;
-
-  g_return_val_if_fail (port != NULL, OMX_ErrorUndefined);
-
-  comp = port->comp;
-
-  g_mutex_lock (&comp->lock);
-
-  GST_DEBUG_OBJECT (comp->parent, "Manual reconfigure of port %u %s",
-      port->index, (start ? "start" : "stsop"));
-
-  gst_omx_component_handle_messages (comp);
-
-  if ((err = comp->last_error) != OMX_ErrorNone)
-    goto done;
-
-  if (start)
-    port->settings_cookie++;
-  else
-    port->configured_settings_cookie = port->settings_cookie;
-
-  if (port->port_def.eDir == OMX_DirOutput) {
-    GList *l;
-
-    if (start) {
-      for (l = comp->pending_reconfigure_outports; l; l = l->next) {
-        if (l->data == (gpointer) port)
-          break;
-      }
-
-      if (!l) {
-        comp->pending_reconfigure_outports =
-            g_list_prepend (comp->pending_reconfigure_outports, port);
-      }
-    } else {
-      for (l = comp->pending_reconfigure_outports; l; l = l->next) {
-        if (l->data == (gpointer) port) {
-          comp->pending_reconfigure_outports =
-              g_list_delete_link (comp->pending_reconfigure_outports, l);
-          break;
-        }
-      }
-      if (!comp->pending_reconfigure_outports)
-        gst_omx_component_send_message (comp, NULL);
-    }
-  }
-
-
-done:
-  gst_omx_port_update_port_definition (port, NULL);
-
-  GST_DEBUG_OBJECT (comp->parent, "Manual reconfigure of port %u: %s (0x%08x)",
+  GST_DEBUG_OBJECT (comp->parent, "Marked port %u as reconfigured: %s (0x%08x)",
       port->index, gst_omx_error_to_string (err), err);
 
   g_mutex_unlock (&comp->lock);
index c3e1ac9..8b1badf 100644 (file)
@@ -119,9 +119,6 @@ typedef enum {
   GST_OMX_ACQUIRE_BUFFER_FLUSHING,
   /* The port must be reconfigured */
   GST_OMX_ACQUIRE_BUFFER_RECONFIGURE,
-  /* The port was reconfigured and the caps might have changed
-   * NOTE: This is only returned a single time! */
-  GST_OMX_ACQUIRE_BUFFER_RECONFIGURED,
   /* A fatal error happened */
   GST_OMX_ACQUIRE_BUFFER_ERROR
 } GstOMXAcquireBufferReturn;
@@ -191,8 +188,6 @@ struct _GstOMXPort {
   OMX_PARAM_PORTDEFINITIONTYPE port_def;
   GPtrArray *buffers; /* Contains GstOMXBuffer* */
   GQueue pending_buffers; /* Contains GstOMXBuffer* */
-  /* If TRUE we need to get the new caps of this port */
-  gboolean settings_changed;
   gboolean flushing;
   gboolean flushed; /* TRUE after OMX_CommandFlush was done */
   gboolean enabled_pending;  /* TRUE after OMX_Command{En,Dis}able */
@@ -284,8 +279,6 @@ const gchar *     gst_omx_component_get_last_error_string (GstOMXComponent * com
 GstOMXPort *      gst_omx_component_add_port (GstOMXComponent * comp, guint32 index);
 GstOMXPort *      gst_omx_component_get_port (GstOMXComponent * comp, guint32 index);
 
-void              gst_omx_component_trigger_settings_changed (GstOMXComponent * comp, guint32 port_index);
-
 OMX_ERRORTYPE     gst_omx_component_get_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer param);
 OMX_ERRORTYPE     gst_omx_component_set_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer param);
 
@@ -308,13 +301,12 @@ OMX_ERRORTYPE     gst_omx_port_allocate_buffers (GstOMXPort *port);
 OMX_ERRORTYPE     gst_omx_port_deallocate_buffers (GstOMXPort *port);
 OMX_ERRORTYPE     gst_omx_port_wait_buffers_released (GstOMXPort * port, GstClockTime timeout);
 
-OMX_ERRORTYPE     gst_omx_port_reconfigure (GstOMXPort * port);
+OMX_ERRORTYPE     gst_omx_port_mark_reconfigured (GstOMXPort * port);
 
 OMX_ERRORTYPE     gst_omx_port_set_enabled (GstOMXPort * port, gboolean enabled);
 OMX_ERRORTYPE     gst_omx_port_wait_enabled (GstOMXPort * port, GstClockTime timeout);
 gboolean          gst_omx_port_is_enabled (GstOMXPort * port);
 
-OMX_ERRORTYPE     gst_omx_port_manual_reconfigure (GstOMXPort * port, gboolean start);
 
 void              gst_omx_set_default_role (GstOMXClassData *class_data, const gchar *default_role);
 
index c7a8309..dc7d2a0 100644 (file)
@@ -296,15 +296,47 @@ gst_omx_audio_enc_loop (GstOMXAudioEnc * self)
   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
     goto flushing;
   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
-    if (gst_omx_port_reconfigure (self->enc_out_port) != OMX_ErrorNone)
+    OMX_ERRORTYPE err;
+
+    /* Reallocate all buffers */
+    err = gst_omx_port_set_enabled (port, FALSE);
+    if (err != OMX_ErrorNone)
       goto reconfigure_error;
-    /* And restart the loop */
-    return;
+
+    err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_deallocate_buffers (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_set_enabled (port, TRUE);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_allocate_buffers (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_mark_reconfigured (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    /* Update caps below */
   }
 
   GST_AUDIO_ENCODER_STREAM_LOCK (self);
   if (!gst_pad_has_current_caps (GST_AUDIO_ENCODER_SRC_PAD (self))
-      || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURED) {
+      || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
     GstAudioInfo *info =
         gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (self));
     GstCaps *caps;
@@ -599,9 +631,6 @@ gst_omx_audio_enc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
     GST_DEBUG_OBJECT (self, "Need to disable and drain encoder");
     gst_omx_audio_enc_drain (self);
 
-    if (gst_omx_port_manual_reconfigure (self->enc_in_port,
-            TRUE) != OMX_ErrorNone)
-      return FALSE;
     if (gst_omx_port_set_enabled (self->enc_in_port, FALSE) != OMX_ErrorNone)
       return FALSE;
     if (gst_omx_port_wait_buffers_released (self->enc_in_port,
@@ -704,8 +733,7 @@ gst_omx_audio_enc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
     if (gst_omx_port_wait_enabled (self->enc_in_port,
             5 * GST_SECOND) != OMX_ErrorNone)
       return FALSE;
-    if (gst_omx_port_manual_reconfigure (self->enc_in_port,
-            FALSE) != OMX_ErrorNone)
+    if (gst_omx_port_mark_reconfigured (self->enc_in_port) != OMX_ErrorNone)
       return FALSE;
   } else {
     if (gst_omx_component_set_state (self->enc, OMX_StateIdle) != OMX_ErrorNone)
@@ -786,6 +814,7 @@ gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
 {
   GstOMXAcquireBufferReturn acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR;
   GstOMXAudioEnc *self;
+  GstOMXPort *port;
   GstOMXBuffer *buf;
   gsize size;
   guint offset = 0;
@@ -810,13 +839,15 @@ gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
   timestamp = GST_BUFFER_TIMESTAMP (inbuf);
   duration = GST_BUFFER_DURATION (inbuf);
 
+  port = self->enc_in_port;
+
   size = gst_buffer_get_size (inbuf);
   while (offset < size) {
     /* Make sure to release the base class stream lock, otherwise
      * _loop() can't call _finish_frame() and we might block forever
      * because no input buffers are released */
     GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
-    acq_ret = gst_omx_port_acquire_buffer (self->enc_in_port, &buf);
+    acq_ret = gst_omx_port_acquire_buffer (port, &buf);
 
     if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) {
       GST_AUDIO_ENCODER_STREAM_LOCK (self);
@@ -825,29 +856,72 @@ 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) {
-      if (gst_omx_port_reconfigure (self->enc_in_port) != OMX_ErrorNone) {
+      OMX_ERRORTYPE err;
+
+      /* Reallocate all buffers */
+      err = gst_omx_port_set_enabled (port, FALSE);
+      if (err != OMX_ErrorNone) {
+        GST_AUDIO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
+        GST_AUDIO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_deallocate_buffers (port);
+      if (err != OMX_ErrorNone) {
+        GST_AUDIO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
+        GST_AUDIO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_set_enabled (port, TRUE);
+      if (err != OMX_ErrorNone) {
+        GST_AUDIO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_allocate_buffers (port);
+      if (err != OMX_ErrorNone) {
         GST_AUDIO_ENCODER_STREAM_LOCK (self);
         goto reconfigure_error;
       }
+
+      err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
+        GST_AUDIO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_mark_reconfigured (port);
+      if (err != OMX_ErrorNone) {
+        GST_AUDIO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
       /* Now get a new buffer and fill it */
       GST_AUDIO_ENCODER_STREAM_LOCK (self);
       continue;
-    } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURED) {
-      /* TODO: Anything to do here? Don't think so */
-      GST_AUDIO_ENCODER_STREAM_LOCK (self);
-      continue;
     }
     GST_AUDIO_ENCODER_STREAM_LOCK (self);
 
     g_assert (acq_ret == GST_OMX_ACQUIRE_BUFFER_OK && buf != NULL);
 
     if (self->downstream_flow_ret != GST_FLOW_OK) {
-      gst_omx_port_release_buffer (self->enc_in_port, buf);
+      gst_omx_port_release_buffer (port, buf);
       return self->downstream_flow_ret;
     }
 
     if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <= 0) {
-      gst_omx_port_release_buffer (self->enc_in_port, buf);
+      gst_omx_port_release_buffer (port, buf);
       goto full_buffer;
     }
 
@@ -881,7 +955,7 @@ gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
 
     offset += buf->omx_buf->nFilledLen;
     self->started = TRUE;
-    gst_omx_port_release_buffer (self->enc_in_port, buf);
+    gst_omx_port_release_buffer (port, buf);
   }
 
   GST_DEBUG_OBJECT (self, "Passed frame to component");
index feb437b..9817238 100644 (file)
@@ -565,15 +565,47 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
     goto flushing;
   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
-    if (gst_omx_port_reconfigure (self->dec_out_port) != OMX_ErrorNone)
+    OMX_ERRORTYPE err;
+
+    /* Reallocate all buffers */
+    err = gst_omx_port_set_enabled (port, FALSE);
+    if (err != OMX_ErrorNone)
       goto reconfigure_error;
-    /* And restart the loop */
-    return;
+
+    err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_deallocate_buffers (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_set_enabled (port, TRUE);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_allocate_buffers (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_mark_reconfigured (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    /* Update caps below */
   }
 
   GST_VIDEO_DECODER_STREAM_LOCK (self);
   if (!gst_pad_has_current_caps (GST_VIDEO_DECODER_SRC_PAD (self))
-      || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURED) {
+      || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
     GstVideoCodecState *state;
     OMX_PARAM_PORTDEFINITIONTYPE port_def;
     GstVideoFormat format;
@@ -1109,10 +1141,6 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
         return FALSE;
       needs_disable = FALSE;
     } else {
-      if (gst_omx_port_manual_reconfigure (self->dec_in_port,
-              TRUE) != OMX_ErrorNone)
-        return FALSE;
-
       if (gst_omx_port_set_enabled (self->dec_in_port, FALSE) != OMX_ErrorNone)
         return FALSE;
       if (gst_omx_port_wait_buffers_released (self->dec_in_port,
@@ -1171,8 +1199,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
     if (gst_omx_port_wait_enabled (self->dec_in_port,
             5 * GST_SECOND) != OMX_ErrorNone)
       return FALSE;
-    if (gst_omx_port_manual_reconfigure (self->dec_in_port,
-            FALSE) != OMX_ErrorNone)
+    if (gst_omx_port_mark_reconfigured (self->dec_in_port) != OMX_ErrorNone)
       return FALSE;
   } else {
     if (gst_omx_component_set_state (self->dec, OMX_StateIdle) != OMX_ErrorNone)
@@ -1262,6 +1289,7 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
   GstOMXAcquireBufferReturn acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR;
   GstOMXVideoDec *self;
   GstOMXVideoDecClass *klass;
+  GstOMXPort *port;
   GstOMXBuffer *buf;
   GstBuffer *codec_data = NULL;
   guint offset = 0, size;
@@ -1298,13 +1326,15 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
     }
   }
 
+  port = self->dec_in_port;
+
   size = gst_buffer_get_size (frame->input_buffer);
   while (offset < size) {
     /* Make sure to release the base class stream lock, otherwise
      * _loop() can't call _finish_frame() and we might block forever
      * because no input buffers are released */
     GST_VIDEO_DECODER_STREAM_UNLOCK (self);
-    acq_ret = gst_omx_port_acquire_buffer (self->dec_in_port, &buf);
+    acq_ret = gst_omx_port_acquire_buffer (port, &buf);
 
     if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) {
       GST_VIDEO_DECODER_STREAM_LOCK (self);
@@ -1313,7 +1343,53 @@ 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) {
-      if (gst_omx_port_reconfigure (self->dec_in_port) != OMX_ErrorNone) {
+      OMX_ERRORTYPE err;
+
+      /* Reallocate all buffers */
+      err = gst_omx_port_set_enabled (port, FALSE);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_DECODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_DECODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_deallocate_buffers (port);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_DECODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_DECODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_set_enabled (port, TRUE);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_DECODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_allocate_buffers (port);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_DECODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_DECODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_mark_reconfigured (port);
+      if (err != OMX_ErrorNone) {
         GST_VIDEO_DECODER_STREAM_LOCK (self);
         goto reconfigure_error;
       }
@@ -1321,22 +1397,18 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
       /* Now get a new buffer and fill it */
       GST_VIDEO_DECODER_STREAM_LOCK (self);
       continue;
-    } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURED) {
-      /* TODO: Anything to do here? Don't think so */
-      GST_VIDEO_DECODER_STREAM_LOCK (self);
-      continue;
     }
     GST_VIDEO_DECODER_STREAM_LOCK (self);
 
     g_assert (acq_ret == GST_OMX_ACQUIRE_BUFFER_OK && buf != NULL);
 
     if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <= 0) {
-      gst_omx_port_release_buffer (self->dec_in_port, buf);
+      gst_omx_port_release_buffer (port, buf);
       goto full_buffer;
     }
 
     if (self->downstream_flow_ret != GST_FLOW_OK) {
-      gst_omx_port_release_buffer (self->dec_in_port, buf);
+      gst_omx_port_release_buffer (port, buf);
       goto flow_error;
     }
 
@@ -1347,7 +1419,7 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
 
       if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <
           gst_buffer_get_size (codec_data)) {
-        gst_omx_port_release_buffer (self->dec_in_port, buf);
+        gst_omx_port_release_buffer (port, buf);
         goto too_large_codec_data;
       }
 
@@ -1358,7 +1430,7 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
           buf->omx_buf->nFilledLen);
 
       self->started = TRUE;
-      gst_omx_port_release_buffer (self->dec_in_port, buf);
+      gst_omx_port_release_buffer (port, buf);
       gst_buffer_replace (&self->codec_data, NULL);
       /* Acquire new buffer for the actual frame */
       continue;
@@ -1412,7 +1484,7 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
 
     offset += buf->omx_buf->nFilledLen;
     self->started = TRUE;
-    gst_omx_port_release_buffer (self->dec_in_port, buf);
+    gst_omx_port_release_buffer (port, buf);
   }
 
   gst_video_codec_frame_unref (frame);
index 4a4faa4..0e799c3 100644 (file)
@@ -747,15 +747,47 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self)
   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
     goto flushing;
   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
-    if (gst_omx_port_reconfigure (self->enc_out_port) != OMX_ErrorNone)
+    OMX_ERRORTYPE err;
+
+    /* Reallocate all buffers */
+    err = gst_omx_port_set_enabled (port, FALSE);
+    if (err != OMX_ErrorNone)
       goto reconfigure_error;
-    /* And restart the loop */
-    return;
+
+    err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_deallocate_buffers (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_set_enabled (port, TRUE);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_allocate_buffers (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    err = gst_omx_port_mark_reconfigured (port);
+    if (err != OMX_ErrorNone)
+      goto reconfigure_error;
+
+    /* Update caps below */
   }
 
   GST_VIDEO_ENCODER_STREAM_LOCK (self);
   if (!gst_pad_has_current_caps (GST_VIDEO_ENCODER_SRC_PAD (self))
-      || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURED) {
+      || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
     GstCaps *caps;
     GstVideoCodecState *state;
 
@@ -1068,9 +1100,6 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
     GST_DEBUG_OBJECT (self, "Need to disable and drain encoder");
     gst_omx_video_enc_drain (self, FALSE);
 
-    if (gst_omx_port_manual_reconfigure (self->enc_in_port,
-            TRUE) != OMX_ErrorNone)
-      return FALSE;
     if (gst_omx_port_set_enabled (self->enc_in_port, FALSE) != OMX_ErrorNone)
       return FALSE;
     if (gst_omx_port_wait_buffers_released (self->enc_in_port,
@@ -1178,8 +1207,7 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
     if (gst_omx_port_wait_enabled (self->enc_in_port,
             5 * GST_SECOND) != OMX_ErrorNone)
       return FALSE;
-    if (gst_omx_port_manual_reconfigure (self->enc_in_port,
-            FALSE) != OMX_ErrorNone)
+    if (gst_omx_port_mark_reconfigured (self->enc_in_port) != OMX_ErrorNone)
       return FALSE;
   } else {
     if (gst_omx_component_set_state (self->enc, OMX_StateIdle) != OMX_ErrorNone)
@@ -1434,6 +1462,7 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
 {
   GstOMXAcquireBufferReturn acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR;
   GstOMXVideoEnc *self;
+  GstOMXPort *port;
   GstOMXBuffer *buf;
 
   self = GST_OMX_VIDEO_ENC (encoder);
@@ -1451,6 +1480,8 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
     return self->downstream_flow_ret;
   }
 
+  port = self->enc_in_port;
+
   while (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) {
     BufferIdentification *id;
     GstClockTime timestamp, duration;
@@ -1459,7 +1490,7 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
      * _loop() can't call _finish_frame() and we might block forever
      * because no input buffers are released */
     GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
-    acq_ret = gst_omx_port_acquire_buffer (self->enc_in_port, &buf);
+    acq_ret = gst_omx_port_acquire_buffer (port, &buf);
 
     if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) {
       GST_VIDEO_ENCODER_STREAM_LOCK (self);
@@ -1468,29 +1499,72 @@ 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) {
-      if (gst_omx_port_reconfigure (self->enc_in_port) != OMX_ErrorNone) {
+      OMX_ERRORTYPE err;
+
+      /* Reallocate all buffers */
+      err = gst_omx_port_set_enabled (port, FALSE);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_deallocate_buffers (port);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
         GST_VIDEO_ENCODER_STREAM_LOCK (self);
         goto reconfigure_error;
       }
+
+      err = gst_omx_port_set_enabled (port, TRUE);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_allocate_buffers (port);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
+      err = gst_omx_port_mark_reconfigured (port);
+      if (err != OMX_ErrorNone) {
+        GST_VIDEO_ENCODER_STREAM_LOCK (self);
+        goto reconfigure_error;
+      }
+
       /* Now get a new buffer and fill it */
       GST_VIDEO_ENCODER_STREAM_LOCK (self);
       continue;
-    } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURED) {
-      /* TODO: Anything to do here? Don't think so */
-      GST_VIDEO_ENCODER_STREAM_LOCK (self);
-      continue;
     }
     GST_VIDEO_ENCODER_STREAM_LOCK (self);
 
     g_assert (acq_ret == GST_OMX_ACQUIRE_BUFFER_OK && buf != NULL);
 
     if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <= 0) {
-      gst_omx_port_release_buffer (self->enc_in_port, buf);
+      gst_omx_port_release_buffer (port, buf);
       goto full_buffer;
     }
 
     if (self->downstream_flow_ret != GST_FLOW_OK) {
-      gst_omx_port_release_buffer (self->enc_in_port, buf);
+      gst_omx_port_release_buffer (port, buf);
       goto flow_error;
     }
 
@@ -1502,7 +1576,7 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
       OMX_CONFIG_INTRAREFRESHVOPTYPE config;
 
       GST_OMX_INIT_STRUCT (&config);
-      config.nPortIndex = self->enc_out_port->index;
+      config.nPortIndex = port->index;
       config.IntraRefreshVOP = OMX_TRUE;
 
       GST_DEBUG_OBJECT (self, "Forcing a keyframe");
@@ -1517,7 +1591,7 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
     /* Copy the buffer content in chunks of size as requested
      * by the port */
     if (!gst_omx_video_enc_fill_buffer (self, frame->input_buffer, buf)) {
-      gst_omx_port_release_buffer (self->enc_in_port, buf);
+      gst_omx_port_release_buffer (port, buf);
       goto buffer_fill_error;
     }
 
@@ -1542,7 +1616,7 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
         (GDestroyNotify) buffer_identification_free);
 
     self->started = TRUE;
-    gst_omx_port_release_buffer (self->enc_in_port, buf);
+    gst_omx_port_release_buffer (port, buf);
 
     GST_DEBUG_OBJECT (self, "Passed frame to component");
   }