diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2013-03-14 12:49:42 +0100 |
---|---|---|
committer | Josep Torra <n770galaxy@gmail.com> | 2013-03-15 10:07:43 +0100 |
commit | 931beef8c0a275b670b765f1bf3458998ec9c755 (patch) | |
tree | 2c47f30af11c869eb60c22b542e319c6acafca44 | |
parent | 7a888e7ba541ec59a34522efb2b54b555234bd78 (diff) | |
download | gst-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.c | 56 | ||||
-rw-r--r-- | omx/gstomx.h | 8 | ||||
-rw-r--r-- | omx/gstomxaudioenc.c | 184 | ||||
-rw-r--r-- | omx/gstomxvideodec.c | 161 | ||||
-rw-r--r-- | omx/gstomxvideoenc.c | 70 |
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) { |