mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 04:45:36 +00:00
videodecoder: push pending events before gap
Push all pending events before pushing the gap. This ensures the segment is pushed before the gap so it can be properly translated to the running time Includes unit test. https://bugzilla.gnome.org/show_bug.cgi?id=753360
This commit is contained in:
parent
4665c0802a
commit
e59d1308cc
2 changed files with 82 additions and 13 deletions
|
@ -439,6 +439,8 @@ static void gst_video_decoder_reset (GstVideoDecoder * decoder, gboolean full,
|
|||
static GstFlowReturn gst_video_decoder_decode_frame (GstVideoDecoder * decoder,
|
||||
GstVideoCodecFrame * frame);
|
||||
|
||||
static void gst_video_decoder_push_event_list (GstVideoDecoder * decoder,
|
||||
GList * events);
|
||||
static GstClockTime gst_video_decoder_get_frame_duration (GstVideoDecoder *
|
||||
decoder, GstVideoCodecFrame * frame);
|
||||
static GstVideoCodecFrame *gst_video_decoder_new_frame (GstVideoDecoder *
|
||||
|
@ -1222,6 +1224,8 @@ gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
|
|||
{
|
||||
GstFlowReturn flow_ret = GST_FLOW_OK;
|
||||
gboolean needs_reconfigure = FALSE;
|
||||
GList *events;
|
||||
GList *frame_events;
|
||||
|
||||
flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
|
||||
ret = (flow_ret == GST_FLOW_OK);
|
||||
|
@ -1247,8 +1251,19 @@ gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
|
|||
gst_pad_mark_reconfigure (decoder->srcpad);
|
||||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (decoder, "Pushing all pending serialized events"
|
||||
" before the gap");
|
||||
events = decoder->priv->pending_events;
|
||||
frame_events = decoder->priv->current_frame_events;
|
||||
decoder->priv->pending_events = NULL;
|
||||
decoder->priv->current_frame_events = NULL;
|
||||
|
||||
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||||
|
||||
gst_video_decoder_push_event_list (decoder, events);
|
||||
gst_video_decoder_push_event_list (decoder, frame_events);
|
||||
|
||||
/* Forward GAP immediately. Everything is drained after
|
||||
* the GAP event and we can forward this event immediately
|
||||
* now without having buffers out of order.
|
||||
|
@ -2543,6 +2558,19 @@ gst_video_decoder_new_frame (GstVideoDecoder * decoder)
|
|||
return frame;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_decoder_push_event_list (GstVideoDecoder * decoder, GList * events)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
/* events are stored in reverse order */
|
||||
for (l = g_list_last (events); l; l = g_list_previous (l)) {
|
||||
GST_LOG_OBJECT (decoder, "pushing %s event", GST_EVENT_TYPE_NAME (l->data));
|
||||
gst_video_decoder_push_event (decoder, l->data);
|
||||
}
|
||||
g_list_free (events);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_decoder_prepare_finish_frame (GstVideoDecoder *
|
||||
decoder, GstVideoCodecFrame * frame, gboolean dropping)
|
||||
|
@ -2584,21 +2612,10 @@ gst_video_decoder_prepare_finish_frame (GstVideoDecoder *
|
|||
decoder->priv->pending_events =
|
||||
g_list_concat (decoder->priv->pending_events, events);
|
||||
} else {
|
||||
for (l = g_list_last (decoder->priv->pending_events); l;
|
||||
l = g_list_previous (l)) {
|
||||
GST_LOG_OBJECT (decoder, "pushing %s event",
|
||||
GST_EVENT_TYPE_NAME (l->data));
|
||||
gst_video_decoder_push_event (decoder, l->data);
|
||||
}
|
||||
g_list_free (decoder->priv->pending_events);
|
||||
gst_video_decoder_push_event_list (decoder, decoder->priv->pending_events);
|
||||
decoder->priv->pending_events = NULL;
|
||||
|
||||
for (l = g_list_last (events); l; l = g_list_previous (l)) {
|
||||
GST_LOG_OBJECT (decoder, "pushing %s event",
|
||||
GST_EVENT_TYPE_NAME (l->data));
|
||||
gst_video_decoder_push_event (decoder, l->data);
|
||||
}
|
||||
g_list_free (events);
|
||||
gst_video_decoder_push_event_list (decoder, events);
|
||||
}
|
||||
|
||||
/* Check if the data should not be displayed. For example altref/invisible
|
||||
|
|
|
@ -680,6 +680,57 @@ GST_START_TEST (videodecoder_buffer_after_segment)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
/* make sure that the segment event is pushed before the gap */
|
||||
GST_START_TEST (videodecoder_first_data_is_gap)
|
||||
{
|
||||
GstSegment segment;
|
||||
GList *events_iter;
|
||||
|
||||
setup_videodecodertester (NULL, NULL);
|
||||
|
||||
gst_pad_set_active (mysrcpad, TRUE);
|
||||
gst_element_set_state (dec, GST_STATE_PLAYING);
|
||||
gst_pad_set_active (mysinkpad, TRUE);
|
||||
|
||||
send_startup_events ();
|
||||
|
||||
/* push a new segment */
|
||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||
fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
|
||||
|
||||
/* push a gap */
|
||||
fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_gap (0,
|
||||
GST_SECOND)));
|
||||
events_iter = events;
|
||||
/* make sure the usual events have been received */
|
||||
{
|
||||
GstEvent *sstart = events_iter->data;
|
||||
fail_unless (GST_EVENT_TYPE (sstart) == GST_EVENT_STREAM_START);
|
||||
events_iter = g_list_next (events_iter);
|
||||
}
|
||||
{
|
||||
GstEvent *caps_event = events_iter->data;
|
||||
fail_unless (GST_EVENT_TYPE (caps_event) == GST_EVENT_CAPS);
|
||||
events_iter = g_list_next (events_iter);
|
||||
}
|
||||
{
|
||||
GstEvent *segment_event = events_iter->data;
|
||||
fail_unless (GST_EVENT_TYPE (segment_event) == GST_EVENT_SEGMENT);
|
||||
events_iter = g_list_next (events_iter);
|
||||
}
|
||||
|
||||
/* Make sure the gap was pushed */
|
||||
{
|
||||
GstEvent *gap = events_iter->data;
|
||||
fail_unless (GST_EVENT_TYPE (gap) == GST_EVENT_GAP);
|
||||
events_iter = g_list_next (events_iter);
|
||||
}
|
||||
fail_unless (events_iter == NULL);
|
||||
|
||||
cleanup_videodecodertest ();
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (videodecoder_backwards_playback)
|
||||
{
|
||||
|
@ -1041,6 +1092,7 @@ gst_videodecoder_suite (void)
|
|||
tcase_add_test (tc, videodecoder_playback_with_events);
|
||||
tcase_add_test (tc, videodecoder_playback_first_frames_not_decoded);
|
||||
tcase_add_test (tc, videodecoder_buffer_after_segment);
|
||||
tcase_add_test (tc, videodecoder_first_data_is_gap);
|
||||
|
||||
tcase_add_test (tc, videodecoder_backwards_playback);
|
||||
tcase_add_test (tc, videodecoder_backwards_buffer_after_segment);
|
||||
|
|
Loading…
Reference in a new issue