Add rtsp-server-record example with authentication and TLS

Update the generated files to include TLS related functions,
override some auth and token functions.
This commit is contained in:
Mathieu Duponchelle 2018-02-23 03:33:37 +01:00 committed by Sebastian Dröge
parent f8108d3dcf
commit e6265341d5
10 changed files with 339 additions and 41 deletions

View file

@ -44,6 +44,9 @@ manual = [
"GObject.Object",
"Gio.TlsCertificateFlags",
"Gio.TlsCertificate",
"Gio.TlsDatabase",
"Gio.TlsConnection",
"Gio.TlsAuthenticationMode",
"Gio.Socket",
"Gio.Cancellable",
"Gio.SocketFamily",
@ -229,3 +232,17 @@ status="generate"
name = "make_basic"
[object.function.return]
nullable = false
[[object.function]]
name = "set_default_token"
# gir forgets mut
ignore = true
[[object]]
name="GstRtspServer.RTSPToken"
status = "generate"
concurrency = "none"
[[object.function]]
name = "writable_structure"
# mutable ref
ignore = true

View file

@ -10,7 +10,9 @@ gstreamer-app = { path = "../gstreamer-app" }
gstreamer-audio = { path = "../gstreamer-audio" }
gstreamer-video = { path = "../gstreamer-video" }
gstreamer-player = { path = "../gstreamer-player", optional = true }
gstreamer-rtsp = { path = "../gstreamer-rtsp", optional = true }
gstreamer-rtsp-server = { path = "../gstreamer-rtsp-server", optional = true }
gstreamer-rtsp-server-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
gtk = { git = "https://github.com/gtk-rs/gtk", features = ["v3_6"], optional = true }
gdk = { git = "https://github.com/gtk-rs/gdk", optional = true }
gio = { git = "https://github.com/gtk-rs/gio", optional = true }
@ -29,6 +31,7 @@ gtkvideooverlay-x11 = ["gtkvideooverlay"]
gtkvideooverlay-quartz = ["gtkvideooverlay"]
tokio = ["gstreamer/futures", "futures", "tokio-core"]
gst-rtsp-server = ["gstreamer-rtsp-server"]
gst-rtsp-server-record = ["gstreamer-rtsp-server", "gstreamer-rtsp", "gio"]
default-features = []
v1_10 = ["gstreamer/v1_10"]
@ -96,3 +99,7 @@ name = "toc"
[[bin]]
name = "tokio"
required-features = ["tokio"]
[[bin]]
name = "rtsp-server-record"
required-features = ["gst-rtsp-server-record"]

View file

@ -0,0 +1,113 @@
extern crate glib;
extern crate failure;
extern crate gio;
#[macro_use]
extern crate failure_derive;
extern crate gstreamer_rtsp_server_sys as ffi;
extern crate gstreamer_rtsp_server as gst_rtsp_server;
extern crate gstreamer_rtsp as gst_rtsp;
extern crate gstreamer as gst;
use std::env;
use std::ptr;
use failure::Error;
use glib::translate::*;
use gst_rtsp_server::prelude::*;
use gst_rtsp_server::*;
use gst_rtsp::*;
#[path = "../examples-common.rs"]
mod examples_common;
#[derive(Debug, Fail)]
#[fail(display = "Could not get mount points")]
struct NoMountPoints;
#[derive(Debug, Fail)]
#[fail(display = "Usage: {} LAUNCH_LINE", _0)]
struct UsageError(String);
fn main_loop() -> Result<(), Error> {
let args: Vec<_> = env::args().collect();
if args.len() != 2 {
return Err(Error::from(UsageError(args[0].clone())));
}
let main_loop = glib::MainLoop::new(None, false);
let server = RTSPServer::new();
let factory = RTSPMediaFactory::new();
let mounts = server.get_mount_points().ok_or(NoMountPoints)?;
let auth = RTSPAuth::new();
let mut token = RTSPToken::new(&[(*RTSP_TOKEN_MEDIA_FACTORY_ROLE, &"user")]);
let basic = RTSPAuth::make_basic("user", "password");
let cert = gio::TlsCertificate::new_from_pem (
"-----BEGIN CERTIFICATE-----\
MIICJjCCAY+gAwIBAgIBBzANBgkqhkiG9w0BAQUFADCBhjETMBEGCgmSJomT8ixk\
ARkWA0NPTTEXMBUGCgmSJomT8ixkARkWB0VYQU1QTEUxHjAcBgNVBAsTFUNlcnRp\
ZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAxMOY2EuZXhhbXBsZS5jb20xHTAbBgkq\
hkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tMB4XDTExMDExNzE5NDcxN1oXDTIxMDEx\
NDE5NDcxN1owSzETMBEGCgmSJomT8ixkARkWA0NPTTEXMBUGCgmSJomT8ixkARkW\
B0VYQU1QTEUxGzAZBgNVBAMTEnNlcnZlci5leGFtcGxlLmNvbTBcMA0GCSqGSIb3\
DQEBAQUAA0sAMEgCQQDYScTxk55XBmbDM9zzwO+grVySE4rudWuzH2PpObIonqbf\
hRoAalKVluG9jvbHI81eXxCdSObv1KBP1sbN5RzpAgMBAAGjIjAgMAkGA1UdEwQC\
MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQADgYEAYx6fMqT1\
Gvo0jq88E8mc+bmp4LfXD4wJ7KxYeadQxt75HFRpj4FhFO3DOpVRFgzHlOEo3Fwk\
PZOKjvkT0cbcoEq5whLH25dHoQxGoVQgFyAP5s+7Vp5AlHh8Y/vAoXeEVyy/RCIH\
QkhUlAflfDMcrrYjsmwoOPSjhx6Mm/AopX4=\
-----END CERTIFICATE-----\
-----BEGIN PRIVATE KEY-----\
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA2EnE8ZOeVwZmwzPc\
88DvoK1ckhOK7nVrsx9j6TmyKJ6m34UaAGpSlZbhvY72xyPNXl8QnUjm79SgT9bG\
zeUc6QIDAQABAkBRFJZ32VbqWMP9OVwDJLiwC01AlYLnka0mIQZbT/2xq9dUc9GW\
U3kiVw4lL8v/+sPjtTPCYYdzHHOyDen6znVhAiEA9qJT7BtQvRxCvGrAhr9MS022\
tTdPbW829BoUtIeH64cCIQDggG5i48v7HPacPBIH1RaSVhXl8qHCpQD3qrIw3FMw\
DwIga8PqH5Sf5sHedy2+CiK0V4MRfoU4c3zQ6kArI+bEgSkCIQCLA1vXBiE31B5s\
bdHoYa1BXebfZVd+1Hd95IfEM5mbRwIgSkDuQwV55BBlvWph3U8wVIMIb4GStaH8\
W535W8UBbEg=-----END PRIVATE KEY-----")?;
// Bindable versions were added in b1f515178a363df0322d7adbd5754e1f6e2083c9
unsafe {
ffi::gst_rtsp_media_factory_add_role(factory.to_glib_none().0,
"user".to_glib_none().0,
RTSP_PERM_MEDIA_FACTORY_ACCESS.to_glib_none().0,
<bool as StaticType>::static_type().to_glib() as *const u8,
true.to_glib() as *const u8,
RTSP_PERM_MEDIA_FACTORY_CONSTRUCT.as_ptr() as *const u8,
<bool as StaticType>::static_type().to_glib() as *const u8,
true.to_glib() as *const u8,
ptr::null_mut::<u8>());
}
auth.set_tls_certificate(&cert);
auth.add_basic(basic.as_str(), &mut token);
server.set_auth(&auth);
factory.set_launch(args[1].as_str());
factory.set_transport_mode(RTSPTransportMode::RECORD);
factory.set_profiles(RTSPProfile::SAVP | RTSPProfile::SAVPF);
mounts.add_factory("/test", &factory);
server.attach(None);
println!("Stream ready at rtsps://127.0.0.1:{}/test", server.get_bound_port());
main_loop.run();
Ok(())
}
fn example_main() -> Result<(), Error> {
gst::init()?;
main_loop()
}
fn main() {
match examples_common::run(example_main) {
Ok(r) => r,
Err(e) => eprintln!("Error! {}", e),
}
}

View file

@ -15,6 +15,7 @@ build = "build.rs"
[dependencies]
bitflags = "1.0"
libc = "0.2"
lazy_static = "1.0"
glib-sys = { git = "https://github.com/gtk-rs/sys" }
gio-sys = { git = "https://github.com/gtk-rs/sys" }
gobject-sys = { git = "https://github.com/gtk-rs/sys" }

View file

@ -61,6 +61,9 @@ pub use self::r_t_s_p_thread_pool::RTSPThreadPoolExt;
mod r_t_s_p_address;
pub use self::r_t_s_p_address::RTSPAddress;
mod r_t_s_p_token;
pub use self::r_t_s_p_token::RTSPToken;
mod enums;
pub use self::enums::RTSPAddressPoolResult;
pub use self::enums::RTSPMediaStatus;

View file

@ -2,15 +2,23 @@
// from gir-files (https://github.com/gtk-rs/gir-files @ ???)
// DO NOT EDIT
use RTSPToken;
use ffi;
use gio;
use gio_ffi;
use glib;
use glib::object::Downcast;
use glib::object::IsA;
use glib::signal::SignalHandlerId;
use glib::signal::connect;
use glib::translate::*;
use glib_ffi;
use gobject_ffi;
#[cfg(any(feature = "v1_12", feature = "dox"))]
use gst_rtsp;
use std::boxed::Box as Box_;
use std::mem;
use std::mem::transmute;
use std::ptr;
glib_wrapper! {
@ -54,54 +62,58 @@ unsafe impl Send for RTSPAuth {}
unsafe impl Sync for RTSPAuth {}
pub trait RTSPAuthExt {
//fn add_basic(&self, basic: &str, token: /*Ignored*/&mut RTSPToken);
fn add_basic(&self, basic: &str, token: &mut RTSPToken);
//#[cfg(any(feature = "v1_12", feature = "dox"))]
//fn add_digest(&self, user: &str, pass: &str, token: /*Ignored*/&mut RTSPToken);
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn add_digest(&self, user: &str, pass: &str, token: &mut RTSPToken);
//fn get_default_token(&self) -> /*Ignored*/Option<RTSPToken>;
fn get_default_token(&self) -> Option<RTSPToken>;
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn get_supported_methods(&self) -> gst_rtsp::RTSPAuthMethod;
//fn get_tls_authentication_mode(&self) -> /*Ignored*/gio::TlsAuthenticationMode;
fn get_tls_authentication_mode(&self) -> gio::TlsAuthenticationMode;
fn get_tls_certificate(&self) -> Option<gio::TlsCertificate>;
//fn get_tls_database(&self) -> /*Ignored*/Option<gio::TlsDatabase>;
fn get_tls_database(&self) -> Option<gio::TlsDatabase>;
fn remove_basic(&self, basic: &str);
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn remove_digest(&self, user: &str);
//fn set_default_token<'a, P: Into<Option<&'a /*Ignored*/RTSPToken>>>(&self, token: P);
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn set_supported_methods(&self, methods: gst_rtsp::RTSPAuthMethod);
//fn set_tls_authentication_mode<'a, P: Into<Option<&'a /*Ignored*/gio::TlsAuthenticationMode>>>(&self, mode: P);
fn set_tls_authentication_mode(&self, mode: gio::TlsAuthenticationMode);
fn set_tls_certificate<'a, P: Into<Option<&'a gio::TlsCertificate>>>(&self, cert: P);
//fn set_tls_database<'a, P: IsA</*Ignored*/gio::TlsDatabase> + 'a, Q: Into<Option<&'a P>>>(&self, database: Q);
fn set_tls_database<'a, P: IsA<gio::TlsDatabase> + 'a, Q: Into<Option<&'a P>>>(&self, database: Q);
//fn connect_accept_certificate<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId;
fn connect_accept_certificate<F: Fn(&Self, &gio::TlsConnection, &gio::TlsCertificate, gio::TlsCertificateFlags) -> bool + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
}
impl<O: IsA<RTSPAuth>> RTSPAuthExt for O {
//fn add_basic(&self, basic: &str, token: /*Ignored*/&mut RTSPToken) {
// unsafe { TODO: call ffi::gst_rtsp_auth_add_basic() }
//}
impl<O: IsA<RTSPAuth> + IsA<glib::object::Object>> RTSPAuthExt for O {
fn add_basic(&self, basic: &str, token: &mut RTSPToken) {
unsafe {
ffi::gst_rtsp_auth_add_basic(self.to_glib_none().0, basic.to_glib_none().0, token.to_glib_none_mut().0);
}
}
//#[cfg(any(feature = "v1_12", feature = "dox"))]
//fn add_digest(&self, user: &str, pass: &str, token: /*Ignored*/&mut RTSPToken) {
// unsafe { TODO: call ffi::gst_rtsp_auth_add_digest() }
//}
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn add_digest(&self, user: &str, pass: &str, token: &mut RTSPToken) {
unsafe {
ffi::gst_rtsp_auth_add_digest(self.to_glib_none().0, user.to_glib_none().0, pass.to_glib_none().0, token.to_glib_none_mut().0);
}
}
//fn get_default_token(&self) -> /*Ignored*/Option<RTSPToken> {
// unsafe { TODO: call ffi::gst_rtsp_auth_get_default_token() }
//}
fn get_default_token(&self) -> Option<RTSPToken> {
unsafe {
from_glib_full(ffi::gst_rtsp_auth_get_default_token(self.to_glib_none().0))
}
}
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn get_supported_methods(&self) -> gst_rtsp::RTSPAuthMethod {
@ -110,9 +122,11 @@ impl<O: IsA<RTSPAuth>> RTSPAuthExt for O {
}
}
//fn get_tls_authentication_mode(&self) -> /*Ignored*/gio::TlsAuthenticationMode {
// unsafe { TODO: call ffi::gst_rtsp_auth_get_tls_authentication_mode() }
//}
fn get_tls_authentication_mode(&self) -> gio::TlsAuthenticationMode {
unsafe {
from_glib(ffi::gst_rtsp_auth_get_tls_authentication_mode(self.to_glib_none().0))
}
}
fn get_tls_certificate(&self) -> Option<gio::TlsCertificate> {
unsafe {
@ -120,9 +134,11 @@ impl<O: IsA<RTSPAuth>> RTSPAuthExt for O {
}
}
//fn get_tls_database(&self) -> /*Ignored*/Option<gio::TlsDatabase> {
// unsafe { TODO: call ffi::gst_rtsp_auth_get_tls_database() }
//}
fn get_tls_database(&self) -> Option<gio::TlsDatabase> {
unsafe {
from_glib_full(ffi::gst_rtsp_auth_get_tls_database(self.to_glib_none().0))
}
}
fn remove_basic(&self, basic: &str) {
unsafe {
@ -137,10 +153,6 @@ impl<O: IsA<RTSPAuth>> RTSPAuthExt for O {
}
}
//fn set_default_token<'a, P: Into<Option<&'a /*Ignored*/RTSPToken>>>(&self, token: P) {
// unsafe { TODO: call ffi::gst_rtsp_auth_set_default_token() }
//}
#[cfg(any(feature = "v1_12", feature = "dox"))]
fn set_supported_methods(&self, methods: gst_rtsp::RTSPAuthMethod) {
unsafe {
@ -148,9 +160,11 @@ impl<O: IsA<RTSPAuth>> RTSPAuthExt for O {
}
}
//fn set_tls_authentication_mode<'a, P: Into<Option<&'a /*Ignored*/gio::TlsAuthenticationMode>>>(&self, mode: P) {
// unsafe { TODO: call ffi::gst_rtsp_auth_set_tls_authentication_mode() }
//}
fn set_tls_authentication_mode(&self, mode: gio::TlsAuthenticationMode) {
unsafe {
ffi::gst_rtsp_auth_set_tls_authentication_mode(self.to_glib_none().0, mode.to_glib());
}
}
fn set_tls_certificate<'a, P: Into<Option<&'a gio::TlsCertificate>>>(&self, cert: P) {
let cert = cert.into();
@ -160,11 +174,25 @@ impl<O: IsA<RTSPAuth>> RTSPAuthExt for O {
}
}
//fn set_tls_database<'a, P: IsA</*Ignored*/gio::TlsDatabase> + 'a, Q: Into<Option<&'a P>>>(&self, database: Q) {
// unsafe { TODO: call ffi::gst_rtsp_auth_set_tls_database() }
//}
//fn connect_accept_certificate<Unsupported or ignored types>(&self, f: F) -> SignalHandlerId {
// Ignored connection: Gio.TlsConnection
//}
fn set_tls_database<'a, P: IsA<gio::TlsDatabase> + 'a, Q: Into<Option<&'a P>>>(&self, database: Q) {
let database = database.into();
let database = database.to_glib_none();
unsafe {
ffi::gst_rtsp_auth_set_tls_database(self.to_glib_none().0, database.0);
}
}
fn connect_accept_certificate<F: Fn(&Self, &gio::TlsConnection, &gio::TlsCertificate, gio::TlsCertificateFlags) -> bool + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
unsafe {
let f: Box_<Box_<Fn(&Self, &gio::TlsConnection, &gio::TlsCertificate, gio::TlsCertificateFlags) -> bool + Send + Sync + 'static>> = Box_::new(Box_::new(f));
connect(self.to_glib_none().0, "accept-certificate",
transmute(accept_certificate_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
}
}
}
unsafe extern "C" fn accept_certificate_trampoline<P>(this: *mut ffi::GstRTSPAuth, connection: *mut gio_ffi::GTlsConnection, peer_cert: *mut gio_ffi::GTlsCertificate, errors: gio_ffi::GTlsCertificateFlags, f: glib_ffi::gpointer) -> glib_ffi::gboolean
where P: IsA<RTSPAuth> {
let f: &&(Fn(&P, &gio::TlsConnection, &gio::TlsCertificate, gio::TlsCertificateFlags) -> bool + Send + Sync + 'static) = transmute(f);
f(&RTSPAuth::from_glib_borrow(this).downcast_unchecked(), &from_glib_borrow(connection), &from_glib_borrow(peer_cert), from_glib(errors)).to_glib()
}

View file

@ -0,0 +1,56 @@
// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955)
// from gir-files (https://github.com/gtk-rs/gir-files @ ???)
// DO NOT EDIT
use ffi;
use glib::translate::*;
use glib_ffi;
use gobject_ffi;
use gst;
use std::mem;
use std::ptr;
glib_wrapper! {
pub struct RTSPToken(Boxed<ffi::GstRTSPToken>);
match fn {
copy => |ptr| gobject_ffi::g_boxed_copy(ffi::gst_rtsp_token_get_type(), ptr as *mut _) as *mut ffi::GstRTSPToken,
free => |ptr| gobject_ffi::g_boxed_free(ffi::gst_rtsp_token_get_type(), ptr as *mut _),
get_type => || ffi::gst_rtsp_token_get_type(),
}
}
impl RTSPToken {
//pub fn new(firstfield: &str, : /*Unknown conversion*//*Unimplemented*/Fundamental: VarArgs) -> RTSPToken {
// unsafe { TODO: call ffi::gst_rtsp_token_new() }
//}
pub fn new_empty() -> RTSPToken {
assert_initialized_main_thread!();
unsafe {
from_glib_full(ffi::gst_rtsp_token_new_empty())
}
}
//pub fn new_valist(firstfield: &str, var_args: /*Unknown conversion*//*Unimplemented*/Unsupported) -> RTSPToken {
// unsafe { TODO: call ffi::gst_rtsp_token_new_valist() }
//}
pub fn get_string(&mut self, field: &str) -> Option<String> {
unsafe {
from_glib_none(ffi::gst_rtsp_token_get_string(self.to_glib_none_mut().0, field.to_glib_none().0))
}
}
pub fn get_structure(&mut self) -> Option<gst::Structure> {
unsafe {
from_glib_none(ffi::gst_rtsp_token_get_structure(self.to_glib_none_mut().0))
}
}
pub fn is_allowed(&mut self, field: &str) -> bool {
unsafe {
from_glib(ffi::gst_rtsp_token_is_allowed(self.to_glib_none_mut().0, field.to_glib_none().0))
}
}
}

View file

@ -8,10 +8,13 @@
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate gio;
extern crate gio_sys as gio_ffi;
use std::ffi::CStr;
#[macro_use]
extern crate glib;
extern crate glib_sys as glib_ffi;
@ -51,13 +54,31 @@ mod r_t_s_p_address_pool;
mod r_t_s_p_client;
mod r_t_s_p_session_pool;
mod r_t_s_p_context;
mod r_t_s_p_auth;
mod r_t_s_p_token;
pub use r_t_s_p_server::RTSPServerExtManual;
pub use r_t_s_p_address_pool::RTSPAddressPoolExtManual;
pub use r_t_s_p_client::RTSPClientExtManual;
pub use r_t_s_p_session_pool::RTSPSessionPoolExtManual;
pub use r_t_s_p_auth::RTSPAuthExtManual;
pub use r_t_s_p_context::*;
pub use r_t_s_p_token::*;
lazy_static! {
pub static ref RTSP_ADDRESS_POOL_ANY_IPV4: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_ADDRESS_POOL_ANY_IPV4).to_str().unwrap()};
pub static ref RTSP_ADDRESS_POOL_ANY_IPV6: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_ADDRESS_POOL_ANY_IPV6).to_str().unwrap()};
pub static ref RTSP_AUTH_CHECK_CONNECT: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_CONNECT).to_str().unwrap()};
pub static ref RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS).to_str().unwrap()};
pub static ref RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT).to_str().unwrap()};
pub static ref RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS).to_str().unwrap()};
pub static ref RTSP_AUTH_CHECK_URL: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_URL).to_str().unwrap()};
pub static ref RTSP_PERM_MEDIA_FACTORY_ACCESS: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_PERM_MEDIA_FACTORY_ACCESS).to_str().unwrap()};
pub static ref RTSP_PERM_MEDIA_FACTORY_CONSTRUCT: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT).to_str().unwrap()};
pub static ref RTSP_TOKEN_MEDIA_FACTORY_ROLE: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE).to_str().unwrap()};
pub static ref RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS: &'static str = unsafe{CStr::from_ptr(ffi::GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS).to_str().unwrap()};
}
// Re-export all the traits in a prelude module, so that applications
// can always "use gst::prelude::*" without getting conflicts
@ -71,4 +92,5 @@ pub mod prelude {
pub use r_t_s_p_address_pool::RTSPAddressPoolExtManual;
pub use r_t_s_p_client::RTSPClientExtManual;
pub use r_t_s_p_session_pool::RTSPSessionPoolExtManual;
pub use r_t_s_p_auth::RTSPAuthExtManual;
}

View file

@ -0,0 +1,19 @@
use RTSPAuth;
use RTSPToken;
use ffi;
use glib::object::IsA;
use glib::translate::*;
pub trait RTSPAuthExtManual {
fn set_default_token<'a, P: Into<Option<&'a mut RTSPToken>>>(&self, token: P);
}
impl<O: IsA<RTSPAuth>> RTSPAuthExtManual for O {
fn set_default_token<'a, P: Into<Option<&'a mut RTSPToken>>>(&self, token: P) {
let mut token = token.into();
unsafe {
ffi::gst_rtsp_auth_set_default_token(self.to_glib_none().0, token.to_glib_none_mut().0);
}
}
}

View file

@ -0,0 +1,32 @@
use RTSPToken;
use glib::value::ToSendValue;
use gst;
use ffi;
use glib::translate::*;
impl RTSPToken {
pub fn new(values: &[(&str, &ToSendValue)]) -> RTSPToken {
let mut token = RTSPToken::new_empty();
{
let structure = token.writable_structure().unwrap();
for &(f, v) in values {
structure.set_value(f, v.to_send_value());
}
}
token
}
pub fn writable_structure(&mut self) -> Option<&mut gst::StructureRef> {
unsafe {
let structure = ffi::gst_rtsp_token_writable_structure(self.to_glib_none_mut().0);
if structure.is_null() {
None
} else {
Some(gst::StructureRef::from_glib_borrow_mut(structure))
}
}
}
}