mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
ksvideosrc: don't try to align current timestamp on previous timestamp
this causes frames to be dropped. Based on a patch by Sebastian Dröge https://bugzilla.gnome.org/show_bug.cgi?id=748337
This commit is contained in:
parent
dd738842e4
commit
c4657f4276
1 changed files with 3 additions and 73 deletions
|
@ -98,8 +98,6 @@ struct _GstKsVideoSrcPrivate
|
||||||
GstKsClock *ksclock;
|
GstKsClock *ksclock;
|
||||||
GstKsVideoDevice *device;
|
GstKsVideoDevice *device;
|
||||||
|
|
||||||
guint64 offset;
|
|
||||||
GstClockTime prev_ts;
|
|
||||||
gboolean running;
|
gboolean running;
|
||||||
|
|
||||||
/* Worker thread */
|
/* Worker thread */
|
||||||
|
@ -343,10 +341,6 @@ gst_ks_video_src_reset (GstKsVideoSrc * self)
|
||||||
priv->count = 0;
|
priv->count = 0;
|
||||||
priv->fps = -1;
|
priv->fps = -1;
|
||||||
|
|
||||||
/* Reset timestamping state */
|
|
||||||
priv->offset = 0;
|
|
||||||
priv->prev_ts = GST_CLOCK_TIME_NONE;
|
|
||||||
|
|
||||||
priv->running = FALSE;
|
priv->running = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,12 +807,11 @@ gst_ks_video_src_timestamp_buffer (GstKsVideoSrc * self, GstBuffer * buf,
|
||||||
GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self);
|
GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self);
|
||||||
GstClockTime duration;
|
GstClockTime duration;
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp, base_time;
|
||||||
|
|
||||||
/* Don't timestamp muxed streams */
|
/* Don't timestamp muxed streams */
|
||||||
if (gst_ks_video_device_stream_is_muxed (priv->device)) {
|
if (gst_ks_video_device_stream_is_muxed (priv->device)) {
|
||||||
duration = timestamp = GST_CLOCK_TIME_NONE;
|
duration = timestamp = GST_CLOCK_TIME_NONE;
|
||||||
priv->offset++;
|
|
||||||
goto timestamp;
|
goto timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,88 +821,25 @@ gst_ks_video_src_timestamp_buffer (GstKsVideoSrc * self, GstBuffer * buf,
|
||||||
clock = GST_ELEMENT_CLOCK (self);
|
clock = GST_ELEMENT_CLOCK (self);
|
||||||
if (clock != NULL) {
|
if (clock != NULL) {
|
||||||
gst_object_ref (clock);
|
gst_object_ref (clock);
|
||||||
timestamp = GST_ELEMENT (self)->base_time;
|
base_time = GST_ELEMENT (self)->base_time;
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (presentation_time)) {
|
|
||||||
if (presentation_time > GST_ELEMENT (self)->base_time)
|
|
||||||
presentation_time -= GST_ELEMENT (self)->base_time;
|
|
||||||
else
|
|
||||||
presentation_time = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
timestamp = GST_CLOCK_TIME_NONE;
|
timestamp = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (self);
|
GST_OBJECT_UNLOCK (self);
|
||||||
|
|
||||||
if (clock != NULL) {
|
if (clock != NULL) {
|
||||||
|
|
||||||
/* The time according to the current clock */
|
/* The time according to the current clock */
|
||||||
timestamp = gst_clock_get_time (clock) - timestamp;
|
timestamp = gst_clock_get_time (clock) - base_time;
|
||||||
if (timestamp > duration)
|
if (timestamp > duration)
|
||||||
timestamp -= duration;
|
timestamp -= duration;
|
||||||
else
|
else
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (presentation_time)) {
|
|
||||||
/*
|
|
||||||
* We don't use this for anything yet, need to ponder how to deal
|
|
||||||
* with pins that use an internal clock and timestamp from 0.
|
|
||||||
*/
|
|
||||||
GstClockTimeDiff diff = GST_CLOCK_DIFF (presentation_time, timestamp);
|
|
||||||
GST_DEBUG_OBJECT (self, "diff between gst and driver timestamp: %"
|
|
||||||
G_GINT64_FORMAT, diff);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_object_unref (clock);
|
gst_object_unref (clock);
|
||||||
clock = NULL;
|
clock = NULL;
|
||||||
|
|
||||||
/* Unless it's the first frame, align the current timestamp on a multiple
|
|
||||||
* of duration since the previous */
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (priv->prev_ts)) {
|
|
||||||
GstClockTime delta;
|
|
||||||
guint delta_remainder, delta_offset;
|
|
||||||
|
|
||||||
/* REVISIT: I've seen this happen with the GstSystemClock on Windows,
|
|
||||||
* scary... */
|
|
||||||
if (timestamp < priv->prev_ts) {
|
|
||||||
GST_INFO_OBJECT (self, "clock is ticking backwards");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Round to a duration boundary */
|
|
||||||
delta = timestamp - priv->prev_ts;
|
|
||||||
delta_remainder = delta % duration;
|
|
||||||
|
|
||||||
if (delta_remainder < duration / 3)
|
|
||||||
timestamp -= delta_remainder;
|
|
||||||
else
|
|
||||||
timestamp += duration - delta_remainder;
|
|
||||||
|
|
||||||
/* How many frames are we off then? */
|
|
||||||
delta = timestamp - priv->prev_ts;
|
|
||||||
delta_offset = delta / duration;
|
|
||||||
|
|
||||||
if (delta_offset == 1) /* perfect */
|
|
||||||
GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
|
|
||||||
else if (delta_offset > 1) {
|
|
||||||
guint lost = delta_offset - 1;
|
|
||||||
GST_INFO_OBJECT (self, "lost %d frame%s, setting discont flag",
|
|
||||||
lost, (lost > 1) ? "s" : "");
|
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
|
||||||
} else if (delta_offset == 0) { /* overproduction, skip this frame */
|
|
||||||
GST_INFO_OBJECT (self, "skipping frame");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->offset += delta_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->prev_ts = timestamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp:
|
timestamp:
|
||||||
GST_BUFFER_OFFSET (buf) = priv->offset;
|
|
||||||
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET (buf) + 1;
|
|
||||||
GST_BUFFER_PTS (buf) = timestamp;
|
GST_BUFFER_PTS (buf) = timestamp;
|
||||||
GST_BUFFER_DTS (buf) = GST_CLOCK_TIME_NONE;
|
GST_BUFFER_DTS (buf) = GST_CLOCK_TIME_NONE;
|
||||||
GST_BUFFER_DURATION (buf) = duration;
|
GST_BUFFER_DURATION (buf) = duration;
|
||||||
|
|
Loading…
Reference in a new issue