diff options
author | Olivier CrĂȘte <olivier.crete@collabora.com> | 2020-07-24 17:41:57 -0400 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@ocrete.ca> | 2021-09-15 15:35:43 +0000 |
commit | 6f7922b4dbba5ed780e7b0988669a81848a9e333 (patch) | |
tree | 64913f5038334bda303905234842faf5d1c21794 /gst/videorate/gstvideorate.c | |
parent | a76f38b2c7ddbed546bb058c32ebcf8a553c003f (diff) | |
download | gstreamer-plugins-base-6f7922b4dbba5ed780e7b0988669a81848a9e333.tar.gz |
videorate: Only "close" the segment if it is discontinous
Otherwise, it will drop valid buffers on a simple segment update
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/767>
Diffstat (limited to 'gst/videorate/gstvideorate.c')
-rw-r--r-- | gst/videorate/gstvideorate.c | 94 |
1 files changed, 54 insertions, 40 deletions
diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c index d00f102a8..e12fe391c 100644 --- a/gst/videorate/gstvideorate.c +++ b/gst/videorate/gstvideorate.c @@ -794,48 +794,14 @@ gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event) { GstSegment segment; gint seqnum; + GstClockTime base_ts, next_ts; + gboolean reset_base_ts = FALSE; gst_event_copy_segment (event, &segment); if (segment.format != GST_FORMAT_TIME) goto format_error; - GST_DEBUG_OBJECT (videorate, "handle NEWSEGMENT"); - - /* close up the previous segment, if appropriate */ - if (videorate->prevbuf) { - gint count = 0; - GstFlowReturn res; - - res = GST_FLOW_OK; - /* fill up to the end of current segment, - * or only send out the stored buffer if there is no specific stop. - * regardless, prevent going loopy in strange cases */ - while (res == GST_FLOW_OK && count <= MAGIC_LIMIT - && !videorate->drop_only - && ((videorate->segment.rate > 0.0 - && GST_CLOCK_TIME_IS_VALID (videorate->segment.stop) - && GST_CLOCK_TIME_IS_VALID (videorate->next_ts) - && videorate->next_ts - videorate->segment.base < - videorate->segment.stop) || (videorate->segment.rate < 0.0 - && GST_CLOCK_TIME_IS_VALID (videorate->segment.start) - && GST_CLOCK_TIME_IS_VALID (videorate->next_ts) - && videorate->next_ts - videorate->segment.base >= - videorate->segment.start) - || count < 1)) { - res = - gst_video_rate_flush_prev (videorate, count > 0, - GST_CLOCK_TIME_NONE); - count++; - } - if (count > 1) { - videorate->dup += count - 1; - if (!videorate->silent) - gst_video_rate_notify_duplicate (videorate); - } - /* clean up for the new one; _chain will resume from the new start */ - gst_video_rate_swap_prev (videorate, NULL, 0); - } - + GST_DEBUG_OBJECT (videorate, "handle SEGMENT event"); /* We just want to update the accumulated stream_time */ @@ -845,20 +811,68 @@ gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event) segment.stop = (gint64) (segment.stop / videorate->rate); segment.time = (gint64) (segment.time / videorate->rate); - videorate->base_ts = gst_segment_position_from_running_time (&segment, + base_ts = gst_segment_position_from_running_time (&segment, GST_FORMAT_TIME, gst_segment_to_running_time (&videorate->segment, GST_FORMAT_TIME, videorate->base_ts)); - videorate->next_ts = gst_segment_position_from_running_time (&segment, + next_ts = gst_segment_position_from_running_time (&segment, GST_FORMAT_TIME, gst_segment_to_running_time (&videorate->segment, GST_FORMAT_TIME, videorate->next_ts)); + /* Reset if the segment is discontinuous */ + if (next_ts == GST_CLOCK_TIME_NONE) { + reset_base_ts = TRUE; + + /* close up the previous segment, if appropriate */ + if (videorate->prevbuf) { + gint count = 0; + GstFlowReturn res; + + res = GST_FLOW_OK; + /* fill up to the end of current segment, + * or only send out the stored buffer if there is no specific stop. + * regardless, prevent going loopy in strange cases */ + while (res == GST_FLOW_OK && count <= MAGIC_LIMIT + && !videorate->drop_only + && ((videorate->segment.rate > 0.0 + && GST_CLOCK_TIME_IS_VALID (videorate->segment.stop) + && GST_CLOCK_TIME_IS_VALID (videorate->next_ts) + && videorate->next_ts - videorate->segment.base < + videorate->segment.stop) || (videorate->segment.rate < 0.0 + && GST_CLOCK_TIME_IS_VALID (videorate->segment.start) + && GST_CLOCK_TIME_IS_VALID (videorate->next_ts) + && videorate->next_ts - videorate->segment.base >= + videorate->segment.start) + || count < 1)) { + res = + gst_video_rate_flush_prev (videorate, count > 0, + GST_CLOCK_TIME_NONE); + count++; + } + if (count > 1) { + videorate->dup += count - 1; + if (!videorate->silent) + gst_video_rate_notify_duplicate (videorate); + } + /* clean up for the new one; _chain will resume from the new start */ + gst_video_rate_swap_prev (videorate, NULL, 0); + } + } else if (base_ts == GST_CLOCK_TIME_NONE) { + reset_base_ts = TRUE; + } + + if (reset_base_ts) { + base_ts = 0; + videorate->out_frame_count = 0; + } + videorate->next_ts = next_ts; + videorate->base_ts = base_ts; + gst_segment_copy_into (&segment, &videorate->segment); GST_DEBUG_OBJECT (videorate, "updated segment: %" GST_SEGMENT_FORMAT, &videorate->segment); - seqnum = gst_event_get_seqnum (event); gst_event_unref (event); event = gst_event_new_segment (&segment); |