From f8168cd75f12d31332e981dcb2bbb8b56af967ec Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 8 Jun 2011 18:22:03 +0200 Subject: [PATCH] basesrc: add dynamic size handling This allows subclass to indicate that size reported by src may not be static and should as such be updated regularly, rather than only when really needed. Particular examples are filesrc or fdsrc reading from a file that is still growing (e.g. being downloaded). Fixes #652037. --- libs/gst/base/gstbasesrc.c | 33 +++++++++++++++++++++++++++++++-- libs/gst/base/gstbasesrc.h | 2 ++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c index 59319e2..d4f332c 100644 --- a/libs/gst/base/gstbasesrc.c +++ b/libs/gst/base/gstbasesrc.c @@ -234,6 +234,7 @@ struct _GstBaseSrcPrivate GstClockTimeDiff ts_offset; gboolean do_timestamp; + volatile gint dynamic_size; /* stream sequence number */ guint32 seqnum; @@ -323,6 +324,8 @@ static GstFlowReturn gst_base_src_pad_get_range (GstPad * pad, guint64 offset, static GstFlowReturn gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length, GstBuffer ** buf); static gboolean gst_base_src_seekable (GstBaseSrc * src); +static gboolean gst_base_src_update_length (GstBaseSrc * src, guint64 offset, + guint * length); static void gst_base_src_base_init (gpointer g_class) @@ -585,6 +588,23 @@ gst_base_src_set_format (GstBaseSrc * src, GstFormat format) } /** + * gst_base_src_set_dynamic_size: + * @src: base source instance + * @dynamic: new dynamic size mode + * + * If not @dynamic, size is only updated when needed, such as when trying to + * read past current tracked size. Otherwise, size is checked for upon each + * read. + */ +void +gst_base_src_set_dynamic_size (GstBaseSrc * src, gboolean dynamic) +{ + g_return_if_fail (GST_IS_BASE_SRC (src)); + + g_atomic_int_set (&src->priv->dynamic_size, dynamic); +} + +/** * gst_base_src_query_latency: * @src: the source * @live: (out) (allow-none): if the source is live @@ -932,9 +952,14 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query) { gint64 duration; GstFormat seg_format; + guint length = 0; + + /* may have to refresh duration */ + if (g_atomic_int_get (&src->priv->dynamic_size)) + gst_base_src_update_length (src, 0, &length); - GST_OBJECT_LOCK (src); /* this is the duration as configured by the subclass. */ + GST_OBJECT_LOCK (src); duration = src->segment.duration; seg_format = src->segment.format; GST_OBJECT_UNLOCK (src); @@ -2028,6 +2053,7 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length) GstBaseSrcClass *bclass; GstFormat format; gint64 stop; + gboolean dynamic; bclass = GST_BASE_SRC_GET_CLASS (src); @@ -2052,11 +2078,14 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length) ", segment.stop %" G_GINT64_FORMAT ", maxsize %" G_GINT64_FORMAT, offset, *length, size, stop, maxsize); + dynamic = g_atomic_int_get (&src->priv->dynamic_size); + GST_DEBUG_OBJECT (src, "dynamic size: %d", dynamic); + /* check size if we have one */ if (maxsize != -1) { /* if we run past the end, check if the file became bigger and * retry. */ - if (G_UNLIKELY (offset + *length >= maxsize)) { + if (G_UNLIKELY (offset + *length >= maxsize || dynamic)) { /* see if length of the file changed */ if (bclass->get_size) if (!bclass->get_size (src, &size)) diff --git a/libs/gst/base/gstbasesrc.h b/libs/gst/base/gstbasesrc.h index 2a3caec..87e1c06 100644 --- a/libs/gst/base/gstbasesrc.h +++ b/libs/gst/base/gstbasesrc.h @@ -245,6 +245,8 @@ gboolean gst_base_src_is_live (GstBaseSrc *src); void gst_base_src_set_format (GstBaseSrc *src, GstFormat format); +void gst_base_src_set_dynamic_size (GstBaseSrc * src, gboolean dynamic); + gboolean gst_base_src_query_latency (GstBaseSrc *src, gboolean * live, GstClockTime * min_latency, GstClockTime * max_latency); -- 2.7.4