mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-24 11:00:29 +00:00
Port everything else over to glib/gobject/gstreamer-sys
This commit is contained in:
parent
e4ababa98f
commit
24a10bb614
19 changed files with 509 additions and 751 deletions
|
@ -14,9 +14,9 @@ slog = { version = "1.3", features = ["max_level_trace"] }
|
|||
lazy_static = "0.2"
|
||||
byteorder = "1.0"
|
||||
num-rational = { version = "0.1", default-features = false, features = [] }
|
||||
glib-sys = "0.3"
|
||||
gobject-sys = "0.3"
|
||||
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys.git" }
|
||||
glib-sys = { git = "https://github.com/gtk-rs/sys.git" }
|
||||
gobject-sys = { git = "https://github.com/gtk-rs/sys.git" }
|
||||
gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys.git", features = ["v1_10"] }
|
||||
derivative = "1.0"
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -14,7 +14,7 @@ fn main() {
|
|||
let gstbase = pkg_config::probe_library("gstreamer-base-1.0").unwrap();
|
||||
let includes = [gstreamer.include_paths, gstbase.include_paths];
|
||||
|
||||
let files = ["src/error.c", "src/log.c", "src/source.c", "src/sink.c", "src/demuxer.c"];
|
||||
let files = ["src/source.c", "src/sink.c", "src/demuxer.c"];
|
||||
|
||||
let mut config = gcc::Config::new();
|
||||
config.include("src");
|
||||
|
|
|
@ -179,7 +179,10 @@ impl Adapter {
|
|||
trace!(LOGGER, "Get buffer of {} bytes, copy into new buffer", size);
|
||||
let mut new = Buffer::new_with_size(size).unwrap();
|
||||
{
|
||||
let mut map = new.get_mut().unwrap().map_readwrite().unwrap();
|
||||
let mut map = new.get_mut()
|
||||
.unwrap()
|
||||
.map_readwrite()
|
||||
.unwrap();
|
||||
let data = map.as_mut_slice();
|
||||
Self::copy_data(&self.deque, self.skip, data, size);
|
||||
}
|
||||
|
@ -204,7 +207,10 @@ impl Adapter {
|
|||
|
||||
let mut left = size;
|
||||
while left > 0 {
|
||||
let front_size = self.deque.front().unwrap().get_size() - self.skip;
|
||||
let front_size = self.deque
|
||||
.front()
|
||||
.unwrap()
|
||||
.get_size() - self.skip;
|
||||
|
||||
if front_size <= left {
|
||||
trace!(LOGGER,
|
||||
|
@ -234,15 +240,11 @@ impl Adapter {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use std::ptr;
|
||||
use std::os::raw::c_void;
|
||||
use gst;
|
||||
|
||||
fn init() {
|
||||
extern "C" {
|
||||
fn gst_init(argc: *mut c_void, argv: *mut c_void);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
gst_init(ptr::null_mut(), ptr::null_mut());
|
||||
gst::gst_init(ptr::null_mut(), ptr::null_mut());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use std::os::raw::c_void;
|
||||
use std::slice;
|
||||
use std::u64;
|
||||
use std::usize;
|
||||
|
@ -54,22 +53,24 @@ pub struct ReadWriteMappedBuffer {
|
|||
}
|
||||
|
||||
unsafe impl MiniObject for Buffer {
|
||||
unsafe fn as_ptr(&self) -> *mut c_void {
|
||||
self.0 as *mut c_void
|
||||
type PtrType = gst::GstBuffer;
|
||||
|
||||
unsafe fn as_ptr(&self) -> *mut gst::GstBuffer {
|
||||
self.0
|
||||
}
|
||||
|
||||
unsafe fn replace_ptr(&mut self, ptr: *mut c_void) {
|
||||
self.0 = ptr as *mut gst::GstBuffer
|
||||
unsafe fn replace_ptr(&mut self, ptr: *mut gst::GstBuffer) {
|
||||
self.0 = ptr
|
||||
}
|
||||
|
||||
unsafe fn new_from_ptr(ptr: *mut c_void) -> Self {
|
||||
Buffer(ptr as *mut gst::GstBuffer)
|
||||
unsafe fn new_from_ptr(ptr: *mut gst::GstBuffer) -> Self {
|
||||
Buffer(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn new() -> GstRc<Buffer> {
|
||||
unsafe { GstRc::new_from_owned_ptr(gst::gst_buffer_new() as *mut c_void) }
|
||||
unsafe { GstRc::new_from_owned_ptr(gst::gst_buffer_new()) }
|
||||
}
|
||||
|
||||
pub fn new_with_size(size: usize) -> Option<GstRc<Buffer>> {
|
||||
|
@ -77,7 +78,7 @@ impl Buffer {
|
|||
if raw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { GstRc::new_from_owned_ptr(raw as *mut c_void) })
|
||||
Some(unsafe { GstRc::new_from_owned_ptr(raw) })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,17 +106,13 @@ impl Buffer {
|
|||
if raw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { GstRc::new_from_owned_ptr(raw as *mut c_void) })
|
||||
Some(unsafe { GstRc::new_from_owned_ptr(raw) })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_read(&self) -> Option<ReadBufferMap> {
|
||||
let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() };
|
||||
let res = unsafe {
|
||||
gst::gst_buffer_map(self.0,
|
||||
&mut map_info as *mut gst::GstMapInfo,
|
||||
gst::GST_MAP_READ)
|
||||
};
|
||||
let res = unsafe { gst::gst_buffer_map(self.0, &mut map_info, gst::GST_MAP_READ) };
|
||||
if res == glib::GTRUE {
|
||||
Some(ReadBufferMap {
|
||||
buffer: self,
|
||||
|
@ -128,11 +125,7 @@ impl Buffer {
|
|||
|
||||
pub fn map_readwrite(&mut self) -> Option<ReadWriteBufferMap> {
|
||||
let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() };
|
||||
let res = unsafe {
|
||||
gst::gst_buffer_map(self.0,
|
||||
&mut map_info as *mut gst::GstMapInfo,
|
||||
gst::GST_MAP_READWRITE)
|
||||
};
|
||||
let res = unsafe { gst::gst_buffer_map(self.0, &mut map_info, gst::GST_MAP_READWRITE) };
|
||||
if res == glib::GTRUE {
|
||||
Some(ReadWriteBufferMap {
|
||||
buffer: self,
|
||||
|
@ -145,11 +138,7 @@ impl Buffer {
|
|||
|
||||
pub fn into_read_mapped_buffer(buffer: GstRc<Buffer>) -> Option<ReadMappedBuffer> {
|
||||
let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() };
|
||||
let res = unsafe {
|
||||
gst::gst_buffer_map(buffer.0,
|
||||
&mut map_info as *mut gst::GstMapInfo,
|
||||
gst::GST_MAP_READ)
|
||||
};
|
||||
let res = unsafe { gst::gst_buffer_map(buffer.0, &mut map_info, gst::GST_MAP_READ) };
|
||||
if res == glib::GTRUE {
|
||||
Some(ReadMappedBuffer {
|
||||
buffer: buffer,
|
||||
|
@ -162,11 +151,7 @@ impl Buffer {
|
|||
|
||||
pub fn into_readwrite_mapped_buffer(buffer: GstRc<Buffer>) -> Option<ReadWriteMappedBuffer> {
|
||||
let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() };
|
||||
let res = unsafe {
|
||||
gst::gst_buffer_map(buffer.0,
|
||||
&mut map_info as *mut gst::GstMapInfo,
|
||||
gst::GST_MAP_READWRITE)
|
||||
};
|
||||
let res = unsafe { gst::gst_buffer_map(buffer.0, &mut map_info, gst::GST_MAP_READWRITE) };
|
||||
if res == glib::GTRUE {
|
||||
Some(ReadWriteMappedBuffer {
|
||||
buffer: buffer,
|
||||
|
@ -182,8 +167,7 @@ impl Buffer {
|
|||
GstRc::new_from_owned_ptr(gst::gst_buffer_append(buffer.into_ptr() as
|
||||
*mut gst::GstBuffer,
|
||||
other.into_ptr() as
|
||||
*mut gst::GstBuffer) as
|
||||
*mut c_void)
|
||||
*mut gst::GstBuffer))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +181,7 @@ impl Buffer {
|
|||
if raw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { GstRc::new_from_owned_ptr(raw as *mut c_void) })
|
||||
Some(unsafe { GstRc::new_from_owned_ptr(raw) })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,7 +370,7 @@ impl<'a> ReadBufferMap<'a> {
|
|||
impl<'a> Drop for ReadBufferMap<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info as *mut gst::GstMapInfo);
|
||||
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -412,7 +396,7 @@ impl<'a> ReadWriteBufferMap<'a> {
|
|||
impl<'a> Drop for ReadWriteBufferMap<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info as *mut gst::GstMapInfo);
|
||||
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +419,7 @@ impl Drop for ReadMappedBuffer {
|
|||
fn drop(&mut self) {
|
||||
if !self.buffer.0.is_null() {
|
||||
unsafe {
|
||||
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info as *mut gst::GstMapInfo);
|
||||
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -466,7 +450,7 @@ impl Drop for ReadWriteMappedBuffer {
|
|||
fn drop(&mut self) {
|
||||
if !self.buffer.0.is_null() {
|
||||
unsafe {
|
||||
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info as *mut gst::GstMapInfo);
|
||||
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,62 +6,52 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use libc::c_char;
|
||||
use std::os::raw::c_void;
|
||||
use std::ffi::CString;
|
||||
use std::ffi::CStr;
|
||||
use std::fmt;
|
||||
use value::*;
|
||||
use utils::*;
|
||||
use miniobject::*;
|
||||
|
||||
use glib;
|
||||
use gobject;
|
||||
use gst;
|
||||
|
||||
#[derive(Eq)]
|
||||
pub struct Caps(*mut c_void);
|
||||
pub struct Caps(*mut gst::GstCaps);
|
||||
|
||||
unsafe impl MiniObject for Caps {
|
||||
unsafe fn as_ptr(&self) -> *mut c_void {
|
||||
type PtrType = gst::GstCaps;
|
||||
|
||||
unsafe fn as_ptr(&self) -> *mut gst::GstCaps {
|
||||
self.0
|
||||
}
|
||||
|
||||
unsafe fn replace_ptr(&mut self, ptr: *mut c_void) {
|
||||
unsafe fn replace_ptr(&mut self, ptr: *mut gst::GstCaps) {
|
||||
self.0 = ptr
|
||||
}
|
||||
|
||||
unsafe fn new_from_ptr(ptr: *mut c_void) -> Self {
|
||||
unsafe fn new_from_ptr(ptr: *mut gst::GstCaps) -> Self {
|
||||
Caps(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl Caps {
|
||||
pub fn new_empty() -> GstRc<Self> {
|
||||
extern "C" {
|
||||
fn gst_caps_new_empty() -> *mut c_void;
|
||||
}
|
||||
|
||||
unsafe { GstRc::new_from_owned_ptr(gst_caps_new_empty()) }
|
||||
unsafe { GstRc::new_from_owned_ptr(gst::gst_caps_new_empty()) }
|
||||
}
|
||||
|
||||
pub fn new_any() -> GstRc<Self> {
|
||||
extern "C" {
|
||||
fn gst_caps_new_any() -> *mut c_void;
|
||||
}
|
||||
|
||||
unsafe { GstRc::new_from_owned_ptr(gst_caps_new_any()) }
|
||||
unsafe { GstRc::new_from_owned_ptr(gst::gst_caps_new_any()) }
|
||||
}
|
||||
|
||||
pub fn new_simple(name: &str, values: &[(&str, &Value)]) -> GstRc<Self> {
|
||||
extern "C" {
|
||||
fn gst_caps_append_structure(caps: *mut c_void, structure: *mut c_void);
|
||||
fn gst_structure_new_empty(name: *const c_char) -> *mut c_void;
|
||||
}
|
||||
|
||||
let mut caps = Caps::new_empty();
|
||||
|
||||
let name_cstr = CString::new(name).unwrap();
|
||||
let structure = unsafe { gst_structure_new_empty(name_cstr.as_ptr()) };
|
||||
let structure = unsafe { gst::gst_structure_new_empty(name_cstr.as_ptr()) };
|
||||
|
||||
unsafe {
|
||||
gst_caps_append_structure(caps.as_ptr(), structure);
|
||||
gst::gst_caps_append_structure((*caps).0, structure);
|
||||
}
|
||||
|
||||
caps.get_mut().unwrap().set_simple(values);
|
||||
|
@ -70,14 +60,10 @@ impl Caps {
|
|||
}
|
||||
|
||||
pub fn from_string(value: &str) -> Option<GstRc<Self>> {
|
||||
extern "C" {
|
||||
fn gst_caps_from_string(value: *const c_char) -> *mut c_void;
|
||||
}
|
||||
|
||||
let value_cstr = CString::new(value).unwrap();
|
||||
|
||||
unsafe {
|
||||
let caps_ptr = gst_caps_from_string(value_cstr.as_ptr());
|
||||
let caps_ptr = gst::gst_caps_from_string(value_cstr.as_ptr());
|
||||
|
||||
if caps_ptr.is_null() {
|
||||
None
|
||||
|
@ -88,30 +74,21 @@ impl Caps {
|
|||
}
|
||||
|
||||
pub fn set_simple(&mut self, values: &[(&str, &Value)]) {
|
||||
extern "C" {
|
||||
fn gst_caps_set_value(caps: *mut c_void, name: *const c_char, value: *const GValue);
|
||||
}
|
||||
|
||||
for value in values {
|
||||
let name_cstr = CString::new(value.0).unwrap();
|
||||
let mut gvalue = value.1.to_gvalue();
|
||||
|
||||
unsafe {
|
||||
gst_caps_set_value(self.0, name_cstr.as_ptr(), &mut gvalue as *mut GValue);
|
||||
let mut gvalue = value.1.to_gvalue();
|
||||
gst::gst_caps_set_value(self.0, name_cstr.as_ptr(), &mut gvalue);
|
||||
gobject::g_value_unset(&mut gvalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
extern "C" {
|
||||
fn gst_caps_to_string(caps: *mut c_void) -> *mut c_char;
|
||||
fn g_free(ptr: *mut c_char);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let ptr = gst_caps_to_string(self.0);
|
||||
let ptr = gst::gst_caps_to_string(self.0);
|
||||
let s = CStr::from_ptr(ptr).to_str().unwrap().into();
|
||||
g_free(ptr);
|
||||
glib::g_free(ptr as glib::gpointer);
|
||||
|
||||
s
|
||||
}
|
||||
|
@ -126,11 +103,7 @@ impl fmt::Debug for Caps {
|
|||
|
||||
impl PartialEq for Caps {
|
||||
fn eq(&self, other: &Caps) -> bool {
|
||||
extern "C" {
|
||||
fn gst_caps_is_equal(a: *const c_void, b: *const c_void) -> GBoolean;
|
||||
}
|
||||
|
||||
unsafe { gst_caps_is_equal(self.0, other.0).to_bool() }
|
||||
(unsafe { gst::gst_caps_is_equal(self.0, other.0) } == glib::GTRUE)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,15 +114,10 @@ unsafe impl Send for Caps {}
|
|||
mod tests {
|
||||
use super::*;
|
||||
use std::ptr;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
fn init() {
|
||||
extern "C" {
|
||||
fn gst_init(argc: *mut c_void, argv: *mut c_void);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
gst_init(ptr::null_mut(), ptr::null_mut());
|
||||
gst::gst_init(ptr::null_mut(), ptr::null_mut());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ use log::*;
|
|||
use caps::Caps;
|
||||
use plugin::Plugin;
|
||||
|
||||
use glib;
|
||||
use gst;
|
||||
|
||||
pub type StreamIndex = u32;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -89,14 +92,14 @@ impl Stream {
|
|||
}
|
||||
|
||||
pub struct DemuxerWrapper {
|
||||
raw: *mut c_void,
|
||||
raw: *mut gst::GstElement,
|
||||
logger: Logger,
|
||||
demuxer: Mutex<Box<Demuxer>>,
|
||||
panicked: AtomicBool,
|
||||
}
|
||||
|
||||
impl DemuxerWrapper {
|
||||
fn new(raw: *mut c_void, demuxer: Box<Demuxer>) -> DemuxerWrapper {
|
||||
fn new(raw: *mut gst::GstElement, demuxer: Box<Demuxer>) -> DemuxerWrapper {
|
||||
DemuxerWrapper {
|
||||
raw: raw,
|
||||
logger: Logger::root(GstDebugDrain::new(Some(unsafe { &Element::new(raw) }),
|
||||
|
@ -164,44 +167,44 @@ impl DemuxerWrapper {
|
|||
}
|
||||
|
||||
|
||||
fn get_position(&self, position: &mut u64) -> GBoolean {
|
||||
fn get_position(&self, position: &mut u64) -> glib::gboolean {
|
||||
let demuxer = &self.demuxer.lock().unwrap();
|
||||
|
||||
match demuxer.get_position() {
|
||||
None => {
|
||||
trace!(self.logger, "Got no position");
|
||||
*position = u64::MAX;
|
||||
GBoolean::False
|
||||
glib::GFALSE
|
||||
}
|
||||
Some(pos) => {
|
||||
trace!(self.logger, "Returning position {}", pos);
|
||||
*position = pos;
|
||||
GBoolean::True
|
||||
glib::GTRUE
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn get_duration(&self, duration: &mut u64) -> GBoolean {
|
||||
fn get_duration(&self, duration: &mut u64) -> glib::gboolean {
|
||||
let demuxer = &self.demuxer.lock().unwrap();
|
||||
|
||||
match demuxer.get_duration() {
|
||||
None => {
|
||||
trace!(self.logger, "Got no duration");
|
||||
*duration = u64::MAX;
|
||||
GBoolean::False
|
||||
glib::GFALSE
|
||||
}
|
||||
Some(dur) => {
|
||||
trace!(self.logger, "Returning duration {}", dur);
|
||||
*duration = dur;
|
||||
GBoolean::True
|
||||
glib::GTRUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn seek(&self, start: u64, stop: u64, offset: &mut u64) -> bool {
|
||||
extern "C" {
|
||||
fn gst_rs_demuxer_stream_eos(raw: *mut c_void, index: u32);
|
||||
fn gst_rs_demuxer_stream_eos(raw: *mut gst::GstElement, index: u32);
|
||||
};
|
||||
|
||||
let stop = if stop == u64::MAX { None } else { Some(stop) };
|
||||
|
@ -246,19 +249,19 @@ impl DemuxerWrapper {
|
|||
|
||||
fn handle_buffer(&self, buffer: GstRc<Buffer>) -> GstFlowReturn {
|
||||
extern "C" {
|
||||
fn gst_rs_demuxer_stream_eos(raw: *mut c_void, index: u32);
|
||||
fn gst_rs_demuxer_add_stream(raw: *mut c_void,
|
||||
fn gst_rs_demuxer_stream_eos(raw: *mut gst::GstElement, index: u32);
|
||||
fn gst_rs_demuxer_add_stream(raw: *mut gst::GstElement,
|
||||
index: u32,
|
||||
caps: *const c_void,
|
||||
caps: *const gst::GstCaps,
|
||||
stream_id: *const c_char);
|
||||
fn gst_rs_demuxer_added_all_streams(raw: *mut c_void);
|
||||
// fn gst_rs_demuxer_remove_all_streams(raw: *mut c_void);
|
||||
fn gst_rs_demuxer_stream_format_changed(raw: *mut c_void,
|
||||
fn gst_rs_demuxer_added_all_streams(raw: *mut gst::GstElement);
|
||||
// fn gst_rs_demuxer_remove_all_streams(raw: *mut gst::GstElement);
|
||||
fn gst_rs_demuxer_stream_format_changed(raw: *mut gst::GstElement,
|
||||
index: u32,
|
||||
caps: *const c_void);
|
||||
fn gst_rs_demuxer_stream_push_buffer(raw: *mut c_void,
|
||||
caps: *const gst::GstCaps);
|
||||
fn gst_rs_demuxer_stream_push_buffer(raw: *mut gst::GstElement,
|
||||
index: u32,
|
||||
buffer: *mut c_void)
|
||||
buffer: *mut gst::GstBuffer)
|
||||
-> GstFlowReturn;
|
||||
};
|
||||
|
||||
|
@ -379,7 +382,7 @@ impl DemuxerWrapper {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn demuxer_new(demuxer: *mut c_void,
|
||||
pub unsafe extern "C" fn demuxer_new(demuxer: *mut gst::GstElement,
|
||||
create_instance: fn(Element) -> Box<Demuxer>)
|
||||
-> *mut DemuxerWrapper {
|
||||
let instance = create_instance(Element::new(demuxer));
|
||||
|
@ -394,40 +397,52 @@ pub unsafe extern "C" fn demuxer_drop(ptr: *mut DemuxerWrapper) {
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn demuxer_start(ptr: *const DemuxerWrapper,
|
||||
upstream_size: u64,
|
||||
random_access: GBoolean)
|
||||
-> GBoolean {
|
||||
random_access: glib::gboolean)
|
||||
-> glib::gboolean {
|
||||
let wrap: &DemuxerWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
GBoolean::from_bool(wrap.start(upstream_size, random_access.to_bool()))
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
if wrap.start(upstream_size, random_access != glib::GFALSE) {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn demuxer_stop(ptr: *const DemuxerWrapper) -> GBoolean {
|
||||
pub unsafe extern "C" fn demuxer_stop(ptr: *const DemuxerWrapper) -> glib::gboolean {
|
||||
let wrap: &DemuxerWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::True, {
|
||||
GBoolean::from_bool(wrap.stop())
|
||||
panic_to_error!(wrap, glib::GTRUE, {
|
||||
if wrap.stop() {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn demuxer_is_seekable(ptr: *const DemuxerWrapper) -> GBoolean {
|
||||
pub unsafe extern "C" fn demuxer_is_seekable(ptr: *const DemuxerWrapper) -> glib::gboolean {
|
||||
let wrap: &DemuxerWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
GBoolean::from_bool(wrap.is_seekable())
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
if wrap.is_seekable() {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn demuxer_get_position(ptr: *const DemuxerWrapper,
|
||||
position: *mut u64)
|
||||
-> GBoolean {
|
||||
-> glib::gboolean {
|
||||
let wrap: &DemuxerWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
let position = &mut *position;
|
||||
wrap.get_position(position)
|
||||
})
|
||||
|
@ -436,10 +451,10 @@ pub unsafe extern "C" fn demuxer_get_position(ptr: *const DemuxerWrapper,
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn demuxer_get_duration(ptr: *const DemuxerWrapper,
|
||||
duration: *mut u64)
|
||||
-> GBoolean {
|
||||
-> glib::gboolean {
|
||||
let wrap: &DemuxerWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
let duration = &mut *duration;
|
||||
wrap.get_duration(duration)
|
||||
})
|
||||
|
@ -450,20 +465,24 @@ pub unsafe extern "C" fn demuxer_seek(ptr: *mut DemuxerWrapper,
|
|||
start: u64,
|
||||
stop: u64,
|
||||
offset: *mut u64)
|
||||
-> GBoolean {
|
||||
-> glib::gboolean {
|
||||
|
||||
let wrap: &mut DemuxerWrapper = &mut *ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
let offset = &mut *offset;
|
||||
|
||||
GBoolean::from_bool(wrap.seek(start, stop, offset))
|
||||
if wrap.seek(start, stop, offset) {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn demuxer_handle_buffer(ptr: *mut DemuxerWrapper,
|
||||
buffer: *mut c_void)
|
||||
buffer: *mut gst::GstBuffer)
|
||||
-> GstFlowReturn {
|
||||
let wrap: &mut DemuxerWrapper = &mut *ptr;
|
||||
|
||||
|
@ -496,7 +515,7 @@ pub struct DemuxerInfo<'a> {
|
|||
|
||||
pub fn demuxer_register(plugin: &Plugin, demuxer_info: &DemuxerInfo) {
|
||||
extern "C" {
|
||||
fn gst_rs_demuxer_register(plugin: *const c_void,
|
||||
fn gst_rs_demuxer_register(plugin: *const gst::GstPlugin,
|
||||
name: *const c_char,
|
||||
long_name: *const c_char,
|
||||
description: *const c_char,
|
||||
|
@ -504,9 +523,9 @@ pub fn demuxer_register(plugin: &Plugin, demuxer_info: &DemuxerInfo) {
|
|||
author: *const c_char,
|
||||
rank: i32,
|
||||
create_instance: *const c_void,
|
||||
input_caps: *const c_void,
|
||||
output_caps: *const c_void)
|
||||
-> GBoolean;
|
||||
input_caps: *const gst::GstCaps,
|
||||
output_caps: *const gst::GstCaps)
|
||||
-> glib::gboolean;
|
||||
}
|
||||
|
||||
let cname = CString::new(demuxer_info.name).unwrap();
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/* Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
* option. This file may not be copied, modified, or distributed
|
||||
* except according to those terms.
|
||||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
void
|
||||
gst_rs_element_error (GstElement * element, GQuark error_domain,
|
||||
gint error_code, const gchar * message, const gchar * debug,
|
||||
const gchar * file, const gchar * function, guint line)
|
||||
{
|
||||
gst_element_message_full (element, GST_MESSAGE_ERROR, error_domain,
|
||||
error_code, g_strdup (message), g_strdup (debug), file, function, line);
|
||||
}
|
|
@ -6,8 +6,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use libc::c_char;
|
||||
use std::os::raw::c_void;
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
use std::error::Error;
|
||||
|
@ -19,6 +17,9 @@ use url::Url;
|
|||
|
||||
use utils::*;
|
||||
|
||||
use glib;
|
||||
use gst;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! error_msg(
|
||||
// Plain strings
|
||||
|
@ -61,20 +62,12 @@ pub trait ToGError {
|
|||
fn to_gerror(&self) -> (u32, i32);
|
||||
}
|
||||
|
||||
pub fn gst_library_error_domain() -> u32 {
|
||||
extern "C" {
|
||||
fn gst_library_error_quark() -> u32;
|
||||
}
|
||||
|
||||
unsafe { gst_library_error_quark() }
|
||||
pub fn gst_library_error_domain() -> glib::GQuark {
|
||||
unsafe { gst::gst_library_error_quark() }
|
||||
}
|
||||
|
||||
pub fn gst_resource_error_domain() -> u32 {
|
||||
extern "C" {
|
||||
fn gst_resource_error_quark() -> u32;
|
||||
}
|
||||
|
||||
unsafe { gst_resource_error_quark() }
|
||||
pub fn gst_resource_error_domain() -> glib::GQuark {
|
||||
unsafe { gst::gst_resource_error_quark() }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -110,18 +103,7 @@ impl ErrorMessage {
|
|||
}
|
||||
|
||||
|
||||
pub unsafe fn post(&self, element: *mut c_void) {
|
||||
extern "C" {
|
||||
fn gst_rs_element_error(sink: *mut c_void,
|
||||
error_domain: u32,
|
||||
error_code: i32,
|
||||
message: *const c_char,
|
||||
debug: *const c_char,
|
||||
filename: *const c_char,
|
||||
function: *const c_char,
|
||||
line: u32);
|
||||
}
|
||||
|
||||
pub unsafe fn post(&self, element: *mut gst::GstElement) {
|
||||
let ErrorMessage { error_domain,
|
||||
error_code,
|
||||
ref message,
|
||||
|
@ -142,14 +124,15 @@ impl ErrorMessage {
|
|||
let function_cstr = CString::new(function.as_bytes()).unwrap();
|
||||
let function_ptr = function_cstr.as_ptr();
|
||||
|
||||
gst_rs_element_error(element,
|
||||
gst::gst_element_message_full(element,
|
||||
gst::GST_MESSAGE_ERROR,
|
||||
error_domain,
|
||||
error_code,
|
||||
message_ptr,
|
||||
debug_ptr,
|
||||
glib::g_strdup(message_ptr),
|
||||
glib::g_strdup(debug_ptr),
|
||||
file_ptr,
|
||||
function_ptr,
|
||||
line);
|
||||
line as i32);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,25 +216,16 @@ impl UriError {
|
|||
&self.error_kind
|
||||
}
|
||||
|
||||
pub unsafe fn into_gerror(self, err: *mut c_void) {
|
||||
extern "C" {
|
||||
fn g_set_error_literal(err: *mut c_void,
|
||||
domain: u32,
|
||||
code: i32,
|
||||
message: *const c_char);
|
||||
fn gst_uri_error_quark() -> u32;
|
||||
}
|
||||
|
||||
|
||||
pub unsafe fn into_gerror(self, err: *mut *mut glib::GError) {
|
||||
if let Some(msg) = self.message {
|
||||
let cmsg = CString::new(msg.as_str()).unwrap();
|
||||
g_set_error_literal(err,
|
||||
gst_uri_error_quark(),
|
||||
glib::g_set_error_literal(err,
|
||||
gst::gst_uri_error_quark(),
|
||||
self.error_kind as i32,
|
||||
cmsg.as_ptr());
|
||||
} else {
|
||||
g_set_error_literal(err,
|
||||
gst_uri_error_quark(),
|
||||
glib::g_set_error_literal(err,
|
||||
gst::gst_uri_error_quark(),
|
||||
self.error_kind as i32,
|
||||
ptr::null());
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ extern crate byteorder;
|
|||
extern crate num_rational;
|
||||
#[macro_use]
|
||||
extern crate derivative;
|
||||
extern crate gobject_sys as gobject;
|
||||
extern crate glib_sys as glib;
|
||||
extern crate gstreamer_sys as gst;
|
||||
pub extern crate gobject_sys as gobject;
|
||||
pub extern crate glib_sys as glib;
|
||||
pub extern crate gstreamer_sys as gst;
|
||||
|
||||
#[macro_use]
|
||||
pub mod utils;
|
||||
|
@ -41,3 +41,9 @@ pub mod bytes;
|
|||
pub mod tags;
|
||||
pub mod streams;
|
||||
pub mod miniobject;
|
||||
|
||||
pub mod ffi {
|
||||
pub use glib;
|
||||
pub use gobject;
|
||||
pub use gst;
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/* Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
* option. This file may not be copied, modified, or distributed
|
||||
* except according to those terms.
|
||||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
void
|
||||
gst_rs_debug_log (GstDebugCategory * category,
|
||||
GstDebugLevel level,
|
||||
const gchar * file,
|
||||
const gchar * function, gint line, GObject * object, const gchar * message)
|
||||
{
|
||||
gst_debug_log (category, level, file, function, line, object, "%s", message);
|
||||
}
|
|
@ -6,19 +6,21 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::os::raw::c_void;
|
||||
use libc::c_char;
|
||||
use std::ffi::CString;
|
||||
use slog::{Drain, Record, OwnedKeyValueList, Never, Level};
|
||||
use std::fmt;
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
|
||||
use utils::Element;
|
||||
|
||||
#[derive(Debug)]
|
||||
use gobject;
|
||||
use gst;
|
||||
|
||||
pub struct GstDebugDrain {
|
||||
category: *const c_void,
|
||||
element: *const c_void,
|
||||
category: *mut gst::GstDebugCategory,
|
||||
element: gobject::GWeakRef,
|
||||
}
|
||||
|
||||
impl GstDebugDrain {
|
||||
|
@ -31,7 +33,7 @@ impl GstDebugDrain {
|
|||
fn _gst_debug_category_new(name: *const c_char,
|
||||
color: u32,
|
||||
description: *const c_char)
|
||||
-> *const c_void;
|
||||
-> *mut gst::GstDebugCategory;
|
||||
}
|
||||
|
||||
let name_cstr = CString::new(name.as_bytes()).unwrap();
|
||||
|
@ -47,18 +49,14 @@ impl GstDebugDrain {
|
|||
None => ptr::null(),
|
||||
};
|
||||
|
||||
let drain = GstDebugDrain {
|
||||
let mut drain = GstDebugDrain {
|
||||
category: category,
|
||||
element: ptr::null(),
|
||||
element: unsafe { mem::zeroed() },
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
fn g_weak_ref_set(weak_ref: &*const c_void, obj: *const c_void);
|
||||
}
|
||||
|
||||
if !element.is_null() {
|
||||
unsafe {
|
||||
g_weak_ref_set(&drain.element, element);
|
||||
gobject::g_weak_ref_set(&mut drain.element, element as *mut gobject::GObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,14 +66,8 @@ impl GstDebugDrain {
|
|||
|
||||
impl Drop for GstDebugDrain {
|
||||
fn drop(&mut self) {
|
||||
extern "C" {
|
||||
fn g_weak_ref_clear(weak_ref: &*const c_void);
|
||||
}
|
||||
|
||||
if !self.element.is_null() {
|
||||
unsafe {
|
||||
g_weak_ref_clear(&self.element);
|
||||
}
|
||||
gobject::g_weak_ref_clear(&mut self.element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,30 +76,17 @@ impl Drain for GstDebugDrain {
|
|||
type Error = Never;
|
||||
|
||||
fn log(&self, record: &Record, _: &OwnedKeyValueList) -> Result<(), Never> {
|
||||
extern "C" {
|
||||
fn gst_rs_debug_log(category: *const c_void,
|
||||
level: u32,
|
||||
file: *const c_char,
|
||||
function: *const c_char,
|
||||
line: u32,
|
||||
object: *const c_void,
|
||||
message: *const c_char);
|
||||
fn gst_debug_category_get_threshold(category: *const c_void) -> u32;
|
||||
fn g_weak_ref_get(weak_ref: &*const c_void) -> *const c_void;
|
||||
fn gst_object_unref(obj: *const c_void);
|
||||
}
|
||||
|
||||
let level = match record.level() {
|
||||
Level::Critical | Level::Error => 1,
|
||||
Level::Warning => 2,
|
||||
Level::Info => 4,
|
||||
Level::Debug => 5,
|
||||
Level::Trace => 7,
|
||||
Level::Critical | Level::Error => gst::GST_LEVEL_ERROR,
|
||||
Level::Warning => gst::GST_LEVEL_WARNING,
|
||||
Level::Info => gst::GST_LEVEL_INFO,
|
||||
Level::Debug => gst::GST_LEVEL_DEBUG,
|
||||
Level::Trace => gst::GST_LEVEL_TRACE,
|
||||
};
|
||||
|
||||
let threshold = unsafe { gst_debug_category_get_threshold(self.category) };
|
||||
let threshold = unsafe { gst::gst_debug_category_get_threshold(self.category) };
|
||||
|
||||
if level > threshold {
|
||||
if level as u32 > threshold as u32 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -119,22 +98,19 @@ impl Drain for GstDebugDrain {
|
|||
let message_cstr = CString::new(fmt::format(record.msg()).as_bytes()).unwrap();
|
||||
|
||||
unsafe {
|
||||
let element = if self.element.is_null() {
|
||||
ptr::null()
|
||||
} else {
|
||||
g_weak_ref_get(&self.element)
|
||||
};
|
||||
let element = gobject::g_weak_ref_get(&self.element as *const gobject::GWeakRef as
|
||||
*mut gobject::GWeakRef);
|
||||
|
||||
gst_rs_debug_log(self.category,
|
||||
gst::gst_debug_log(self.category,
|
||||
level,
|
||||
file_cstr.as_ptr(),
|
||||
function_cstr.as_ptr(),
|
||||
record.line(),
|
||||
element,
|
||||
record.line() as i32,
|
||||
element as *mut gobject::GObject,
|
||||
message_cstr.as_ptr());
|
||||
|
||||
if !element.is_null() {
|
||||
gst_object_unref(element);
|
||||
gst::gst_object_unref(element as *mut gst::GstObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::os::raw::c_void;
|
||||
use std::{fmt, ops, borrow, ptr};
|
||||
use std::marker::PhantomData;
|
||||
use utils::*;
|
||||
|
||||
use glib;
|
||||
use gst;
|
||||
|
||||
#[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct GstRc<T: MiniObject> {
|
||||
|
@ -18,31 +19,24 @@ pub struct GstRc<T: MiniObject> {
|
|||
|
||||
impl<T: MiniObject> GstRc<T> {
|
||||
unsafe fn new(obj: T, owned: bool) -> Self {
|
||||
extern "C" {
|
||||
fn gst_mini_object_ref(obj: *mut c_void) -> *mut c_void;
|
||||
}
|
||||
|
||||
assert!(!obj.as_ptr().is_null());
|
||||
|
||||
if !owned {
|
||||
gst_mini_object_ref(obj.as_ptr());
|
||||
gst::gst_mini_object_ref(obj.as_ptr() as *mut gst::GstMiniObject);
|
||||
}
|
||||
|
||||
GstRc { obj: obj }
|
||||
}
|
||||
|
||||
pub unsafe fn new_from_owned_ptr(ptr: *mut c_void) -> Self {
|
||||
pub unsafe fn new_from_owned_ptr(ptr: *mut T::PtrType) -> Self {
|
||||
Self::new(T::new_from_ptr(ptr), true)
|
||||
}
|
||||
|
||||
pub unsafe fn new_from_unowned_ptr(ptr: *mut c_void) -> Self {
|
||||
pub unsafe fn new_from_unowned_ptr(ptr: *mut T::PtrType) -> Self {
|
||||
Self::new(T::new_from_ptr(ptr), false)
|
||||
}
|
||||
|
||||
pub fn make_mut(&mut self) -> &mut T {
|
||||
extern "C" {
|
||||
fn gst_mini_object_make_writable(obj: *mut c_void) -> *mut c_void;
|
||||
}
|
||||
unsafe {
|
||||
let ptr = self.obj.as_ptr();
|
||||
|
||||
|
@ -50,7 +44,9 @@ impl<T: MiniObject> GstRc<T> {
|
|||
return &mut self.obj;
|
||||
}
|
||||
|
||||
self.obj.replace_ptr(gst_mini_object_make_writable(ptr));
|
||||
self.obj.replace_ptr(gst::gst_mini_object_make_writable(ptr as
|
||||
*mut gst::GstMiniObject) as
|
||||
*mut T::PtrType);
|
||||
assert!(self.is_writable());
|
||||
|
||||
&mut self.obj
|
||||
|
@ -66,20 +62,20 @@ impl<T: MiniObject> GstRc<T> {
|
|||
}
|
||||
|
||||
pub fn copy(&self) -> Self {
|
||||
extern "C" {
|
||||
fn gst_mini_object_copy(obj: *const c_void) -> *mut c_void;
|
||||
unsafe {
|
||||
GstRc::new_from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
|
||||
*const gst::GstMiniObject) as
|
||||
*mut T::PtrType)
|
||||
}
|
||||
unsafe { GstRc::new_from_owned_ptr(gst_mini_object_copy(self.obj.as_ptr())) }
|
||||
}
|
||||
|
||||
fn is_writable(&self) -> bool {
|
||||
extern "C" {
|
||||
fn gst_mini_object_is_writable(obj: *mut c_void) -> GBoolean;
|
||||
}
|
||||
unsafe { gst_mini_object_is_writable(self.as_ptr()).to_bool() }
|
||||
(unsafe {
|
||||
gst::gst_mini_object_is_writable(self.as_ptr() as *const gst::GstMiniObject)
|
||||
} == glib::GTRUE)
|
||||
}
|
||||
|
||||
pub unsafe fn into_ptr(mut self) -> *mut c_void {
|
||||
pub unsafe fn into_ptr(mut self) -> *mut T::PtrType {
|
||||
self.obj.swap_ptr(ptr::null_mut())
|
||||
}
|
||||
}
|
||||
|
@ -111,13 +107,9 @@ impl<T: MiniObject> Clone for GstRc<T> {
|
|||
|
||||
impl<T: MiniObject> Drop for GstRc<T> {
|
||||
fn drop(&mut self) {
|
||||
extern "C" {
|
||||
fn gst_mini_object_unref(obj: *mut c_void) -> *mut c_void;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
if !self.obj.as_ptr().is_null() {
|
||||
gst_mini_object_unref(self.obj.as_ptr());
|
||||
gst::gst_mini_object_unref(self.obj.as_ptr() as *mut gst::GstMiniObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,16 +126,18 @@ impl<T: MiniObject + fmt::Display> fmt::Display for GstRc<T> {
|
|||
|
||||
// NOTE: Reference counting must not happen in here
|
||||
pub unsafe trait MiniObject {
|
||||
unsafe fn as_ptr(&self) -> *mut c_void;
|
||||
unsafe fn replace_ptr(&mut self, ptr: *mut c_void);
|
||||
unsafe fn swap_ptr(&mut self, new_ptr: *mut c_void) -> *mut c_void {
|
||||
type PtrType;
|
||||
|
||||
unsafe fn as_ptr(&self) -> *mut Self::PtrType;
|
||||
unsafe fn replace_ptr(&mut self, ptr: *mut Self::PtrType);
|
||||
unsafe fn swap_ptr(&mut self, new_ptr: *mut Self::PtrType) -> *mut Self::PtrType {
|
||||
let ptr = self.as_ptr();
|
||||
self.replace_ptr(new_ptr);
|
||||
|
||||
ptr
|
||||
}
|
||||
|
||||
unsafe fn new_from_ptr(ptr: *mut c_void) -> Self;
|
||||
unsafe fn new_from_ptr(ptr: *mut Self::PtrType) -> Self;
|
||||
}
|
||||
|
||||
impl<'a, T: MiniObject> From<&'a T> for GstRc<T> {
|
||||
|
@ -159,19 +153,19 @@ impl<'a, T: MiniObject> From<&'a mut T> for GstRc<T> {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct GstRefPtr(*mut c_void);
|
||||
pub struct GstRefPtr<T: MiniObject>(*mut T::PtrType);
|
||||
|
||||
#[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct GstRef<'a, T: MiniObject> {
|
||||
pub struct GstRef<'a, T: 'a + MiniObject> {
|
||||
obj: T,
|
||||
#[allow(dead_code)]
|
||||
phantom: PhantomData<&'a GstRefPtr>,
|
||||
phantom: PhantomData<&'a GstRefPtr<T>>,
|
||||
}
|
||||
|
||||
impl<'a, T: MiniObject> GstRef<'a, T> {
|
||||
pub unsafe fn new(ptr: &'a GstRefPtr) -> GstRef<'a, T> {
|
||||
pub unsafe fn new(ptr: &'a GstRefPtr<T>) -> GstRef<'a, T> {
|
||||
GstRef {
|
||||
obj: T::new_from_ptr(ptr.0),
|
||||
obj: T::new_from_ptr(ptr.0 as *mut T::PtrType),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -185,20 +179,20 @@ impl<'a, T: MiniObject> GstRef<'a, T> {
|
|||
}
|
||||
|
||||
pub fn copy(&self) -> GstRc<T> {
|
||||
extern "C" {
|
||||
fn gst_mini_object_copy(obj: *const c_void) -> *mut c_void;
|
||||
unsafe {
|
||||
GstRc::new_from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
|
||||
*const gst::GstMiniObject) as
|
||||
*mut T::PtrType)
|
||||
}
|
||||
unsafe { GstRc::new_from_owned_ptr(gst_mini_object_copy(self.obj.as_ptr())) }
|
||||
}
|
||||
|
||||
fn is_writable(&self) -> bool {
|
||||
extern "C" {
|
||||
fn gst_mini_object_is_writable(obj: *mut c_void) -> GBoolean;
|
||||
}
|
||||
unsafe { gst_mini_object_is_writable(self.as_ptr()).to_bool() }
|
||||
(unsafe {
|
||||
gst::gst_mini_object_is_writable(self.as_ptr() as *const gst::GstMiniObject)
|
||||
} == glib::GTRUE)
|
||||
}
|
||||
|
||||
pub unsafe fn into_ptr(mut self) -> *mut c_void {
|
||||
pub unsafe fn into_ptr(mut self) -> *mut T::PtrType {
|
||||
self.obj.swap_ptr(ptr::null_mut())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::os::raw::c_void;
|
||||
use gst;
|
||||
|
||||
pub struct Plugin(*const c_void);
|
||||
pub struct Plugin(*mut gst::GstPlugin);
|
||||
|
||||
impl Plugin {
|
||||
pub unsafe fn new(plugin: *const c_void) -> Plugin {
|
||||
pub unsafe fn new(plugin: *mut gst::GstPlugin) -> Plugin {
|
||||
Plugin(plugin)
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const c_void {
|
||||
pub unsafe fn as_ptr(&self) -> *mut gst::GstPlugin {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
@ -26,47 +26,41 @@ macro_rules! plugin_define(
|
|||
$version:expr, $license:expr, $source:expr,
|
||||
$package:expr, $origin:expr, $release_datetime:expr) => {
|
||||
pub mod plugin_desc {
|
||||
use std::os::raw::c_void;
|
||||
use $crate::utils::GBoolean;
|
||||
use $crate::plugin::Plugin;
|
||||
use $crate::ffi::gst;
|
||||
use $crate::ffi::glib;
|
||||
|
||||
// Not using c_char here because it requires the libc crate
|
||||
#[allow(non_camel_case_types)]
|
||||
type c_char = i8;
|
||||
|
||||
#[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],
|
||||
}
|
||||
|
||||
pub struct GstPluginDesc(gst::GstPluginDesc);
|
||||
unsafe impl Sync for GstPluginDesc {}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub static gst_plugin_desc: GstPluginDesc = GstPluginDesc {
|
||||
pub static gst_plugin_desc: GstPluginDesc = GstPluginDesc(gst::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],
|
||||
};
|
||||
name: $name as *const u8 as *const c_char,
|
||||
description: $description as *const u8 as *const c_char,
|
||||
plugin_init: Some(plugin_init_trampoline),
|
||||
version: $version as *const u8 as *const c_char,
|
||||
license: $license as *const u8 as *const c_char,
|
||||
source: $source as *const u8 as *const c_char,
|
||||
package: $package as *const u8 as *const c_char,
|
||||
origin: $origin as *const u8 as *const c_char,
|
||||
release_datetime: $release_datetime as *const u8 as *const c_char,
|
||||
_gst_reserved: [0 as glib::gpointer; 4],
|
||||
});
|
||||
|
||||
unsafe extern "C" fn plugin_init_trampoline(plugin: *const c_void) -> GBoolean {
|
||||
GBoolean::from_bool(super::$plugin_init(&Plugin::new(plugin)))
|
||||
unsafe extern "C" fn plugin_init_trampoline(plugin: *mut gst::GstPlugin) -> glib::gboolean {
|
||||
if super::$plugin_init(&Plugin::new(plugin)) {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -28,6 +28,9 @@ use miniobject::*;
|
|||
use log::*;
|
||||
use plugin::Plugin;
|
||||
|
||||
use glib;
|
||||
use gst;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SinkError {
|
||||
Failure,
|
||||
|
@ -50,7 +53,7 @@ impl ToGError for SinkError {
|
|||
}
|
||||
|
||||
pub struct SinkWrapper {
|
||||
raw: *mut c_void,
|
||||
raw: *mut gst::GstElement,
|
||||
logger: Logger,
|
||||
uri: Mutex<(Option<Url>, bool)>,
|
||||
uri_validator: Box<UriValidator>,
|
||||
|
@ -68,7 +71,7 @@ pub trait Sink {
|
|||
}
|
||||
|
||||
impl SinkWrapper {
|
||||
fn new(raw: *mut c_void, sink: Box<Sink>) -> SinkWrapper {
|
||||
fn new(raw: *mut gst::GstElement, sink: Box<Sink>) -> SinkWrapper {
|
||||
SinkWrapper {
|
||||
raw: raw,
|
||||
logger: Logger::root(GstDebugDrain::new(Some(unsafe { &Element::new(raw) }),
|
||||
|
@ -141,7 +144,10 @@ impl SinkWrapper {
|
|||
Err(ref msg) => {
|
||||
error!(self.logger, "Failed to start: {:?}", msg);
|
||||
|
||||
self.uri.lock().unwrap().1 = false;
|
||||
self.uri
|
||||
.lock()
|
||||
.unwrap()
|
||||
.1 = false;
|
||||
self.post_message(msg);
|
||||
false
|
||||
}
|
||||
|
@ -156,7 +162,10 @@ impl SinkWrapper {
|
|||
match sink.stop() {
|
||||
Ok(..) => {
|
||||
trace!(self.logger, "Stopped successfully");
|
||||
self.uri.lock().unwrap().1 = false;
|
||||
self.uri
|
||||
.lock()
|
||||
.unwrap()
|
||||
.1 = false;
|
||||
true
|
||||
}
|
||||
Err(ref msg) => {
|
||||
|
@ -195,7 +204,7 @@ impl SinkWrapper {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sink_new(sink: *mut c_void,
|
||||
pub unsafe extern "C" fn sink_new(sink: *mut gst::GstElement,
|
||||
create_instance: fn(Element) -> Box<Sink>)
|
||||
-> *mut SinkWrapper {
|
||||
let instance = create_instance(Element::new(sink));
|
||||
|
@ -210,11 +219,11 @@ pub unsafe extern "C" fn sink_drop(ptr: *mut SinkWrapper) {
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sink_set_uri(ptr: *const SinkWrapper,
|
||||
uri_ptr: *const c_char,
|
||||
cerr: *mut c_void)
|
||||
-> GBoolean {
|
||||
cerr: *mut *mut glib::GError)
|
||||
-> glib::gboolean {
|
||||
let wrap: &SinkWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
let uri_str = if uri_ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
@ -225,9 +234,9 @@ pub unsafe extern "C" fn sink_set_uri(ptr: *const SinkWrapper,
|
|||
Err(err) => {
|
||||
error!(wrap.logger, "Failed to set URI {:?}", err);
|
||||
err.into_gerror(cerr);
|
||||
GBoolean::False
|
||||
glib::GFALSE
|
||||
}
|
||||
Ok(_) => GBoolean::True,
|
||||
Ok(_) => glib::GTRUE,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -245,24 +254,34 @@ pub unsafe extern "C" fn sink_get_uri(ptr: *const SinkWrapper) -> *mut c_char {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sink_start(ptr: *const SinkWrapper) -> GBoolean {
|
||||
pub unsafe extern "C" fn sink_start(ptr: *const SinkWrapper) -> glib::gboolean {
|
||||
let wrap: &SinkWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
GBoolean::from_bool(wrap.start())
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
if wrap.start() {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sink_stop(ptr: *const SinkWrapper) -> GBoolean {
|
||||
pub unsafe extern "C" fn sink_stop(ptr: *const SinkWrapper) -> glib::gboolean {
|
||||
let wrap: &SinkWrapper = &*ptr;
|
||||
panic_to_error!(wrap, GBoolean::True, {
|
||||
GBoolean::from_bool(wrap.stop())
|
||||
panic_to_error!(wrap, glib::GTRUE, {
|
||||
if wrap.stop() {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sink_render(ptr: *const SinkWrapper, buffer: GstRefPtr) -> GstFlowReturn {
|
||||
pub unsafe extern "C" fn sink_render(ptr: *const SinkWrapper,
|
||||
buffer: GstRefPtr<Buffer>)
|
||||
-> GstFlowReturn {
|
||||
let wrap: &SinkWrapper = &*ptr;
|
||||
panic_to_error!(wrap, GstFlowReturn::Error, {
|
||||
let buffer: GstRef<Buffer> = GstRef::new(&buffer);
|
||||
|
@ -283,7 +302,7 @@ pub struct SinkInfo<'a> {
|
|||
|
||||
pub fn sink_register(plugin: &Plugin, sink_info: &SinkInfo) {
|
||||
extern "C" {
|
||||
fn gst_rs_sink_register(plugin: *const c_void,
|
||||
fn gst_rs_sink_register(plugin: *const gst::GstPlugin,
|
||||
name: *const c_char,
|
||||
long_name: *const c_char,
|
||||
description: *const c_char,
|
||||
|
@ -292,7 +311,7 @@ pub fn sink_register(plugin: &Plugin, sink_info: &SinkInfo) {
|
|||
rank: i32,
|
||||
create_instance: *const c_void,
|
||||
protocols: *const c_char)
|
||||
-> GBoolean;
|
||||
-> glib::gboolean;
|
||||
}
|
||||
|
||||
let cname = CString::new(sink_info.name).unwrap();
|
||||
|
|
|
@ -28,6 +28,9 @@ use buffer::*;
|
|||
use miniobject::*;
|
||||
use log::*;
|
||||
|
||||
use glib;
|
||||
use gst;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SourceError {
|
||||
Failure,
|
||||
|
@ -50,7 +53,7 @@ impl ToGError for SourceError {
|
|||
}
|
||||
|
||||
pub struct SourceWrapper {
|
||||
raw: *mut c_void,
|
||||
raw: *mut gst::GstElement,
|
||||
logger: Logger,
|
||||
uri: Mutex<(Option<Url>, bool)>,
|
||||
uri_validator: Box<UriValidator>,
|
||||
|
@ -71,7 +74,7 @@ pub trait Source {
|
|||
}
|
||||
|
||||
impl SourceWrapper {
|
||||
fn new(raw: *mut c_void, source: Box<Source>) -> SourceWrapper {
|
||||
fn new(raw: *mut gst::GstElement, source: Box<Source>) -> SourceWrapper {
|
||||
SourceWrapper {
|
||||
raw: raw,
|
||||
logger: Logger::root(GstDebugDrain::new(Some(unsafe { &Element::new(raw) }),
|
||||
|
@ -154,7 +157,10 @@ impl SourceWrapper {
|
|||
Err(ref msg) => {
|
||||
error!(self.logger, "Failed to start: {:?}", msg);
|
||||
|
||||
self.uri.lock().unwrap().1 = false;
|
||||
self.uri
|
||||
.lock()
|
||||
.unwrap()
|
||||
.1 = false;
|
||||
self.post_message(msg);
|
||||
false
|
||||
}
|
||||
|
@ -169,7 +175,10 @@ impl SourceWrapper {
|
|||
match source.stop() {
|
||||
Ok(..) => {
|
||||
trace!(self.logger, "Stopped successfully");
|
||||
self.uri.lock().unwrap().1 = false;
|
||||
self.uri
|
||||
.lock()
|
||||
.unwrap()
|
||||
.1 = false;
|
||||
true
|
||||
}
|
||||
Err(ref msg) => {
|
||||
|
@ -227,7 +236,7 @@ impl SourceWrapper {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn source_new(source: *mut c_void,
|
||||
pub unsafe extern "C" fn source_new(source: *mut gst::GstElement,
|
||||
create_instance: fn(Element) -> Box<Source>)
|
||||
-> *mut SourceWrapper {
|
||||
let instance = create_instance(Element::new(source));
|
||||
|
@ -243,11 +252,11 @@ pub unsafe extern "C" fn source_drop(ptr: *mut SourceWrapper) {
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn source_set_uri(ptr: *const SourceWrapper,
|
||||
uri_ptr: *const c_char,
|
||||
cerr: *mut c_void)
|
||||
-> GBoolean {
|
||||
cerr: *mut *mut glib::GError)
|
||||
-> glib::gboolean {
|
||||
let wrap: &SourceWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
let uri_str = if uri_ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
@ -258,9 +267,9 @@ pub unsafe extern "C" fn source_set_uri(ptr: *const SourceWrapper,
|
|||
Err(err) => {
|
||||
error!(wrap.logger, "Failed to set URI {:?}", err);
|
||||
err.into_gerror(cerr);
|
||||
GBoolean::False
|
||||
glib::GFALSE
|
||||
}
|
||||
Ok(_) => GBoolean::True,
|
||||
Ok(_) => glib::GTRUE,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -277,11 +286,15 @@ pub unsafe extern "C" fn source_get_uri(ptr: *const SourceWrapper) -> *mut c_cha
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn source_is_seekable(ptr: *const SourceWrapper) -> GBoolean {
|
||||
pub unsafe extern "C" fn source_is_seekable(ptr: *const SourceWrapper) -> glib::gboolean {
|
||||
let wrap: &SourceWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
GBoolean::from_bool(wrap.is_seekable())
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
if wrap.is_seekable() {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -294,20 +307,28 @@ pub unsafe extern "C" fn source_get_size(ptr: *const SourceWrapper) -> u64 {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn source_start(ptr: *const SourceWrapper) -> GBoolean {
|
||||
pub unsafe extern "C" fn source_start(ptr: *const SourceWrapper) -> glib::gboolean {
|
||||
let wrap: &SourceWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
GBoolean::from_bool(wrap.start())
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
if wrap.start() {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn source_stop(ptr: *const SourceWrapper) -> GBoolean {
|
||||
pub unsafe extern "C" fn source_stop(ptr: *const SourceWrapper) -> glib::gboolean {
|
||||
let wrap: &SourceWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::True, {
|
||||
GBoolean::from_bool(wrap.stop())
|
||||
panic_to_error!(wrap, glib::GTRUE, {
|
||||
if wrap.stop() {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -315,7 +336,7 @@ pub unsafe extern "C" fn source_stop(ptr: *const SourceWrapper) -> GBoolean {
|
|||
pub unsafe extern "C" fn source_fill(ptr: *const SourceWrapper,
|
||||
offset: u64,
|
||||
length: u32,
|
||||
buffer: GstRefPtr)
|
||||
buffer: GstRefPtr<Buffer>)
|
||||
-> GstFlowReturn {
|
||||
let wrap: &SourceWrapper = &*ptr;
|
||||
|
||||
|
@ -326,11 +347,18 @@ pub unsafe extern "C" fn source_fill(ptr: *const SourceWrapper,
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn source_seek(ptr: *const SourceWrapper, start: u64, stop: u64) -> GBoolean {
|
||||
pub unsafe extern "C" fn source_seek(ptr: *const SourceWrapper,
|
||||
start: u64,
|
||||
stop: u64)
|
||||
-> glib::gboolean {
|
||||
let wrap: &SourceWrapper = &*ptr;
|
||||
|
||||
panic_to_error!(wrap, GBoolean::False, {
|
||||
GBoolean::from_bool(wrap.seek(start, if stop == u64::MAX { None } else { Some(stop) }))
|
||||
panic_to_error!(wrap, glib::GFALSE, {
|
||||
if wrap.seek(start, if stop == u64::MAX { None } else { Some(stop) }) {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -349,7 +377,7 @@ pub struct SourceInfo<'a> {
|
|||
pub fn source_register(plugin: &Plugin, source_info: &SourceInfo) {
|
||||
|
||||
extern "C" {
|
||||
fn gst_rs_source_register(plugin: *const c_void,
|
||||
fn gst_rs_source_register(plugin: *const gst::GstPlugin,
|
||||
name: *const c_char,
|
||||
long_name: *const c_char,
|
||||
description: *const c_char,
|
||||
|
@ -358,8 +386,8 @@ pub fn source_register(plugin: &Plugin, source_info: &SourceInfo) {
|
|||
rank: i32,
|
||||
create_instance: *const c_void,
|
||||
protocols: *const c_char,
|
||||
push_only: GBoolean)
|
||||
-> GBoolean;
|
||||
push_only: glib::gboolean)
|
||||
-> glib::gboolean;
|
||||
}
|
||||
|
||||
let cname = CString::new(source_info.name).unwrap();
|
||||
|
@ -379,6 +407,10 @@ pub fn source_register(plugin: &Plugin, source_info: &SourceInfo) {
|
|||
source_info.rank,
|
||||
source_info.create_instance as *const c_void,
|
||||
cprotocols.as_ptr(),
|
||||
GBoolean::from_bool(source_info.push_only));
|
||||
if source_info.push_only {
|
||||
glib::GTRUE
|
||||
} else {
|
||||
glib::GFALSE
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,17 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr;
|
||||
use libc::c_char;
|
||||
use std::mem;
|
||||
use std::ffi::{CStr, CString};
|
||||
use caps::Caps;
|
||||
use miniobject::*;
|
||||
use tags::TagList;
|
||||
|
||||
pub struct Stream(*mut c_void);
|
||||
pub struct StreamCollection(*mut c_void);
|
||||
use gst;
|
||||
|
||||
pub struct Stream(*mut gst::GstStream);
|
||||
pub struct StreamCollection(*mut gst::GstStreamCollection);
|
||||
|
||||
bitflags! {
|
||||
#[repr(C)]
|
||||
|
@ -43,30 +44,23 @@ impl Stream {
|
|||
t: StreamType,
|
||||
flags: StreamFlags)
|
||||
-> Self {
|
||||
extern "C" {
|
||||
fn gst_stream_new(stream_id: *const c_char,
|
||||
caps: *const c_void,
|
||||
t: StreamType,
|
||||
flags: StreamFlags)
|
||||
-> *mut c_void;
|
||||
}
|
||||
|
||||
let stream_id_cstr = CString::new(stream_id).unwrap();
|
||||
let caps = caps.map(|caps| unsafe { caps.as_ptr() }).unwrap_or(ptr::null_mut());
|
||||
|
||||
Stream(unsafe { gst_stream_new(stream_id_cstr.as_ptr(), caps, t, flags) })
|
||||
Stream(unsafe {
|
||||
gst::gst_stream_new(stream_id_cstr.as_ptr(),
|
||||
caps,
|
||||
mem::transmute(t.bits()),
|
||||
mem::transmute(flags.bits()))
|
||||
})
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const c_void {
|
||||
pub unsafe fn as_ptr(&self) -> *const gst::GstStream {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn get_caps(&self) -> Option<GstRc<Caps>> {
|
||||
extern "C" {
|
||||
fn gst_stream_get_caps(stream: *mut c_void) -> *mut c_void;
|
||||
}
|
||||
|
||||
let ptr = unsafe { gst_stream_get_caps(self.0) };
|
||||
let ptr = unsafe { gst::gst_stream_get_caps(self.0) };
|
||||
|
||||
if ptr.is_null() {
|
||||
return None;
|
||||
|
@ -76,36 +70,20 @@ impl Stream {
|
|||
}
|
||||
|
||||
pub fn get_stream_flags(&self) -> StreamFlags {
|
||||
extern "C" {
|
||||
fn gst_stream_get_stream_flags(stream: *mut c_void) -> u32;
|
||||
}
|
||||
|
||||
StreamFlags::from_bits_truncate(unsafe { gst_stream_get_stream_flags(self.0) })
|
||||
StreamFlags::from_bits_truncate(unsafe { gst::gst_stream_get_stream_flags(self.0).bits() })
|
||||
}
|
||||
|
||||
pub fn get_stream_type(&self) -> StreamType {
|
||||
extern "C" {
|
||||
fn gst_stream_get_stream_type(stream: *mut c_void) -> u32;
|
||||
}
|
||||
|
||||
StreamType::from_bits_truncate(unsafe { gst_stream_get_stream_type(self.0) })
|
||||
StreamType::from_bits_truncate(unsafe { gst::gst_stream_get_stream_type(self.0).bits() })
|
||||
}
|
||||
|
||||
pub fn get_stream_id(&self) -> &str {
|
||||
extern "C" {
|
||||
fn gst_stream_get_stream_id(collection: *mut c_void) -> *mut c_char;
|
||||
}
|
||||
|
||||
let cstr = unsafe { CStr::from_ptr(gst_stream_get_stream_id(self.0)) };
|
||||
let cstr = unsafe { CStr::from_ptr(gst::gst_stream_get_stream_id(self.0)) };
|
||||
cstr.to_str().unwrap()
|
||||
}
|
||||
|
||||
pub fn get_tags(&self) -> Option<TagList> {
|
||||
extern "C" {
|
||||
fn gst_stream_get_tags(stream: *mut c_void) -> *mut c_void;
|
||||
}
|
||||
|
||||
let ptr = unsafe { gst_stream_get_tags(self.0) };
|
||||
let ptr = unsafe { gst::gst_stream_get_tags(self.0) };
|
||||
|
||||
if ptr.is_null() {
|
||||
return None;
|
||||
|
@ -115,75 +93,46 @@ impl Stream {
|
|||
}
|
||||
|
||||
pub fn set_caps(&self, caps: Option<GstRc<Caps>>) {
|
||||
extern "C" {
|
||||
fn gst_stream_set_caps(stream: *mut c_void, caps: *mut c_void);
|
||||
}
|
||||
|
||||
let ptr = caps.map(|caps| unsafe { caps.as_ptr() }).unwrap_or(ptr::null_mut());
|
||||
|
||||
unsafe { gst_stream_set_caps(self.0, ptr as *mut c_void) }
|
||||
unsafe { gst::gst_stream_set_caps(self.0, ptr) }
|
||||
}
|
||||
|
||||
pub fn set_stream_flags(&self, flags: StreamFlags) {
|
||||
extern "C" {
|
||||
fn gst_stream_set_stream_flags(stream: *mut c_void, flags: u32);
|
||||
}
|
||||
|
||||
unsafe { gst_stream_set_stream_flags(self.0, flags.bits()) }
|
||||
unsafe { gst::gst_stream_set_stream_flags(self.0, mem::transmute(flags.bits())) }
|
||||
}
|
||||
|
||||
pub fn set_stream_type(&self, t: StreamType) {
|
||||
extern "C" {
|
||||
fn gst_stream_set_stream_type(stream: *mut c_void, t: u32);
|
||||
}
|
||||
|
||||
unsafe { gst_stream_set_stream_type(self.0, t.bits()) }
|
||||
unsafe { gst::gst_stream_set_stream_type(self.0, mem::transmute(t.bits())) }
|
||||
}
|
||||
|
||||
pub fn set_tags(&self, tags: Option<TagList>) {
|
||||
extern "C" {
|
||||
fn gst_stream_set_tags(stream: *mut c_void, tags: *mut c_void);
|
||||
}
|
||||
|
||||
let ptr = tags.map(|tags| unsafe { tags.as_ptr() }).unwrap_or(ptr::null_mut());
|
||||
|
||||
unsafe { gst_stream_set_tags(self.0, ptr as *mut c_void) }
|
||||
unsafe { gst::gst_stream_set_tags(self.0, ptr) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Stream {
|
||||
fn clone(&self) -> Self {
|
||||
extern "C" {
|
||||
fn gst_object_ref(object: *mut c_void) -> *mut c_void;
|
||||
}
|
||||
|
||||
unsafe { Stream(gst_object_ref(self.0)) }
|
||||
unsafe { Stream(gst::gst_object_ref(self.0 as *mut gst::GstObject) as *mut gst::GstStream) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Stream {
|
||||
fn drop(&mut self) {
|
||||
extern "C" {
|
||||
fn gst_object_unref(object: *mut c_void);
|
||||
}
|
||||
|
||||
unsafe { gst_object_unref(self.0) }
|
||||
unsafe { gst::gst_object_unref(self.0 as *mut gst::GstObject) }
|
||||
}
|
||||
}
|
||||
|
||||
impl StreamCollection {
|
||||
pub fn new(upstream_id: &str, streams: &[Stream]) -> Self {
|
||||
extern "C" {
|
||||
fn gst_stream_collection_new(upstream_id: *const c_char) -> *mut c_void;
|
||||
fn gst_stream_collection_add_stream(collection: *mut c_void, stream: *mut c_void);
|
||||
}
|
||||
|
||||
let upstream_id_cstr = CString::new(upstream_id).unwrap();
|
||||
let collection =
|
||||
StreamCollection(unsafe { gst_stream_collection_new(upstream_id_cstr.as_ptr()) });
|
||||
StreamCollection(unsafe { gst::gst_stream_collection_new(upstream_id_cstr.as_ptr()) });
|
||||
|
||||
for stream in streams {
|
||||
unsafe { gst_stream_collection_add_stream(collection.0, stream.clone().0) }
|
||||
unsafe { gst::gst_stream_collection_add_stream(collection.0, stream.clone().0) };
|
||||
}
|
||||
|
||||
collection
|
||||
|
@ -194,11 +143,7 @@ impl StreamCollection {
|
|||
}
|
||||
|
||||
pub fn len(&self) -> u32 {
|
||||
extern "C" {
|
||||
fn gst_stream_collection_get_size(collection: *mut c_void) -> u32;
|
||||
}
|
||||
|
||||
unsafe { gst_stream_collection_get_size(self.0) }
|
||||
unsafe { gst::gst_stream_collection_get_size(self.0) }
|
||||
}
|
||||
|
||||
pub fn empty(&self) -> bool {
|
||||
|
@ -206,15 +151,11 @@ impl StreamCollection {
|
|||
}
|
||||
|
||||
pub fn get_upstream_id(&self) -> &str {
|
||||
extern "C" {
|
||||
fn gst_stream_collection_get_upstream_id(collection: *mut c_void) -> *mut c_char;
|
||||
}
|
||||
|
||||
let cstr = unsafe { CStr::from_ptr(gst_stream_collection_get_upstream_id(self.0)) };
|
||||
let cstr = unsafe { CStr::from_ptr(gst::gst_stream_collection_get_upstream_id(self.0)) };
|
||||
cstr.to_str().unwrap()
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const c_void {
|
||||
pub unsafe fn as_ptr(&self) -> *const gst::GstStreamCollection {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
@ -239,44 +180,35 @@ impl<'a> Iterator for StreamCollectionIterator<'a> {
|
|||
type Item = Stream;
|
||||
|
||||
fn next(&mut self) -> Option<Stream> {
|
||||
extern "C" {
|
||||
fn gst_stream_collection_get_stream(collection: *mut c_void,
|
||||
index: u32)
|
||||
-> *mut c_void;
|
||||
fn gst_object_ref(object: *mut c_void) -> *mut c_void;
|
||||
}
|
||||
|
||||
if self.position == self.length {
|
||||
return None;
|
||||
}
|
||||
|
||||
let stream = unsafe { gst_stream_collection_get_stream(self.collection.0, self.position) };
|
||||
let stream =
|
||||
unsafe { gst::gst_stream_collection_get_stream(self.collection.0, self.position) };
|
||||
if stream.is_null() {
|
||||
self.position = self.length;
|
||||
return None;
|
||||
}
|
||||
self.position += 1;
|
||||
|
||||
Some(unsafe { Stream(gst_object_ref(stream)) })
|
||||
Some(unsafe {
|
||||
Stream(gst::gst_object_ref(stream as *mut gst::GstObject) as *mut gst::GstStream)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for StreamCollection {
|
||||
fn clone(&self) -> Self {
|
||||
extern "C" {
|
||||
fn gst_object_ref(object: *mut c_void) -> *mut c_void;
|
||||
unsafe {
|
||||
StreamCollection(gst::gst_object_ref(self.0 as *mut gst::GstObject) as
|
||||
*mut gst::GstStreamCollection)
|
||||
}
|
||||
|
||||
unsafe { StreamCollection(gst_object_ref(self.0)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for StreamCollection {
|
||||
fn drop(&mut self) {
|
||||
extern "C" {
|
||||
fn gst_object_unref(object: *mut c_void);
|
||||
}
|
||||
|
||||
unsafe { gst_object_unref(self.0) }
|
||||
unsafe { gst::gst_object_unref(self.0 as *mut gst::GstObject) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,16 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::os::raw::c_void;
|
||||
use std::fmt;
|
||||
use libc::c_char;
|
||||
use std::mem;
|
||||
use std::ffi::{CStr, CString};
|
||||
use utils::*;
|
||||
use value::*;
|
||||
use miniobject::*;
|
||||
|
||||
use glib;
|
||||
use gobject;
|
||||
use gst;
|
||||
|
||||
pub trait Tag {
|
||||
type TagType: ValueType;
|
||||
fn tag_name() -> &'static str;
|
||||
|
@ -44,9 +46,8 @@ impl_tag!(LanguageCode, String, "language-code");
|
|||
impl_tag!(Duration, u64, "duration");
|
||||
impl_tag!(NominalBitrate, u32, "nominal-bitrate");
|
||||
|
||||
#[repr(C)]
|
||||
pub enum MergeMode {
|
||||
ReplaceAll = 1,
|
||||
ReplaceAll,
|
||||
Replace,
|
||||
Append,
|
||||
Prepend,
|
||||
|
@ -54,91 +55,86 @@ pub enum MergeMode {
|
|||
KeepAll,
|
||||
}
|
||||
|
||||
impl MergeMode {
|
||||
fn to_ffi(&self) -> gst::GstTagMergeMode {
|
||||
match *self {
|
||||
MergeMode::ReplaceAll => gst::GST_TAG_MERGE_REPLACE_ALL,
|
||||
MergeMode::Replace => gst::GST_TAG_MERGE_REPLACE,
|
||||
MergeMode::Append => gst::GST_TAG_MERGE_APPEND,
|
||||
MergeMode::Prepend => gst::GST_TAG_MERGE_PREPEND,
|
||||
MergeMode::Keep => gst::GST_TAG_MERGE_KEEP,
|
||||
MergeMode::KeepAll => gst::GST_TAG_MERGE_KEEP_ALL,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq)]
|
||||
pub struct TagList(*mut c_void);
|
||||
pub struct TagList(*mut gst::GstTagList);
|
||||
|
||||
unsafe impl MiniObject for TagList {
|
||||
unsafe fn as_ptr(&self) -> *mut c_void {
|
||||
type PtrType = gst::GstTagList;
|
||||
|
||||
unsafe fn as_ptr(&self) -> *mut gst::GstTagList {
|
||||
self.0
|
||||
}
|
||||
|
||||
unsafe fn replace_ptr(&mut self, ptr: *mut c_void) {
|
||||
unsafe fn replace_ptr(&mut self, ptr: *mut gst::GstTagList) {
|
||||
self.0 = ptr
|
||||
}
|
||||
|
||||
unsafe fn new_from_ptr(ptr: *mut c_void) -> Self {
|
||||
unsafe fn new_from_ptr(ptr: *mut gst::GstTagList) -> Self {
|
||||
TagList(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl TagList {
|
||||
pub fn new() -> GstRc<Self> {
|
||||
extern "C" {
|
||||
fn gst_tag_list_new_empty() -> *mut c_void;
|
||||
}
|
||||
|
||||
unsafe { GstRc::new_from_owned_ptr(gst_tag_list_new_empty()) }
|
||||
unsafe { GstRc::new_from_owned_ptr(gst::gst_tag_list_new_empty()) }
|
||||
}
|
||||
|
||||
pub fn add<T: Tag>(&mut self, value: T::TagType, mode: MergeMode)
|
||||
where Value: From<<T as Tag>::TagType>
|
||||
{
|
||||
extern "C" {
|
||||
fn gst_tag_list_add_value(list: *mut c_void,
|
||||
mode: u32,
|
||||
tag: *const c_char,
|
||||
value: *const GValue);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let v = Value::from(value);
|
||||
let gvalue = v.to_gvalue();
|
||||
let mut gvalue = v.to_gvalue();
|
||||
let tag_name = CString::new(T::tag_name()).unwrap();
|
||||
|
||||
unsafe {
|
||||
gst_tag_list_add_value(self.0,
|
||||
mode as u32,
|
||||
tag_name.as_ptr(),
|
||||
&gvalue as *const GValue);
|
||||
gst::gst_tag_list_add_value(self.0, mode.to_ffi(), tag_name.as_ptr(), &gvalue);
|
||||
|
||||
gobject::g_value_unset(&mut gvalue);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<T: Tag>(&self) -> Option<TypedValue<T::TagType>>
|
||||
where Value: From<<T as Tag>::TagType>
|
||||
{
|
||||
extern "C" {
|
||||
fn gst_tag_list_copy_value(value: *mut GValue,
|
||||
list: *mut c_void,
|
||||
tag: *const c_char)
|
||||
-> GBoolean;
|
||||
}
|
||||
|
||||
let mut gvalue = GValue::new();
|
||||
unsafe {
|
||||
let mut gvalue = mem::zeroed();
|
||||
let tag_name = CString::new(T::tag_name()).unwrap();
|
||||
|
||||
let found = unsafe {
|
||||
gst_tag_list_copy_value(&mut gvalue as *mut GValue, self.0, tag_name.as_ptr())
|
||||
};
|
||||
let found = gst::gst_tag_list_copy_value(&mut gvalue, self.0, tag_name.as_ptr());
|
||||
|
||||
if !found.to_bool() {
|
||||
if found == glib::GFALSE {
|
||||
return None;
|
||||
}
|
||||
|
||||
match Value::from_gvalue(&gvalue) {
|
||||
let res = match Value::from_gvalue(&gvalue) {
|
||||
Some(value) => Some(TypedValue::new(value)),
|
||||
None => None,
|
||||
};
|
||||
|
||||
gobject::g_value_unset(&mut gvalue);
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
extern "C" {
|
||||
fn gst_tag_list_to_string(tag_list: *mut c_void) -> *mut c_char;
|
||||
fn g_free(ptr: *mut c_char);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let ptr = gst_tag_list_to_string(self.0);
|
||||
let ptr = gst::gst_tag_list_to_string(self.0);
|
||||
let s = CStr::from_ptr(ptr).to_str().unwrap().into();
|
||||
g_free(ptr);
|
||||
glib::g_free(ptr as glib::gpointer);
|
||||
|
||||
s
|
||||
}
|
||||
|
@ -153,11 +149,7 @@ impl fmt::Debug for TagList {
|
|||
|
||||
impl PartialEq for TagList {
|
||||
fn eq(&self, other: &TagList) -> bool {
|
||||
extern "C" {
|
||||
fn gst_tag_list_is_equal(a: *const c_void, b: *const c_void) -> GBoolean;
|
||||
}
|
||||
|
||||
unsafe { gst_tag_list_is_equal(self.0, other.0).to_bool() }
|
||||
(unsafe { gst::gst_tag_list_is_equal(self.0, other.0) } == glib::GTRUE)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,15 +160,10 @@ unsafe impl Send for TagList {}
|
|||
mod tests {
|
||||
use super::*;
|
||||
use std::ptr;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
fn init() {
|
||||
extern "C" {
|
||||
fn gst_init(argc: *mut c_void, argv: *mut c_void);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
gst_init(ptr::null_mut(), ptr::null_mut());
|
||||
gst::gst_init(ptr::null_mut(), ptr::null_mut());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
// except according to those terms.
|
||||
|
||||
use libc::c_char;
|
||||
use std::os::raw::c_void;
|
||||
use std::ffi::CString;
|
||||
use std::i32;
|
||||
use num_rational::Rational32;
|
||||
|
||||
use gst;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum GstFlowReturn {
|
||||
|
@ -23,53 +24,28 @@ pub enum GstFlowReturn {
|
|||
Error = -5,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum GBoolean {
|
||||
False = 0,
|
||||
True = 1,
|
||||
}
|
||||
|
||||
impl GBoolean {
|
||||
pub fn from_bool(v: bool) -> GBoolean {
|
||||
if v { GBoolean::True } else { GBoolean::False }
|
||||
}
|
||||
|
||||
pub fn to_bool(&self) -> bool {
|
||||
!(*self == GBoolean::False)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Element(*const c_void);
|
||||
pub struct Element(*mut gst::GstElement);
|
||||
|
||||
impl Element {
|
||||
pub unsafe fn new(element: *const c_void) -> Element {
|
||||
extern "C" {
|
||||
fn gst_object_ref(object: *const c_void) -> *const c_void;
|
||||
}
|
||||
|
||||
pub unsafe fn new(element: *mut gst::GstElement) -> Element {
|
||||
if element.is_null() {
|
||||
panic!("NULL not allowed");
|
||||
}
|
||||
|
||||
gst_object_ref(element);
|
||||
gst::gst_object_ref(element as *mut gst::GstObject);
|
||||
|
||||
Element(element)
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const c_void {
|
||||
pub unsafe fn as_ptr(&self) -> *mut gst::GstElement {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Element {
|
||||
fn drop(&mut self) {
|
||||
extern "C" {
|
||||
fn gst_object_unref(object: *const c_void);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
gst_object_unref(self.0);
|
||||
gst::gst_object_unref(self.0 as *mut gst::GstObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use libc::c_char;
|
||||
use std::os::raw::c_void;
|
||||
use std::ffi::{CString, CStr};
|
||||
use std::mem;
|
||||
use std::marker::PhantomData;
|
||||
|
@ -18,6 +16,10 @@ pub use num_rational::Rational32;
|
|||
use buffer::*;
|
||||
use miniobject::*;
|
||||
|
||||
use glib;
|
||||
use gobject;
|
||||
use gst;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Value {
|
||||
Bool(bool),
|
||||
|
@ -58,145 +60,76 @@ impl_value_type!(Rational32, Fraction);
|
|||
impl_value_type!(GstRc<Buffer>, Buffer);
|
||||
impl_value_type!(Vec<Value>, Array);
|
||||
|
||||
#[repr(C)]
|
||||
pub struct GValue {
|
||||
typ: usize,
|
||||
data: [u64; 2],
|
||||
}
|
||||
|
||||
impl GValue {
|
||||
pub fn new() -> GValue {
|
||||
unsafe { mem::zeroed() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for GValue {
|
||||
fn drop(&mut self) {
|
||||
extern "C" {
|
||||
fn g_value_unset(value: *mut GValue);
|
||||
}
|
||||
|
||||
if self.typ != 0 {
|
||||
unsafe { g_value_unset(self as *mut GValue) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See gtype.h
|
||||
const TYPE_BOOLEAN: usize = (5 << 2);
|
||||
const TYPE_INT: usize = (6 << 2);
|
||||
const TYPE_UINT: usize = (7 << 2);
|
||||
const TYPE_INT64: usize = (10 << 2);
|
||||
const TYPE_UINT64: usize = (11 << 2);
|
||||
const TYPE_STRING: usize = (16 << 2);
|
||||
|
||||
extern "C" {
|
||||
fn gst_buffer_get_type() -> usize;
|
||||
fn gst_fraction_get_type() -> usize;
|
||||
fn gst_value_array_get_type() -> usize;
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref TYPE_BUFFER: usize = unsafe { gst_buffer_get_type() };
|
||||
static ref TYPE_FRACTION: usize = unsafe { gst_fraction_get_type() };
|
||||
static ref TYPE_GST_VALUE_ARRAY: usize = unsafe { gst_value_array_get_type() };
|
||||
static ref TYPE_BUFFER: glib::GType = unsafe { gst::gst_buffer_get_type() };
|
||||
static ref TYPE_FRACTION: glib::GType = unsafe { gst::gst_fraction_get_type() };
|
||||
static ref TYPE_GST_VALUE_ARRAY: glib::GType = unsafe { gst::gst_value_array_get_type() };
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn to_gvalue(&self) -> GValue {
|
||||
extern "C" {
|
||||
fn g_value_init(value: *mut GValue, gtype: usize);
|
||||
fn g_value_set_boolean(value: *mut GValue, value: i32);
|
||||
fn g_value_set_int(value: *mut GValue, value: i32);
|
||||
fn g_value_set_uint(value: *mut GValue, value: u32);
|
||||
fn g_value_set_int64(value: *mut GValue, value: i64);
|
||||
fn g_value_set_uint64(value: *mut GValue, value: u64);
|
||||
fn g_value_set_string(value: *mut GValue, value: *const c_char);
|
||||
fn gst_value_set_fraction(value: *mut GValue, value_n: i32, value_d: i32);
|
||||
fn g_value_set_boxed(value: *mut GValue, boxed: *const c_void);
|
||||
fn gst_value_array_append_and_take_value(value: *mut GValue, element: *mut GValue);
|
||||
}
|
||||
|
||||
let mut gvalue = GValue::new();
|
||||
pub unsafe fn to_gvalue(&self) -> gobject::GValue {
|
||||
let mut gvalue = mem::zeroed();
|
||||
|
||||
match *self {
|
||||
Value::Bool(v) => unsafe {
|
||||
g_value_init(&mut gvalue as *mut GValue, TYPE_BOOLEAN);
|
||||
g_value_set_boolean(&mut gvalue as *mut GValue, if v { 1 } else { 0 });
|
||||
},
|
||||
Value::Int(v) => unsafe {
|
||||
g_value_init(&mut gvalue as *mut GValue, TYPE_INT);
|
||||
g_value_set_int(&mut gvalue as *mut GValue, v);
|
||||
},
|
||||
Value::UInt(v) => unsafe {
|
||||
g_value_init(&mut gvalue as *mut GValue, TYPE_UINT);
|
||||
g_value_set_uint(&mut gvalue as *mut GValue, v);
|
||||
},
|
||||
Value::Int64(v) => unsafe {
|
||||
g_value_init(&mut gvalue as *mut GValue, TYPE_INT64);
|
||||
g_value_set_int64(&mut gvalue as *mut GValue, v);
|
||||
},
|
||||
Value::UInt64(v) => unsafe {
|
||||
g_value_init(&mut gvalue as *mut GValue, TYPE_UINT64);
|
||||
g_value_set_uint64(&mut gvalue as *mut GValue, v);
|
||||
},
|
||||
Value::String(ref v) => unsafe {
|
||||
Value::Bool(v) => {
|
||||
gobject::g_value_init(&mut gvalue, gobject::G_TYPE_BOOLEAN);
|
||||
gobject::g_value_set_boolean(&mut gvalue,
|
||||
if v { glib::GTRUE } else { glib::GFALSE });
|
||||
}
|
||||
Value::Int(v) => {
|
||||
gobject::g_value_init(&mut gvalue, gobject::G_TYPE_INT);
|
||||
gobject::g_value_set_int(&mut gvalue, v);
|
||||
}
|
||||
Value::UInt(v) => {
|
||||
gobject::g_value_init(&mut gvalue, gobject::G_TYPE_UINT);
|
||||
gobject::g_value_set_uint(&mut gvalue, v);
|
||||
}
|
||||
Value::Int64(v) => {
|
||||
gobject::g_value_init(&mut gvalue, gobject::G_TYPE_INT64);
|
||||
gobject::g_value_set_int64(&mut gvalue, v);
|
||||
}
|
||||
Value::UInt64(v) => {
|
||||
gobject::g_value_init(&mut gvalue, gobject::G_TYPE_UINT64);
|
||||
gobject::g_value_set_uint64(&mut gvalue, v);
|
||||
}
|
||||
Value::String(ref v) => {
|
||||
let v_cstr = CString::new(String::from(v.clone())).unwrap();
|
||||
|
||||
g_value_init(&mut gvalue as *mut GValue, TYPE_STRING);
|
||||
g_value_set_string(&mut gvalue as *mut GValue, v_cstr.as_ptr());
|
||||
},
|
||||
Value::Fraction(ref v) => unsafe {
|
||||
g_value_init(&mut gvalue as *mut GValue, *TYPE_FRACTION);
|
||||
gst_value_set_fraction(&mut gvalue as *mut GValue, *v.numer(), *v.denom());
|
||||
},
|
||||
Value::Buffer(ref buffer) => unsafe {
|
||||
g_value_init(&mut gvalue as *mut GValue, *TYPE_BUFFER);
|
||||
g_value_set_boxed(&mut gvalue as *mut GValue, buffer.as_ptr());
|
||||
},
|
||||
Value::Array(ref array) => unsafe {
|
||||
g_value_init(&mut gvalue as *mut GValue, *TYPE_GST_VALUE_ARRAY);
|
||||
gobject::g_value_init(&mut gvalue, gobject::G_TYPE_STRING);
|
||||
gobject::g_value_set_string(&mut gvalue, v_cstr.as_ptr());
|
||||
}
|
||||
Value::Fraction(ref v) => {
|
||||
gobject::g_value_init(&mut gvalue, *TYPE_FRACTION);
|
||||
gst::gst_value_set_fraction(&mut gvalue, *v.numer(), *v.denom());
|
||||
}
|
||||
Value::Buffer(ref buffer) => {
|
||||
gobject::g_value_init(&mut gvalue, *TYPE_BUFFER);
|
||||
gobject::g_value_set_boxed(&mut gvalue, buffer.as_ptr() as glib::gconstpointer);
|
||||
}
|
||||
Value::Array(ref array) => {
|
||||
gobject::g_value_init(&mut gvalue, *TYPE_GST_VALUE_ARRAY);
|
||||
|
||||
for e in array {
|
||||
let mut e_value = e.to_gvalue();
|
||||
gst_value_array_append_and_take_value(&mut gvalue as *mut GValue,
|
||||
&mut e_value as *mut GValue);
|
||||
// Takes ownership, invalidate GValue
|
||||
e_value.typ = 0;
|
||||
gst::gst_value_array_append_and_take_value(&mut gvalue, &mut e_value);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
gvalue
|
||||
}
|
||||
|
||||
pub fn from_gvalue(gvalue: &GValue) -> Option<Self> {
|
||||
extern "C" {
|
||||
fn g_value_get_boolean(value: *const GValue) -> i32;
|
||||
fn g_value_get_int(value: *const GValue) -> i32;
|
||||
fn g_value_get_uint(value: *const GValue) -> u32;
|
||||
fn g_value_get_int64(value: *const GValue) -> i64;
|
||||
fn g_value_get_uint64(value: *const GValue) -> u64;
|
||||
fn g_value_get_string(value: *const GValue) -> *const c_char;
|
||||
fn gst_value_get_fraction_numerator(value: *const GValue) -> i32;
|
||||
fn gst_value_get_fraction_denominator(value: *const GValue) -> i32;
|
||||
fn g_value_get_boxed(value: *const GValue) -> *mut c_void;
|
||||
fn gst_value_array_get_size(value: *const GValue) -> u32;
|
||||
fn gst_value_array_get_value(value: *const GValue, index: u32) -> *const GValue;
|
||||
pub unsafe fn from_gvalue(gvalue: &gobject::GValue) -> Option<Self> {
|
||||
match gvalue.g_type {
|
||||
gobject::G_TYPE_BOOLEAN => {
|
||||
Some(Value::Bool(!(gobject::g_value_get_boolean(gvalue) == 0)))
|
||||
}
|
||||
|
||||
match gvalue.typ {
|
||||
TYPE_BOOLEAN => unsafe {
|
||||
Some(Value::Bool(!(g_value_get_boolean(gvalue as *const GValue) == 0)))
|
||||
},
|
||||
TYPE_INT => unsafe { Some(Value::Int(g_value_get_int(gvalue as *const GValue))) },
|
||||
TYPE_UINT => unsafe { Some(Value::UInt(g_value_get_uint(gvalue as *const GValue))) },
|
||||
TYPE_INT64 => unsafe { Some(Value::Int64(g_value_get_int64(gvalue as *const GValue))) },
|
||||
TYPE_UINT64 => unsafe {
|
||||
Some(Value::UInt64(g_value_get_uint64(gvalue as *const GValue)))
|
||||
},
|
||||
TYPE_STRING => unsafe {
|
||||
let s = g_value_get_string(gvalue as *const GValue);
|
||||
gobject::G_TYPE_INT => Some(Value::Int(gobject::g_value_get_int(gvalue))),
|
||||
gobject::G_TYPE_UINT => Some(Value::UInt(gobject::g_value_get_uint(gvalue))),
|
||||
gobject::G_TYPE_INT64 => Some(Value::Int64(gobject::g_value_get_int64(gvalue))),
|
||||
gobject::G_TYPE_UINT64 => Some(Value::UInt64(gobject::g_value_get_uint64(gvalue))),
|
||||
gobject::G_TYPE_STRING => {
|
||||
let s = gobject::g_value_get_string(gvalue);
|
||||
if s.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
@ -206,29 +139,29 @@ impl Value {
|
|||
Err(_) => None,
|
||||
Ok(s) => Some(Value::String(s.into())),
|
||||
}
|
||||
},
|
||||
typ if typ == *TYPE_FRACTION => unsafe {
|
||||
let n = gst_value_get_fraction_numerator(gvalue as *const GValue);
|
||||
let d = gst_value_get_fraction_denominator(gvalue as *const GValue);
|
||||
}
|
||||
typ if typ == *TYPE_FRACTION => {
|
||||
let n = gst::gst_value_get_fraction_numerator(gvalue);
|
||||
let d = gst::gst_value_get_fraction_denominator(gvalue);
|
||||
|
||||
Some(Value::Fraction(Rational32::new(n, d)))
|
||||
},
|
||||
typ if typ == *TYPE_BUFFER => unsafe {
|
||||
let b = g_value_get_boxed(gvalue as *const GValue);
|
||||
}
|
||||
typ if typ == *TYPE_BUFFER => {
|
||||
let b = gobject::g_value_get_boxed(gvalue);
|
||||
|
||||
if b.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Value::Buffer(GstRc::new_from_unowned_ptr(b)))
|
||||
},
|
||||
typ if typ == *TYPE_GST_VALUE_ARRAY => unsafe {
|
||||
let n = gst_value_array_get_size(gvalue as *const GValue);
|
||||
Some(Value::Buffer(GstRc::new_from_unowned_ptr(b as *mut gst::GstBuffer)))
|
||||
}
|
||||
typ if typ == *TYPE_GST_VALUE_ARRAY => {
|
||||
let n = gst::gst_value_array_get_size(gvalue);
|
||||
|
||||
let mut vec = Vec::with_capacity(n as usize);
|
||||
|
||||
for i in 0..n {
|
||||
let val = gst_value_array_get_value(gvalue as *const GValue, i);
|
||||
let val = gst::gst_value_array_get_value(gvalue, i);
|
||||
|
||||
if val.is_null() {
|
||||
return None;
|
||||
|
@ -242,7 +175,7 @@ impl Value {
|
|||
}
|
||||
|
||||
Some(Value::Array(vec))
|
||||
},
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue