mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
fdsrc: allow specifying the size in bytes on the uri
Parse a size=value from the query string to specify a size. This is interesting when reading from a file descriptor that actually has a size (and is not stat-able, such as the socket of an http connection)
This commit is contained in:
parent
db172aaa6f
commit
65752f7e8d
2 changed files with 34 additions and 5 deletions
|
@ -212,6 +212,7 @@ gst_fd_src_init (GstFdSrc * fdsrc, GstFdSrcClass * klass)
|
||||||
fdsrc->new_fd = DEFAULT_FD;
|
fdsrc->new_fd = DEFAULT_FD;
|
||||||
fdsrc->seekable_fd = FALSE;
|
fdsrc->seekable_fd = FALSE;
|
||||||
fdsrc->fd = -1;
|
fdsrc->fd = -1;
|
||||||
|
fdsrc->size = -1;
|
||||||
fdsrc->timeout = DEFAULT_TIMEOUT;
|
fdsrc->timeout = DEFAULT_TIMEOUT;
|
||||||
fdsrc->uri = g_strdup_printf ("fd://0");
|
fdsrc->uri = g_strdup_printf ("fd://0");
|
||||||
fdsrc->curoffset = 0;
|
fdsrc->curoffset = 0;
|
||||||
|
@ -229,7 +230,7 @@ gst_fd_src_dispose (GObject * obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_fd_src_update_fd (GstFdSrc * src)
|
gst_fd_src_update_fd (GstFdSrc * src, guint64 size)
|
||||||
{
|
{
|
||||||
struct stat stat_results;
|
struct stat stat_results;
|
||||||
|
|
||||||
|
@ -252,11 +253,15 @@ gst_fd_src_update_fd (GstFdSrc * src)
|
||||||
gst_poll_fd_ctl_read (src->fdset, &fd, TRUE);
|
gst_poll_fd_ctl_read (src->fdset, &fd, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (src->fd != src->new_fd) {
|
if (src->fd != src->new_fd) {
|
||||||
GST_INFO_OBJECT (src, "Updating to fd %d", src->new_fd);
|
GST_INFO_OBJECT (src, "Updating to fd %d", src->new_fd);
|
||||||
|
|
||||||
src->fd = src->new_fd;
|
src->fd = src->new_fd;
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (src, "Setting size to fd %" G_GUINT64_FORMAT, size);
|
||||||
|
src->size = size;
|
||||||
|
|
||||||
g_free (src->uri);
|
g_free (src->uri);
|
||||||
src->uri = g_strdup_printf ("fd://%d", src->fd);
|
src->uri = g_strdup_printf ("fd://%d", src->fd);
|
||||||
|
|
||||||
|
@ -292,7 +297,7 @@ gst_fd_src_start (GstBaseSrc * bsrc)
|
||||||
if ((src->fdset = gst_poll_new (TRUE)) == NULL)
|
if ((src->fdset = gst_poll_new (TRUE)) == NULL)
|
||||||
goto socket_pair;
|
goto socket_pair;
|
||||||
|
|
||||||
gst_fd_src_update_fd (src);
|
gst_fd_src_update_fd (src, -1);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -359,7 +364,7 @@ gst_fd_src_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
GST_OBJECT_LOCK (object);
|
GST_OBJECT_LOCK (object);
|
||||||
if (GST_STATE (GST_ELEMENT (src)) <= GST_STATE_READY) {
|
if (GST_STATE (GST_ELEMENT (src)) <= GST_STATE_READY) {
|
||||||
GST_DEBUG_OBJECT (src, "state ready or lower, updating to use new fd");
|
GST_DEBUG_OBJECT (src, "state ready or lower, updating to use new fd");
|
||||||
gst_fd_src_update_fd (src);
|
gst_fd_src_update_fd (src, -1);
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (src, "state above ready, not updating to new fd yet");
|
GST_DEBUG_OBJECT (src, "state above ready, not updating to new fd yet");
|
||||||
}
|
}
|
||||||
|
@ -546,6 +551,11 @@ gst_fd_src_get_size (GstBaseSrc * bsrc, guint64 * size)
|
||||||
GstFdSrc *src = GST_FD_SRC (bsrc);
|
GstFdSrc *src = GST_FD_SRC (bsrc);
|
||||||
struct stat stat_results;
|
struct stat stat_results;
|
||||||
|
|
||||||
|
if (src->size != -1) {
|
||||||
|
*size = src->size;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!src->seekable_fd) {
|
if (!src->seekable_fd) {
|
||||||
/* If it isn't seekable, we won't know the length (but fstat will still
|
/* If it isn't seekable, we won't know the length (but fstat will still
|
||||||
* succeed, and wrongly say our length is zero. */
|
* succeed, and wrongly say our length is zero. */
|
||||||
|
@ -620,9 +630,12 @@ gst_fd_src_uri_get_uri (GstURIHandler * handler)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_fd_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
|
gst_fd_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
|
||||||
{
|
{
|
||||||
gchar *protocol;
|
gchar *protocol, *q;
|
||||||
GstFdSrc *src = GST_FD_SRC (handler);
|
GstFdSrc *src = GST_FD_SRC (handler);
|
||||||
gint fd;
|
gint fd;
|
||||||
|
guint64 size = -1;
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (src, "checking uri %s", uri);
|
||||||
|
|
||||||
protocol = gst_uri_get_protocol (uri);
|
protocol = gst_uri_get_protocol (uri);
|
||||||
if (strcmp (protocol, "fd") != 0) {
|
if (strcmp (protocol, "fd") != 0) {
|
||||||
|
@ -634,11 +647,26 @@ gst_fd_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
|
||||||
if (sscanf (uri, "fd://%d", &fd) != 1 || fd < 0)
|
if (sscanf (uri, "fd://%d", &fd) != 1 || fd < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if ((q = g_strstr_len (uri, -1, "?"))) {
|
||||||
|
gchar *sp;
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (src, "found ?");
|
||||||
|
|
||||||
|
if ((sp = g_strstr_len (q, -1, "size="))) {
|
||||||
|
if (sscanf (sp, "size=%" G_GUINT64_FORMAT, &size) != 1) {
|
||||||
|
GST_INFO_OBJECT (src, "parsing size failed");
|
||||||
|
size = -1;
|
||||||
|
} else {
|
||||||
|
GST_INFO_OBJECT (src, "found size %" G_GUINT64_FORMAT, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
src->new_fd = fd;
|
src->new_fd = fd;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (src);
|
GST_OBJECT_LOCK (src);
|
||||||
if (GST_STATE (GST_ELEMENT (src)) <= GST_STATE_READY) {
|
if (GST_STATE (GST_ELEMENT (src)) <= GST_STATE_READY) {
|
||||||
gst_fd_src_update_fd (src);
|
gst_fd_src_update_fd (src, size);
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (src);
|
GST_OBJECT_UNLOCK (src);
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ struct _GstFdSrc {
|
||||||
/* fd and flag indicating whether fd is seekable */
|
/* fd and flag indicating whether fd is seekable */
|
||||||
gint fd;
|
gint fd;
|
||||||
gboolean seekable_fd;
|
gboolean seekable_fd;
|
||||||
|
guint64 size;
|
||||||
|
|
||||||
/* poll timeout */
|
/* poll timeout */
|
||||||
guint64 timeout;
|
guint64 timeout;
|
||||||
|
|
Loading…
Reference in a new issue