From 17b17a566f7dc7c043f14c2a6de89c3515060438 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 28 May 2008 14:49:24 +0000 Subject: [PATCH] gst/videorate/gstvideorate.*: React (more) to NEWSEGMENT Original commit message from CVS: Patch by: Mark Nauwelaerts * gst/videorate/gstvideorate.c: (gst_video_rate_reset), (gst_video_rate_flush_prev), (gst_video_rate_event), (gst_video_rate_chain): * gst/videorate/gstvideorate.h: React (more) to NEWSEGMENT Small adjustment in timestamp calculation to prevent mismatches Fixes #435633. --- ChangeLog | 12 ++++++++++++ common | 2 +- gst/videorate/gstvideorate.c | 39 +++++++++++++++++++++++++++++++++++++-- gst/videorate/gstvideorate.h | 1 + 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 782a6bf..0166b1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-05-28 Wim Taymans + + Patch by: Mark Nauwelaerts + + * gst/videorate/gstvideorate.c: (gst_video_rate_reset), + (gst_video_rate_flush_prev), (gst_video_rate_event), + (gst_video_rate_chain): + * gst/videorate/gstvideorate.h: + React (more) to NEWSEGMENT + Small adjustment in timestamp calculation to prevent mismatches + Fixes #435633. + 2008-05-28 Tim-Philipp Müller * tests/examples/seek/seek.c: (make_parselaunch_pipeline): diff --git a/common b/common index 032f2d9..130fa8f 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 032f2d973bd5c9a9b457cb5fc72d13dafe85c01e +Subproject commit 130fa8f739ff09aedb520c33239f53d06cfe9bd5 diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c index 47c8518..ce7582e 100644 --- a/gst/videorate/gstvideorate.c +++ b/gst/videorate/gstvideorate.c @@ -364,6 +364,7 @@ gst_video_rate_reset (GstVideoRate * videorate) videorate->in = 0; videorate->out = 0; + videorate->segment_out = 0; videorate->drop = 0; videorate->dup = 0; videorate->next_ts = GST_CLOCK_TIME_NONE; @@ -423,10 +424,11 @@ gst_video_rate_flush_prev (GstVideoRate * videorate) push_ts = videorate->next_ts; videorate->out++; + videorate->segment_out++; if (videorate->to_rate_numerator) { /* interpolate next expected timestamp in the segment */ videorate->next_ts = videorate->segment.accum + videorate->segment.start + - gst_util_uint64_scale (videorate->out, + gst_util_uint64_scale (videorate->segment_out, videorate->to_rate_denominator * GST_SECOND, videorate->to_rate_numerator); GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts; @@ -464,6 +466,7 @@ gst_video_rate_swap_prev (GstVideoRate * videorate, GstBuffer * buffer, videorate->prev_ts = time; } +#define MAGIC_LIMIT 25 static gboolean gst_video_rate_event (GstPad * pad, GstEvent * event) { @@ -488,6 +491,38 @@ gst_video_rate_event (GstPad * pad, GstEvent * event) GST_DEBUG_OBJECT (videorate, "handle NEWSEGMENT"); + /* close up the previous segment, if appropriate */ + if (!update && 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 && + ((GST_CLOCK_TIME_IS_VALID (videorate->segment.stop) && + videorate->next_ts - videorate->segment.accum + < videorate->segment.stop) + || count < 1)) { + gst_video_rate_flush_prev (videorate); + count++; + } + if (count > 1) { + videorate->dup += count - 1; + if (!videorate->silent) + g_object_notify (G_OBJECT (videorate), "duplicate"); + } else if (count == 0) { + videorate->drop++; + if (!videorate->silent) + g_object_notify (G_OBJECT (videorate), "drop"); + } + /* clean up for the new one; _chain will resume from the new start */ + videorate->segment_out = 0; + gst_video_rate_swap_prev (videorate, NULL, 0); + videorate->next_ts = GST_CLOCK_TIME_NONE; + } + /* We just want to update the accumulated stream_time */ gst_segment_set_newsegment_full (&videorate->segment, update, rate, arate, format, start, stop, time); @@ -617,7 +652,7 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer) if (!GST_CLOCK_TIME_IS_VALID (videorate->next_ts)) { /* new buffer, we expect to output a buffer that matches the first * timestamp in the segment */ - videorate->next_ts = videorate->segment.start; + videorate->next_ts = videorate->segment.start + videorate->segment.accum; } } else { GstClockTime prevtime; diff --git a/gst/videorate/gstvideorate.h b/gst/videorate/gstvideorate.h index 36cae5c..ea6063b 100644 --- a/gst/videorate/gstvideorate.h +++ b/gst/videorate/gstvideorate.h @@ -55,6 +55,7 @@ struct _GstVideoRate guint64 next_ts; /* Timestamp of next buffer to output */ GstBuffer *prevbuf; guint64 prev_ts; /* Previous buffer timestamp */ + guint64 segment_out; /* in-segment counting */ /* segment handling */ GstSegment segment; -- 2.7.4