diff options
author | Tim-Philipp Müller <tim@centricular.net> | 2007-09-05 14:43:16 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.net> | 2007-09-05 14:43:16 +0000 |
commit | 7c69e902364f02b40c054befed6857fddb8b945d (patch) | |
tree | 05980ff023f7fdac568d1b353484cab1dbcf4b7c /sys/v4l2/gstv4l2src.c | |
parent | 3ee2bed9c63142a106d16406848a4729ad9c4005 (diff) |
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.
Diffstat (limited to 'sys/v4l2/gstv4l2src.c')
-rw-r--r-- | sys/v4l2/gstv4l2src.c | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index d0c1ddb0..5a892bda 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -237,6 +237,7 @@ static gboolean gst_v4l2src_start (GstBaseSrc * src); static gboolean gst_v4l2src_stop (GstBaseSrc * src); static gboolean gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps); 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 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, G_PARAM_READWRITE)); - basesrc_class->get_caps = gst_v4l2src_get_caps; - basesrc_class->set_caps = gst_v4l2src_set_caps; - basesrc_class->start = gst_v4l2src_start; - basesrc_class->stop = gst_v4l2src_stop; + basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_get_caps); + basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_set_caps); + basesrc_class->start = GST_DEBUG_FUNCPTR (gst_v4l2src_start); + 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 @@ -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_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; } +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 * 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. @@ -901,6 +955,9 @@ gst_v4l2src_stop (GstBaseSrc * src) if (!gst_v4l2_object_stop (v4l2src->v4l2object)) return FALSE; + v4l2src->fps_d = 0; + v4l2src->fps_n = 0; + return TRUE; } @@ -950,9 +1007,20 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf) GST_OBJECT_UNLOCK (v4l2src); if (clock) { + GstClockTime latency; + /* the time now is the time of the clock minus the base time */ timestamp = gst_clock_get_time (clock) - timestamp; 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! */ |