diff options
author | Peter Seiderer <ps.report@gmx.net> | 2014-11-14 14:18:51 +0100 |
---|---|---|
committer | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2015-04-02 17:40:19 -0400 |
commit | 866d97fa2c9fe3b2de70d1b04454baa83edea92c (patch) | |
tree | 6c79a46a30c948224979d5f27e0b0876c7395e5b /sys | |
parent | f16fe891fb58c1a588bcf84b917eefb8777279b2 (diff) |
v4l2src: add frame loss detection
In case of v4l2 driver filled offset/sequence values add frame
loss detection (and write a warning message).
Move offset meta data setting and frame loss checking after the
timestamp adjustment code to get proper timestamps for the
warning message.
https://bugzilla.gnome.org/show_bug.cgi?id=745441
Diffstat (limited to 'sys')
-rw-r--r-- | sys/v4l2/gstv4l2src.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index e4b068702..ab36a5820 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -675,6 +675,7 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf) GstClock *clock; GstClockTime abs_time, base_time, timestamp, duration; GstClockTime delay; + GstMessage *qos_msg; do { ret = GST_BASE_SRC_CLASS (parent_class)->alloc (GST_BASE_SRC (src), 0, @@ -779,13 +780,6 @@ retry: /* set buffer metadata */ - /* use generated offset values only if there are not already valid ones - * set by the v4l2 device */ - if (!GST_BUFFER_OFFSET_IS_VALID (*buf) || !GST_BUFFER_OFFSET_END_IS_VALID (*buf)) { - GST_BUFFER_OFFSET (*buf) = v4l2src->offset++; - GST_BUFFER_OFFSET_END (*buf) = v4l2src->offset; - } - if (G_LIKELY (abs_time != GST_CLOCK_TIME_NONE)) { /* the time now is the time of the clock minus the base time */ timestamp = abs_time - base_time; @@ -813,6 +807,28 @@ retry: GST_INFO_OBJECT (src, "sync to %" GST_TIME_FORMAT " out ts %" GST_TIME_FORMAT, GST_TIME_ARGS (v4l2src->ctrl_time), GST_TIME_ARGS (timestamp)); + /* use generated offset values only if there are not already valid ones + * set by the v4l2 device */ + if (!GST_BUFFER_OFFSET_IS_VALID (*buf) || !GST_BUFFER_OFFSET_END_IS_VALID (*buf)) { + GST_BUFFER_OFFSET (*buf) = v4l2src->offset++; + GST_BUFFER_OFFSET_END (*buf) = v4l2src->offset; + } else { + /* check for frame loss with given (from v4l2 device) buffer offset */ + if ((v4l2src->offset != 0) && (GST_BUFFER_OFFSET (*buf) != (v4l2src->offset + 1))) { + guint64 lost_frame_count = GST_BUFFER_OFFSET (*buf) - v4l2src->offset - 1; + GST_WARNING_OBJECT (v4l2src, + "lost frames detected: count = %" G_GUINT64_FORMAT " - ts: %" GST_TIME_FORMAT, + lost_frame_count, GST_TIME_ARGS (timestamp)); + + qos_msg = gst_message_new_qos (GST_OBJECT_CAST (v4l2src), TRUE, + GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, timestamp, + GST_CLOCK_TIME_IS_VALID (duration) ? lost_frame_count * duration : GST_CLOCK_TIME_NONE); + gst_element_post_message (GST_ELEMENT_CAST (v4l2src), qos_msg); + + } + v4l2src->offset = GST_BUFFER_OFFSET (*buf); + } + GST_BUFFER_TIMESTAMP (*buf) = timestamp; GST_BUFFER_DURATION (*buf) = duration; |