omx: Clean up port settings change handling

This commit is contained in:
Sebastian Dröge 2013-02-27 15:49:56 +01:00
parent 26b69d99a2
commit b12610efd7
5 changed files with 284 additions and 209 deletions

View 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);

View 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);

View 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");

View 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);

View 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");
}