Use a Source trait instead of directly working with FileSrc

This commit is contained in:
Sebastian Dröge 2016-05-14 13:34:50 +03:00
parent 15865ab86b
commit 35a7cfa032
2 changed files with 59 additions and 43 deletions

View file

@ -5,14 +5,14 @@
/* Declarations for Rust code */
extern void * filesrc_new (void);
extern void filesrc_drop (void * filesrc);
extern GstFlowReturn filesrc_fill (void * filesrc, uint64_t offset, void * data, size_t * data_len);
extern gboolean filesrc_set_uri (void * filesrc, const char *uri);
extern char * filesrc_get_uri (void * filesrc);
extern uint64_t filesrc_get_size (void * filesrc);
extern gboolean filesrc_is_seekable (void * filesrc);
extern gboolean filesrc_start (void * filesrc);
extern gboolean filesrc_stop (void * filesrc);
extern void source_drop (void * filesrc);
extern GstFlowReturn source_fill (void * filesrc, uint64_t offset, void * data, size_t * data_len);
extern gboolean source_set_uri (void * filesrc, const char *uri);
extern char * source_get_uri (void * filesrc);
extern uint64_t source_get_size (void * filesrc);
extern gboolean source_is_seekable (void * filesrc);
extern gboolean source_start (void * filesrc);
extern gboolean source_stop (void * filesrc);
GST_DEBUG_CATEGORY_STATIC (gst_rsfile_src_debug);
#define GST_CAT_DEFAULT gst_rsfile_src_debug
@ -101,7 +101,7 @@ gst_rsfile_src_finalize (GObject * object)
{
GstRsfileSrc *src = GST_RSFILE_SRC (object);
filesrc_drop (src->instance);
source_drop (src->instance);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -114,7 +114,7 @@ gst_rsfile_src_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case PROP_URI:
filesrc_set_uri (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);
@ -130,7 +130,7 @@ gst_rsfile_src_get_property (GObject * object, guint prop_id, GValue * value,
switch (prop_id) {
case PROP_URI:
g_value_take_string (value, filesrc_get_uri (src->instance));
g_value_take_string (value, source_get_uri (src->instance));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -149,7 +149,7 @@ gst_rsfile_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length,
gst_buffer_map (buf, &map, GST_MAP_READWRITE);
size = map.size;
ret = filesrc_fill (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)
gst_buffer_resize (buf, 0, size);
@ -162,7 +162,7 @@ gst_rsfile_src_is_seekable (GstBaseSrc * basesrc)
{
GstRsfileSrc *src = GST_RSFILE_SRC (basesrc);
return filesrc_is_seekable (src->instance);
return source_is_seekable (src->instance);
}
static gboolean
@ -170,7 +170,7 @@ gst_rsfile_src_get_size (GstBaseSrc * basesrc, guint64 * size)
{
GstRsfileSrc *src = GST_RSFILE_SRC (basesrc);
*size = filesrc_get_size (src->instance);
*size = source_get_size (src->instance);
return TRUE;
}
@ -181,7 +181,7 @@ gst_rsfile_src_start (GstBaseSrc * basesrc)
{
GstRsfileSrc *src = GST_RSFILE_SRC (basesrc);
return filesrc_start (src->instance);
return source_start (src->instance);
}
/* unmap and close the rsfile */
@ -190,7 +190,7 @@ gst_rsfile_src_stop (GstBaseSrc * basesrc)
{
GstRsfileSrc *src = GST_RSFILE_SRC (basesrc);
return filesrc_stop (src->instance);
return source_stop (src->instance);
}
static GstURIType
@ -212,7 +212,7 @@ gst_rsfile_src_uri_get_uri (GstURIHandler * handler)
{
GstRsfileSrc *src = GST_RSFILE_SRC (handler);
return filesrc_get_uri (src->instance);
return source_get_uri (src->instance);
}
static gboolean
@ -221,7 +221,7 @@ gst_rsfile_src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
{
GstRsfileSrc *src = GST_RSFILE_SRC (handler);
if (!filesrc_set_uri (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;

View file

@ -42,6 +42,16 @@ impl GBoolean {
}
}
pub trait Source {
fn set_uri(&mut self, uri_str: &Option<String>) -> bool;
fn get_uri(&self) -> Option<String>;
fn is_seekable(&self) -> bool;
fn get_size(&self) -> u64;
fn start(&mut self) -> bool;
fn stop(&mut self) -> bool;
fn fill(&mut self, offset: u64, data: &mut [u8]) -> Result<usize, GstFlowReturn>;
}
#[derive(Debug)]
pub struct FileSrc {
location: Option<PathBuf>,
@ -54,6 +64,12 @@ impl FileSrc {
FileSrc { location: None, file: None, position: 0 }
}
fn new_source() -> Box<Source> {
Box::new(FileSrc::new())
}
}
impl Source for FileSrc {
fn set_uri(&mut self, uri_str: &Option<String>) -> bool {
match *uri_str {
None => {
@ -166,33 +182,33 @@ impl FileSrc {
}
#[no_mangle]
pub extern "C" fn filesrc_new() -> *mut FileSrc {
let instance = Box::new(FileSrc::new());
pub extern "C" fn filesrc_new() -> *mut Box<Source> {
let instance = Box::new(FileSrc::new_source());
return Box::into_raw(instance);
}
#[no_mangle]
pub extern "C" fn filesrc_drop(ptr: *mut FileSrc) {
pub extern "C" fn source_drop(ptr: *mut Box<Source>) {
unsafe { Box::from_raw(ptr) };
}
#[no_mangle]
pub extern "C" fn filesrc_set_uri(ptr: *mut FileSrc, uri_ptr: *const c_char) -> GBoolean{
let filesrc: &mut FileSrc = unsafe { &mut *ptr };
pub extern "C" fn source_set_uri(ptr: *mut Box<Source>, uri_ptr: *const c_char) -> GBoolean{
let source: &mut Box<Source> = unsafe { &mut *ptr };
if uri_ptr.is_null() {
GBoolean::from_bool(filesrc.set_uri(&None))
GBoolean::from_bool(source.set_uri(&None))
} else {
let uri = unsafe { CStr::from_ptr(uri_ptr) };
GBoolean::from_bool(filesrc.set_uri(&Some(String::from(uri.to_str().unwrap()))))
GBoolean::from_bool(source.set_uri(&Some(String::from(uri.to_str().unwrap()))))
}
}
#[no_mangle]
pub extern "C" fn filesrc_get_uri(ptr: *mut FileSrc) -> *mut c_char {
let filesrc: &mut FileSrc = unsafe { &mut *ptr };
pub extern "C" fn source_get_uri(ptr: *mut Box<Source>) -> *mut c_char {
let source: &mut Box<Source> = unsafe { &mut *ptr };
match filesrc.get_uri() {
match source.get_uri() {
Some(ref uri) =>
CString::new(uri.clone().into_bytes()).unwrap().into_raw(),
None =>
@ -201,12 +217,12 @@ pub extern "C" fn filesrc_get_uri(ptr: *mut FileSrc) -> *mut c_char {
}
#[no_mangle]
pub extern "C" fn filesrc_fill(ptr: *mut FileSrc, offset: u64, data_ptr: *mut u8, data_len_ptr: *mut usize) -> GstFlowReturn {
let filesrc: &mut FileSrc = unsafe { &mut *ptr };
pub extern "C" fn source_fill(ptr: *mut Box<Source>, offset: u64, data_ptr: *mut u8, data_len_ptr: *mut usize) -> GstFlowReturn {
let source: &mut Box<Source> = unsafe { &mut *ptr };
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 filesrc.fill(offset, data) {
match source.fill(offset, data) {
Ok(actual_len) => {
*data_len = actual_len;
GstFlowReturn::Ok
@ -216,30 +232,30 @@ pub extern "C" fn filesrc_fill(ptr: *mut FileSrc, offset: u64, data_ptr: *mut u8
}
#[no_mangle]
pub extern "C" fn filesrc_get_size(ptr: *mut FileSrc) -> u64 {
let filesrc: &mut FileSrc = unsafe { &mut *ptr };
pub extern "C" fn source_get_size(ptr: *mut Box<Source>) -> u64 {
let source: &mut Box<Source> = unsafe { &mut *ptr };
return filesrc.get_size();
return source.get_size();
}
#[no_mangle]
pub extern "C" fn filesrc_start(ptr: *mut FileSrc) -> GBoolean {
let filesrc: &mut FileSrc = unsafe { &mut *ptr };
pub extern "C" fn source_start(ptr: *mut Box<Source>) -> GBoolean {
let source: &mut Box<Source> = unsafe { &mut *ptr };
GBoolean::from_bool(filesrc.start())
GBoolean::from_bool(source.start())
}
#[no_mangle]
pub extern "C" fn filesrc_stop(ptr: *mut FileSrc) -> GBoolean {
let filesrc: &mut FileSrc = unsafe { &mut *ptr };
pub extern "C" fn source_stop(ptr: *mut Box<Source>) -> GBoolean {
let source: &mut Box<Source> = unsafe { &mut *ptr };
GBoolean::from_bool(filesrc.stop())
GBoolean::from_bool(source.stop())
}
#[no_mangle]
pub extern "C" fn filesrc_is_seekable(ptr: *mut FileSrc) -> GBoolean {
let filesrc: &mut FileSrc = unsafe { &mut *ptr };
pub extern "C" fn source_is_seekable(ptr: *mut Box<Source>) -> GBoolean {
let source: &mut Box<Source> = unsafe { &mut *ptr };
GBoolean::from_bool(filesrc.is_seekable())
GBoolean::from_bool(source.is_seekable())
}