mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 23:48:53 +00:00
sys/v4l2/: Implement LATENCY queries in the crudest way possible so I don't have to use sync=false any longer when te...
Original commit message from CVS: * sys/v4l2/gstv4l2src.c: * sys/v4l2/gstv4l2src.h: * sys/v4l2/v4l2src_calls.c: Implement LATENCY queries in the crudest way possible so I don't have to use sync=false any longer when testing with videosinks.
This commit is contained in:
parent
3ee2bed9c6
commit
7c69e90236
4 changed files with 86 additions and 5 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2007-09-05 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
|
* sys/v4l2/gstv4l2src.c:
|
||||||
|
* sys/v4l2/gstv4l2src.h:
|
||||||
|
* sys/v4l2/v4l2src_calls.c:
|
||||||
|
Implement LATENCY queries in the crudest way possible so I don't
|
||||||
|
have to use sync=false any longer when testing with videosinks.
|
||||||
|
|
||||||
2007-09-05 Tim-Philipp Müller <tim at centricular dot net>
|
2007-09-05 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
|
|
@ -237,6 +237,7 @@ static gboolean gst_v4l2src_start (GstBaseSrc * src);
|
||||||
static gboolean gst_v4l2src_stop (GstBaseSrc * src);
|
static gboolean gst_v4l2src_stop (GstBaseSrc * src);
|
||||||
static gboolean gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps);
|
static gboolean gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps);
|
||||||
static GstCaps *gst_v4l2src_get_caps (GstBaseSrc * src);
|
static GstCaps *gst_v4l2src_get_caps (GstBaseSrc * src);
|
||||||
|
static gboolean gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query);
|
||||||
static GstFlowReturn gst_v4l2src_create (GstPushSrc * src, GstBuffer ** out);
|
static GstFlowReturn gst_v4l2src_create (GstPushSrc * src, GstBuffer ** out);
|
||||||
|
|
||||||
static void gst_v4l2src_fixate (GstPad * pad, GstCaps * caps);
|
static void gst_v4l2src_fixate (GstPad * pad, GstCaps * caps);
|
||||||
|
@ -289,12 +290,13 @@ gst_v4l2src_class_init (GstV4l2SrcClass * klass)
|
||||||
GST_V4L2_MIN_BUFFERS, GST_V4L2_MAX_BUFFERS, GST_V4L2_MIN_BUFFERS,
|
GST_V4L2_MIN_BUFFERS, GST_V4L2_MAX_BUFFERS, GST_V4L2_MIN_BUFFERS,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
basesrc_class->get_caps = gst_v4l2src_get_caps;
|
basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_get_caps);
|
||||||
basesrc_class->set_caps = gst_v4l2src_set_caps;
|
basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_set_caps);
|
||||||
basesrc_class->start = gst_v4l2src_start;
|
basesrc_class->start = GST_DEBUG_FUNCPTR (gst_v4l2src_start);
|
||||||
basesrc_class->stop = gst_v4l2src_stop;
|
basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_v4l2src_stop);
|
||||||
|
basesrc_class->query = GST_DEBUG_FUNCPTR (gst_v4l2src_query);
|
||||||
|
|
||||||
pushsrc_class->create = gst_v4l2src_create;
|
pushsrc_class->create = GST_DEBUG_FUNCPTR (gst_v4l2src_create);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -316,6 +318,9 @@ gst_v4l2src_init (GstV4l2Src * v4l2src, GstV4l2SrcClass * klass)
|
||||||
|
|
||||||
gst_base_src_set_format (GST_BASE_SRC (v4l2src), GST_FORMAT_TIME);
|
gst_base_src_set_format (GST_BASE_SRC (v4l2src), GST_FORMAT_TIME);
|
||||||
gst_base_src_set_live (GST_BASE_SRC (v4l2src), TRUE);
|
gst_base_src_set_live (GST_BASE_SRC (v4l2src), TRUE);
|
||||||
|
|
||||||
|
v4l2src->fps_d = 0;
|
||||||
|
v4l2src->fps_n = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -865,6 +870,55 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query)
|
||||||
|
{
|
||||||
|
GstV4l2Src *src;
|
||||||
|
gboolean res = FALSE;
|
||||||
|
|
||||||
|
src = GST_V4L2SRC (bsrc);
|
||||||
|
|
||||||
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
|
case GST_QUERY_LATENCY:{
|
||||||
|
GstClockTime min_latency, max_latency;
|
||||||
|
|
||||||
|
/* device must be open */
|
||||||
|
if (!GST_V4L2_IS_OPEN (src->v4l2object))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* we must have a framerate */
|
||||||
|
if (src->fps_n <= 0 || src->fps_d <= 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* min latency is the time to capture one frame */
|
||||||
|
min_latency =
|
||||||
|
gst_util_uint64_scale_int (GST_SECOND, src->fps_d, src->fps_n);
|
||||||
|
|
||||||
|
/* max latency is total duration of the frame buffer */
|
||||||
|
/* FIXME: what to use here? */
|
||||||
|
max_latency = 1 * min_latency;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (bsrc,
|
||||||
|
"report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
|
||||||
|
|
||||||
|
/* we are always live, the min latency is 1 frame and the max latency is
|
||||||
|
* the complete buffer of frames. */
|
||||||
|
gst_query_set_latency (query, TRUE, min_latency, max_latency);
|
||||||
|
|
||||||
|
res = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/* start and stop are not symmetric -- start will open the device, but not start
|
/* start and stop are not symmetric -- start will open the device, but not start
|
||||||
* capture. it's setcaps that will start capture, which is called via basesrc's
|
* capture. it's setcaps that will start capture, which is called via basesrc's
|
||||||
* negotiate method. stop will both stop capture and close the device.
|
* negotiate method. stop will both stop capture and close the device.
|
||||||
|
@ -901,6 +955,9 @@ gst_v4l2src_stop (GstBaseSrc * src)
|
||||||
if (!gst_v4l2_object_stop (v4l2src->v4l2object))
|
if (!gst_v4l2_object_stop (v4l2src->v4l2object))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
v4l2src->fps_d = 0;
|
||||||
|
v4l2src->fps_n = 0;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,9 +1007,20 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
|
||||||
GST_OBJECT_UNLOCK (v4l2src);
|
GST_OBJECT_UNLOCK (v4l2src);
|
||||||
|
|
||||||
if (clock) {
|
if (clock) {
|
||||||
|
GstClockTime latency;
|
||||||
|
|
||||||
/* the time now is the time of the clock minus the base time */
|
/* the time now is the time of the clock minus the base time */
|
||||||
timestamp = gst_clock_get_time (clock) - timestamp;
|
timestamp = gst_clock_get_time (clock) - timestamp;
|
||||||
gst_object_unref (clock);
|
gst_object_unref (clock);
|
||||||
|
|
||||||
|
latency =
|
||||||
|
gst_util_uint64_scale_int (GST_SECOND, v4l2src->fps_d,
|
||||||
|
v4l2src->fps_n);
|
||||||
|
|
||||||
|
if (timestamp > latency)
|
||||||
|
timestamp -= latency;
|
||||||
|
else
|
||||||
|
timestamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: use the timestamp from the buffer itself! */
|
/* FIXME: use the timestamp from the buffer itself! */
|
||||||
|
|
|
@ -106,6 +106,8 @@ struct _GstV4l2Src
|
||||||
gboolean is_capturing;
|
gboolean is_capturing;
|
||||||
|
|
||||||
guint64 offset;
|
guint64 offset;
|
||||||
|
|
||||||
|
gint fps_d, fps_n; /* framerate if device is open */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstV4l2SrcClass
|
struct _GstV4l2SrcClass
|
||||||
|
|
|
@ -968,6 +968,9 @@ gst_v4l2src_set_capture (GstV4l2Src * v4l2src, guint32 pixelformat,
|
||||||
|| stream.parm.capture.timeperframe.denominator != fps_n)
|
|| stream.parm.capture.timeperframe.denominator != fps_n)
|
||||||
goto invalid_framerate;
|
goto invalid_framerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v4l2src->fps_d = fps_d;
|
||||||
|
v4l2src->fps_n = fps_n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in a new issue