summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Seiderer <ps.report@gmx.net>2014-11-14 14:18:51 +0100
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2015-04-02 17:40:19 -0400
commit866d97fa2c9fe3b2de70d1b04454baa83edea92c (patch)
tree6c79a46a30c948224979d5f27e0b0876c7395e5b
parentf16fe891fb58c1a588bcf84b917eefb8777279b2 (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
-rw-r--r--sys/v4l2/gstv4l2src.c30
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;