Port everything else over to glib/gobject/gstreamer-sys

This commit is contained in:
Sebastian Dröge 2017-04-10 00:29:07 +03:00
parent e4ababa98f
commit 24a10bb614
19 changed files with 509 additions and 751 deletions

View file

@ -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]

View file

@ -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");

View file

@ -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());
}
}

View file

@ -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);
}
}
}

View file

@ -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());
}
}

View file

@ -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();

View file

@ -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);
}

View file

@ -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,
error_domain,
error_code,
message_ptr,
debug_ptr,
file_ptr,
function_ptr,
line);
gst::gst_element_message_full(element,
gst::GST_MESSAGE_ERROR,
error_domain,
error_code,
glib::g_strdup(message_ptr),
glib::g_strdup(debug_ptr),
file_ptr,
function_ptr,
line as i32);
}
}
@ -233,27 +216,18 @@ 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(),
self.error_kind as i32,
cmsg.as_ptr());
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(),
self.error_kind as i32,
ptr::null());
glib::g_set_error_literal(err,
gst::gst_uri_error_quark(),
self.error_kind as i32,
ptr::null());
}
}
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}
unsafe {
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,
level,
file_cstr.as_ptr(),
function_cstr.as_ptr(),
record.line(),
element,
message_cstr.as_ptr());
gst::gst_debug_log(self.category,
level,
file_cstr.as_ptr(),
function_cstr.as_ptr(),
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);
}
}

View file

@ -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())
}
}

View file

@ -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
}
}
}
};

View file

@ -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();

View file

@ -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
});
}
}

View file

@ -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) }
}
}

View file

@ -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);
}
let v = Value::from(value);
let 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);
let v = Value::from(value);
let mut gvalue = v.to_gvalue();
let tag_name = CString::new(T::tag_name()).unwrap();
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;
}
unsafe {
let mut gvalue = mem::zeroed();
let tag_name = CString::new(T::tag_name()).unwrap();
let mut gvalue = GValue::new();
let tag_name = CString::new(T::tag_name()).unwrap();
let found = gst::gst_tag_list_copy_value(&mut gvalue, self.0, tag_name.as_ptr());
let found = unsafe {
gst_tag_list_copy_value(&mut gvalue as *mut GValue, self.0, tag_name.as_ptr())
};
if found == glib::GFALSE {
return None;
}
if !found.to_bool() {
return None;
}
let res = match Value::from_gvalue(&gvalue) {
Some(value) => Some(TypedValue::new(value)),
None => None,
};
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());
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
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);
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)))
}
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,
}
}