diff --git a/src/lib.rs b/src/lib.rs index a49591cb..236fa08a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,10 +31,10 @@ pub mod rshttpsrc; pub mod rsfilesink; use utils::*; -use rssource::Source; +use rssource::{Source, SourceController}; use rsfilesrc::FileSrc; use rshttpsrc::HttpSrc; -use rssink::Sink; +use rssink::{Sink, SinkController}; use rsfilesink::FileSink; use std::os::raw::c_void; @@ -49,7 +49,8 @@ extern "C" { classification: *const c_char, author: *const c_char, rank: i32, - create_instance: extern "C" fn() -> *mut Box, + create_instance: extern "C" fn(controller: SourceController) + -> *mut Box, protocols: *const c_char, push_only: GBoolean) -> GBoolean; @@ -63,7 +64,8 @@ extern "C" { classification: *const c_char, author: *const c_char, rank: i32, - create_instance: extern "C" fn() -> *mut Box, + create_instance: extern "C" fn(controller: SinkController) + -> *mut Box, protocols: *const c_char) -> GBoolean; } diff --git a/src/rsfilesink.rs b/src/rsfilesink.rs index 9ad19121..a6d2c4b2 100644 --- a/src/rsfilesink.rs +++ b/src/rsfilesink.rs @@ -28,6 +28,7 @@ use rssink::*; #[derive(Debug)] pub struct FileSink { + controller: SinkController, location: Mutex>, file: Option, position: u64, @@ -37,19 +38,17 @@ unsafe impl Sync for FileSink {} unsafe impl Send for FileSink {} impl FileSink { - fn new() -> FileSink { + fn new(controller: SinkController) -> FileSink { FileSink { + controller: controller, location: Mutex::new(None), file: None, position: 0, } } - fn new_source() -> Box { - Box::new(FileSink::new()) - } - pub extern "C" fn new_ptr() -> *mut Box { - let instance = Box::new(FileSink::new_source()); + pub extern "C" fn new_ptr(controller: SinkController) -> *mut Box { + let instance: Box> = Box::new(Box::new(FileSink::new(controller))); return Box::into_raw(instance); } } diff --git a/src/rsfilesrc.rs b/src/rsfilesrc.rs index 2a098f22..fc859b28 100644 --- a/src/rsfilesrc.rs +++ b/src/rsfilesrc.rs @@ -29,6 +29,7 @@ use rssource::*; #[derive(Debug)] pub struct FileSrc { + controller: SourceController, location: Mutex>, file: Option, position: u64, @@ -38,19 +39,17 @@ unsafe impl Sync for FileSrc {} unsafe impl Send for FileSrc {} impl FileSrc { - fn new() -> FileSrc { + fn new(controller: SourceController) -> FileSrc { FileSrc { + controller: controller, location: Mutex::new(None), file: None, position: 0, } } - fn new_source() -> Box { - Box::new(FileSrc::new()) - } - pub extern "C" fn new_ptr() -> *mut Box { - let instance = Box::new(FileSrc::new_source()); + pub extern "C" fn new_ptr(controller: SourceController) -> *mut Box { + let instance: Box> = Box::new(Box::new(FileSrc::new(controller))); return Box::into_raw(instance); } } diff --git a/src/rshttpsrc.rs b/src/rshttpsrc.rs index d4255fab..cf7cffb0 100644 --- a/src/rshttpsrc.rs +++ b/src/rshttpsrc.rs @@ -32,6 +32,7 @@ use rssource::*; #[derive(Debug)] pub struct HttpSrc { + controller: SourceController, url: Mutex>, client: Client, response: Option, @@ -46,8 +47,9 @@ unsafe impl Sync for HttpSrc {} unsafe impl Send for HttpSrc {} impl HttpSrc { - fn new() -> HttpSrc { + fn new(controller: SourceController) -> HttpSrc { HttpSrc { + controller: controller, url: Mutex::new(None), client: Client::new(), response: None, @@ -59,11 +61,8 @@ impl HttpSrc { } } - fn new_source() -> Box { - Box::new(HttpSrc::new()) - } - pub extern "C" fn new_ptr() -> *mut Box { - let instance = Box::new(HttpSrc::new_source()); + pub extern "C" fn new_ptr(controller: SourceController) -> *mut Box { + let instance: Box> = Box::new(Box::new(HttpSrc::new(controller))); return Box::into_raw(instance); } diff --git a/src/rssink.c b/src/rssink.c index 3353b0c1..24973ca5 100644 --- a/src/rssink.c +++ b/src/rssink.c @@ -29,13 +29,14 @@ typedef struct gchar *description; gchar *classification; gchar *author; - void *(*create_instance) (void); + void *create_instance; gchar **protocols; } ElementData; static GHashTable *sinks; /* Declarations for Rust code */ extern gboolean sinks_register (void *plugin); +extern void *sink_new (GstRsSink * sink, void *create_instance); extern GstFlowReturn sink_render (void *filesink, void *data, size_t data_len); extern gboolean sink_set_uri (void *filesink, const char *uri); extern char *sink_get_uri (void *filesink); @@ -118,7 +119,7 @@ gst_rs_sink_init (GstRsSink * sink, GstRsSinkClass * klass) gst_base_sink_set_sync (GST_BASE_SINK (sink), FALSE); - sink->instance = data->create_instance (); + sink->instance = sink_new (sink, data->create_instance); } static void @@ -263,7 +264,7 @@ gboolean gst_rs_sink_register (GstPlugin * plugin, const gchar * name, const gchar * long_name, const gchar * description, const gchar * classification, const gchar * author, GstRank rank, - void *(*create_instance) (void), const gchar * protocols) + void *create_instance, const gchar * protocols) { GTypeInfo type_info = { sizeof (GstRsSinkClass), diff --git a/src/rssink.rs b/src/rssink.rs index 5d342d2b..18cb5074 100644 --- a/src/rssink.rs +++ b/src/rssink.rs @@ -17,6 +17,7 @@ // Boston, MA 02110-1301, USA. use libc::c_char; +use std::os::raw::c_void; use std::ffi::{CStr, CString}; use std::slice; use std::ptr; @@ -26,6 +27,17 @@ use url::Url; use utils::*; +#[derive(Debug)] +pub struct SinkController { + sink: *mut c_void, +} + +impl SinkController { + fn new(sink: *mut c_void) -> SinkController { + SinkController { sink: sink } + } +} + pub trait Sink: Sync + Send { // Called from any thread at any time fn set_uri(&mut self, uri: Option) -> bool; @@ -37,6 +49,14 @@ pub trait Sink: Sync + Send { fn render(&mut self, data: &[u8]) -> GstFlowReturn; } +#[no_mangle] +pub extern "C" fn sink_new(sink: *mut c_void, + create_instance: extern "C" fn(controller: SinkController) + -> *mut Box) + -> *mut Box { + create_instance(SinkController::new(sink)) +} + #[no_mangle] pub extern "C" fn sink_drop(ptr: *mut Box) { unsafe { Box::from_raw(ptr) }; diff --git a/src/rssource.c b/src/rssource.c index fed3f837..bb1f3901 100644 --- a/src/rssource.c +++ b/src/rssource.c @@ -27,13 +27,14 @@ typedef struct gchar *description; gchar *classification; gchar *author; - void *(*create_instance) (void); + void *create_instance; gchar **protocols; } ElementData; static GHashTable *sources; /* Declarations for Rust code */ extern gboolean sources_register (void *plugin); +extern void *source_new (GstRsSrc * source, void *create_instance); extern void source_drop (void *source); extern GstFlowReturn source_fill (void *source, uint64_t offset, void *data, size_t * data_len); @@ -127,7 +128,7 @@ gst_rs_src_init (GstRsSrc * src, GstRsSrcClass * klass) gst_base_src_set_blocksize (GST_BASE_SRC (src), 4096); - src->instance = data->create_instance (); + src->instance = source_new (src, data->create_instance); } static void @@ -308,8 +309,7 @@ gboolean gst_rs_source_register (GstPlugin * plugin, const gchar * name, const gchar * long_name, const gchar * description, const gchar * classification, const gchar * author, GstRank rank, - void *(*create_instance) (void), const gchar * protocols, - gboolean push_only) + void *create_instance, const gchar * protocols, gboolean push_only) { GTypeInfo type_info = { sizeof (GstRsSrcClass), diff --git a/src/rssource.rs b/src/rssource.rs index aab975e9..4d955765 100644 --- a/src/rssource.rs +++ b/src/rssource.rs @@ -16,6 +16,7 @@ // Boston, MA 02110-1301, USA. use libc::c_char; +use std::os::raw::c_void; use std::ffi::{CStr, CString}; use std::slice; use std::ptr; @@ -25,6 +26,17 @@ use url::Url; use utils::*; +#[derive(Debug)] +pub struct SourceController { + source: *mut c_void, +} + +impl SourceController { + fn new(source: *mut c_void) -> SourceController { + SourceController { source: source } + } +} + pub trait Source: Sync + Send { // Called from any thread at any time fn set_uri(&mut self, uri: Option) -> bool; @@ -41,6 +53,14 @@ pub trait Source: Sync + Send { fn get_size(&self) -> u64; } +#[no_mangle] +pub extern "C" fn source_new(source: *mut c_void, + create_instance: extern "C" fn(controller: SourceController) + -> *mut Box) + -> *mut Box { + create_instance(SourceController::new(source)) +} + #[no_mangle] pub extern "C" fn source_drop(ptr: *mut Box) { unsafe { Box::from_raw(ptr) };