mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-06-16 13:10:34 +00:00
Never let panics propagate to C and instead convert them to error messages
This commit is contained in:
parent
95dd469fbf
commit
f9adac5f7e
35
src/error.rs
35
src/error.rs
|
@ -293,3 +293,38 @@ impl Error for UriError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type UriValidator = Fn(&Url) -> Result<(), UriError>;
|
pub type UriValidator = Fn(&Url) -> Result<(), UriError>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PanicError;
|
||||||
|
|
||||||
|
impl ToGError for PanicError {
|
||||||
|
fn to_gerror(&self) -> (u32, i32) {
|
||||||
|
(gst_library_error_domain(), 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! panic_to_error(
|
||||||
|
($wrap:expr, $ret:expr, $code:block) => {{
|
||||||
|
if $wrap.panicked.load(Ordering::Relaxed) {
|
||||||
|
error_msg!(PanicError, ["Panicked"]).post($wrap.raw);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = panic::catch_unwind(AssertUnwindSafe(|| $code));
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(err) => {
|
||||||
|
$wrap.panicked.store(true, Ordering::Relaxed);
|
||||||
|
if let Some(cause) = err.downcast_ref::<&str>() {
|
||||||
|
error_msg!(PanicError, ["Panicked: {}", cause]).post($wrap.raw);
|
||||||
|
} else if let Some(cause) = err.downcast_ref::<String>() {
|
||||||
|
error_msg!(PanicError, ["Panicked: {}", cause]).post($wrap.raw);
|
||||||
|
} else {
|
||||||
|
error_msg!(PanicError, ["Panicked"]).post($wrap.raw);
|
||||||
|
}
|
||||||
|
$ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
|
166
src/rssink.rs
166
src/rssink.rs
|
@ -22,7 +22,10 @@ use std::ffi::{CStr, CString};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
use std::panic::{self, AssertUnwindSafe};
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -51,10 +54,11 @@ impl ToGError for SinkError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SinkWrapper {
|
pub struct SinkWrapper {
|
||||||
sink_raw: *mut c_void,
|
raw: *mut c_void,
|
||||||
uri: Mutex<(Option<Url>, bool)>,
|
uri: Mutex<(Option<Url>, bool)>,
|
||||||
uri_validator: Box<UriValidator>,
|
uri_validator: Box<UriValidator>,
|
||||||
sink: Mutex<Box<Sink>>,
|
sink: Mutex<Box<Sink>>,
|
||||||
|
panicked: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Sink {
|
pub trait Sink {
|
||||||
|
@ -67,12 +71,13 @@ pub trait Sink {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SinkWrapper {
|
impl SinkWrapper {
|
||||||
fn new(sink_raw: *mut c_void, sink: Box<Sink>) -> SinkWrapper {
|
fn new(raw: *mut c_void, sink: Box<Sink>) -> SinkWrapper {
|
||||||
SinkWrapper {
|
SinkWrapper {
|
||||||
sink_raw: sink_raw,
|
raw: raw,
|
||||||
uri: Mutex::new((None, false)),
|
uri: Mutex::new((None, false)),
|
||||||
uri_validator: sink.uri_validator(),
|
uri_validator: sink.uri_validator(),
|
||||||
sink: Mutex::new(sink),
|
sink: Mutex::new(sink),
|
||||||
|
panicked: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,96 +100,107 @@ pub unsafe extern "C" fn sink_set_uri(ptr: *const SinkWrapper,
|
||||||
cerr: *mut c_void)
|
cerr: *mut c_void)
|
||||||
-> GBoolean {
|
-> GBoolean {
|
||||||
let wrap: &SinkWrapper = &*ptr;
|
let wrap: &SinkWrapper = &*ptr;
|
||||||
let uri_storage = &mut wrap.uri.lock().unwrap();
|
|
||||||
|
|
||||||
if uri_storage.1 {
|
panic_to_error!(wrap, GBoolean::False, {
|
||||||
UriError::new(UriErrorKind::BadState, Some("Already started".to_string()))
|
let uri_storage = &mut wrap.uri.lock().unwrap();
|
||||||
.into_gerror(cerr);
|
|
||||||
return GBoolean::False;
|
|
||||||
}
|
|
||||||
|
|
||||||
uri_storage.0 = None;
|
if uri_storage.1 {
|
||||||
if uri_ptr.is_null() {
|
UriError::new(UriErrorKind::BadState, Some("Already started".to_string()))
|
||||||
GBoolean::True
|
.into_gerror(cerr);
|
||||||
} else {
|
return GBoolean::False;
|
||||||
let uri_str = CStr::from_ptr(uri_ptr).to_str().unwrap();
|
}
|
||||||
|
|
||||||
match Url::parse(uri_str) {
|
uri_storage.0 = None;
|
||||||
Ok(uri) => {
|
if uri_ptr.is_null() {
|
||||||
if let Err(err) = (*wrap.uri_validator)(&uri) {
|
GBoolean::True
|
||||||
err.into_gerror(cerr);
|
} else {
|
||||||
|
let uri_str = CStr::from_ptr(uri_ptr).to_str().unwrap();
|
||||||
|
|
||||||
|
match Url::parse(uri_str) {
|
||||||
|
Ok(uri) => {
|
||||||
|
if let Err(err) = (*wrap.uri_validator)(&uri) {
|
||||||
|
err.into_gerror(cerr);
|
||||||
|
|
||||||
|
GBoolean::False
|
||||||
|
} else {
|
||||||
|
uri_storage.0 = Some(uri);
|
||||||
|
|
||||||
|
GBoolean::True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
UriError::new(UriErrorKind::BadUri,
|
||||||
|
Some(format!("Failed to parse URI '{}': {}", uri_str, err)))
|
||||||
|
.into_gerror(cerr);
|
||||||
|
|
||||||
GBoolean::False
|
GBoolean::False
|
||||||
} else {
|
|
||||||
uri_storage.0 = Some(uri);
|
|
||||||
|
|
||||||
GBoolean::True
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
|
||||||
UriError::new(UriErrorKind::BadUri,
|
|
||||||
Some(format!("Failed to parse URI '{}': {}", uri_str, err)))
|
|
||||||
.into_gerror(cerr);
|
|
||||||
|
|
||||||
GBoolean::False
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sink_get_uri(ptr: *const SinkWrapper) -> *mut c_char {
|
pub unsafe extern "C" fn sink_get_uri(ptr: *const SinkWrapper) -> *mut c_char {
|
||||||
let wrap: &SinkWrapper = &*ptr;
|
let wrap: &SinkWrapper = &*ptr;
|
||||||
let uri_storage = &mut wrap.uri.lock().unwrap();
|
|
||||||
|
|
||||||
match uri_storage.0 {
|
panic_to_error!(wrap, ptr::null_mut(), {
|
||||||
Some(ref uri) => CString::new(uri.as_ref().as_bytes()).unwrap().into_raw(),
|
let uri_storage = &mut wrap.uri.lock().unwrap();
|
||||||
None => ptr::null_mut(),
|
|
||||||
}
|
match uri_storage.0 {
|
||||||
|
Some(ref uri) => CString::new(uri.as_ref().as_bytes()).unwrap().into_raw(),
|
||||||
|
None => ptr::null_mut(),
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sink_start(ptr: *const SinkWrapper) -> GBoolean {
|
pub unsafe extern "C" fn sink_start(ptr: *const SinkWrapper) -> GBoolean {
|
||||||
let wrap: &SinkWrapper = &*ptr;
|
let wrap: &SinkWrapper = &*ptr;
|
||||||
let sink = &mut wrap.sink.lock().unwrap();
|
|
||||||
|
|
||||||
let uri = match *wrap.uri.lock().unwrap() {
|
panic_to_error!(wrap, GBoolean::False, {
|
||||||
(Some(ref uri), ref mut started) => {
|
let sink = &mut wrap.sink.lock().unwrap();
|
||||||
*started = true;
|
|
||||||
|
|
||||||
uri.clone()
|
let uri = match *wrap.uri.lock().unwrap() {
|
||||||
}
|
(Some(ref uri), ref mut started) => {
|
||||||
(None, _) => {
|
*started = true;
|
||||||
error_msg!(SinkError::OpenFailed, ["No URI given"]).post(wrap.sink_raw);
|
|
||||||
return GBoolean::False;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match sink.start(uri) {
|
uri.clone()
|
||||||
Ok(..) => GBoolean::True,
|
}
|
||||||
Err(ref msg) => {
|
(None, _) => {
|
||||||
wrap.uri.lock().unwrap().1 = false;
|
error_msg!(SinkError::OpenFailed, ["No URI given"]).post(wrap.raw);
|
||||||
msg.post(wrap.sink_raw);
|
return GBoolean::False;
|
||||||
GBoolean::False
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match sink.start(uri) {
|
||||||
|
Ok(..) => GBoolean::True,
|
||||||
|
Err(ref msg) => {
|
||||||
|
wrap.uri.lock().unwrap().1 = false;
|
||||||
|
msg.post(wrap.raw);
|
||||||
|
GBoolean::False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sink_stop(ptr: *const SinkWrapper) -> GBoolean {
|
pub unsafe extern "C" fn sink_stop(ptr: *const SinkWrapper) -> GBoolean {
|
||||||
let wrap: &SinkWrapper = &*ptr;
|
let wrap: &SinkWrapper = &*ptr;
|
||||||
let sink = &mut wrap.sink.lock().unwrap();
|
panic_to_error!(wrap, GBoolean::False, {
|
||||||
|
let sink = &mut wrap.sink.lock().unwrap();
|
||||||
|
|
||||||
match sink.stop() {
|
match sink.stop() {
|
||||||
Ok(..) => {
|
Ok(..) => {
|
||||||
wrap.uri.lock().unwrap().1 = false;
|
wrap.uri.lock().unwrap().1 = false;
|
||||||
GBoolean::True
|
GBoolean::True
|
||||||
|
}
|
||||||
|
Err(ref msg) => {
|
||||||
|
msg.post(wrap.raw);
|
||||||
|
GBoolean::False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(ref msg) => {
|
})
|
||||||
msg.post(wrap.sink_raw);
|
|
||||||
GBoolean::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -193,18 +209,20 @@ pub unsafe extern "C" fn sink_render(ptr: *const SinkWrapper,
|
||||||
data_len: usize)
|
data_len: usize)
|
||||||
-> GstFlowReturn {
|
-> GstFlowReturn {
|
||||||
let wrap: &SinkWrapper = &*ptr;
|
let wrap: &SinkWrapper = &*ptr;
|
||||||
let sink = &mut wrap.sink.lock().unwrap();
|
panic_to_error!(wrap, GstFlowReturn::Error, {
|
||||||
let data = slice::from_raw_parts(data_ptr, data_len);
|
let sink = &mut wrap.sink.lock().unwrap();
|
||||||
|
let data = slice::from_raw_parts(data_ptr, data_len);
|
||||||
|
|
||||||
match sink.render(data) {
|
match sink.render(data) {
|
||||||
Ok(..) => GstFlowReturn::Ok,
|
Ok(..) => GstFlowReturn::Ok,
|
||||||
Err(flow_error) => {
|
Err(flow_error) => {
|
||||||
match flow_error {
|
match flow_error {
|
||||||
FlowError::NotNegotiated(ref msg) |
|
FlowError::NotNegotiated(ref msg) |
|
||||||
FlowError::Error(ref msg) => msg.post(wrap.sink_raw),
|
FlowError::Error(ref msg) => msg.post(wrap.raw),
|
||||||
_ => (),
|
_ => (),
|
||||||
|
}
|
||||||
|
flow_error.to_native()
|
||||||
}
|
}
|
||||||
flow_error.to_native()
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
212
src/rssource.rs
212
src/rssource.rs
|
@ -22,7 +22,10 @@ use std::slice;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::u64;
|
use std::u64;
|
||||||
|
|
||||||
|
use std::panic::{self, AssertUnwindSafe};
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -51,10 +54,11 @@ impl ToGError for SourceError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SourceWrapper {
|
pub struct SourceWrapper {
|
||||||
source_raw: *mut c_void,
|
raw: *mut c_void,
|
||||||
uri: Mutex<(Option<Url>, bool)>,
|
uri: Mutex<(Option<Url>, bool)>,
|
||||||
uri_validator: Box<UriValidator>,
|
uri_validator: Box<UriValidator>,
|
||||||
source: Mutex<Box<Source>>,
|
source: Mutex<Box<Source>>,
|
||||||
|
panicked: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Source {
|
pub trait Source {
|
||||||
|
@ -70,12 +74,13 @@ pub trait Source {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SourceWrapper {
|
impl SourceWrapper {
|
||||||
fn new(source_raw: *mut c_void, source: Box<Source>) -> SourceWrapper {
|
fn new(raw: *mut c_void, source: Box<Source>) -> SourceWrapper {
|
||||||
SourceWrapper {
|
SourceWrapper {
|
||||||
source_raw: source_raw,
|
raw: raw,
|
||||||
uri: Mutex::new((None, false)),
|
uri: Mutex::new((None, false)),
|
||||||
uri_validator: source.uri_validator(),
|
uri_validator: source.uri_validator(),
|
||||||
source: Mutex::new(source),
|
source: Mutex::new(source),
|
||||||
|
panicked: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,115 +103,132 @@ pub unsafe extern "C" fn source_set_uri(ptr: *const SourceWrapper,
|
||||||
cerr: *mut c_void)
|
cerr: *mut c_void)
|
||||||
-> GBoolean {
|
-> GBoolean {
|
||||||
let wrap: &SourceWrapper = &*ptr;
|
let wrap: &SourceWrapper = &*ptr;
|
||||||
let uri_storage = &mut wrap.uri.lock().unwrap();
|
|
||||||
|
|
||||||
if uri_storage.1 {
|
panic_to_error!(wrap, GBoolean::False, {
|
||||||
UriError::new(UriErrorKind::BadState, Some("Already started".to_string()))
|
let uri_storage = &mut wrap.uri.lock().unwrap();
|
||||||
.into_gerror(cerr);
|
|
||||||
return GBoolean::False;
|
|
||||||
}
|
|
||||||
|
|
||||||
uri_storage.0 = None;
|
if uri_storage.1 {
|
||||||
if uri_ptr.is_null() {
|
UriError::new(UriErrorKind::BadState, Some("Already started".to_string()))
|
||||||
GBoolean::True
|
.into_gerror(cerr);
|
||||||
} else {
|
return GBoolean::False;
|
||||||
let uri_str = CStr::from_ptr(uri_ptr).to_str().unwrap();
|
}
|
||||||
|
|
||||||
match Url::parse(uri_str) {
|
uri_storage.0 = None;
|
||||||
Ok(uri) => {
|
if uri_ptr.is_null() {
|
||||||
if let Err(err) = (*wrap.uri_validator)(&uri) {
|
GBoolean::True
|
||||||
err.into_gerror(cerr);
|
} else {
|
||||||
|
let uri_str = CStr::from_ptr(uri_ptr).to_str().unwrap();
|
||||||
|
|
||||||
|
match Url::parse(uri_str) {
|
||||||
|
Ok(uri) => {
|
||||||
|
if let Err(err) = (*wrap.uri_validator)(&uri) {
|
||||||
|
err.into_gerror(cerr);
|
||||||
|
|
||||||
|
GBoolean::False
|
||||||
|
} else {
|
||||||
|
uri_storage.0 = Some(uri);
|
||||||
|
|
||||||
|
GBoolean::True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
UriError::new(UriErrorKind::BadUri,
|
||||||
|
Some(format!("Failed to parse URI '{}': {}", uri_str, err)))
|
||||||
|
.into_gerror(cerr);
|
||||||
|
|
||||||
GBoolean::False
|
GBoolean::False
|
||||||
} else {
|
|
||||||
uri_storage.0 = Some(uri);
|
|
||||||
|
|
||||||
GBoolean::True
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
|
||||||
UriError::new(UriErrorKind::BadUri,
|
|
||||||
Some(format!("Failed to parse URI '{}': {}", uri_str, err)))
|
|
||||||
.into_gerror(cerr);
|
|
||||||
|
|
||||||
GBoolean::False
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn source_get_uri(ptr: *const SourceWrapper) -> *mut c_char {
|
pub unsafe extern "C" fn source_get_uri(ptr: *const SourceWrapper) -> *mut c_char {
|
||||||
let wrap: &SourceWrapper = &*ptr;
|
let wrap: &SourceWrapper = &*ptr;
|
||||||
let uri_storage = &mut wrap.uri.lock().unwrap();
|
panic_to_error!(wrap, ptr::null_mut(), {
|
||||||
|
let uri_storage = &mut wrap.uri.lock().unwrap();
|
||||||
|
|
||||||
match uri_storage.0 {
|
match uri_storage.0 {
|
||||||
Some(ref uri) => CString::new(uri.as_ref().as_bytes()).unwrap().into_raw(),
|
Some(ref uri) => CString::new(uri.as_ref().as_bytes()).unwrap().into_raw(),
|
||||||
None => ptr::null_mut(),
|
None => ptr::null_mut(),
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[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) -> GBoolean {
|
||||||
let wrap: &SourceWrapper = &*ptr;
|
let wrap: &SourceWrapper = &*ptr;
|
||||||
let source = &wrap.source.lock().unwrap();
|
|
||||||
|
|
||||||
GBoolean::from_bool(source.is_seekable())
|
panic_to_error!(wrap, GBoolean::False, {
|
||||||
|
let source = &wrap.source.lock().unwrap();
|
||||||
|
|
||||||
|
GBoolean::from_bool(source.is_seekable())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn source_get_size(ptr: *const SourceWrapper) -> u64 {
|
pub unsafe extern "C" fn source_get_size(ptr: *const SourceWrapper) -> u64 {
|
||||||
let wrap: &SourceWrapper = &*ptr;
|
let wrap: &SourceWrapper = &*ptr;
|
||||||
let source = &wrap.source.lock().unwrap();
|
panic_to_error!(wrap, u64::MAX, {
|
||||||
|
|
||||||
match source.get_size() {
|
let source = &wrap.source.lock().unwrap();
|
||||||
Some(size) => size,
|
|
||||||
None => u64::MAX,
|
match source.get_size() {
|
||||||
}
|
Some(size) => size,
|
||||||
|
None => u64::MAX,
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn source_start(ptr: *const SourceWrapper) -> GBoolean {
|
pub unsafe extern "C" fn source_start(ptr: *const SourceWrapper) -> GBoolean {
|
||||||
let wrap: &SourceWrapper = &*ptr;
|
let wrap: &SourceWrapper = &*ptr;
|
||||||
let source = &mut wrap.source.lock().unwrap();
|
|
||||||
|
|
||||||
let uri = match *wrap.uri.lock().unwrap() {
|
panic_to_error!(wrap, GBoolean::False, {
|
||||||
(Some(ref uri), ref mut started) => {
|
let source = &mut wrap.source.lock().unwrap();
|
||||||
*started = true;
|
|
||||||
|
|
||||||
uri.clone()
|
let uri = match *wrap.uri.lock().unwrap() {
|
||||||
}
|
(Some(ref uri), ref mut started) => {
|
||||||
(None, _) => {
|
*started = true;
|
||||||
error_msg!(SourceError::OpenFailed, ["No URI given"]).post(wrap.source_raw);
|
|
||||||
return GBoolean::False;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match source.start(uri) {
|
uri.clone()
|
||||||
Ok(..) => GBoolean::True,
|
}
|
||||||
Err(ref msg) => {
|
(None, _) => {
|
||||||
wrap.uri.lock().unwrap().1 = false;
|
error_msg!(SourceError::OpenFailed, ["No URI given"]).post(wrap.raw);
|
||||||
msg.post(wrap.source_raw);
|
return GBoolean::False;
|
||||||
GBoolean::False
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match source.start(uri) {
|
||||||
|
Ok(..) => GBoolean::True,
|
||||||
|
Err(ref msg) => {
|
||||||
|
wrap.uri.lock().unwrap().1 = false;
|
||||||
|
msg.post(wrap.raw);
|
||||||
|
GBoolean::False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn source_stop(ptr: *const SourceWrapper) -> GBoolean {
|
pub unsafe extern "C" fn source_stop(ptr: *const SourceWrapper) -> GBoolean {
|
||||||
let wrap: &SourceWrapper = &*ptr;
|
let wrap: &SourceWrapper = &*ptr;
|
||||||
let source = &mut wrap.source.lock().unwrap();
|
|
||||||
|
|
||||||
match source.stop() {
|
panic_to_error!(wrap, GBoolean::False, {
|
||||||
Ok(..) => {
|
let source = &mut wrap.source.lock().unwrap();
|
||||||
wrap.uri.lock().unwrap().1 = false;
|
|
||||||
GBoolean::True
|
match source.stop() {
|
||||||
|
Ok(..) => {
|
||||||
|
wrap.uri.lock().unwrap().1 = false;
|
||||||
|
GBoolean::True
|
||||||
|
}
|
||||||
|
Err(ref msg) => {
|
||||||
|
msg.post(wrap.raw);
|
||||||
|
GBoolean::False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(ref msg) => {
|
})
|
||||||
msg.post(wrap.source_raw);
|
|
||||||
GBoolean::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -216,36 +238,42 @@ pub unsafe extern "C" fn source_fill(ptr: *const SourceWrapper,
|
||||||
data_len_ptr: *mut usize)
|
data_len_ptr: *mut usize)
|
||||||
-> GstFlowReturn {
|
-> GstFlowReturn {
|
||||||
let wrap: &SourceWrapper = &*ptr;
|
let wrap: &SourceWrapper = &*ptr;
|
||||||
let source = &mut wrap.source.lock().unwrap();
|
|
||||||
let mut data_len: &mut usize = &mut *data_len_ptr;
|
|
||||||
let mut data = slice::from_raw_parts_mut(data_ptr, *data_len);
|
|
||||||
|
|
||||||
match source.fill(offset, data) {
|
panic_to_error!(wrap, GstFlowReturn::Error, {
|
||||||
Ok(actual_len) => {
|
let source = &mut wrap.source.lock().unwrap();
|
||||||
*data_len = actual_len;
|
let mut data_len: &mut usize = &mut *data_len_ptr;
|
||||||
GstFlowReturn::Ok
|
let mut data = slice::from_raw_parts_mut(data_ptr, *data_len);
|
||||||
}
|
|
||||||
Err(flow_error) => {
|
match source.fill(offset, data) {
|
||||||
match flow_error {
|
Ok(actual_len) => {
|
||||||
FlowError::NotNegotiated(ref msg) |
|
*data_len = actual_len;
|
||||||
FlowError::Error(ref msg) => msg.post(wrap.source_raw),
|
GstFlowReturn::Ok
|
||||||
_ => (),
|
}
|
||||||
|
Err(flow_error) => {
|
||||||
|
match flow_error {
|
||||||
|
FlowError::NotNegotiated(ref msg) |
|
||||||
|
FlowError::Error(ref msg) => msg.post(wrap.raw),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
flow_error.to_native()
|
||||||
}
|
}
|
||||||
flow_error.to_native()
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[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) -> GBoolean {
|
||||||
let wrap: &SourceWrapper = &*ptr;
|
let wrap: &SourceWrapper = &*ptr;
|
||||||
let source = &mut wrap.source.lock().unwrap();
|
|
||||||
|
|
||||||
match source.seek(start, if stop == u64::MAX { None } else { Some(stop) }) {
|
panic_to_error!(wrap, GBoolean::False, {
|
||||||
Ok(..) => GBoolean::True,
|
let source = &mut wrap.source.lock().unwrap();
|
||||||
Err(ref msg) => {
|
|
||||||
msg.post(wrap.source_raw);
|
match source.seek(start, if stop == u64::MAX { None } else { Some(stop) }) {
|
||||||
GBoolean::False
|
Ok(..) => GBoolean::True,
|
||||||
|
Err(ref msg) => {
|
||||||
|
msg.post(wrap.raw);
|
||||||
|
GBoolean::False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue