mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
androidmedia: Fix draining logic to let the base class handle EOS events
https://bugzilla.gnome.org//show_bug.cgi?id=734775
This commit is contained in:
parent
17181bfe16
commit
ca62186797
6 changed files with 39 additions and 101 deletions
|
@ -717,7 +717,7 @@ gst_amc_audio_dec_start (GstAudioDecoder * decoder)
|
||||||
|
|
||||||
self = GST_AMC_AUDIO_DEC (decoder);
|
self = GST_AMC_AUDIO_DEC (decoder);
|
||||||
self->last_upstream_ts = 0;
|
self->last_upstream_ts = 0;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
self->downstream_flow_ret = GST_FLOW_OK;
|
self->downstream_flow_ret = GST_FLOW_OK;
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
|
@ -758,7 +758,7 @@ gst_amc_audio_dec_stop (GstAudioDecoder * decoder)
|
||||||
self->codec_datas = NULL;
|
self->codec_datas = NULL;
|
||||||
|
|
||||||
self->downstream_flow_ret = GST_FLOW_FLUSHING;
|
self->downstream_flow_ret = GST_FLOW_FLUSHING;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
g_mutex_lock (&self->drain_lock);
|
g_mutex_lock (&self->drain_lock);
|
||||||
self->draining = FALSE;
|
self->draining = FALSE;
|
||||||
g_cond_broadcast (&self->drain_cond);
|
g_cond_broadcast (&self->drain_cond);
|
||||||
|
@ -990,7 +990,7 @@ gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard)
|
||||||
|
|
||||||
/* Start the srcpad loop again */
|
/* Start the srcpad loop again */
|
||||||
self->last_upstream_ts = 0;
|
self->last_upstream_ts = 0;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
self->downstream_flow_ret = GST_FLOW_OK;
|
self->downstream_flow_ret = GST_FLOW_OK;
|
||||||
gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self),
|
gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self),
|
||||||
(GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL);
|
(GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL);
|
||||||
|
@ -1029,13 +1029,6 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->eos) {
|
|
||||||
GST_WARNING_OBJECT (self, "Got frame after EOS");
|
|
||||||
if (inbuf)
|
|
||||||
gst_buffer_unref (inbuf);
|
|
||||||
return GST_FLOW_EOS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->flushing)
|
if (self->flushing)
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
|
||||||
|
@ -1144,6 +1137,7 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
}
|
}
|
||||||
goto queue_error;
|
goto queue_error;
|
||||||
}
|
}
|
||||||
|
self->drained = FALSE;
|
||||||
}
|
}
|
||||||
gst_buffer_unmap (inbuf, &minfo);
|
gst_buffer_unmap (inbuf, &minfo);
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
|
@ -1212,9 +1206,9 @@ gst_amc_audio_dec_drain (GstAmcAudioDec * self)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't send EOS buffer twice, this doesn't work */
|
/* Don't send drain buffer twice, this doesn't work */
|
||||||
if (self->eos) {
|
if (self->drained) {
|
||||||
GST_DEBUG_OBJECT (self, "Codec is EOS already");
|
GST_DEBUG_OBJECT (self, "Codec is drained already");
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,6 +1252,8 @@ gst_amc_audio_dec_drain (GstAmcAudioDec * self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->drained = TRUE;
|
||||||
|
self->draining = FALSE;
|
||||||
g_mutex_unlock (&self->drain_lock);
|
g_mutex_unlock (&self->drain_lock);
|
||||||
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
||||||
} else if (idx >= self->n_input_buffers) {
|
} else if (idx >= self->n_input_buffers) {
|
||||||
|
|
|
@ -78,9 +78,8 @@ struct _GstAmcAudioDec
|
||||||
GCond drain_cond;
|
GCond drain_cond;
|
||||||
/* TRUE if EOS buffers shouldn't be forwarded */
|
/* TRUE if EOS buffers shouldn't be forwarded */
|
||||||
gboolean draining;
|
gboolean draining;
|
||||||
|
/* TRUE if the component is drained currently */
|
||||||
/* TRUE if upstream is EOS */
|
gboolean drained;
|
||||||
gboolean eos;
|
|
||||||
|
|
||||||
GstFlowReturn downstream_flow_ret;
|
GstFlowReturn downstream_flow_ret;
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,7 @@ static GstFlowReturn gst_amc_video_dec_finish (GstVideoDecoder * decoder);
|
||||||
static gboolean gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec,
|
static gboolean gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec,
|
||||||
GstQuery * query);
|
GstQuery * query);
|
||||||
|
|
||||||
static GstFlowReturn gst_amc_video_dec_drain (GstAmcVideoDec * self,
|
static GstFlowReturn gst_amc_video_dec_drain (GstAmcVideoDec * self);
|
||||||
gboolean at_eos);
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -874,7 +873,7 @@ gst_amc_video_dec_start (GstVideoDecoder * decoder)
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_DEC (decoder);
|
self = GST_AMC_VIDEO_DEC (decoder);
|
||||||
self->last_upstream_ts = 0;
|
self->last_upstream_ts = 0;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
self->downstream_flow_ret = GST_FLOW_OK;
|
self->downstream_flow_ret = GST_FLOW_OK;
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
|
@ -909,7 +908,7 @@ gst_amc_video_dec_stop (GstVideoDecoder * decoder)
|
||||||
gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder));
|
gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder));
|
||||||
|
|
||||||
self->downstream_flow_ret = GST_FLOW_FLUSHING;
|
self->downstream_flow_ret = GST_FLOW_FLUSHING;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
g_mutex_lock (&self->drain_lock);
|
g_mutex_lock (&self->drain_lock);
|
||||||
self->draining = FALSE;
|
self->draining = FALSE;
|
||||||
g_cond_broadcast (&self->drain_cond);
|
g_cond_broadcast (&self->drain_cond);
|
||||||
|
@ -983,7 +982,7 @@ gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needs_disable && is_format_change) {
|
if (needs_disable && is_format_change) {
|
||||||
gst_amc_video_dec_drain (self, FALSE);
|
gst_amc_video_dec_drain (self);
|
||||||
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
|
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
|
||||||
gst_amc_video_dec_stop (GST_VIDEO_DECODER (self));
|
gst_amc_video_dec_stop (GST_VIDEO_DECODER (self));
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||||
|
@ -1104,7 +1103,7 @@ gst_amc_video_dec_flush (GstVideoDecoder * decoder)
|
||||||
|
|
||||||
/* Start the srcpad loop again */
|
/* Start the srcpad loop again */
|
||||||
self->last_upstream_ts = 0;
|
self->last_upstream_ts = 0;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
self->downstream_flow_ret = GST_FLOW_OK;
|
self->downstream_flow_ret = GST_FLOW_OK;
|
||||||
gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self),
|
gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self),
|
||||||
(GstTaskFunction) gst_amc_video_dec_loop, decoder, NULL);
|
(GstTaskFunction) gst_amc_video_dec_loop, decoder, NULL);
|
||||||
|
@ -1139,12 +1138,6 @@ gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->eos) {
|
|
||||||
GST_WARNING_OBJECT (self, "Got frame after EOS");
|
|
||||||
gst_video_codec_frame_unref (frame);
|
|
||||||
return GST_FLOW_EOS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->flushing)
|
if (self->flushing)
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
|
||||||
|
@ -1254,6 +1247,7 @@ gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
}
|
}
|
||||||
goto queue_error;
|
goto queue_error;
|
||||||
}
|
}
|
||||||
|
self->drained = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unmap (frame->input_buffer, &minfo);
|
gst_buffer_unmap (frame->input_buffer, &minfo);
|
||||||
|
@ -1312,11 +1306,11 @@ gst_amc_video_dec_finish (GstVideoDecoder * decoder)
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_DEC (decoder);
|
self = GST_AMC_VIDEO_DEC (decoder);
|
||||||
|
|
||||||
return gst_amc_video_dec_drain (self, TRUE);
|
return gst_amc_video_dec_drain (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_amc_video_dec_drain (GstAmcVideoDec * self, gboolean at_eos)
|
gst_amc_video_dec_drain (GstAmcVideoDec * self)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
@ -1328,13 +1322,11 @@ gst_amc_video_dec_drain (GstAmcVideoDec * self, gboolean at_eos)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't send EOS buffer twice, this doesn't work */
|
/* Don't send drain buffer twice, this doesn't work */
|
||||||
if (self->eos) {
|
if (self->drained) {
|
||||||
GST_DEBUG_OBJECT (self, "Codec is EOS already");
|
GST_DEBUG_OBJECT (self, "Codec is drained already");
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
if (at_eos)
|
|
||||||
self->eos = TRUE;
|
|
||||||
|
|
||||||
/* Make sure to release the base class stream lock, otherwise
|
/* Make sure to release the base class stream lock, otherwise
|
||||||
* _loop() can't call _finish_frame() and we might block forever
|
* _loop() can't call _finish_frame() and we might block forever
|
||||||
|
@ -1376,6 +1368,8 @@ gst_amc_video_dec_drain (GstAmcVideoDec * self, gboolean at_eos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->drained = TRUE;
|
||||||
|
self->draining = FALSE;
|
||||||
g_mutex_unlock (&self->drain_lock);
|
g_mutex_unlock (&self->drain_lock);
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||||
} else if (idx >= self->n_input_buffers) {
|
} else if (idx >= self->n_input_buffers) {
|
||||||
|
|
|
@ -75,9 +75,8 @@ struct _GstAmcVideoDec
|
||||||
GCond drain_cond;
|
GCond drain_cond;
|
||||||
/* TRUE if EOS buffers shouldn't be forwarded */
|
/* TRUE if EOS buffers shouldn't be forwarded */
|
||||||
gboolean draining;
|
gboolean draining;
|
||||||
|
/* TRUE if the component is drained currently */
|
||||||
/* TRUE if upstream is EOS */
|
gboolean drained;
|
||||||
gboolean eos;
|
|
||||||
|
|
||||||
GstFlowReturn downstream_flow_ret;
|
GstFlowReturn downstream_flow_ret;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1172,7 +1172,7 @@ gst_amc_video_enc_start (GstVideoEncoder * encoder)
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_ENC (encoder);
|
self = GST_AMC_VIDEO_ENC (encoder);
|
||||||
self->last_upstream_ts = 0;
|
self->last_upstream_ts = 0;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
self->downstream_flow_ret = GST_FLOW_OK;
|
self->downstream_flow_ret = GST_FLOW_OK;
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
|
@ -1207,7 +1207,7 @@ gst_amc_video_enc_stop (GstVideoEncoder * encoder)
|
||||||
gst_pad_stop_task (GST_VIDEO_ENCODER_SRC_PAD (encoder));
|
gst_pad_stop_task (GST_VIDEO_ENCODER_SRC_PAD (encoder));
|
||||||
|
|
||||||
self->downstream_flow_ret = GST_FLOW_FLUSHING;
|
self->downstream_flow_ret = GST_FLOW_FLUSHING;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
g_mutex_lock (&self->drain_lock);
|
g_mutex_lock (&self->drain_lock);
|
||||||
self->draining = FALSE;
|
self->draining = FALSE;
|
||||||
g_cond_broadcast (&self->drain_cond);
|
g_cond_broadcast (&self->drain_cond);
|
||||||
|
@ -1384,7 +1384,7 @@ gst_amc_video_enc_flush (GstVideoEncoder * encoder)
|
||||||
|
|
||||||
/* Start the srcpad loop again */
|
/* Start the srcpad loop again */
|
||||||
self->last_upstream_ts = 0;
|
self->last_upstream_ts = 0;
|
||||||
self->eos = FALSE;
|
self->drained = TRUE;
|
||||||
self->downstream_flow_ret = GST_FLOW_OK;
|
self->downstream_flow_ret = GST_FLOW_OK;
|
||||||
gst_pad_start_task (GST_VIDEO_ENCODER_SRC_PAD (self),
|
gst_pad_start_task (GST_VIDEO_ENCODER_SRC_PAD (self),
|
||||||
(GstTaskFunction) gst_amc_video_enc_loop, encoder, NULL);
|
(GstTaskFunction) gst_amc_video_enc_loop, encoder, NULL);
|
||||||
|
@ -1416,12 +1416,6 @@ gst_amc_video_enc_handle_frame (GstVideoEncoder * encoder,
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->eos) {
|
|
||||||
GST_WARNING_OBJECT (self, "Got frame after EOS");
|
|
||||||
gst_video_codec_frame_unref (frame);
|
|
||||||
return GST_FLOW_EOS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->flushing)
|
if (self->flushing)
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
|
||||||
|
@ -1527,6 +1521,8 @@ again:
|
||||||
goto queue_error;
|
goto queue_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->drained = FALSE;
|
||||||
|
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
|
|
||||||
return self->downstream_flow_ret;
|
return self->downstream_flow_ret;
|
||||||
|
@ -1578,57 +1574,10 @@ static GstFlowReturn
|
||||||
gst_amc_video_enc_finish (GstVideoEncoder * encoder)
|
gst_amc_video_enc_finish (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstAmcVideoEnc *self;
|
GstAmcVideoEnc *self;
|
||||||
gint idx;
|
|
||||||
GError *err = NULL;
|
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_ENC (encoder);
|
self = GST_AMC_VIDEO_ENC (encoder);
|
||||||
GST_DEBUG_OBJECT (self, "Sending EOS to the component");
|
|
||||||
|
|
||||||
/* Don't send EOS buffer twice, this doesn't work */
|
return gst_amc_video_enc_drain (self);
|
||||||
if (self->eos) {
|
|
||||||
GST_DEBUG_OBJECT (self, "Component is already EOS");
|
|
||||||
return GST_VIDEO_ENCODER_FLOW_DROPPED;
|
|
||||||
}
|
|
||||||
self->eos = 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_VIDEO_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.
|
|
||||||
* Wait at most 0.5s here. */
|
|
||||||
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000, &err);
|
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
|
||||||
|
|
||||||
if (idx >= 0 && idx < self->n_input_buffers) {
|
|
||||||
GstAmcBufferInfo buffer_info;
|
|
||||||
|
|
||||||
memset (&buffer_info, 0, sizeof (buffer_info));
|
|
||||||
buffer_info.size = 0;
|
|
||||||
buffer_info.presentation_time_us =
|
|
||||||
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
|
||||||
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
|
||||||
|
|
||||||
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err)) {
|
|
||||||
GST_DEBUG_OBJECT (self, "Sent EOS to the codec");
|
|
||||||
} else {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to send EOS to the codec");
|
|
||||||
if (!self->flushing)
|
|
||||||
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
|
||||||
g_clear_error (&err);
|
|
||||||
}
|
|
||||||
} else if (idx >= self->n_input_buffers) {
|
|
||||||
GST_ERROR_OBJECT (self, "Invalid input buffer index %d of %d",
|
|
||||||
idx, self->n_input_buffers);
|
|
||||||
} else {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to dequeue input buffer for EOS: %d", idx);
|
|
||||||
if (err)
|
|
||||||
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GST_VIDEO_ENCODER_FLOW_DROPPED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -1644,9 +1593,9 @@ gst_amc_video_enc_drain (GstAmcVideoEnc * self)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't send EOS buffer twice, this doesn't work */
|
/* Don't send drain buffer twice, this doesn't work */
|
||||||
if (self->eos) {
|
if (self->drained) {
|
||||||
GST_DEBUG_OBJECT (self, "Codec is EOS already");
|
GST_DEBUG_OBJECT (self, "Codec is drained already");
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1690,6 +1639,8 @@ gst_amc_video_enc_drain (GstAmcVideoEnc * self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->drained = TRUE;
|
||||||
|
self->draining = FALSE;
|
||||||
g_mutex_unlock (&self->drain_lock);
|
g_mutex_unlock (&self->drain_lock);
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
||||||
} else if (idx >= self->n_input_buffers) {
|
} else if (idx >= self->n_input_buffers) {
|
||||||
|
|
|
@ -78,9 +78,8 @@ struct _GstAmcVideoEnc
|
||||||
GCond drain_cond;
|
GCond drain_cond;
|
||||||
/* TRUE if EOS buffers shouldn't be forwarded */
|
/* TRUE if EOS buffers shouldn't be forwarded */
|
||||||
gboolean draining;
|
gboolean draining;
|
||||||
|
/* TRUE if the component is drained */
|
||||||
/* TRUE if upstream is EOS */
|
gboolean drained;
|
||||||
gboolean eos;
|
|
||||||
|
|
||||||
GstFlowReturn downstream_flow_ret;
|
GstFlowReturn downstream_flow_ret;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue