summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2020-07-24 17:41:57 -0400
committerOlivier CrĂȘte <olivier.crete@ocrete.ca>2021-09-15 15:35:43 +0000
commit6f7922b4dbba5ed780e7b0988669a81848a9e333 (patch)
tree64913f5038334bda303905234842faf5d1c21794
parenta76f38b2c7ddbed546bb058c32ebcf8a553c003f (diff)
downloadgstreamer-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>
-rw-r--r--gst/videorate/gstvideorate.c94
-rw-r--r--tests/check/elements/videorate.c6
2 files changed, 60 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);
diff --git a/tests/check/elements/videorate.c b/tests/check/elements/videorate.c
index a12393599..d3782155c 100644
--- a/tests/check/elements/videorate.c
+++ b/tests/check/elements/videorate.c
@@ -1645,12 +1645,17 @@ GST_START_TEST (test_segment_update)
next_ts += GST_SECOND / 25;
}
gst_check_drop_buffers ();
+ fail_unless_equals_uint64 (next_ts, 1 * GST_SECOND + (GST_SECOND / 25));
/* Send a pointless segment update, shouldn't change anything */
gst_segment_init (&segment, GST_FORMAT_TIME);
segment.position = 5 * GST_SECOND;
fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
+ /* Shouldnt push anything, rest is same as above */
+ fail_unless_equals_int (g_list_length (buffers), 0);
+ assert_videorate_stats (videorate, "second", 2, 26, 0, 25);
+
/* third buffer */
third = gst_buffer_new_and_alloc (4);
GST_BUFFER_TIMESTAMP (third) = 3 * GST_SECOND;
@@ -1671,6 +1676,7 @@ GST_START_TEST (test_segment_update)
next_ts += GST_SECOND / 25;
}
+ fail_unless_equals_uint64 (next_ts, (25 + 25 + 13) * (GST_SECOND / 25));
/* cleanup */
gst_buffer_unref (first);