diff --git a/build.rs b/build.rs index 244c3d7d..4c98e8f9 100644 --- a/build.rs +++ b/build.rs @@ -6,7 +6,7 @@ fn main() { let gstbase = pkg_config::probe_library("gstreamer-base-1.0").unwrap(); let includes = [gstreamer.include_paths, gstbase.include_paths]; - let files = ["src/plugin.c", "src/rsfilesrc.c"]; + let files = ["src/plugin.c", "src/rsfilesrc.c", "src/rsfilesink.c"]; let mut config = gcc::Config::new(); config.include("src"); diff --git a/src/lib.rs b/src/lib.rs index 73b0c0c9..902318ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,4 @@ extern crate libc; pub mod rsfilesrc; +pub mod rsfilesink; diff --git a/src/plugin.c b/src/plugin.c index f8d4d978..8c9e4623 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -1,6 +1,7 @@ #include #include "rsfilesrc.h" +#include "rsfilesink.h" static gboolean plugin_init (GstPlugin * plugin) @@ -10,6 +11,11 @@ plugin_init (GstPlugin * plugin) return FALSE; } + if (!gst_element_register (plugin, "rsfilesink", GST_RANK_NONE, + GST_TYPE_RSFILE_SINK)) { + return FALSE; + } + return TRUE; } diff --git a/src/rsfilesink.c b/src/rsfilesink.c new file mode 100644 index 00000000..c7301508 --- /dev/null +++ b/src/rsfilesink.c @@ -0,0 +1,159 @@ +#include "rsfilesink.h" + +GST_DEBUG_CATEGORY_STATIC (gst_rsfile_sink_debug); +#define GST_CAT_DEFAULT gst_rsfile_sink_debug + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +enum +{ + PROP_0, + PROP_LOCATION +}; + +static void gst_rsfile_sink_finalize (GObject * object); + +static void gst_rsfile_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_rsfile_sink_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static gboolean gst_rsfile_sink_start (GstBaseSink * basesink); +static gboolean gst_rsfile_sink_stop (GstBaseSink * basesink); +static gboolean gst_rsfile_sink_query (GstBaseSink * basesink, GstQuery * query); +static GstFlowReturn gst_rsfile_sink_render (GstBaseSink * sink, GstBuffer * buffer); +static gboolean gst_rsfile_sink_event (GstBaseSink * sink, GstEvent * event); + +#define _do_init \ + GST_DEBUG_CATEGORY_INIT (gst_rsfile_sink_debug, "rsfilesink", 0, "rsfilesink element"); +#define gst_rsfile_sink_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstRsFileSink, gst_rsfile_sink, GST_TYPE_BASE_SINK, _do_init); + +static void +gst_rsfile_sink_class_init (GstRsFileSinkClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstBaseSinkClass *gstbasesink_class; + + gobject_class = G_OBJECT_CLASS (klass); + gstelement_class = GST_ELEMENT_CLASS (klass); + gstbasesink_class = GST_BASE_SINK_CLASS (klass); + + gobject_class->set_property = gst_rsfile_sink_set_property; + gobject_class->get_property = gst_rsfile_sink_get_property; + + g_object_class_install_property (gobject_class, PROP_LOCATION, + g_param_spec_string ("location", "File Location", + "Location of the file to read", NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY)); + + gobject_class->finalize = gst_rsfile_sink_finalize; + + gst_element_class_set_static_metadata (gstelement_class, + "File Sink", + "Sink/Rsfile", + "Write to a file", + "Luis de Bethencourt "); + gst_element_class_add_static_pad_template (gstelement_class, &sink_template); + + gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_rsfile_sink_start); + gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_rsfile_sink_stop); + gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_rsfile_sink_query); + gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_rsfile_sink_render); + gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_rsfile_sink_event); +} + +static void +gst_rsfile_sink_init (GstRsFileSink * src) +{ + gst_base_sink_set_blocksize (GST_BASE_SINK (src), 4096); +} + +static void +gst_rsfile_sink_finalize (GObject * object) +{ + GstRsFileSink *src = GST_RSFILE_SINK (object); + + g_free (src->location); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_rsfile_sink_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstRsFileSink *src = GST_RSFILE_SINK (object); + + switch (prop_id) { + case PROP_LOCATION: + if (src->location) + g_free (src->location); + src->location = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_rsfile_sink_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstRsFileSink *src = GST_RSFILE_SINK (object); + + switch (prop_id) { + case PROP_LOCATION: + g_value_set_string (value, src->location); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +extern void bar(void); + +static GstFlowReturn +gst_rsfile_sink_render (GstBaseSink * sink, GstBuffer * buffer) +{ + bar(); +} + +static gboolean +gst_rsfile_sink_query (GstBaseSink * basesink, GstQuery * query) +{ + GstRsFileSink *sink = GST_RSFILE_SINK (basesink); + + return TRUE; +} + +static gboolean +gst_rsfile_sink_event (GstBaseSink * sink, GstEvent * event) +{ + return TRUE; +} + +/* open the rsfile, necessary to go to READY state */ +static gboolean +gst_rsfile_sink_start (GstBaseSink * basesink) +{ + GstRsFileSink *src = GST_RSFILE_SINK (basesink); + + return TRUE; +} + +/* unmap and close the rsfile */ +static gboolean +gst_rsfile_sink_stop (GstBaseSink * basesink) +{ + GstRsFileSink *src = GST_RSFILE_SINK (basesink); + + return TRUE; +} diff --git a/src/rsfilesink.h b/src/rsfilesink.h new file mode 100644 index 00000000..1ea88b78 --- /dev/null +++ b/src/rsfilesink.h @@ -0,0 +1,38 @@ +#ifndef __GST_RSFILE_SINK_H__ +#define __GST_RSFILE_SINK_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_RSFILE_SINK \ + (gst_rsfile_sink_get_type()) +#define GST_RSFILE_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RSFILE_SINK,GstRsFileSink)) +#define GST_RSFILE_SINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RSFILE_SINK,GstRsFileSinkClass)) +#define GST_IS_RSFILE_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RSFILE_SINK)) +#define GST_IS_RSFILE_SINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RSFILE_SINK)) +#define GST_RSFILE_SINK_CAST(obj) ((GstRsFileSink*) obj) + +typedef struct _GstRsFileSink GstRsFileSink; +typedef struct _GstRsFileSinkClass GstRsFileSinkClass; + +struct _GstRsFileSink { + GstBaseSink element; + + gchar *location; +}; + +struct _GstRsFileSinkClass { + GstBaseSinkClass parent_class; +}; + +G_GNUC_INTERNAL GType gst_rsfile_sink_get_type (void); + +G_END_DECLS + +#endif /* __GST_RSFILE_SINK_H__ */ diff --git a/src/rsfilesink.rs b/src/rsfilesink.rs new file mode 100644 index 00000000..c3033d09 --- /dev/null +++ b/src/rsfilesink.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern fn bar() { + print!("bar\n"); +}