summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2013-03-14 12:49:42 +0100
committerJosep Torra <n770galaxy@gmail.com>2013-03-15 10:07:43 +0100
commit931beef8c0a275b670b765f1bf3458998ec9c755 (patch)
tree2c47f30af11c869eb60c22b542e319c6acafca44
parent7a888e7ba541ec59a34522efb2b54b555234bd78 (diff)
downloadgst-omx-931beef8c0a275b670b765f1bf3458998ec9c755.tar.gz
omx: Handle the OMX_EventBufferFlag to detect EOS too
Conflicts: omx/gstomxaudioenc.c omx/gstomxvideodec.c omx/gstomxvideoenc.c
-rw-r--r--omx/gstomx.c56
-rw-r--r--omx/gstomx.h8
-rw-r--r--omx/gstomxaudioenc.c184
-rw-r--r--omx/gstomxvideodec.c161
-rw-r--r--omx/gstomxvideoenc.c70
5 files changed, 272 insertions, 207 deletions
diff --git a/omx/gstomx.c b/omx/gstomx.c
index 71cba27..1d8867d 100644
--- a/omx/gstomx.c
+++ b/omx/gstomx.c
@@ -322,6 +322,23 @@ gst_omx_component_handle_messages (GstOMXComponent * comp)
break;
}
+ case GST_OMX_MESSAGE_BUFFER_FLAG:{
+ GstOMXPort *port = NULL;
+ OMX_U32 index = msg->content.buffer_flag.port;
+ OMX_U32 flags = msg->content.buffer_flag.flags;
+
+ port = gst_omx_component_get_port (comp, index);
+ if (!port)
+ break;
+
+ GST_DEBUG_OBJECT (comp->parent, "Port %u got buffer flags 0x%08x",
+ port->index, flags);
+ if ((flags & OMX_BUFFERFLAG_EOS)
+ && port->port_def.eDir == OMX_DirOutput)
+ port->eos = TRUE;
+
+ break;
+ }
case GST_OMX_MESSAGE_BUFFER_DONE:{
GstOMXBuffer *buf = msg->content.buffer_done.buffer->pAppPrivate;
GstOMXPort *port;
@@ -357,6 +374,10 @@ gst_omx_component_handle_messages (GstOMXComponent * comp)
* the port was flushed */
GST_DEBUG_OBJECT (comp->parent, "Port %u filled buffer %p (%p)",
port->index, buf, buf->omx_buf->pBuffer);
+
+ if ((buf->omx_buf->nFlags & OMX_BUFFERFLAG_EOS)
+ && port->port_def.eDir == OMX_DirOutput)
+ port->eos = TRUE;
}
buf->used = FALSE;
@@ -492,8 +513,21 @@ EventHandler (OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_EVENTTYPE eEvent,
gst_omx_component_send_message (comp, msg);
break;
}
+ case OMX_EventBufferFlag:{
+ GstOMXMessage *msg;
+
+ msg = g_slice_new (GstOMXMessage);
+
+ msg->type = GST_OMX_MESSAGE_BUFFER_FLAG;
+ msg->content.buffer_flag.port = nData1;
+ msg->content.buffer_flag.flags = nData2;
+ GST_DEBUG_OBJECT (comp->parent, "Port %u got buffer flags 0x%08x",
+ msg->content.buffer_flag.port, msg->content.buffer_flag.flags);
+
+ gst_omx_component_send_message (comp, msg);
+ break;
+ }
case OMX_EventPortFormatDetected:
- case OMX_EventBufferFlag:
default:
GST_DEBUG_OBJECT (comp->parent, "Unknown event 0x%08x", eEvent);
break;
@@ -886,6 +920,7 @@ gst_omx_component_add_port (GstOMXComponent * comp, guint32 index)
port->flushed = FALSE;
port->enabled_pending = FALSE;
port->disabled_pending = FALSE;
+ port->eos = FALSE;
if (port->port_def.eDir == OMX_DirInput)
comp->n_in_ports++;
@@ -1244,8 +1279,22 @@ retry:
goto done;
}
+ if (port->port_def.eDir == OMX_DirOutput && port->eos) {
+ if (!g_queue_is_empty (&port->pending_buffers)) {
+ GST_DEBUG_OBJECT (comp->parent,
+ "Output port %u is EOS but has buffers pending", port->index);
+ _buf = g_queue_pop_head (&port->pending_buffers);
+
+ ret = GST_OMX_ACQUIRE_BUFFER_OK;
+ goto done;
+ }
+
+ ret = GST_OMX_ACQUIRE_BUFFER_EOS;
+ goto done;
+ }
+
/*
- * At this point we have no error or flushing port
+ * At this point we have no error or flushing/eos port
* and a properly configured port.
*
*/
@@ -1486,6 +1535,9 @@ gst_omx_port_set_flushing (GstOMXPort * port, GstClockTime timeout,
err = OMX_ErrorTimeout;
goto done;
}
+
+ /* Reset EOS flag */
+ port->eos = FALSE;
}
done:
diff --git a/omx/gstomx.h b/omx/gstomx.h
index 3fb6a6a..9d3b027 100644
--- a/omx/gstomx.h
+++ b/omx/gstomx.h
@@ -130,6 +130,8 @@ typedef enum {
GST_OMX_ACQUIRE_BUFFER_FLUSHING,
/* The port must be reconfigured */
GST_OMX_ACQUIRE_BUFFER_RECONFIGURE,
+ /* The port is EOS */
+ GST_OMX_ACQUIRE_BUFFER_EOS,
/* A fatal error happened */
GST_OMX_ACQUIRE_BUFFER_ERROR
} GstOMXAcquireBufferReturn;
@@ -158,6 +160,7 @@ typedef enum {
GST_OMX_MESSAGE_ERROR,
GST_OMX_MESSAGE_PORT_ENABLE,
GST_OMX_MESSAGE_PORT_SETTINGS_CHANGED,
+ GST_OMX_MESSAGE_BUFFER_FLAG,
GST_OMX_MESSAGE_BUFFER_DONE,
} GstOMXMessageType;
@@ -182,6 +185,10 @@ struct _GstOMXMessage {
OMX_U32 port;
} port_settings_changed;
struct {
+ OMX_U32 port;
+ OMX_U32 flags;
+ } buffer_flag;
+ struct {
OMX_HANDLETYPE component;
OMX_PTR app_data;
OMX_BUFFERHEADERTYPE *buffer;
@@ -203,6 +210,7 @@ struct _GstOMXPort {
gboolean flushed; /* TRUE after OMX_CommandFlush was done */
gboolean enabled_pending; /* TRUE after OMX_Command{En,Dis}able */
gboolean disabled_pending; /* was done until it took effect */
+ gboolean eos; /* TRUE after a buffer with EOS flag was received */
/* Increased whenever the settings of these port change.
* If settings_cookie != configured_settings_cookie
diff --git a/omx/gstomxaudioenc.c b/omx/gstomxaudioenc.c
index a5a4f8b..ec95d4b 100644
--- a/omx/gstomxaudioenc.c
+++ b/omx/gstomxaudioenc.c
@@ -307,7 +307,6 @@ gst_omx_audio_enc_loop (GstOMXAudioEnc * self)
GstOMXBuffer *buf = NULL;
GstFlowReturn flow_ret = GST_FLOW_OK;
GstOMXAcquireBufferReturn acq_return;
- gboolean is_eos;
OMX_ERRORTYPE err;
klass = GST_OMX_AUDIO_ENC_GET_CLASS (self);
@@ -317,6 +316,8 @@ gst_omx_audio_enc_loop (GstOMXAudioEnc * self)
goto component_error;
} else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
goto flushing;
+ } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) {
+ goto eos;
}
if (!GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (self))
@@ -399,112 +400,94 @@ gst_omx_audio_enc_loop (GstOMXAudioEnc * self)
}
g_assert (acq_return == GST_OMX_ACQUIRE_BUFFER_OK);
-
- if (buf) {
- GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %lu", buf->omx_buf->nFlags,
- buf->omx_buf->nTimeStamp);
-
- /* This prevents a deadlock between the srcpad stream
- * lock and the videocodec stream lock, if ::reset()
- * is called at the wrong time
- */
- if (gst_omx_port_is_flushing (self->enc_out_port)) {
- GST_DEBUG_OBJECT (self, "Flushing");
- gst_omx_port_release_buffer (self->enc_out_port, buf);
- goto flushing;
- }
-
+ if (!buf) {
+ g_assert ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER));
GST_AUDIO_ENCODER_STREAM_LOCK (self);
- is_eos = ! !(buf->omx_buf->nFlags & OMX_BUFFERFLAG_EOS);
+ goto eos;
+ }
- if ((buf->omx_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
- && buf->omx_buf->nFilledLen > 0) {
- GstCaps *caps;
- GstBuffer *codec_data;
+ GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %lu", buf->omx_buf->nFlags,
+ buf->omx_buf->nTimeStamp);
- GST_DEBUG_OBJECT (self, "Handling codec data");
- caps = gst_caps_copy (GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (self)));
- codec_data = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
- memcpy (GST_BUFFER_DATA (codec_data),
- buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
- buf->omx_buf->nFilledLen);
+ /* This prevents a deadlock between the srcpad stream
+ * lock and the videocodec stream lock, if ::reset()
+ * is called at the wrong time
+ */
+ if (gst_omx_port_is_flushing (self->enc_out_port)) {
+ GST_DEBUG_OBJECT (self, "Flushing");
+ gst_omx_port_release_buffer (self->enc_out_port, buf);
+ goto flushing;
+ }
- gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data,
- NULL);
- if (!gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (self), caps)) {
- gst_caps_unref (caps);
- if (buf)
- gst_omx_port_release_buffer (self->enc_out_port, buf);
- GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
- goto caps_failed;
- }
- gst_caps_unref (caps);
- flow_ret = GST_FLOW_OK;
- } else if (buf->omx_buf->nFilledLen > 0) {
- GstBuffer *outbuf;
- guint n_samples;
+ GST_AUDIO_ENCODER_STREAM_LOCK (self);
- GST_DEBUG_OBJECT (self, "Handling output data");
+ if ((buf->omx_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
+ && buf->omx_buf->nFilledLen > 0) {
+ GstCaps *caps;
+ GstBuffer *codec_data;
- n_samples =
- klass->get_num_samples (self, self->enc_out_port,
- gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (self)), buf);
+ GST_DEBUG_OBJECT (self, "Handling codec data");
+ caps = gst_caps_copy (GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (self)));
+ codec_data = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
- if (buf->omx_buf->nFilledLen > 0) {
- outbuf = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
+ memcpy (GST_BUFFER_DATA (codec_data),
+ buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
+ buf->omx_buf->nFilledLen);
- memcpy (GST_BUFFER_DATA (outbuf),
- buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
- buf->omx_buf->nFilledLen);
- } else {
- outbuf = gst_buffer_new ();
- }
+ gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
+ if (!gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (self), caps)) {
+ gst_caps_unref (caps);
+ if (buf)
+ gst_omx_port_release_buffer (self->enc_out_port, buf);
+ GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
+ goto caps_failed;
+ }
+ gst_caps_unref (caps);
+ flow_ret = GST_FLOW_OK;
+ } else if (buf->omx_buf->nFilledLen > 0) {
+ GstBuffer *outbuf;
+ guint n_samples;
- gst_buffer_set_caps (outbuf,
- GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (self)));
+ GST_DEBUG_OBJECT (self, "Handling output data");
- GST_BUFFER_TIMESTAMP (outbuf) =
- gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND,
- OMX_TICKS_PER_SECOND);
- if (buf->omx_buf->nTickCount != 0)
- GST_BUFFER_DURATION (outbuf) =
- gst_util_uint64_scale (buf->omx_buf->nTickCount, GST_SECOND,
- OMX_TICKS_PER_SECOND);
-
- flow_ret =
- gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (self),
- outbuf, n_samples);
- }
+ n_samples =
+ klass->get_num_samples (self, self->enc_out_port,
+ gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (self)), buf);
- GST_DEBUG_OBJECT (self, "Handled output data");
+ if (buf->omx_buf->nFilledLen > 0) {
+ outbuf = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
+
+ memcpy (GST_BUFFER_DATA (outbuf),
+ buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
+ buf->omx_buf->nFilledLen);
- if (is_eos || flow_ret == GST_FLOW_UNEXPECTED) {
- g_mutex_lock (self->drain_lock);
- if (self->draining) {
- GST_DEBUG_OBJECT (self, "Drained");
- self->draining = FALSE;
- g_cond_broadcast (self->drain_cond);
- } else if (flow_ret == GST_FLOW_OK) {
- GST_DEBUG_OBJECT (self, "Component signalled EOS");
- flow_ret = GST_FLOW_UNEXPECTED;
- }
- g_mutex_unlock (self->drain_lock);
} else {
- GST_DEBUG_OBJECT (self, "Finished frame: %s",
- gst_flow_get_name (flow_ret));
+ outbuf = gst_buffer_new ();
}
- err = gst_omx_port_release_buffer (port, buf);
- if (err != OMX_ErrorNone)
- goto release_error;
+ GST_BUFFER_TIMESTAMP (outbuf) =
+ gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND,
+ OMX_TICKS_PER_SECOND);
+ if (buf->omx_buf->nTickCount != 0)
+ GST_BUFFER_DURATION (outbuf) =
+ gst_util_uint64_scale (buf->omx_buf->nTickCount, GST_SECOND,
+ OMX_TICKS_PER_SECOND);
- self->downstream_flow_ret = flow_ret;
- } else {
- g_assert ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER));
- GST_AUDIO_ENCODER_STREAM_LOCK (self);
- flow_ret = GST_FLOW_UNEXPECTED;
+ flow_ret =
+ gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (self),
+ outbuf, n_samples);
}
+ GST_DEBUG_OBJECT (self, "Handled output data");
+
+ GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret));
+
+ err = gst_omx_port_release_buffer (port, buf);
+ if (err != OMX_ErrorNone)
+ goto release_error;
+
+ self->downstream_flow_ret = flow_ret;
+
if (flow_ret != GST_FLOW_OK)
goto flow_error;
@@ -532,6 +515,29 @@ flushing:
self->started = FALSE;
return;
}
+eos:
+ {
+ g_mutex_lock (self->drain_lock);
+ if (self->draining) {
+ GST_DEBUG_OBJECT (self, "Drained");
+ self->draining = FALSE;
+ g_cond_broadcast (self->drain_cond);
+ flow_ret = GST_FLOW_OK;
+ } else {
+ GST_DEBUG_OBJECT (self, "Component signalled EOS");
+ flow_ret = GST_FLOW_UNEXPECTED;
+ }
+ g_mutex_unlock (self->drain_lock);
+
+ self->downstream_flow_ret = flow_ret;
+
+ if (flow_ret != GST_FLOW_OK)
+ goto flow_error;
+
+ GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
+
+ return;
+ }
flow_error:
{
if (flow_ret == GST_FLOW_UNEXPECTED) {
diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index 4a9b777..ba6e083 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -664,23 +664,21 @@ gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec * self)
static void
gst_omx_video_dec_loop (GstOMXVideoDec * self)
{
- GstOMXVideoDecClass *klass;
GstOMXPort *port = self->dec_out_port;
GstOMXBuffer *buf = NULL;
GstVideoCodecFrame *frame;
GstFlowReturn flow_ret = GST_FLOW_OK;
GstOMXAcquireBufferReturn acq_return;
GstClockTimeDiff deadline;
- gboolean is_eos;
OMX_ERRORTYPE err;
- klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
-
acq_return = gst_omx_port_acquire_buffer (port, &buf);
if (acq_return == GST_OMX_ACQUIRE_BUFFER_ERROR) {
goto component_error;
} else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
goto flushing;
+ } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) {
+ goto eos;
}
if (!GST_PAD_CAPS (GST_VIDEO_DECODER_SRC_PAD (self)) ||
@@ -793,98 +791,76 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
goto flushing;
}
- if (buf) {
- GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %lu",
- buf->omx_buf->nFlags, buf->omx_buf->nTimeStamp);
-
- GST_VIDEO_DECODER_STREAM_LOCK (self);
- frame = _find_nearest_frame (self, buf);
-
- is_eos = ! !(buf->omx_buf->nFlags & OMX_BUFFERFLAG_EOS);
+ GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %lu",
+ buf->omx_buf->nFlags, buf->omx_buf->nTimeStamp);
- if (frame
- && (deadline = gst_video_decoder_get_max_decode_time
- (GST_VIDEO_DECODER (self), frame)) < 0) {
- GST_WARNING_OBJECT (self,
- "Frame is too late, dropping (deadline %" GST_TIME_FORMAT ")",
- GST_TIME_ARGS (-deadline));
- flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
- frame = NULL;
- } else if (!frame && buf->omx_buf->nFilledLen > 0) {
- GstBuffer *outbuf;
-
- /* This sometimes happens at EOS or if the input is not properly framed,
- * let's handle it gracefully by allocating a new buffer for the current
- * caps and filling it
- */
+ GST_VIDEO_DECODER_STREAM_LOCK (self);
+ frame = _find_nearest_frame (self, buf);
+
+ if (frame
+ && (deadline = gst_video_decoder_get_max_decode_time
+ (GST_VIDEO_DECODER (self), frame)) < 0) {
+ GST_WARNING_OBJECT (self,
+ "Frame is too late, dropping (deadline %" GST_TIME_FORMAT ")",
+ GST_TIME_ARGS (-deadline));
+ flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
+ frame = NULL;
+ } else if (!frame && buf->omx_buf->nFilledLen > 0) {
+ GstBuffer *outbuf;
+
+ /* This sometimes happens at EOS or if the input is not properly framed,
+ * let's handle it gracefully by allocating a new buffer for the current
+ * caps and filling it
+ */
- GST_ERROR_OBJECT (self, "No corresponding frame found");
+ GST_ERROR_OBJECT (self, "No corresponding frame found");
- outbuf = gst_video_decoder_alloc_output_buffer (GST_VIDEO_DECODER (self));
+ outbuf = gst_video_decoder_alloc_output_buffer (GST_VIDEO_DECODER (self));
- if (!gst_omx_video_dec_fill_buffer (self, buf, outbuf)) {
- gst_buffer_unref (outbuf);
- gst_omx_port_release_buffer (port, buf);
- goto invalid_buffer;
- }
+ if (!gst_omx_video_dec_fill_buffer (self, buf, outbuf)) {
+ gst_buffer_unref (outbuf);
+ gst_omx_port_release_buffer (port, buf);
+ goto invalid_buffer;
+ }
- flow_ret = gst_pad_push (GST_VIDEO_DECODER_SRC_PAD (self), outbuf);
- } else if (buf->omx_buf->nFilledLen > 0) {
- if ((flow_ret =
- gst_video_decoder_alloc_output_frame (GST_VIDEO_DECODER
- (self), frame)) == GST_FLOW_OK) {
- /* FIXME: This currently happens because of a race condition too.
- * We first need to reconfigure the output port and then the input
- * port if both need reconfiguration.
- */
- if (!gst_omx_video_dec_fill_buffer (self, buf, frame->output_buffer)) {
- gst_buffer_replace (&frame->output_buffer, NULL);
- flow_ret =
- gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
- frame = NULL;
- gst_omx_port_release_buffer (port, buf);
- goto invalid_buffer;
- }
+ flow_ret = gst_pad_push (GST_VIDEO_DECODER_SRC_PAD (self), outbuf);
+ } else if (buf->omx_buf->nFilledLen > 0) {
+ if ((flow_ret =
+ gst_video_decoder_alloc_output_frame (GST_VIDEO_DECODER
+ (self), frame)) == GST_FLOW_OK) {
+ /* FIXME: This currently happens because of a race condition too.
+ * We first need to reconfigure the output port and then the input
+ * port if both need reconfiguration.
+ */
+ if (!gst_omx_video_dec_fill_buffer (self, buf, frame->output_buffer)) {
+ gst_buffer_replace (&frame->output_buffer, NULL);
flow_ret =
- gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
+ gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
frame = NULL;
+ gst_omx_port_release_buffer (port, buf);
+ goto invalid_buffer;
}
- } else if (frame != NULL) {
- flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
+ flow_ret =
+ gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
frame = NULL;
}
+ } else if (frame != NULL) {
+ flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
+ frame = NULL;
+ }
- GST_DEBUG_OBJECT (self, "Read frame from component");
-
- if (is_eos || flow_ret == GST_FLOW_UNEXPECTED) {
- g_mutex_lock (self->drain_lock);
- if (self->draining) {
- GST_DEBUG_OBJECT (self, "Drained");
- self->draining = FALSE;
- g_cond_broadcast (self->drain_cond);
- } else if (flow_ret == GST_FLOW_OK) {
- GST_DEBUG_OBJECT (self, "Component signalled EOS");
- flow_ret = GST_FLOW_UNEXPECTED;
- }
- g_mutex_unlock (self->drain_lock);
- } else {
- GST_DEBUG_OBJECT (self, "Finished frame: %s",
- gst_flow_get_name (flow_ret));
- }
+ GST_DEBUG_OBJECT (self, "Read frame from component");
- if (buf) {
- err = gst_omx_port_release_buffer (port, buf);
- if (err != OMX_ErrorNone)
- goto release_error;
- }
+ GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret));
- self->downstream_flow_ret = flow_ret;
- } else {
- g_assert ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER));
- GST_VIDEO_DECODER_STREAM_LOCK (self);
- flow_ret = GST_FLOW_UNEXPECTED;
+ if (buf) {
+ err = gst_omx_port_release_buffer (port, buf);
+ if (err != OMX_ErrorNone)
+ goto release_error;
}
+ self->downstream_flow_ret = flow_ret;
+
if (flow_ret != GST_FLOW_OK)
goto flow_error;
@@ -914,6 +890,29 @@ flushing:
return;
}
+eos:
+ {
+ g_mutex_lock (self->drain_lock);
+ if (self->draining) {
+ GST_DEBUG_OBJECT (self, "Drained");
+ self->draining = FALSE;
+ g_cond_broadcast (self->drain_cond);
+ flow_ret = GST_FLOW_OK;
+ } else {
+ GST_DEBUG_OBJECT (self, "Component signalled EOS");
+ flow_ret = GST_FLOW_UNEXPECTED;
+ }
+ g_mutex_unlock (self->drain_lock);
+ self->downstream_flow_ret = flow_ret;
+
+ if (flow_ret != GST_FLOW_OK)
+ goto flow_error;
+
+ GST_VIDEO_DECODER_STREAM_UNLOCK (self);
+
+ return;
+ }
+
flow_error:
{
if (flow_ret == GST_FLOW_UNEXPECTED) {
diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c
index 66e589e..b436824 100644
--- a/omx/gstomxvideoenc.c
+++ b/omx/gstomxvideoenc.c
@@ -737,7 +737,6 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self)
GstVideoCodecFrame *frame;
GstFlowReturn flow_ret = GST_FLOW_OK;
GstOMXAcquireBufferReturn acq_return;
- gboolean is_eos;
OMX_ERRORTYPE err;
klass = GST_OMX_VIDEO_ENC_GET_CLASS (self);
@@ -747,6 +746,8 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self)
goto component_error;
} else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
goto flushing;
+ } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) {
+ goto eos;
}
if (!GST_PAD_CAPS (GST_VIDEO_ENCODER_SRC_PAD (self))
@@ -844,45 +845,22 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self)
goto flushing;
}
- if (buf) {
- GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %lu", buf->omx_buf->nFlags,
- buf->omx_buf->nTimeStamp);
+ GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %lu", buf->omx_buf->nFlags,
+ buf->omx_buf->nTimeStamp);
- GST_VIDEO_ENCODER_STREAM_LOCK (self);
- frame = _find_nearest_frame (self, buf);
-
- is_eos = ! !(buf->omx_buf->nFlags & OMX_BUFFERFLAG_EOS);
+ GST_VIDEO_ENCODER_STREAM_LOCK (self);
+ frame = _find_nearest_frame (self, buf);
- g_assert (klass->handle_output_frame);
- flow_ret =
- klass->handle_output_frame (self, self->enc_out_port, buf, frame);
+ g_assert (klass->handle_output_frame);
+ flow_ret = klass->handle_output_frame (self, self->enc_out_port, buf, frame);
- if (is_eos || flow_ret == GST_FLOW_UNEXPECTED) {
- g_mutex_lock (self->drain_lock);
- if (self->draining) {
- GST_DEBUG_OBJECT (self, "Drained");
- self->draining = FALSE;
- g_cond_broadcast (self->drain_cond);
- } else if (flow_ret == GST_FLOW_OK) {
- GST_DEBUG_OBJECT (self, "Component signalled EOS");
- flow_ret = GST_FLOW_UNEXPECTED;
- }
- g_mutex_unlock (self->drain_lock);
- } else {
- GST_DEBUG_OBJECT (self, "Finished frame: %s",
- gst_flow_get_name (flow_ret));
- }
+ GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret));
- err = gst_omx_port_release_buffer (port, buf);
- if (err != OMX_ErrorNone)
- goto release_error;
+ err = gst_omx_port_release_buffer (port, buf);
+ if (err != OMX_ErrorNone)
+ goto release_error;
- self->downstream_flow_ret = flow_ret;
- } else {
- g_assert ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER));
- GST_VIDEO_ENCODER_STREAM_LOCK (self);
- flow_ret = GST_FLOW_UNEXPECTED;
- }
+ self->downstream_flow_ret = flow_ret;
GST_DEBUG_OBJECT (self, "Read frame from component");
@@ -913,6 +891,28 @@ flushing:
self->started = FALSE;
return;
}
+
+eos:
+ {
+ g_mutex_lock (self->drain_lock);
+ if (self->draining) {
+ GST_DEBUG_OBJECT (self, "Drained");
+ self->draining = FALSE;
+ g_cond_broadcast (self->drain_cond);
+ flow_ret = GST_FLOW_OK;
+ } else {
+ GST_DEBUG_OBJECT (self, "Component signalled EOS");
+ flow_ret = GST_FLOW_UNEXPECTED;
+ }
+ g_mutex_unlock (self->drain_lock);
+
+ if (flow_ret != GST_FLOW_OK)
+ goto flow_error;
+
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
+
+ return;
+ }
flow_error:
{
if (flow_ret == GST_FLOW_UNEXPECTED) {