From b12610efd75840269c62e8f69324b7a0fb2c7503 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 27 Feb 2013 15:49:56 +0100 Subject: [PATCH] omx: Clean up port settings change handling --- omx/gstomx.c | 145 ++------------------------------------------------- omx/gstomx.h | 10 +--- omx/gstomxaudioenc.c | 110 +++++++++++++++++++++++++++++++------- omx/gstomxvideodec.c | 114 ++++++++++++++++++++++++++++++++-------- omx/gstomxvideoenc.c | 114 +++++++++++++++++++++++++++++++++------- 5 files changed, 284 insertions(+), 209 deletions(-) diff --git a/omx/gstomx.c b/omx/gstomx.c index 442fd99..9cd6454 100644 --- a/omx/gstomx.c +++ b/omx/gstomx.c @@ -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); diff --git a/omx/gstomx.h b/omx/gstomx.h index c3e1ac9..8b1badf 100644 --- a/omx/gstomx.h +++ b/omx/gstomx.h @@ -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); diff --git a/omx/gstomxaudioenc.c b/omx/gstomxaudioenc.c index c7a8309..dc7d2a0 100644 --- a/omx/gstomxaudioenc.c +++ b/omx/gstomxaudioenc.c @@ -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"); diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c index feb437b..9817238 100644 --- a/omx/gstomxvideodec.c +++ b/omx/gstomxvideodec.c @@ -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); diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c index 4a4faa4..0e799c3 100644 --- a/omx/gstomxvideoenc.c +++ b/omx/gstomxvideoenc.c @@ -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"); } -- 2.7.4