mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
gio: General clean up and simplification
The GInputStreams are now requested by a vfunc from the subclasses instead of relying that the subclass sets it until it's needed. This might also fix bug #587896.
This commit is contained in:
parent
da27fd57e8
commit
160b70e841
5 changed files with 66 additions and 98 deletions
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include "gstgiobasesrc.h"
|
||||
|
||||
#include <gst/base/gsttypefindhelper.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_gio_base_src_debug);
|
||||
#define GST_CAT_DEFAULT gst_gio_base_src_debug
|
||||
|
||||
|
@ -67,9 +69,7 @@ static void
|
|||
gst_gio_base_src_class_init (GstGioBaseSrcClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
GstBaseSrcClass *gstbasesrc_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
|
@ -125,16 +125,19 @@ static gboolean
|
|||
gst_gio_base_src_start (GstBaseSrc * base_src)
|
||||
{
|
||||
GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src);
|
||||
|
||||
if (!G_IS_INPUT_STREAM (src->stream)) {
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
|
||||
("No stream given yet"));
|
||||
return FALSE;
|
||||
}
|
||||
GstGioBaseSrcClass *gbsrc_class = GST_GIO_BASE_SRC_GET_CLASS (src);
|
||||
|
||||
src->position = 0;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "started stream");
|
||||
/* FIXME: This will likely block */
|
||||
src->stream = gbsrc_class->get_stream (src);
|
||||
if (G_UNLIKELY (!G_IS_INPUT_STREAM (src->stream))) {
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
|
||||
("No input stream provided by subclass"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (src, "started source");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -143,9 +146,7 @@ static gboolean
|
|||
gst_gio_base_src_stop (GstBaseSrc * base_src)
|
||||
{
|
||||
GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src);
|
||||
|
||||
gboolean success;
|
||||
|
||||
GError *err = NULL;
|
||||
|
||||
if (G_IS_INPUT_STREAM (src->stream)) {
|
||||
|
@ -180,7 +181,6 @@ gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size)
|
|||
|
||||
if (G_IS_FILE_INPUT_STREAM (src->stream)) {
|
||||
GFileInfo *info;
|
||||
|
||||
GError *err = NULL;
|
||||
|
||||
info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (src->stream),
|
||||
|
@ -207,13 +207,9 @@ gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size)
|
|||
|
||||
if (GST_GIO_STREAM_IS_SEEKABLE (src->stream)) {
|
||||
goffset old;
|
||||
|
||||
goffset stream_size;
|
||||
|
||||
gboolean ret;
|
||||
|
||||
GSeekable *seekable = G_SEEKABLE (src->stream);
|
||||
|
||||
GError *err = NULL;
|
||||
|
||||
old = g_seekable_tell (seekable);
|
||||
|
@ -231,7 +227,6 @@ gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size)
|
|||
} else {
|
||||
GST_WARNING_OBJECT (src, "Seeking to end of stream failed");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -249,7 +244,6 @@ gst_gio_base_src_get_size (GstBaseSrc * base_src, guint64 * size)
|
|||
} else {
|
||||
GST_ERROR_OBJECT (src, "Seeking to the old position faile");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -266,7 +260,6 @@ static gboolean
|
|||
gst_gio_base_src_is_seekable (GstBaseSrc * base_src)
|
||||
{
|
||||
GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src);
|
||||
|
||||
gboolean seekable;
|
||||
|
||||
seekable = GST_GIO_STREAM_IS_SEEKABLE (src->stream);
|
||||
|
@ -303,8 +296,6 @@ gst_gio_base_src_unlock_stop (GstBaseSrc * base_src)
|
|||
static gboolean
|
||||
gst_gio_base_src_check_get_range (GstBaseSrc * base_src)
|
||||
{
|
||||
/* FIXME: Implement dry-run variant using guesswork like gnomevfssrc? */
|
||||
|
||||
return GST_CALL_PARENT_WITH_DEFAULT (GST_BASE_SRC_CLASS,
|
||||
check_get_range, (base_src), FALSE);
|
||||
}
|
||||
|
@ -327,7 +318,6 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
|
|||
* over DBus if our backend is GVfs and this is painfully slow. */
|
||||
if (src->cache && offset >= GST_BUFFER_OFFSET (src->cache) &&
|
||||
offset + size <= GST_BUFFER_OFFSET_END (src->cache)) {
|
||||
|
||||
GST_DEBUG_OBJECT (src, "Creating subbuffer from cached buffer: offset %"
|
||||
G_GUINT64_FORMAT " length %u", offset, size);
|
||||
|
||||
|
@ -339,11 +329,8 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
|
|||
GST_BUFFER_SIZE (buf) = size;
|
||||
} else {
|
||||
guint cachesize = MAX (4096, size);
|
||||
|
||||
gssize read, res;
|
||||
|
||||
gboolean success, eos;
|
||||
|
||||
GError *err = NULL;
|
||||
|
||||
if (src->cache) {
|
||||
|
@ -452,39 +439,3 @@ gst_gio_base_src_query (GstBaseSrc * base_src, GstQuery * query)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
gst_gio_base_src_set_stream (GstGioBaseSrc * src, GInputStream * stream)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
GError *err = NULL;
|
||||
|
||||
g_return_if_fail (G_IS_INPUT_STREAM (stream));
|
||||
g_return_if_fail ((GST_STATE (src) != GST_STATE_PLAYING &&
|
||||
GST_STATE (src) != GST_STATE_PAUSED));
|
||||
|
||||
if (G_IS_INPUT_STREAM (src->stream)) {
|
||||
GST_DEBUG_OBJECT (src, "closing old stream");
|
||||
|
||||
/* FIXME: can block but unfortunately we can't use async operations
|
||||
* here because they require a running main loop */
|
||||
success = g_input_stream_close (src->stream, src->cancel, &err);
|
||||
|
||||
if (!success && !gst_gio_error (src, "g_input_stream_close", &err, NULL)) {
|
||||
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
|
||||
("g_input_stream_close failed: %s", err->message));
|
||||
g_clear_error (&err);
|
||||
} else if (!success) {
|
||||
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
|
||||
("g_input_stream_close failed"));
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (src, "g_input_stream_close succeeded");
|
||||
}
|
||||
|
||||
g_object_unref (src->stream);
|
||||
src->stream = NULL;
|
||||
}
|
||||
|
||||
src->stream = stream;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ G_BEGIN_DECLS
|
|||
(gst_gio_base_src_get_type())
|
||||
#define GST_GIO_BASE_SRC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GIO_BASE_SRC,GstGioBaseSrc))
|
||||
#define GST_GIO_BASE_SRC_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_GIO_BASE_SRC, GstGioBaseSrcClass))
|
||||
#define GST_GIO_BASE_SRC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GIO_BASE_SRC,GstGioBaseSrcClass))
|
||||
#define GST_IS_GIO_BASE_SRC(obj) \
|
||||
|
@ -56,12 +58,12 @@ struct _GstGioBaseSrc
|
|||
struct _GstGioBaseSrcClass
|
||||
{
|
||||
GstBaseSrcClass parent_class;
|
||||
|
||||
GInputStream * (*get_stream) (GstGioBaseSrc *bsrc);
|
||||
};
|
||||
|
||||
GType gst_gio_base_src_get_type (void);
|
||||
|
||||
void gst_gio_base_src_set_stream (GstGioBaseSrc *src, GInputStream *stream);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GIO_BASE_SRC_H__ */
|
||||
|
|
|
@ -81,7 +81,7 @@ static void gst_gio_src_set_property (GObject * object, guint prop_id,
|
|||
static void gst_gio_src_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_gio_src_start (GstBaseSrc * base_src);
|
||||
static GInputStream *gst_gio_src_get_stream (GstGioBaseSrc * bsrc);
|
||||
|
||||
static gboolean gst_gio_src_check_get_range (GstBaseSrc * base_src);
|
||||
|
||||
|
@ -103,14 +103,12 @@ static void
|
|||
gst_gio_src_class_init (GstGioSrcClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
GstBaseSrcClass *gstbasesrc_class;
|
||||
GstGioBaseSrcClass *gstgiobasesrc_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasesrc_class = (GstBaseSrcClass *) klass;
|
||||
gstgiobasesrc_class = (GstGioBaseSrcClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_gio_src_finalize;
|
||||
gobject_class->set_property = gst_gio_src_set_property;
|
||||
|
@ -131,9 +129,10 @@ gst_gio_src_class_init (GstGioSrcClass * klass)
|
|||
g_param_spec_object ("file", "File", "GFile to read from",
|
||||
G_TYPE_FILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gio_src_start);
|
||||
gstbasesrc_class->check_get_range =
|
||||
GST_DEBUG_FUNCPTR (gst_gio_src_check_get_range);
|
||||
|
||||
gstgiobasesrc_class->get_stream = GST_DEBUG_FUNCPTR (gst_gio_src_get_stream);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -279,23 +278,19 @@ done:
|
|||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
gst_gio_src_start (GstBaseSrc * base_src)
|
||||
static GInputStream *
|
||||
gst_gio_src_get_stream (GstGioBaseSrc * bsrc)
|
||||
{
|
||||
GstGioSrc *src = GST_GIO_SRC (base_src);
|
||||
|
||||
GstGioSrc *src = GST_GIO_SRC (bsrc);
|
||||
GError *err = NULL;
|
||||
|
||||
GInputStream *stream;
|
||||
|
||||
GCancellable *cancel = GST_GIO_BASE_SRC (src)->cancel;
|
||||
|
||||
GCancellable *cancel = bsrc->cancel;
|
||||
gchar *uri = NULL;
|
||||
|
||||
if (src->file == NULL) {
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
|
||||
("No location or GFile given"));
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uri = g_file_get_uri (src->file);
|
||||
|
@ -315,16 +310,14 @@ gst_gio_src_start (GstBaseSrc * base_src)
|
|||
|
||||
g_free (uri);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
return NULL;
|
||||
} else if (stream == NULL) {
|
||||
g_free (uri);
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src), stream);
|
||||
|
||||
GST_DEBUG_OBJECT (src, "opened location %s", uri);
|
||||
g_free (uri);
|
||||
|
||||
return GST_BASE_SRC_CLASS (parent_class)->start (base_src);
|
||||
return stream;
|
||||
}
|
||||
|
|
|
@ -73,8 +73,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_gio_stream_src_debug);
|
|||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_STREAM
|
||||
PROP_0,
|
||||
PROP_STREAM
|
||||
};
|
||||
|
||||
GST_BOILERPLATE (GstGioStreamSrc, gst_gio_stream_src, GstGioBaseSrc,
|
||||
|
@ -85,6 +85,7 @@ static void gst_gio_stream_src_set_property (GObject * object, guint prop_id,
|
|||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_gio_stream_src_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static GInputStream *gst_gio_stream_src_get_stream (GstGioBaseSrc * bsrc);
|
||||
|
||||
static void
|
||||
gst_gio_stream_src_base_init (gpointer gclass)
|
||||
|
@ -107,20 +108,21 @@ static void
|
|||
gst_gio_stream_src_class_init (GstGioStreamSrcClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseSrcClass *gstbasesrc_class;
|
||||
GstGioBaseSrcClass *gstgiobasesrc_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasesrc_class = (GstBaseSrcClass *) klass;
|
||||
gstgiobasesrc_class = (GstGioBaseSrcClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_gio_stream_src_finalize;
|
||||
gobject_class->set_property = gst_gio_stream_src_set_property;
|
||||
gobject_class->get_property = gst_gio_stream_src_get_property;
|
||||
|
||||
g_object_class_install_property (gobject_class, ARG_STREAM,
|
||||
g_object_class_install_property (gobject_class, PROP_STREAM,
|
||||
g_param_spec_object ("stream", "Stream", "Stream to read from",
|
||||
G_TYPE_INPUT_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gstgiobasesrc_class->get_stream =
|
||||
GST_DEBUG_FUNCPTR (gst_gio_stream_src_get_stream);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -131,6 +133,13 @@ gst_gio_stream_src_init (GstGioStreamSrc * src, GstGioStreamSrcClass * gclass)
|
|||
static void
|
||||
gst_gio_stream_src_finalize (GObject * object)
|
||||
{
|
||||
GstGioStreamSrc *src = GST_GIO_STREAM_SRC (object);
|
||||
|
||||
if (src->stream) {
|
||||
g_object_unref (src->stream);
|
||||
src->stream = NULL;
|
||||
}
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
|
@ -141,18 +150,20 @@ gst_gio_stream_src_set_property (GObject * object, guint prop_id,
|
|||
GstGioStreamSrc *src = GST_GIO_STREAM_SRC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_STREAM:{
|
||||
case PROP_STREAM:{
|
||||
GObject *stream;
|
||||
|
||||
if (GST_STATE (src) == GST_STATE_PLAYING ||
|
||||
GST_STATE (src) == GST_STATE_PAUSED)
|
||||
GST_STATE (src) == GST_STATE_PAUSED) {
|
||||
GST_WARNING
|
||||
("Setting a new stream not supported in PLAYING or PAUSED state");
|
||||
break;
|
||||
}
|
||||
|
||||
stream = g_value_dup_object (value);
|
||||
if (G_IS_INPUT_STREAM (stream))
|
||||
gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src),
|
||||
G_INPUT_STREAM (stream));
|
||||
|
||||
if (src->stream)
|
||||
g_object_unref (src->stream);
|
||||
src->stream = G_INPUT_STREAM (stream);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -168,11 +179,19 @@ gst_gio_stream_src_get_property (GObject * object, guint prop_id,
|
|||
GstGioStreamSrc *src = GST_GIO_STREAM_SRC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_STREAM:
|
||||
g_value_set_object (value, GST_GIO_BASE_SRC (src)->stream);
|
||||
case PROP_STREAM:
|
||||
g_value_set_object (value, src->stream);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gst_gio_stream_src_get_stream (GstGioBaseSrc * bsrc)
|
||||
{
|
||||
GstGioStreamSrc *src = GST_GIO_STREAM_SRC (bsrc);
|
||||
|
||||
return (src->stream) ? g_object_ref (src->stream) : NULL;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,9 @@ typedef struct _GstGioStreamSrcClass GstGioStreamSrcClass;
|
|||
struct _GstGioStreamSrc
|
||||
{
|
||||
GstGioBaseSrc src;
|
||||
|
||||
/* < private > */
|
||||
GInputStream *stream;
|
||||
};
|
||||
|
||||
struct _GstGioStreamSrcClass
|
||||
|
|
Loading…
Reference in a new issue