summaryrefslogtreecommitdiff
path: root/omx/gstomxvideodec.c
diff options
context:
space:
mode:
Diffstat (limited to 'omx/gstomxvideodec.c')
-rw-r--r--omx/gstomxvideodec.c243
1 files changed, 121 insertions, 122 deletions
diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
index b190dbb..cd8e9bb 100644
--- a/omx/gstomxvideodec.c
+++ b/omx/gstomxvideodec.c
@@ -1361,23 +1361,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_has_current_caps (GST_VIDEO_DECODER_SRC_PAD (self)) ||
@@ -1490,85 +1488,102 @@ 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);
-
- 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;
+ GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %lu",
+ buf->omx_buf->nFlags, buf->omx_buf->nTimeStamp);
- /* 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");
- if (self->out_port_pool) {
- gint i, n;
- GstBufferPoolAcquireParams params = { 0, };
+ if (self->out_port_pool) {
+ gint i, n;
+ GstBufferPoolAcquireParams params = { 0, };
- n = port->buffers->len;
- for (i = 0; i < n; i++) {
- GstOMXBuffer *tmp = g_ptr_array_index (port->buffers, i);
+ n = port->buffers->len;
+ for (i = 0; i < n; i++) {
+ GstOMXBuffer *tmp = g_ptr_array_index (port->buffers, i);
- if (tmp == buf)
- break;
- }
- g_assert (i != n);
+ if (tmp == buf)
+ break;
+ }
+ g_assert (i != n);
- GST_OMX_BUFFER_POOL (self->out_port_pool)->current_buffer_index = i;
- flow_ret =
- gst_buffer_pool_acquire_buffer (self->out_port_pool, &outbuf,
- &params);
- if (flow_ret != GST_FLOW_OK) {
- gst_omx_port_release_buffer (port, buf);
- goto invalid_buffer;
- }
- buf = NULL;
- } else {
- outbuf =
- gst_video_decoder_allocate_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;
- }
+ GST_OMX_BUFFER_POOL (self->out_port_pool)->current_buffer_index = i;
+ flow_ret =
+ gst_buffer_pool_acquire_buffer (self->out_port_pool, &outbuf,
+ &params);
+ if (flow_ret != GST_FLOW_OK) {
+ gst_omx_port_release_buffer (port, buf);
+ goto invalid_buffer;
}
+ buf = NULL;
+ } else {
+ outbuf =
+ gst_video_decoder_allocate_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;
+ }
+ }
- flow_ret = gst_pad_push (GST_VIDEO_DECODER_SRC_PAD (self), outbuf);
- } else if (buf->omx_buf->nFilledLen > 0) {
- if (self->out_port_pool) {
- gint i, n;
- GstBufferPoolAcquireParams params = { 0, };
+ flow_ret = gst_pad_push (GST_VIDEO_DECODER_SRC_PAD (self), outbuf);
+ } else if (buf->omx_buf->nFilledLen > 0) {
+ if (self->out_port_pool) {
+ gint i, n;
+ GstBufferPoolAcquireParams params = { 0, };
- n = port->buffers->len;
- for (i = 0; i < n; i++) {
- GstOMXBuffer *tmp = g_ptr_array_index (port->buffers, i);
+ n = port->buffers->len;
+ for (i = 0; i < n; i++) {
+ GstOMXBuffer *tmp = g_ptr_array_index (port->buffers, i);
- if (tmp == buf)
- break;
- }
- g_assert (i != n);
+ if (tmp == buf)
+ break;
+ }
+ g_assert (i != n);
- GST_OMX_BUFFER_POOL (self->out_port_pool)->current_buffer_index = i;
+ GST_OMX_BUFFER_POOL (self->out_port_pool)->current_buffer_index = i;
+ flow_ret =
+ gst_buffer_pool_acquire_buffer (self->out_port_pool,
+ &frame->output_buffer, &params);
+ if (flow_ret != GST_FLOW_OK) {
flow_ret =
- gst_buffer_pool_acquire_buffer (self->out_port_pool,
- &frame->output_buffer, &params);
- if (flow_ret != GST_FLOW_OK) {
+ 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_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
+ frame = NULL;
+ buf = NULL;
+ } else {
+ if ((flow_ret =
+ gst_video_decoder_allocate_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;
@@ -1578,64 +1593,25 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
flow_ret =
gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
frame = NULL;
- buf = NULL;
- } else {
- if ((flow_ret =
- gst_video_decoder_allocate_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_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;
}
+ } 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_EOS) {
- 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_EOS;
- }
- 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_EOS;
+ 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;
@@ -1665,6 +1641,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_EOS;
+ }
+ 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_EOS) {