diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2014-08-14 17:36:11 +0300 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2014-08-14 17:36:11 +0300 |
commit | d75334456d125bc1d1a3c694ef33e2ce4dd747cf (patch) | |
tree | 73649e4c95e0426f71bbbec4c0567e8a2313c24e | |
parent | 19d77004d2f5bd2ef76a7262c7a26cdaacc5c018 (diff) |
omx: Let base classes handle EOS
https://bugzilla.gnome.org//show_bug.cgi?id=734774
-rw-r--r-- | omx/gstomxaudiodec.c | 27 | ||||
-rw-r--r-- | omx/gstomxaudiodec.h | 3 | ||||
-rw-r--r-- | omx/gstomxaudioenc.c | 90 | ||||
-rw-r--r-- | omx/gstomxaudioenc.h | 3 | ||||
-rw-r--r-- | omx/gstomxvideodec.c | 44 | ||||
-rw-r--r-- | omx/gstomxvideodec.h | 3 | ||||
-rw-r--r-- | omx/gstomxvideoenc.c | 26 | ||||
-rw-r--r-- | omx/gstomxvideoenc.h | 3 |
8 files changed, 22 insertions, 177 deletions
diff --git a/omx/gstomxaudiodec.c b/omx/gstomxaudiodec.c index 8b6440d..e04fc25 100644 --- a/omx/gstomxaudiodec.c +++ b/omx/gstomxaudiodec.c @@ -50,8 +50,7 @@ static gboolean gst_omx_audio_dec_set_format (GstAudioDecoder * decoder, static void gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard); static GstFlowReturn gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * buffer); -static GstFlowReturn gst_omx_audio_dec_drain (GstOMXAudioDec * self, - gboolean is_eos); +static GstFlowReturn gst_omx_audio_dec_drain (GstOMXAudioDec * self); enum { @@ -701,7 +700,6 @@ gst_omx_audio_dec_start (GstAudioDecoder * decoder) self = GST_OMX_AUDIO_DEC (decoder); self->last_upstream_ts = 0; - self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; return TRUE; @@ -726,7 +724,6 @@ gst_omx_audio_dec_stop (GstAudioDecoder * decoder) self->downstream_flow_ret = GST_FLOW_FLUSHING; self->started = FALSE; - self->eos = FALSE; g_mutex_lock (&self->drain_lock); self->draining = FALSE; @@ -781,7 +778,7 @@ gst_omx_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) GST_DEBUG_OBJECT (self, "Need to disable and drain decoder"); - gst_omx_audio_dec_drain (self, FALSE); + gst_omx_audio_dec_drain (self); gst_omx_audio_dec_flush (decoder, FALSE); gst_omx_port_set_flushing (out_port, 5 * GST_SECOND, TRUE); @@ -972,7 +969,6 @@ gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard) /* Reset our state */ self->last_upstream_ts = 0; - self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; self->started = FALSE; GST_DEBUG_OBJECT (self, "Flush finished"); @@ -1001,13 +997,6 @@ gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) if (inbuf) gst_buffer_ref (inbuf); - if (self->eos) { - GST_WARNING_OBJECT (self, "Got frame after EOS"); - if (inbuf) - gst_buffer_unref (inbuf); - return GST_FLOW_EOS; - } - if (self->downstream_flow_ret != GST_FLOW_OK) { if (inbuf) gst_buffer_unref (inbuf); @@ -1021,7 +1010,7 @@ gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) } if (inbuf == NULL) - return gst_omx_audio_dec_drain (self, TRUE); + return gst_omx_audio_dec_drain (self); timestamp = GST_BUFFER_TIMESTAMP (inbuf); duration = GST_BUFFER_DURATION (inbuf); @@ -1272,7 +1261,7 @@ release_error: } static GstFlowReturn -gst_omx_audio_dec_drain (GstOMXAudioDec * self, gboolean is_eos) +gst_omx_audio_dec_drain (GstOMXAudioDec * self) { GstOMXAudioDecClass *klass; GstOMXBuffer *buf; @@ -1289,14 +1278,6 @@ gst_omx_audio_dec_drain (GstOMXAudioDec * self, gboolean is_eos) } self->started = FALSE; - /* Don't send EOS buffer twice, this doesn't work */ - if (self->eos) { - GST_DEBUG_OBJECT (self, "Component is EOS already"); - return GST_FLOW_OK; - } - if (is_eos) - self->eos = TRUE; - if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) { GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers"); return GST_FLOW_OK; diff --git a/omx/gstomxaudiodec.h b/omx/gstomxaudiodec.h index aa720d2..5cefd88 100644 --- a/omx/gstomxaudiodec.h +++ b/omx/gstomxaudiodec.h @@ -76,9 +76,6 @@ struct _GstOMXAudioDec /* TRUE if EOS buffers shouldn't be forwarded */ gboolean draining; - /* TRUE if upstream is EOS */ - gboolean eos; - GstFlowReturn downstream_flow_ret; }; diff --git a/omx/gstomxaudioenc.c b/omx/gstomxaudioenc.c index 2557d81..3049253 100644 --- a/omx/gstomxaudioenc.c +++ b/omx/gstomxaudioenc.c @@ -41,8 +41,6 @@ static gboolean gst_omx_audio_enc_start (GstAudioEncoder * encoder); static gboolean gst_omx_audio_enc_stop (GstAudioEncoder * encoder); static gboolean gst_omx_audio_enc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info); -static gboolean gst_omx_audio_enc_sink_event (GstAudioEncoder * encoder, - GstEvent * event); static GstFlowReturn gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * buffer); static void gst_omx_audio_enc_flush (GstAudioEncoder * encoder); @@ -82,8 +80,6 @@ gst_omx_audio_enc_class_init (GstOMXAudioEncClass * klass) GST_DEBUG_FUNCPTR (gst_omx_audio_enc_set_format); audio_encoder_class->handle_frame = GST_DEBUG_FUNCPTR (gst_omx_audio_enc_handle_frame); - audio_encoder_class->sink_event = - GST_DEBUG_FUNCPTR (gst_omx_audio_enc_sink_event); klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER; klass->cdata.default_sink_template_caps = "audio/x-raw, " @@ -592,7 +588,6 @@ gst_omx_audio_enc_start (GstAudioEncoder * encoder) self = GST_OMX_AUDIO_ENC (encoder); self->last_upstream_ts = 0; - self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; return TRUE; @@ -617,7 +612,6 @@ gst_omx_audio_enc_stop (GstAudioEncoder * encoder) self->downstream_flow_ret = GST_FLOW_FLUSHING; self->started = FALSE; - self->eos = FALSE; g_mutex_lock (&self->drain_lock); self->draining = FALSE; @@ -887,7 +881,7 @@ gst_omx_audio_enc_flush (GstAudioEncoder * encoder) /* Start the srcpad loop again */ self->last_upstream_ts = 0; self->downstream_flow_ret = GST_FLOW_OK; - self->eos = FALSE; + self->started = FALSE; gst_pad_start_task (GST_AUDIO_ENCODER_SRC_PAD (self), (GstTaskFunction) gst_omx_audio_enc_loop, encoder, NULL); } @@ -906,11 +900,6 @@ gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf) self = GST_OMX_AUDIO_ENC (encoder); - if (self->eos) { - GST_WARNING_OBJECT (self, "Got frame after EOS"); - return GST_FLOW_EOS; - } - if (self->downstream_flow_ret != GST_FLOW_OK) { return self->downstream_flow_ret; } @@ -1085,77 +1074,6 @@ release_error: } } -static gboolean -gst_omx_audio_enc_sink_event (GstAudioEncoder * encoder, GstEvent * event) -{ - GstOMXAudioEnc *self; - GstOMXAudioEncClass *klass; - OMX_ERRORTYPE err; - - self = GST_OMX_AUDIO_ENC (encoder); - klass = GST_OMX_AUDIO_ENC_GET_CLASS (self); - - if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { - GstOMXBuffer *buf; - GstOMXAcquireBufferReturn acq_ret; - - GST_DEBUG_OBJECT (self, "Sending EOS to the component"); - - /* Don't send EOS buffer twice, this doesn't work */ - if (self->eos) { - GST_DEBUG_OBJECT (self, "Component is already EOS"); - return TRUE; - } - self->eos = TRUE; - - if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) { - GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers"); - - /* Insert a NULL into the queue to signal EOS */ - g_mutex_lock (&self->enc->lock); - g_queue_push_tail (&self->enc_out_port->pending_buffers, NULL); - g_mutex_unlock (&self->enc->lock); - g_mutex_lock (&self->enc->messages_lock); - g_cond_broadcast (&self->enc->messages_cond); - g_mutex_unlock (&self->enc->messages_lock); - return TRUE; - } - - /* 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); - - /* Send an EOS buffer to the component and let the base - * class drop the EOS event. We will send it later when - * the EOS buffer arrives on the output port. */ - acq_ret = gst_omx_port_acquire_buffer (self->enc_in_port, &buf); - if (acq_ret == GST_OMX_ACQUIRE_BUFFER_OK) { - buf->omx_buf->nFilledLen = 0; - buf->omx_buf->nTimeStamp = - gst_util_uint64_scale (self->last_upstream_ts, OMX_TICKS_PER_SECOND, - GST_SECOND); - buf->omx_buf->nTickCount = 0; - buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS; - err = gst_omx_port_release_buffer (self->enc_in_port, buf); - if (err != OMX_ErrorNone) { - GST_ERROR_OBJECT (self, "Failed to send EOS to component: %s (0x%08x)", - gst_omx_error_to_string (err), err); - } else { - GST_DEBUG_OBJECT (self, "Sent EOS to the component"); - } - } else { - GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", acq_ret); - } - - GST_AUDIO_ENCODER_STREAM_LOCK (self); - - return TRUE; - } - - return FALSE; -} - static GstFlowReturn gst_omx_audio_enc_drain (GstOMXAudioEnc * self) { @@ -1174,12 +1092,6 @@ gst_omx_audio_enc_drain (GstOMXAudioEnc * self) } self->started = FALSE; - /* Don't send EOS buffer twice, this doesn't work */ - if (self->eos) { - GST_DEBUG_OBJECT (self, "Component is EOS already"); - return GST_FLOW_OK; - } - if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) { GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers"); return GST_FLOW_OK; diff --git a/omx/gstomxaudioenc.h b/omx/gstomxaudioenc.h index f7527be..8fe5369 100644 --- a/omx/gstomxaudioenc.h +++ b/omx/gstomxaudioenc.h @@ -60,9 +60,6 @@ struct _GstOMXAudioEnc GstClockTime last_upstream_ts; - /* TRUE if upstream is EOS */ - gboolean eos; - /* Draining state */ GMutex drain_lock; GCond drain_cond; diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c index 8590301..cd24944 100644 --- a/omx/gstomxvideodec.c +++ b/omx/gstomxvideodec.c @@ -75,8 +75,7 @@ static GstFlowReturn gst_omx_video_dec_finish (GstVideoDecoder * decoder); static gboolean gst_omx_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query); -static GstFlowReturn gst_omx_video_dec_drain (GstOMXVideoDec * self, - gboolean is_eos); +static GstFlowReturn gst_omx_video_dec_drain (GstOMXVideoDec * self); static OMX_ERRORTYPE gst_omx_video_dec_allocate_output_buffers (GstOMXVideoDec * self); @@ -1654,7 +1653,6 @@ gst_omx_video_dec_start (GstVideoDecoder * decoder) self = GST_OMX_VIDEO_DEC (decoder); self->last_upstream_ts = 0; - self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; return TRUE; @@ -1688,7 +1686,6 @@ gst_omx_video_dec_stop (GstVideoDecoder * decoder) self->downstream_flow_ret = GST_FLOW_FLUSHING; self->started = FALSE; - self->eos = FALSE; g_mutex_lock (&self->drain_lock); self->draining = FALSE; @@ -1862,7 +1859,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder, GST_DEBUG_OBJECT (self, "Need to disable and drain decoder"); - gst_omx_video_dec_drain (self, FALSE); + gst_omx_video_dec_drain (self); gst_omx_video_dec_flush (decoder); gst_omx_port_set_flushing (out_port, 5 * GST_SECOND, TRUE); @@ -2067,15 +2064,7 @@ gst_omx_video_dec_flush (GstVideoDecoder * decoder) if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded) return TRUE; - /* 0) Wait until the srcpad loop is stopped, - * unlock GST_VIDEO_DECODER_STREAM_LOCK to prevent deadlocks - * caused by using this lock from inside the loop function */ - GST_VIDEO_DECODER_STREAM_UNLOCK (self); - gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder)); - GST_DEBUG_OBJECT (self, "Flushing -- task stopped"); - GST_VIDEO_DECODER_STREAM_LOCK (self); - - /* 1) Pause the components */ + /* 0) Pause the components */ if (gst_omx_component_get_state (self->dec, 0) == OMX_StateExecuting) { gst_omx_component_set_state (self->dec, OMX_StatePause); gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE); @@ -2089,6 +2078,14 @@ gst_omx_video_dec_flush (GstVideoDecoder * decoder) } #endif + /* 1) Wait until the srcpad loop is stopped, + * unlock GST_VIDEO_DECODER_STREAM_LOCK to prevent deadlocks + * caused by using this lock from inside the loop function */ + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder)); + GST_DEBUG_OBJECT (self, "Flushing -- task stopped"); + GST_VIDEO_DECODER_STREAM_LOCK (self); + /* 2) Flush the ports */ GST_DEBUG_OBJECT (self, "flushing ports"); gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE); @@ -2135,7 +2132,6 @@ gst_omx_video_dec_flush (GstVideoDecoder * decoder) /* Reset our state */ self->last_upstream_ts = 0; - self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; self->started = FALSE; GST_DEBUG_OBJECT (self, "Flush finished"); @@ -2162,12 +2158,6 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, GST_DEBUG_OBJECT (self, "Handling frame"); - if (self->eos) { - GST_WARNING_OBJECT (self, "Got frame after EOS"); - gst_video_codec_frame_unref (frame); - return GST_FLOW_EOS; - } - if (!self->started) { if (!GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) { gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame); @@ -2434,11 +2424,11 @@ gst_omx_video_dec_finish (GstVideoDecoder * decoder) self = GST_OMX_VIDEO_DEC (decoder); - return gst_omx_video_dec_drain (self, TRUE); + return gst_omx_video_dec_drain (self); } static GstFlowReturn -gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) +gst_omx_video_dec_drain (GstOMXVideoDec * self) { GstOMXVideoDecClass *klass; GstOMXBuffer *buf; @@ -2455,14 +2445,6 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) } self->started = FALSE; - /* Don't send EOS buffer twice, this doesn't work */ - if (self->eos) { - GST_DEBUG_OBJECT (self, "Component is EOS already"); - return GST_FLOW_OK; - } - if (is_eos) - self->eos = TRUE; - if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) { GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers"); return GST_FLOW_OK; diff --git a/omx/gstomxvideodec.h b/omx/gstomxvideodec.h index 3978865..c79b66d 100644 --- a/omx/gstomxvideodec.h +++ b/omx/gstomxvideodec.h @@ -74,9 +74,6 @@ struct _GstOMXVideoDec /* TRUE if EOS buffers shouldn't be forwarded */ gboolean draining; - /* TRUE if upstream is EOS */ - gboolean eos; - GstFlowReturn downstream_flow_ret; #ifdef USE_OMX_TARGET_RPI GstOMXComponent *egl_render; diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c index 0f64a02..d055816 100644 --- a/omx/gstomxvideoenc.c +++ b/omx/gstomxvideoenc.c @@ -83,8 +83,7 @@ static gboolean gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder, static GstCaps *gst_omx_video_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter); -static GstFlowReturn gst_omx_video_enc_drain (GstOMXVideoEnc * self, - gboolean at_eos); +static GstFlowReturn gst_omx_video_enc_drain (GstOMXVideoEnc * self); static GstFlowReturn gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame); @@ -882,7 +881,6 @@ gst_omx_video_enc_start (GstVideoEncoder * encoder) self = GST_OMX_VIDEO_ENC (encoder); self->last_upstream_ts = 0; - self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; return TRUE; @@ -907,7 +905,6 @@ gst_omx_video_enc_stop (GstVideoEncoder * encoder) self->downstream_flow_ret = GST_FLOW_FLUSHING; self->started = FALSE; - self->eos = FALSE; if (self->input_state) gst_video_codec_state_unref (self->input_state); @@ -951,7 +948,7 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder, */ if (needs_disable) { GST_DEBUG_OBJECT (self, "Need to disable and drain encoder"); - gst_omx_video_enc_drain (self, FALSE); + gst_omx_video_enc_drain (self); gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, TRUE); /* Wait until the srcpad loop is finished, @@ -1206,7 +1203,6 @@ gst_omx_video_enc_flush (GstVideoEncoder * encoder) /* Start the srcpad loop again */ self->last_upstream_ts = 0; - self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_VIDEO_ENCODER_SRC_PAD (self), (GstTaskFunction) gst_omx_video_enc_loop, encoder, NULL); @@ -1394,12 +1390,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, GST_DEBUG_OBJECT (self, "Handling frame"); - if (self->eos) { - GST_WARNING_OBJECT (self, "Got frame after EOS"); - gst_video_codec_frame_unref (frame); - return GST_FLOW_EOS; - } - if (self->downstream_flow_ret != GST_FLOW_OK) { gst_video_codec_frame_unref (frame); return self->downstream_flow_ret; @@ -1606,11 +1596,11 @@ gst_omx_video_enc_finish (GstVideoEncoder * encoder) self = GST_OMX_VIDEO_ENC (encoder); - return gst_omx_video_enc_drain (self, TRUE); + return gst_omx_video_enc_drain (self); } static GstFlowReturn -gst_omx_video_enc_drain (GstOMXVideoEnc * self, gboolean at_eos) +gst_omx_video_enc_drain (GstOMXVideoEnc * self) { GstOMXVideoEncClass *klass; GstOMXBuffer *buf; @@ -1627,14 +1617,6 @@ gst_omx_video_enc_drain (GstOMXVideoEnc * self, gboolean at_eos) } self->started = FALSE; - /* Don't send EOS buffer twice, this doesn't work */ - if (self->eos) { - GST_DEBUG_OBJECT (self, "Component is EOS already"); - return GST_FLOW_OK; - } - if (at_eos) - self->eos = TRUE; - if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) { GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers"); return GST_FLOW_OK; diff --git a/omx/gstomxvideoenc.h b/omx/gstomxvideoenc.h index e266537..176ea99 100644 --- a/omx/gstomxvideoenc.h +++ b/omx/gstomxvideoenc.h @@ -67,9 +67,6 @@ struct _GstOMXVideoEnc /* TRUE if EOS buffers shouldn't be forwarded */ gboolean draining; - /* TRUE if upstream is EOS */ - gboolean eos; - /* properties */ guint32 control_rate; guint32 target_bitrate; |