Create GStreamer plugin from Rust and have the plugin entry point written in Rust

This commit is contained in:
Sebastian Dröge 2016-12-08 21:48:40 +02:00
parent cc183ea92e
commit 78450a035d
6 changed files with 65 additions and 44 deletions

View file

@ -23,7 +23,7 @@ fn main() {
let gstbase = pkg_config::probe_library("gstreamer-base-1.0").unwrap(); let gstbase = pkg_config::probe_library("gstreamer-base-1.0").unwrap();
let includes = [gstreamer.include_paths, gstbase.include_paths]; let includes = [gstreamer.include_paths, gstbase.include_paths];
let files = ["src/plugin.c", "src/rssource.c", "src/rssink.c", "src/rsdemuxer.c"]; let files = ["src/lib.c", "src/rssource.c", "src/rssink.c", "src/rsdemuxer.c"];
let mut config = gcc::Config::new(); let mut config = gcc::Config::new();
config.include("src"); config.include("src");

View file

@ -22,32 +22,6 @@
#include "rssink.h" #include "rssink.h"
#include "rsdemuxer.h" #include "rsdemuxer.h"
static gboolean
plugin_init (GstPlugin * plugin)
{
if (!gst_rs_source_plugin_init (plugin))
return FALSE;
if (!gst_rs_sink_plugin_init (plugin))
return FALSE;
if (!gst_rs_demuxer_plugin_init (plugin))
return FALSE;
return TRUE;
}
#define VERSION "1.0"
#define PACKAGE "rsplugin"
#define GST_PACKAGE_NAME PACKAGE
#define GST_PACKAGE_ORIGIN "http://www.example.org"
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
rsplugin,
"Rust Plugin", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
GST_PACKAGE_ORIGIN);
void void
gst_rs_element_error (GstElement * element, GQuark error_domain, gst_rs_element_error (GstElement * element, GQuark error_domain,
gint error_code, const gchar * message, const gchar * debug, gint error_code, const gchar * message, const gchar * debug,

View file

@ -96,8 +96,7 @@ unsafe fn source_register(plugin: *const c_void,
} }
#[no_mangle] unsafe fn sources_register(plugin: *const c_void) -> GBoolean {
pub unsafe extern "C" fn sources_register(plugin: *const c_void) -> GBoolean {
source_register(plugin, source_register(plugin,
"rsfilesrc", "rsfilesrc",
"File Source", "File Source",
@ -163,8 +162,7 @@ unsafe fn sink_register(plugin: *const c_void,
cprotocols.as_ptr()); cprotocols.as_ptr());
} }
#[no_mangle] unsafe fn sinks_register(plugin: *const c_void) -> GBoolean {
pub unsafe extern "C" fn sinks_register(plugin: *const c_void) -> GBoolean {
sink_register(plugin, sink_register(plugin,
"rsfilesink", "rsfilesink",
"File Sink", "File Sink",
@ -222,8 +220,7 @@ unsafe fn demuxer_register(plugin: *const c_void,
coutput_formats.as_ptr()); coutput_formats.as_ptr());
} }
#[no_mangle] unsafe fn demuxers_register(plugin: *const c_void) -> GBoolean {
pub unsafe extern "C" fn demuxers_register(plugin: *const c_void) -> GBoolean {
demuxer_register(plugin, demuxer_register(plugin,
"rsflvdemux", "rsflvdemux",
"FLV Demuxer", "FLV Demuxer",
@ -237,3 +234,48 @@ pub unsafe extern "C" fn demuxers_register(plugin: *const c_void) -> GBoolean {
GBoolean::True GBoolean::True
} }
#[repr(C)]
pub struct GstPluginDesc {
major_version: i32,
minor_version: i32,
name: *const u8,
description: *const u8,
plugin_init: extern "C" fn(plugin: *const c_void) -> GBoolean,
version: *const u8,
license: *const u8,
source: *const u8,
package: *const u8,
origin: *const u8,
release_datetime: *const u8,
_gst_reserved: [usize; 4],
}
unsafe impl Sync for GstPluginDesc {}
extern "C" fn plugin_init(plugin: *const c_void) -> GBoolean {
unsafe {
sources_register(plugin);
sinks_register(plugin);
demuxers_register(plugin);
}
GBoolean::True
}
#[no_mangle]
#[allow(non_upper_case_globals)]
pub static gst_plugin_desc: GstPluginDesc = GstPluginDesc {
major_version: 1,
minor_version: 10,
name: b"rsplugin\0" as *const u8,
description: b"Rust Plugin\0" as *const u8,
plugin_init: plugin_init,
version: b"1.0\0" as *const u8,
license: b"LGPL\0" as *const u8,
source: b"rsplugin\0" as *const u8,
package: b"rsplugin\0" as *const u8,
origin: b"https://github.com/sdroege/rsplugin\0" as *const u8,
release_datetime: b"2016-12-08\0" as *const u8,
_gst_reserved: [0, 0, 0, 0],
};

View file

@ -470,16 +470,14 @@ gst_rs_demuxer_remove_all_streams (GstRsDemuxer * demuxer)
memset (demuxer->srcpads, 0, sizeof (demuxer->srcpads)); memset (demuxer->srcpads, 0, sizeof (demuxer->srcpads));
} }
gboolean static gpointer
gst_rs_demuxer_plugin_init (GstPlugin * plugin) gst_rs_demuxer_init_class (gpointer data)
{ {
demuxers = g_hash_table_new (g_direct_hash, g_direct_equal); demuxers = g_hash_table_new (g_direct_hash, g_direct_equal);
GST_DEBUG_CATEGORY_INIT (gst_rs_demuxer_debug, "rsdemux", 0, GST_DEBUG_CATEGORY_INIT (gst_rs_demuxer_debug, "rsdemux", 0,
"rsdemux element"); "rsdemux element");
parent_class = g_type_class_ref (GST_TYPE_ELEMENT); parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
return demuxers_register (plugin);
} }
gboolean gboolean
@ -489,6 +487,7 @@ gst_rs_demuxer_register (GstPlugin * plugin, const gchar * name,
void *create_instance, const gchar * input_format, void *create_instance, const gchar * input_format,
const gchar * output_formats) const gchar * output_formats)
{ {
GOnce gonce = G_ONCE_INIT;
GTypeInfo type_info = { GTypeInfo type_info = {
sizeof (GstRsDemuxerClass), sizeof (GstRsDemuxerClass),
NULL, NULL,
@ -504,6 +503,8 @@ gst_rs_demuxer_register (GstPlugin * plugin, const gchar * name,
gchar *type_name; gchar *type_name;
ElementData *data; ElementData *data;
g_once (&gonce, gst_rs_demuxer_init_class, NULL);
data = g_new0 (ElementData, 1); data = g_new0 (ElementData, 1);
data->long_name = g_strdup (long_name); data->long_name = g_strdup (long_name);
data->description = g_strdup (description); data->description = g_strdup (description);

View file

@ -243,15 +243,13 @@ gst_rs_sink_uri_handler_init (gpointer g_iface, gpointer iface_data)
iface->set_uri = gst_rs_sink_uri_set_uri; iface->set_uri = gst_rs_sink_uri_set_uri;
} }
gboolean static gpointer
gst_rs_sink_plugin_init (GstPlugin * plugin) gst_rs_sink_init_class (gpointer data)
{ {
sinks = g_hash_table_new (g_direct_hash, g_direct_equal); sinks = g_hash_table_new (g_direct_hash, g_direct_equal);
GST_DEBUG_CATEGORY_INIT (gst_rs_sink_debug, "rssink", 0, "rssink element"); GST_DEBUG_CATEGORY_INIT (gst_rs_sink_debug, "rssink", 0, "rssink element");
parent_class = g_type_class_ref (GST_TYPE_BASE_SINK); parent_class = g_type_class_ref (GST_TYPE_BASE_SINK);
return sinks_register (plugin);
} }
gboolean gboolean
@ -260,6 +258,7 @@ gst_rs_sink_register (GstPlugin * plugin, const gchar * name,
const gchar * classification, const gchar * author, GstRank rank, const gchar * classification, const gchar * author, GstRank rank,
void *create_instance, const gchar * protocols) void *create_instance, const gchar * protocols)
{ {
static GOnce gonce = G_ONCE_INIT;
GTypeInfo type_info = { GTypeInfo type_info = {
sizeof (GstRsSinkClass), sizeof (GstRsSinkClass),
NULL, NULL,
@ -280,6 +279,8 @@ gst_rs_sink_register (GstPlugin * plugin, const gchar * name,
gchar *type_name; gchar *type_name;
ElementData *data; ElementData *data;
g_once (&gonce, gst_rs_sink_init_class, NULL);
data = g_new0 (ElementData, 1); data = g_new0 (ElementData, 1);
data->name = g_strdup (name); data->name = g_strdup (name);
data->long_name = g_strdup (long_name); data->long_name = g_strdup (long_name);

View file

@ -280,15 +280,15 @@ gst_rs_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
iface->set_uri = gst_rs_src_uri_set_uri; iface->set_uri = gst_rs_src_uri_set_uri;
} }
gboolean static gpointer
gst_rs_source_plugin_init (GstPlugin * plugin) gst_rs_source_init_class (gpointer data)
{ {
sources = g_hash_table_new (g_direct_hash, g_direct_equal); sources = g_hash_table_new (g_direct_hash, g_direct_equal);
GST_DEBUG_CATEGORY_INIT (gst_rs_src_debug, "rssrc", 0, "rssrc element"); GST_DEBUG_CATEGORY_INIT (gst_rs_src_debug, "rssrc", 0, "rssrc element");
parent_class = g_type_class_ref (GST_TYPE_BASE_SRC); parent_class = g_type_class_ref (GST_TYPE_BASE_SRC);
return sources_register (plugin); return NULL;
} }
gboolean gboolean
@ -297,6 +297,7 @@ gst_rs_source_register (GstPlugin * plugin, const gchar * name,
const gchar * classification, const gchar * author, GstRank rank, const gchar * classification, const gchar * author, GstRank rank,
void *create_instance, const gchar * protocols, gboolean push_only) void *create_instance, const gchar * protocols, gboolean push_only)
{ {
static GOnce gonce = G_ONCE_INIT;
GTypeInfo type_info = { GTypeInfo type_info = {
sizeof (GstRsSrcClass), sizeof (GstRsSrcClass),
NULL, NULL,
@ -317,6 +318,8 @@ gst_rs_source_register (GstPlugin * plugin, const gchar * name,
gchar *type_name; gchar *type_name;
ElementData *data; ElementData *data;
g_once (&gonce, gst_rs_source_init_class, NULL);
data = g_new0 (ElementData, 1); data = g_new0 (ElementData, 1);
data->long_name = g_strdup (long_name); data->long_name = g_strdup (long_name);
data->description = g_strdup (description); data->description = g_strdup (description);