+2008-05-28 Wim Taymans <wim.taymans@collabora.co.uk>
+
+ Patch by: Mark Nauwelaerts <manauw at skynet be>
+
+ * 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 <tim.muller at collabora co uk>
* tests/examples/seek/seek.c: (make_parselaunch_pipeline):
videorate->in = 0;
videorate->out = 0;
+ videorate->segment_out = 0;
videorate->drop = 0;
videorate->dup = 0;
videorate->next_ts = GST_CLOCK_TIME_NONE;
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;
videorate->prev_ts = time;
}
+#define MAGIC_LIMIT 25
static gboolean
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);
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;