[rhythmbox] encoder: add RBEncoderFactory singleton for plugin hooks



commit 4e8d220588df0ec0e3db9ffa60ce4334d7901d2f
Author: Jonathan Matthew <jonathan d14n org>
Date:   Tue Jun 2 20:27:08 2009 +1000

    encoder: add RBEncoderFactory singleton for plugin hooks
    
    Since a new encoder instance is created for each file being transferred,
    it's tricky for plugins to make use of any hooks we might add there.
    RBEncoderFactory acts as a well known place for hooks to be located.
    The only hook we have here so far is 'prepare-source', which does the
    same thing as the signal of that name on the player backends.
---
 backends/gstreamer/rb-encoder-gst.h |    2 +-
 backends/rb-encoder.c               |   63 +++++++++++++++++++++++++++++++++++
 backends/rb-encoder.h               |   35 ++++++++++++++++++--
 3 files changed, 96 insertions(+), 4 deletions(-)

diff --git a/backends/gstreamer/rb-encoder-gst.h b/backends/gstreamer/rb-encoder-gst.h
index 70e8529..f52a3f0 100644
--- a/backends/gstreamer/rb-encoder-gst.h
+++ b/backends/gstreamer/rb-encoder-gst.h
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 
 #define RB_TYPE_ENCODER_GST            (rb_encoder_gst_get_type ())
 #define RB_ENCODER_GST(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), RB_TYPE_ENCODER, RBEncoderGst))
-#define RB_ENCODE_GST_CLASS(k)         (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_ENCODER_GST, RBEncoderGstClass))
+#define RB_ENCODER_GST_CLASS(k)        (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_ENCODER_GST, RBEncoderGstClass))
 #define RB_IS_ENCODER_GST(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RB_TYPE_ENCODER))
 #define RB_IS_ENCODER_GST_CLASS(k)     (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_ENCODER_GST))
 #define RB_ENCODER_GST_GET_CLASS(o)    (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_ENCODER_GST, RBEncoderGstClass))
diff --git a/backends/rb-encoder.c b/backends/rb-encoder.c
index 6904b15..39fd4e3 100644
--- a/backends/rb-encoder.c
+++ b/backends/rb-encoder.c
@@ -46,16 +46,57 @@
  * A new encoder instance should be created for each file that is transcoded.
  */
 
+static void rb_encoder_factory_class_init (RBEncoderFactoryClass *klass);
+static void rb_encoder_factory_init       (RBEncoderFactory *encoder);
+
 /* Signals */
 enum {
 	PROGRESS,
 	COMPLETED,
 	ERROR,
+	PREPARE_SOURCE,		/* this is on RBEncoderFactory */
 	LAST_SIGNAL
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+static RBEncoderFactory *the_encoder_factory = NULL;
+static gsize encoder_factory_init = 0;
+
+G_DEFINE_TYPE(RBEncoderFactory, rb_encoder_factory, G_TYPE_OBJECT)
+
+static void
+rb_encoder_factory_init (RBEncoderFactory *factory)
+{
+}
+
+static void
+rb_encoder_factory_class_init (RBEncoderFactoryClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	/**
+	 * RBEncoderFactory::prepare-source:
+	 * @factory: the #RBEncoderFactory instance
+	 * @uri: the URI for the source
+	 * @source: the source object (a GstElement in fact)
+	 *
+	 * Emitted when creating a source to read the specified URI.
+	 * Plugins can use this when just creating a GStreamer element from the URI
+	 * isn't enough.  Typically this happens when there's no way to pass device
+	 * information through the URI format.
+	 */
+	signals[PREPARE_SOURCE] =
+		g_signal_new ("prepare-source",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBEncoderFactoryClass, prepare_source),
+			      NULL, NULL,
+			      rb_marshal_VOID__STRING_OBJECT,
+			      G_TYPE_NONE,
+			      2, G_TYPE_STRING, G_TYPE_OBJECT);
+}
+
 static void
 rb_encoder_interface_init (RBEncoderIface *iface)
 {
@@ -135,6 +176,22 @@ rb_encoder_get_type (void)
 }
 
 /**
+ * rb_encoder_factory_get:
+ *
+ * Return value: the #RBEncoderFactory
+ */
+RBEncoderFactory *
+rb_encoder_factory_get ()
+{
+	if (g_once_init_enter (&encoder_factory_init)) {
+		the_encoder_factory = g_object_new (RB_TYPE_ENCODER_FACTORY, NULL);
+		g_once_init_leave (&encoder_factory_init, 1);
+	}
+
+	return the_encoder_factory;
+}
+
+/**
  * rb_encoder_encode:
  * @encoder: the #RBEncoder
  * @entry: the #RhythmDBEntry to transcode
@@ -232,6 +289,12 @@ _rb_encoder_emit_error (RBEncoder *encoder, GError *error)
 	g_signal_emit (encoder, signals[ERROR], 0, error);
 }
 
+void
+_rb_encoder_emit_prepare_source (RBEncoder *encoder, const char *uri, GObject *source)
+{
+	g_signal_emit (rb_encoder_factory_get (), signals[PREPARE_SOURCE], 0, uri, source);
+}
+
 GQuark
 rb_encoder_error_quark (void)
 {
diff --git a/backends/rb-encoder.h b/backends/rb-encoder.h
index 939a47d..961c070 100644
--- a/backends/rb-encoder.h
+++ b/backends/rb-encoder.h
@@ -42,6 +42,13 @@ G_BEGIN_DECLS
 #define RB_IS_ENCODER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RB_TYPE_ENCODER))
 #define RB_ENCODER_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RB_TYPE_ENCODER, RBEncoderIface))
 
+#define RB_TYPE_ENCODER_FACTORY        (rb_encoder_factory_get_type ())
+#define RB_ENCODER_FACTORY(obj)        (G_TYPE_CHECK_INSTANCE_CAST ((obj), RB_TYPE_ENCODER, RBEncoderFactory))
+#define RB_ENCODER_FACTORY_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_ENCODER_FACTORY, RBEncoderFactoryClass))
+#define RB_IS_ENCODER_FACTORY(obj)     (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RB_TYPE_ENCODER))
+#define RB_IS_ENCODER_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_ENCODER_FACTORY))
+#define RB_ENCODER_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_ENCODER_FACTORY, RBEncoderFactoryClass))
+
 enum
 {
 	RB_ENCODER_ERROR_FORMAT_UNSUPPORTED,
@@ -54,8 +61,11 @@ enum
 GQuark rb_encoder_error_quark (void);
 
 typedef struct _RBEncoder RBEncoder;
+typedef struct _RBEncoderIface RBEncoderIface;
+typedef struct _RBEncoderFactory RBEncoderFactory;
+typedef struct _RBEncoderFactoryClass RBEncoderFactoryClass;
 
-typedef struct
+struct _RBEncoderIface
 {
 	GTypeInterface g_iface;
 
@@ -74,10 +84,27 @@ typedef struct
 	void (*progress) (RBEncoder *encoder,  double fraction);
 	void (*completed) (RBEncoder *encoder, guint64 dest_size);
 	void (*error) (RBEncoder *encoder, GError *error);
-} RBEncoderIface;
+};
+
+struct _RBEncoderFactoryClass
+{
+	GObjectClass obj_class;
+
+	/* signals */
+	void (*prepare_source) (RBEncoderFactory *factory, const char *uri, GObject *source);
+};
+
+struct _RBEncoderFactory
+{
+	GObject obj;
+};
+
+GType 		rb_encoder_factory_get_type (void);
+RBEncoderFactory *rb_encoder_factory_get (void);
+
 
 RBEncoder*	rb_encoder_new		(void);
-GType rb_encoder_get_type (void);
+GType 		rb_encoder_get_type 	(void);
 
 gboolean	rb_encoder_encode	(RBEncoder *encoder,
 					 RhythmDBEntry *entry,
@@ -95,6 +122,8 @@ void	_rb_encoder_emit_progress (RBEncoder *encoder, double fraction);
 void	_rb_encoder_emit_completed (RBEncoder *encoder, guint64 dest_size);
 void	_rb_encoder_emit_error (RBEncoder *encoder, GError *error);
 
+void	_rb_encoder_emit_prepare_source (RBEncoder *encoder, const char *uri, GObject *source);
+
 G_END_DECLS
 
 #endif /* __RB_ENCODER_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]