diff --git a/src/lib.rs b/src/lib.rs index da28f41b..192b33f7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,10 +31,8 @@ pub mod rshttpsrc; pub mod rsfilesink; use utils::*; -use rssource::{Source, SourceController}; use rsfilesrc::FileSrc; use rshttpsrc::HttpSrc; -use rssink::{Sink, SinkController}; use rsfilesink::FileSink; use std::os::raw::c_void; @@ -49,7 +47,7 @@ extern "C" { classification: *const c_char, author: *const c_char, rank: i32, - create_instance: fn(controller: SourceController) -> Box, + create_instance: *const c_void, protocols: *const c_char, push_only: GBoolean) -> GBoolean; @@ -63,60 +61,106 @@ extern "C" { classification: *const c_char, author: *const c_char, rank: i32, - create_instance: fn(controller: SinkController) -> Box, + create_instance: *const c_void, protocols: *const c_char) -> GBoolean; } -#[no_mangle] -pub extern "C" fn sources_register(plugin: *const c_void) -> GBoolean { +unsafe fn source_register(plugin: *const c_void, + name: &str, + long_name: &str, + description: &str, + classification: &str, + author: &str, + rank: i32, + create_instance: *const c_void, + protocols: &str, + push_only: bool) { + let cname = CString::new(name).unwrap(); + let clong_name = CString::new(long_name).unwrap(); + let cdescription = CString::new(description).unwrap(); + let cclassification = CString::new(classification).unwrap(); + let cauthor = CString::new(author).unwrap(); + let cprotocols = CString::new(protocols).unwrap(); - unsafe { - gst_rs_source_register(plugin, - CString::new("rsfilesrc").unwrap().as_ptr(), - CString::new("File Source").unwrap().as_ptr(), - CString::new("Reads local files").unwrap().as_ptr(), - CString::new("Source/File").unwrap().as_ptr(), - CString::new("Sebastian Dröge ") - .unwrap() - .as_ptr(), - 256 + 100, - FileSrc::new_boxed, - CString::new("file").unwrap().as_ptr(), - GBoolean::False); + gst_rs_source_register(plugin, + cname.as_ptr(), + clong_name.as_ptr(), + cdescription.as_ptr(), + cclassification.as_ptr(), + cauthor.as_ptr(), + rank, + create_instance, + cprotocols.as_ptr(), + GBoolean::from_bool(push_only)); - gst_rs_source_register(plugin, - CString::new("rshttpsrc").unwrap().as_ptr(), - CString::new("HTTP Source").unwrap().as_ptr(), - CString::new("Read HTTP/HTTPS files").unwrap().as_ptr(), - CString::new("Source/Network/HTTP").unwrap().as_ptr(), - CString::new("Sebastian Dröge ") - .unwrap() - .as_ptr(), - 256 + 100, - HttpSrc::new_boxed, - CString::new("http:https").unwrap().as_ptr(), - GBoolean::True); - } - - return GBoolean::True; } #[no_mangle] -pub extern "C" fn sinks_register(plugin: *const c_void) -> GBoolean { +pub unsafe extern "C" fn sources_register(plugin: *const c_void) -> GBoolean { + source_register(plugin, + "rsfilesrc", + "File Source", + "Reads local files", + "Source/File", + "Sebastian Dröge ", + 256 + 100, + FileSrc::new_boxed as *const c_void, + "file", + false); - unsafe { - gst_rs_sink_register(plugin, - CString::new("rsfilesink").unwrap().as_ptr(), - CString::new("File Sink").unwrap().as_ptr(), - CString::new("Writes to local files").unwrap().as_ptr(), - CString::new("Sink/File").unwrap().as_ptr(), - CString::new("Luis de Bethencourt ") - .unwrap() - .as_ptr(), - 256 + 100, - FileSink::new_boxed, - CString::new("file").unwrap().as_ptr()); - } - return GBoolean::True; + source_register(plugin, + "rshttpsrc", + "HTTP Source", + "Read HTTP/HTTPS files", + "Source/Network/HTTP", + "Sebastian Dröge ", + 256 + 100, + HttpSrc::new_boxed as *const c_void, + "http:https", + true); + + GBoolean::True +} + +unsafe fn sink_register(plugin: *const c_void, + name: &str, + long_name: &str, + description: &str, + classification: &str, + author: &str, + rank: i32, + create_instance: *const c_void, + protocols: &str) { + let cname = CString::new(name).unwrap(); + let clong_name = CString::new(long_name).unwrap(); + let cdescription = CString::new(description).unwrap(); + let cclassification = CString::new(classification).unwrap(); + let cauthor = CString::new(author).unwrap(); + let cprotocols = CString::new(protocols).unwrap(); + + gst_rs_sink_register(plugin, + cname.as_ptr(), + clong_name.as_ptr(), + cdescription.as_ptr(), + cclassification.as_ptr(), + cauthor.as_ptr(), + rank, + create_instance, + cprotocols.as_ptr()); +} + +#[no_mangle] +pub unsafe extern "C" fn sinks_register(plugin: *const c_void) -> GBoolean { + sink_register(plugin, + "rsfilesink", + "File Sink", + "Writes to local files", + "Sink/File", + "Luis de Bethencourt ", + 256 + 100, + FileSink::new_boxed as *const c_void, + "file"); + + GBoolean::True } diff --git a/src/rssink.c b/src/rssink.c index 37c0ced0..f6e1f9e8 100644 --- a/src/rssink.c +++ b/src/rssink.c @@ -37,13 +37,12 @@ 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 (GstRsSink * sink, void *rssink, void *data, - size_t data_len); -extern gboolean sink_set_uri (GstRsSink * sink, void *rssink, const char *uri); -extern char *sink_get_uri (GstRsSink * sink, void *rssink); -extern gboolean sink_start (GstRsSink * sink, void *rssink); -extern gboolean sink_stop (GstRsSink * sink, void *rssink); -extern void sink_drop (GstRsSink * sink, void *rssink); +extern GstFlowReturn sink_render (void *rssink, void *data, size_t data_len); +extern gboolean sink_set_uri (void *rssink, const char *uri); +extern char *sink_get_uri (void *rssink); +extern gboolean sink_start (void *rssink); +extern gboolean sink_stop (void *rssink); +extern void sink_drop (void *rssink); extern void cstring_drop (void *str); @@ -128,7 +127,7 @@ gst_rs_sink_finalize (GObject * object) { GstRsSink *sink = GST_RS_SINK (object); - sink_drop (sink, sink->instance); + sink_drop (sink->instance); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -141,7 +140,7 @@ gst_rs_sink_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_URI: - sink_set_uri (sink, sink->instance, g_value_get_string (value)); + sink_set_uri (sink->instance, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -157,7 +156,7 @@ gst_rs_sink_get_property (GObject * object, guint prop_id, GValue * value, switch (prop_id) { case PROP_URI:{ - gchar *str = sink_get_uri (sink, sink->instance); + gchar *str = sink_get_uri (sink->instance); g_value_set_string (value, str); if (str) cstring_drop (str); @@ -177,7 +176,7 @@ gst_rs_sink_render (GstBaseSink * basesink, GstBuffer * buffer) GstFlowReturn ret; gst_buffer_map (buffer, &map, GST_MAP_READ); - ret = sink_render (sink, sink->instance, map.data, map.size); + ret = sink_render (sink->instance, map.data, map.size); gst_buffer_unmap (buffer, &map); return ret; @@ -189,7 +188,7 @@ gst_rs_sink_start (GstBaseSink * basesink) { GstRsSink *sink = GST_RS_SINK (basesink); - return sink_start (sink, sink->instance); + return sink_start (sink->instance); } /* unmap and close the rs */ @@ -198,7 +197,7 @@ gst_rs_sink_stop (GstBaseSink * basesink) { GstRsSink *sink = GST_RS_SINK (basesink); - return sink_stop (sink, sink->instance); + return sink_stop (sink->instance); } static GstURIType @@ -221,7 +220,7 @@ gst_rs_sink_uri_get_uri (GstURIHandler * handler) { GstRsSink *sink = GST_RS_SINK (handler); - return sink_get_uri (sink, sink->instance); + return sink_get_uri (sink->instance); } static gboolean @@ -230,7 +229,7 @@ gst_rs_sink_uri_set_uri (GstURIHandler * handler, const gchar * uri, { GstRsSink *sink = GST_RS_SINK (handler); - if (!sink_set_uri (sink, sink->instance, uri)) { + if (!sink_set_uri (sink->instance, uri)) { g_set_error (err, GST_URI_ERROR, GST_URI_ERROR_BAD_URI, "Can't handle URI '%s'", uri); return FALSE; diff --git a/src/rssink.rs b/src/rssink.rs index 7826c247..9f413c9c 100644 --- a/src/rssink.rs +++ b/src/rssink.rs @@ -57,21 +57,19 @@ pub extern "C" fn sink_new(sink: *mut c_void, } #[no_mangle] -pub extern "C" fn sink_drop(sink: *mut c_void, ptr: *mut Box) { - unsafe { Box::from_raw(ptr) }; +pub unsafe extern "C" fn sink_drop(ptr: *mut Box) { + Box::from_raw(ptr); } #[no_mangle] -pub extern "C" fn sink_set_uri(sink: *mut c_void, - ptr: *mut Box, - uri_ptr: *const c_char) - -> GBoolean { - let sink: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn sink_set_uri(ptr: *mut Box, uri_ptr: *const c_char) -> GBoolean { + let sink: &mut Box = &mut *ptr; if uri_ptr.is_null() { GBoolean::from_bool(sink.set_uri(None)) } else { - let uri_str = unsafe { CStr::from_ptr(uri_ptr) }.to_str().unwrap(); + let uri_str = CStr::from_ptr(uri_ptr).to_str().unwrap(); + match Url::parse(uri_str) { Ok(uri) => GBoolean::from_bool(sink.set_uri(Some(uri))), Err(err) => { @@ -84,8 +82,8 @@ pub extern "C" fn sink_set_uri(sink: *mut c_void, } #[no_mangle] -pub extern "C" fn sink_get_uri(sink: *mut c_void, ptr: *const Box) -> *mut c_char { - let sink: &Box = unsafe { &*ptr }; +pub unsafe extern "C" fn sink_get_uri(ptr: *const Box) -> *mut c_char { + let sink: &Box = &*ptr; match sink.get_uri() { Some(uri) => CString::new(uri.into_string().into_bytes()).unwrap().into_raw(), @@ -94,27 +92,26 @@ pub extern "C" fn sink_get_uri(sink: *mut c_void, ptr: *const Box) -> *mut } #[no_mangle] -pub extern "C" fn sink_render(sink: *mut c_void, - ptr: *mut Box, - data_ptr: *const u8, - data_len: usize) - -> GstFlowReturn { - let sink: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn sink_render(ptr: *mut Box, + data_ptr: *const u8, + data_len: usize) + -> GstFlowReturn { + let sink: &mut Box = &mut *ptr; + let data = slice::from_raw_parts(data_ptr, data_len); - let data = unsafe { slice::from_raw_parts(data_ptr, data_len) }; sink.render(data) } #[no_mangle] -pub extern "C" fn sink_start(sink: *mut c_void, ptr: *mut Box) -> GBoolean { - let sink: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn sink_start(ptr: *mut Box) -> GBoolean { + let sink: &mut Box = &mut *ptr; GBoolean::from_bool(sink.start()) } #[no_mangle] -pub extern "C" fn sink_stop(sink: *mut c_void, ptr: *mut Box) -> GBoolean { - let sink: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn sink_stop(ptr: *mut Box) -> GBoolean { + let sink: &mut Box = &mut *ptr; GBoolean::from_bool(sink.stop()) } diff --git a/src/rssource.c b/src/rssource.c index 4598574e..5a545867 100644 --- a/src/rssource.c +++ b/src/rssource.c @@ -35,18 +35,16 @@ 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 (GstRsSrc * source, void *rssource); -extern GstFlowReturn source_fill (GstRsSrc * source, void *rssource, +extern void source_drop (void *rssource); +extern GstFlowReturn source_fill (void *rssource, uint64_t offset, void *data, size_t * data_len); -extern gboolean source_do_seek (GstRsSrc * source, void *rssource, - uint64_t start, uint64_t stop); -extern gboolean source_set_uri (GstRsSrc * source, void *rssource, - const char *uri); -extern char *source_get_uri (GstRsSrc * source, void *rssource); -extern uint64_t source_get_size (GstRsSrc * source, void *rssource); -extern gboolean source_is_seekable (GstRsSrc * source, void *rssource); -extern gboolean source_start (GstRsSrc * source, void *rssource); -extern gboolean source_stop (GstRsSrc * source, void *rssource); +extern gboolean source_do_seek (void *rssource, uint64_t start, uint64_t stop); +extern gboolean source_set_uri (void *rssource, const char *uri); +extern char *source_get_uri (void *rssource); +extern uint64_t source_get_size (void *rssource); +extern gboolean source_is_seekable (void *rssource); +extern gboolean source_start (void *rssource); +extern gboolean source_stop (void *rssource); extern void cstring_drop (void *str); @@ -138,7 +136,7 @@ gst_rs_src_finalize (GObject * object) { GstRsSrc *src = GST_RS_SRC (object); - source_drop (src, src->instance); + source_drop (src->instance); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -151,7 +149,7 @@ gst_rs_src_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_URI: - source_set_uri (src, src->instance, g_value_get_string (value)); + source_set_uri (src->instance, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -167,7 +165,7 @@ gst_rs_src_get_property (GObject * object, guint prop_id, GValue * value, switch (prop_id) { case PROP_URI:{ - gchar *str = source_get_uri (src, src->instance); + gchar *str = source_get_uri (src->instance); g_value_set_string (value, str); if (str) cstring_drop (str); @@ -191,7 +189,7 @@ gst_rs_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length, gst_buffer_map (buf, &map, GST_MAP_READWRITE); size = length; map_size = map.size; - ret = source_fill (src, src->instance, offset, map.data, &size); + ret = source_fill (src->instance, offset, map.data, &size); gst_buffer_unmap (buf, &map); if (ret == GST_FLOW_OK && size != map_size) gst_buffer_resize (buf, 0, size); @@ -204,7 +202,7 @@ gst_rs_src_is_seekable (GstBaseSrc * basesrc) { GstRsSrc *src = GST_RS_SRC (basesrc); - return source_is_seekable (src, src->instance); + return source_is_seekable (src->instance); } static gboolean @@ -212,7 +210,7 @@ gst_rs_src_get_size (GstBaseSrc * basesrc, guint64 * size) { GstRsSrc *src = GST_RS_SRC (basesrc); - *size = source_get_size (src, src->instance); + *size = source_get_size (src->instance); return TRUE; } @@ -223,7 +221,7 @@ gst_rs_src_start (GstBaseSrc * basesrc) { GstRsSrc *src = GST_RS_SRC (basesrc); - return source_start (src, src->instance); + return source_start (src->instance); } static gboolean @@ -231,7 +229,7 @@ gst_rs_src_stop (GstBaseSrc * basesrc) { GstRsSrc *src = GST_RS_SRC (basesrc); - return source_stop (src, src->instance); + return source_stop (src->instance); } static gboolean @@ -240,7 +238,7 @@ gst_rs_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment) GstRsSrc *src = GST_RS_SRC (basesrc); gboolean ret; - ret = source_do_seek (src, src->instance, segment->start, segment->stop); + ret = source_do_seek (src->instance, segment->start, segment->stop); if (!ret) return FALSE; @@ -267,7 +265,7 @@ gst_rs_src_uri_get_uri (GstURIHandler * handler) { GstRsSrc *src = GST_RS_SRC (handler); - return source_get_uri (src, src->instance); + return source_get_uri (src->instance); } static gboolean @@ -276,7 +274,7 @@ gst_rs_src_uri_set_uri (GstURIHandler * handler, const gchar * uri, { GstRsSrc *src = GST_RS_SRC (handler); - if (!source_set_uri (src, src->instance, uri)) { + if (!source_set_uri (src->instance, uri)) { g_set_error (err, GST_URI_ERROR, GST_URI_ERROR_BAD_URI, "Can't handle URI '%s'", uri); return FALSE; diff --git a/src/rssource.rs b/src/rssource.rs index 4262af1e..60ffef26 100644 --- a/src/rssource.rs +++ b/src/rssource.rs @@ -61,21 +61,19 @@ pub extern "C" fn source_new(source: *mut c_void, } #[no_mangle] -pub extern "C" fn source_drop(source: *mut c_void, ptr: *mut Box) { - unsafe { Box::from_raw(ptr) }; +pub unsafe extern "C" fn source_drop(ptr: *mut Box) { + Box::from_raw(ptr); } #[no_mangle] -pub extern "C" fn source_set_uri(source: *mut c_void, - ptr: *mut Box, - uri_ptr: *const c_char) - -> GBoolean { - let source: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn source_set_uri(ptr: *mut Box, uri_ptr: *const c_char) -> GBoolean { + let source: &mut Box = &mut *ptr; if uri_ptr.is_null() { GBoolean::from_bool(source.set_uri(None)) } else { - let uri_str = unsafe { CStr::from_ptr(uri_ptr) }.to_str().unwrap(); + let uri_str = CStr::from_ptr(uri_ptr).to_str().unwrap(); + match Url::parse(uri_str) { Ok(uri) => GBoolean::from_bool(source.set_uri(Some(uri))), Err(err) => { @@ -88,8 +86,8 @@ pub extern "C" fn source_set_uri(source: *mut c_void, } #[no_mangle] -pub extern "C" fn source_get_uri(source: *mut c_void, ptr: *mut Box) -> *mut c_char { - let source: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn source_get_uri(ptr: *mut Box) -> *mut c_char { + let source: &mut Box = &mut *ptr; match source.get_uri() { Some(uri) => CString::new(uri.into_string().into_bytes()).unwrap().into_raw(), @@ -98,16 +96,16 @@ pub extern "C" fn source_get_uri(source: *mut c_void, ptr: *mut Box) -> } #[no_mangle] -pub extern "C" fn source_fill(source: *mut c_void, - ptr: *mut Box, - offset: u64, - data_ptr: *mut u8, - data_len_ptr: *mut usize) - -> GstFlowReturn { - let source: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn source_fill(ptr: *mut Box, + offset: u64, + data_ptr: *mut u8, + data_len_ptr: *mut usize) + -> GstFlowReturn { + let source: &mut Box = &mut *ptr; + + let mut data_len: &mut usize = &mut *data_len_ptr; + let mut data = slice::from_raw_parts_mut(data_ptr, *data_len); - let mut data_len: &mut usize = unsafe { &mut *data_len_ptr }; - let mut data = unsafe { slice::from_raw_parts_mut(data_ptr, *data_len) }; match source.fill(offset, data) { Ok(actual_len) => { *data_len = actual_len; @@ -118,40 +116,36 @@ pub extern "C" fn source_fill(source: *mut c_void, } #[no_mangle] -pub extern "C" fn source_get_size(source: *mut c_void, ptr: *const Box) -> u64 { - let source: &Box = unsafe { &*ptr }; +pub unsafe extern "C" fn source_get_size(ptr: *const Box) -> u64 { + let source: &Box = &*ptr; - return source.get_size(); + source.get_size() } #[no_mangle] -pub extern "C" fn source_start(source: *mut c_void, ptr: *mut Box) -> GBoolean { - let source: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn source_start(ptr: *mut Box) -> GBoolean { + let source: &mut Box = &mut *ptr; GBoolean::from_bool(source.start()) } #[no_mangle] -pub extern "C" fn source_stop(source: *mut c_void, ptr: *mut Box) -> GBoolean { - let source: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn source_stop(ptr: *mut Box) -> GBoolean { + let source: &mut Box = &mut *ptr; GBoolean::from_bool(source.stop()) } #[no_mangle] -pub extern "C" fn source_is_seekable(source: *mut c_void, ptr: *const Box) -> GBoolean { - let source: &Box = unsafe { &*ptr }; +pub unsafe extern "C" fn source_is_seekable(ptr: *const Box) -> GBoolean { + let source: &Box = &*ptr; GBoolean::from_bool(source.is_seekable()) } #[no_mangle] -pub extern "C" fn source_do_seek(source: *mut c_void, - ptr: *mut Box, - start: u64, - stop: u64) - -> GBoolean { - let source: &mut Box = unsafe { &mut *ptr }; +pub unsafe extern "C" fn source_do_seek(ptr: *mut Box, start: u64, stop: u64) -> GBoolean { + let source: &mut Box = &mut *ptr; GBoolean::from_bool(source.do_seek(start, stop)) } diff --git a/src/utils.rs b/src/utils.rs index 71d4ca8e..4ca934d0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -46,16 +46,11 @@ pub enum GBoolean { impl GBoolean { pub fn from_bool(v: bool) -> GBoolean { - match v { - true => GBoolean::True, - false => GBoolean::False, - } + if v { GBoolean::True } else { GBoolean::False } } } #[no_mangle] -pub extern "C" fn cstring_drop(ptr: *mut c_char) { - unsafe { - CString::from_raw(ptr); - } +pub unsafe extern "C" fn cstring_drop(ptr: *mut c_char) { + CString::from_raw(ptr); }