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
This commit is contained in:
Peter Seiderer 2014-11-14 14:18:51 +01:00 committed by Nicolas Dufresne
parent f16fe891fb
commit 866d97fa2c

View file

@ -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;