diff options
Diffstat (limited to 'omx/gstomxvideodec.c')
-rw-r--r-- | omx/gstomxvideodec.c | 243 |
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, - ¶ms); - 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, + ¶ms); + 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, ¶ms); + if (flow_ret != GST_FLOW_OK) { flow_ret = - gst_buffer_pool_acquire_buffer (self->out_port_pool, - &frame->output_buffer, ¶ms); - 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) { |