Refactor plugin registration

This commit is contained in:
Sebastian Dröge 2016-12-23 18:10:38 +02:00
parent 19c8caee1e
commit e25f644f30
5 changed files with 288 additions and 223 deletions

View file

@ -33,6 +33,8 @@ pub mod utils;
pub mod error; pub mod error;
pub mod buffer; pub mod buffer;
pub mod adapter; pub mod adapter;
#[macro_use]
pub mod plugin;
pub mod rssource; pub mod rssource;
pub mod rssink; pub mod rssink;
pub mod rsfilesrc; pub mod rsfilesrc;
@ -41,241 +43,76 @@ pub mod rsfilesink;
pub mod rsdemuxer; pub mod rsdemuxer;
pub mod flvdemux; pub mod flvdemux;
use utils::*; use plugin::*;
use rssource::*;
use rsfilesrc::FileSrc; use rsfilesrc::FileSrc;
use rshttpsrc::HttpSrc; use rshttpsrc::HttpSrc;
use rssink::*;
use rsfilesink::FileSink; use rsfilesink::FileSink;
use rsdemuxer::*;
use flvdemux::FlvDemux; use flvdemux::FlvDemux;
use std::os::raw::c_void; fn plugin_init(plugin: &Plugin) -> bool {
use libc::c_char;
use std::ffi::CString;
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) {
extern "C" {
fn gst_rs_source_register(plugin: *const c_void,
name: *const c_char,
long_name: *const c_char,
description: *const c_char,
classification: *const c_char,
author: *const c_char,
rank: i32,
create_instance: *const c_void,
protocols: *const c_char,
push_only: GBoolean)
-> GBoolean;
}
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_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));
}
unsafe fn sources_register(plugin: *const c_void) -> GBoolean {
source_register(plugin, source_register(plugin,
"rsfilesrc", &SourceInfo {
"File Source", name: "rsfilesrc",
"Reads local files", long_name: "File Source",
"Source/File", description: "Reads local files",
"Sebastian Dröge <sebastian@centricular.com>", classification: "Source/File",
256 + 100, author: "Sebastian Dröge <sebastian@centricular.com>",
FileSrc::new_boxed as *const c_void, rank: 256 + 100,
"file", create_instance: FileSrc::new_boxed,
false); protocols: "file",
push_only: false,
});
source_register(plugin, source_register(plugin,
"rshttpsrc", &SourceInfo {
"HTTP Source", name: "rshttpsrc",
"Read HTTP/HTTPS files", long_name: "HTTP Source",
"Source/Network/HTTP", description: "Reads HTTP/HTTPS streams",
"Sebastian Dröge <sebastian@centricular.com>", classification: "Source/Network/HTTP",
256 + 100, author: "Sebastian Dröge <sebastian@centricular.com>",
HttpSrc::new_boxed as *const c_void, rank: 256 + 100,
"http:https", create_instance: HttpSrc::new_boxed,
true); protocols: "http:https",
push_only: 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) {
extern "C" {
fn gst_rs_sink_register(plugin: *const c_void,
name: *const c_char,
long_name: *const c_char,
description: *const c_char,
classification: *const c_char,
author: *const c_char,
rank: i32,
create_instance: *const c_void,
protocols: *const c_char)
-> GBoolean;
}
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());
}
unsafe fn sinks_register(plugin: *const c_void) -> GBoolean {
sink_register(plugin, sink_register(plugin,
"rsfilesink", &SinkInfo {
"File Sink", name: "rsfilesink",
"Writes to local files", long_name: "File Sink",
"Sink/File", description: "Writes to local files",
"Luis de Bethencourt <luisbg@osg.samsung.com>", classification: "Sink/File",
256 + 100, author: "Luis de Bethencourt <luisbg@osg.samsung.com>",
FileSink::new_boxed as *const c_void, rank: 256 + 100,
"file"); create_instance: FileSink::new_boxed,
protocols: "file",
});
GBoolean::True
}
unsafe fn demuxer_register(plugin: *const c_void,
name: &str,
long_name: &str,
description: &str,
classification: &str,
author: &str,
rank: i32,
create_instance: *const c_void,
input_format: &str,
output_formats: &str) {
extern "C" {
fn gst_rs_demuxer_register(plugin: *const c_void,
name: *const c_char,
long_name: *const c_char,
description: *const c_char,
classification: *const c_char,
author: *const c_char,
rank: i32,
create_instance: *const c_void,
input_format: *const c_char,
output_formats: *const c_char)
-> GBoolean;
}
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 cinput_format = CString::new(input_format).unwrap();
let coutput_formats = CString::new(output_formats).unwrap();
gst_rs_demuxer_register(plugin,
cname.as_ptr(),
clong_name.as_ptr(),
cdescription.as_ptr(),
cclassification.as_ptr(),
cauthor.as_ptr(),
rank,
create_instance,
cinput_format.as_ptr(),
coutput_formats.as_ptr());
}
unsafe fn demuxers_register(plugin: *const c_void) -> GBoolean {
demuxer_register(plugin, demuxer_register(plugin,
"rsflvdemux", &DemuxerInfo {
"FLV Demuxer", name: "rsflvdemux",
"Demuxes FLV Streams", long_name: "FLV Demuxer",
"Codec/Demuxer", description: "Demuxes FLV Streams",
"Sebastian Dröge <sebastian@centricular.com>", classification: "Codec/Demuxer",
256 + 100, author: "Sebastian Dröge <sebastian@centricular.com>",
FlvDemux::new_boxed as *const c_void, rank: 256 + 100,
"video/x-flv", create_instance: FlvDemux::new_boxed,
"ANY"); input_formats: "video/x-flv",
output_formats: "ANY",
});
GBoolean::True true
} }
#[repr(C)] plugin_define!(b"rsplugin\0",
pub struct GstPluginDesc { b"Rust Plugin\0",
major_version: i32, plugin_init,
minor_version: i32, b"1.0\0",
name: *const u8, b"LGPL\0",
description: *const u8, b"rsplugin\0",
plugin_init: extern "C" fn(plugin: *const c_void) -> GBoolean, b"rsplugin\0",
version: *const u8, b"https://github.com/sdroege/rsplugin\0",
license: *const u8, b"2016-12-08\0");
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],
};

82
src/plugin.rs Normal file
View file

@ -0,0 +1,82 @@
// Copyright (C) 2016 Sebastian Dröge <sebastian@centricular.com>
// 2016 Luis de Bethencourt <luisbg@osg.samsung.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301, USA.
use std::os::raw::c_void;
pub struct Plugin(*const c_void);
impl Plugin {
pub unsafe fn new(plugin: *const c_void) -> Plugin {
Plugin(plugin)
}
pub unsafe fn to_raw(&self) -> *const c_void {
self.0
}
}
macro_rules! plugin_define(
($name:expr, $description:expr, $plugin_init:ident,
$version:expr, $license:expr, $source:expr,
$package:expr, $origin:expr, $release_datetime:expr) => {
pub mod plugin_desc {
use std::os::raw::c_void;
use utils::GBoolean;
use plugin::Plugin;
#[repr(C)]
pub struct GstPluginDesc {
major_version: i32,
minor_version: i32,
name: *const u8,
description: *const u8,
plugin_init: unsafe 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 {}
#[no_mangle]
#[allow(non_upper_case_globals)]
pub static gst_plugin_desc: GstPluginDesc = GstPluginDesc {
major_version: 1,
minor_version: 10,
name: $name as *const u8,
description: $description as *const u8,
plugin_init: plugin_init_trampoline,
version: $version as *const u8,
license: $license as *const u8,
source: $source as *const u8,
package: $package as *const u8,
origin: $origin as *const u8,
release_datetime: $release_datetime as *const u8,
_gst_reserved: [0, 0, 0, 0],
};
unsafe extern "C" fn plugin_init_trampoline(plugin: *const c_void) -> GBoolean {
GBoolean::from_bool(super::$plugin_init(&Plugin::new(plugin)))
}
}
};
);

View file

@ -30,6 +30,7 @@ use std::u64;
use utils::*; use utils::*;
use error::*; use error::*;
use buffer::*; use buffer::*;
use plugin::Plugin;
pub type StreamIndex = u32; pub type StreamIndex = u32;
@ -442,3 +443,52 @@ pub unsafe extern "C" fn demuxer_end_of_stream(ptr: *mut DemuxerWrapper) {
wrap.end_of_stream(); wrap.end_of_stream();
}) })
} }
pub struct DemuxerInfo<'a> {
pub name: &'a str,
pub long_name: &'a str,
pub description: &'a str,
pub classification: &'a str,
pub author: &'a str,
pub rank: i32,
pub create_instance: fn() -> Box<Demuxer>,
pub input_formats: &'a str,
pub output_formats: &'a str,
}
pub fn demuxer_register(plugin: &Plugin, demuxer_info: &DemuxerInfo) {
extern "C" {
fn gst_rs_demuxer_register(plugin: *const c_void,
name: *const c_char,
long_name: *const c_char,
description: *const c_char,
classification: *const c_char,
author: *const c_char,
rank: i32,
create_instance: *const c_void,
input_format: *const c_char,
output_formats: *const c_char)
-> GBoolean;
}
let cname = CString::new(demuxer_info.name).unwrap();
let clong_name = CString::new(demuxer_info.long_name).unwrap();
let cdescription = CString::new(demuxer_info.description).unwrap();
let cclassification = CString::new(demuxer_info.classification).unwrap();
let cauthor = CString::new(demuxer_info.author).unwrap();
let cinput_format = CString::new(demuxer_info.input_formats).unwrap();
let coutput_formats = CString::new(demuxer_info.output_formats).unwrap();
unsafe {
gst_rs_demuxer_register(plugin.to_raw(),
cname.as_ptr(),
clong_name.as_ptr(),
cdescription.as_ptr(),
cclassification.as_ptr(),
cauthor.as_ptr(),
demuxer_info.rank,
demuxer_info.create_instance as *const c_void,
cinput_format.as_ptr(),
coutput_formats.as_ptr());
}
}

View file

@ -31,6 +31,7 @@ use url::Url;
use utils::*; use utils::*;
use error::*; use error::*;
use buffer::*; use buffer::*;
use plugin::Plugin;
#[derive(Debug)] #[derive(Debug)]
pub enum SinkError { pub enum SinkError {
@ -249,3 +250,48 @@ pub unsafe extern "C" fn sink_render(ptr: *const SinkWrapper,
wrap.render(&*buffer) wrap.render(&*buffer)
}) })
} }
pub struct SinkInfo<'a> {
pub name: &'a str,
pub long_name: &'a str,
pub description: &'a str,
pub classification: &'a str,
pub author: &'a str,
pub rank: i32,
pub create_instance: fn() -> Box<Sink>,
pub protocols: &'a str,
}
pub fn sink_register(plugin: &Plugin, sink_info: &SinkInfo) {
extern "C" {
fn gst_rs_sink_register(plugin: *const c_void,
name: *const c_char,
long_name: *const c_char,
description: *const c_char,
classification: *const c_char,
author: *const c_char,
rank: i32,
create_instance: *const c_void,
protocols: *const c_char)
-> GBoolean;
}
let cname = CString::new(sink_info.name).unwrap();
let clong_name = CString::new(sink_info.long_name).unwrap();
let cdescription = CString::new(sink_info.description).unwrap();
let cclassification = CString::new(sink_info.classification).unwrap();
let cauthor = CString::new(sink_info.author).unwrap();
let cprotocols = CString::new(sink_info.protocols).unwrap();
unsafe {
gst_rs_sink_register(plugin.to_raw(),
cname.as_ptr(),
clong_name.as_ptr(),
cdescription.as_ptr(),
cclassification.as_ptr(),
cauthor.as_ptr(),
sink_info.rank,
sink_info.create_instance as *const c_void,
cprotocols.as_ptr());
}
}

View file

@ -28,6 +28,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use url::Url; use url::Url;
use plugin::Plugin;
use utils::*; use utils::*;
use error::*; use error::*;
use buffer::*; use buffer::*;
@ -302,3 +303,52 @@ pub unsafe extern "C" fn source_seek(ptr: *const SourceWrapper, start: u64, stop
GBoolean::from_bool(wrap.seek(start, if stop == u64::MAX { None } else { Some(stop) })) GBoolean::from_bool(wrap.seek(start, if stop == u64::MAX { None } else { Some(stop) }))
}) })
} }
pub struct SourceInfo<'a> {
pub name: &'a str,
pub long_name: &'a str,
pub description: &'a str,
pub classification: &'a str,
pub author: &'a str,
pub rank: i32,
pub create_instance: fn() -> Box<Source>,
pub protocols: &'a str,
pub push_only: bool,
}
pub fn source_register(plugin: &Plugin, source_info: &SourceInfo) {
extern "C" {
fn gst_rs_source_register(plugin: *const c_void,
name: *const c_char,
long_name: *const c_char,
description: *const c_char,
classification: *const c_char,
author: *const c_char,
rank: i32,
create_instance: *const c_void,
protocols: *const c_char,
push_only: GBoolean)
-> GBoolean;
}
let cname = CString::new(source_info.name).unwrap();
let clong_name = CString::new(source_info.long_name).unwrap();
let cdescription = CString::new(source_info.description).unwrap();
let cclassification = CString::new(source_info.classification).unwrap();
let cauthor = CString::new(source_info.author).unwrap();
let cprotocols = CString::new(source_info.protocols).unwrap();
unsafe {
gst_rs_source_register(plugin.to_raw(),
cname.as_ptr(),
clong_name.as_ptr(),
cdescription.as_ptr(),
cclassification.as_ptr(),
cauthor.as_ptr(),
source_info.rank,
source_info.create_instance as *const c_void,
cprotocols.as_ptr(),
GBoolean::from_bool(source_info.push_only));
}
}