From 48a61bc754aaec6d7ed593cb85d74bc24a444561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 16 Dec 2017 14:33:19 +0200 Subject: [PATCH] Add bindings for GStreamer Net library --- Cargo.toml | 1 + gstreamer-net-sys/CHANGELOG.md | 46 ++++++ gstreamer-net-sys/Cargo.toml | 39 +++++ gstreamer-net-sys/LICENSE | 23 +++ gstreamer-net-sys/README.md | 31 ++++ gstreamer-net-sys/build.rs | 73 +++++++++ gstreamer-net-sys/src/lib.rs | 282 +++++++++++++++++++++++++++++++++ 7 files changed, 495 insertions(+) create mode 100644 gstreamer-net-sys/CHANGELOG.md create mode 100644 gstreamer-net-sys/Cargo.toml create mode 100644 gstreamer-net-sys/LICENSE create mode 100644 gstreamer-net-sys/README.md create mode 100644 gstreamer-net-sys/build.rs create mode 100644 gstreamer-net-sys/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 0d0abd527..cb3511826 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,5 @@ members = [ "gstreamer-app-sys", "gstreamer-player-sys", "gstreamer-mpegts-sys", + "gstreamer-net-sys", ] diff --git a/gstreamer-net-sys/CHANGELOG.md b/gstreamer-net-sys/CHANGELOG.md new file mode 100644 index 000000000..4ab09c5db --- /dev/null +++ b/gstreamer-net-sys/CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html), +specifically the [variant used by Rust](http://doc.crates.io/manifest.html#the-version-field). + +## [0.2.1] - 2017-09-10 +### Changed +- Add README.md to all crates directly + +### Fixed +- Fix various compiler warnings +- Fix versioning/feature mess. Now each library has features for all major + versions and for the correct minor versions that added API. +- Removed Cargo.lock from GIT + +## [0.2.0] - 2017-08-28 +### Added +- Add GstPlayer bindings + +### Changed +- Depend on bitflags 0.9 +- Update GIR files to 1.12.1 release +- Fix various errors in the GIR files, backported from GStreamer GIT master +- Depend on gobject-sys/glib-sys 0.4.0 for various improvements +- Regenerated everything with latest GIR + +## [0.1.1] - 2017-05-10 +### Added +- Add GstTag and GstApp bindings +- Add lots of missing fields to all the structs thanks to GIR improvements + +### Changed +- Update GIR files to 1.12.0 release +- Depend on gobject-sys/glib-sys 0.3.4 release for more complete structs +- Regenerated everything with latest GIR + +## [0.1.0] - 2017-04-09 + +- Initial release of the autogenerated GStreamer FFI bindings. + +[Unreleased]: https://github.com/sdroege/gstreamer-sys/compare/0.2.1...HEAD +[0.2.1]: https://github.com/sdroege/gstreamer-sys/compare/0.2.0...0.2.1 +[0.2.0]: https://github.com/sdroege/gstreamer-sys/compare/0.1.1...0.2.0 +[0.1.1]: https://github.com/sdroege/gstreamer-sys/compare/0.1.0...0.1.1 diff --git a/gstreamer-net-sys/Cargo.toml b/gstreamer-net-sys/Cargo.toml new file mode 100644 index 000000000..4da3f208c --- /dev/null +++ b/gstreamer-net-sys/Cargo.toml @@ -0,0 +1,39 @@ +[build-dependencies] +pkg-config = "0.3.7" + +[dependencies] +libc = "0.2" +glib-sys = { git = "https://github.com/gtk-rs/sys" } +gobject-sys = { git = "https://github.com/gtk-rs/sys" } +gio-sys = { git = "https://github.com/gtk-rs/sys" } + +[dependencies.gstreamer-sys] +path = "../gstreamer-sys" + +[features] +v1_2 = [] +v1_4 = ["v1_2"] +v1_6 = ["v1_4"] +v1_8 = ["v1_6"] +v1_10 = ["v1_8"] +v1_12 = ["v1_10"] +dox = [] + +[lib] +name = "gstreamer_net_sys" + +[package] +build = "build.rs" +links = "gstnet-1.0" +name = "gstreamer-net-sys" +version = "0.4.0" +authors = ["Sebastian Dröge "] +description = "FFI bindings to libgstnet-1.0" +homepage = "https://gstreamer.freedesktop.org" +keywords = ["ffi", "gstreamer", "gnome", "multimedia"] +repository = "https://github.com/sdroege/gstreamer-sys" +license = "MIT" +readme = "README.md" + +[badges] +travis-ci = { repository = "sdroege/gstreamer-sys", branch = "master" } diff --git a/gstreamer-net-sys/LICENSE b/gstreamer-net-sys/LICENSE new file mode 100644 index 000000000..3d76f6e2f --- /dev/null +++ b/gstreamer-net-sys/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2017 Sebastian Dröge . + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/gstreamer-net-sys/README.md b/gstreamer-net-sys/README.md new file mode 100644 index 000000000..6683a6b76 --- /dev/null +++ b/gstreamer-net-sys/README.md @@ -0,0 +1,31 @@ +# gstreamer-net-sys [![crates.io](https://img.shields.io/crates/v/gstreamer-sys.svg)](https://crates.io/crates/gstreamer-sys) [![Build Status](https://travis-ci.org/sdroege/gstreamer-sys.svg?branch=master)](https://travis-ci.org/sdroege/gstreamer-sys) + +[GStreamer](https://gstreamer.freedesktop.org/) (Net Library) FFI bindings for Rust. + +These bindings are providing unsafe FFI API that can be used to interface with +GStreamer. Generally they are meant to be used as the building block for +higher-level abstractions like: + + * Application-side bindings for GStreamer: https://github.com/sdroege/gstreamer-rs + * Crate for writing GStreamer plugins in Rust: https://github.com/sdroege/gst-plugin-rs + +The bindings are autogenerated with [gir](https://github.com/gtk-rs/gir/) +based on the [GObject-Introspection](https://wiki.gnome.org/Projects/GObjectIntrospection/) +API metadata provided by the GStreamer project. + +## LICENSE + +gstreamer-sys and all crates contained here are licensed under the MIT +license ([LICENSE](LICENSE) or http://opensource.org/licenses/MIT). + +GStreamer itself is licensed under the Lesser General Public License version +2.1 or (at your option) any later version: +https://www.gnu.org/licenses/lgpl-2.1.html + +## Contribution + +Any kinds of contributions are welcome as a pull request. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in gstreamer-rs by you shall be licensed under the MIT license as above, +without any additional terms or conditions. diff --git a/gstreamer-net-sys/build.rs b/gstreamer-net-sys/build.rs new file mode 100644 index 000000000..5087745ab --- /dev/null +++ b/gstreamer-net-sys/build.rs @@ -0,0 +1,73 @@ +extern crate pkg_config; + +use pkg_config::{Config, Error}; +use std::env; +use std::io::prelude::*; +use std::io; +use std::process; + +fn main() { + if let Err(s) = find() { + let _ = writeln!(io::stderr(), "{}", s); + process::exit(1); + } +} + +fn find() -> Result<(), Error> { + let package_name = "gstreamer-net-1.0"; + let shared_libs = ["gstreamer-net-1.0"]; + let version = if cfg!(feature = "v1_12") { + "1.12" + } else if cfg!(feature = "v1_10") { + "1.10" + } else if cfg!(feature = "v1_8") { + "1.8" + } else if cfg!(feature = "v1_6") { + "1.6" + } else if cfg!(feature = "v1_4") { + "1.4" + } else if cfg!(feature = "v1_2") { + "1.2" + } else { + "1.0" + }; + + if let Ok(lib_dir) = env::var("GTK_LIB_DIR") { + for lib_ in shared_libs.iter() { + println!("cargo:rustc-link-lib=dylib={}", lib_); + } + println!("cargo:rustc-link-search=native={}", lib_dir); + return Ok(()) + } + + let target = env::var("TARGET").expect("TARGET environment variable doesn't exist"); + let hardcode_shared_libs = target.contains("windows"); + + let mut config = Config::new(); + config.atleast_version(version); + if hardcode_shared_libs { + config.cargo_metadata(false); + } + match config.probe(package_name) { + Ok(library) => { + if hardcode_shared_libs { + for lib_ in shared_libs.iter() { + println!("cargo:rustc-link-lib=dylib={}", lib_); + } + for path in library.link_paths.iter() { + println!("cargo:rustc-link-search=native={}", + path.to_str().expect("library path doesn't exist")); + } + } + Ok(()) + } + Err(Error::EnvNoPkgConfig(_)) | Err(Error::Command { .. }) => { + for lib_ in shared_libs.iter() { + println!("cargo:rustc-link-lib=dylib={}", lib_); + } + Ok(()) + } + Err(err) => Err(err), + } +} + diff --git a/gstreamer-net-sys/src/lib.rs b/gstreamer-net-sys/src/lib.rs new file mode 100644 index 000000000..a8b22ee0a --- /dev/null +++ b/gstreamer-net-sys/src/lib.rs @@ -0,0 +1,282 @@ +// This file was generated by gir (0113735) from gir-files (???) +// DO NOT EDIT + +#![allow(non_camel_case_types, non_upper_case_globals)] + +extern crate libc; +extern crate glib_sys as glib; +extern crate gobject_sys as gobject; +extern crate gio_sys as gio; +extern crate gstreamer_sys as gst; + +#[allow(unused_imports)] +use libc::{c_int, c_char, c_uchar, c_float, c_uint, c_double, + c_short, c_ushort, c_long, c_ulong, + c_void, size_t, ssize_t, intptr_t, uintptr_t, time_t, FILE}; + +#[allow(unused_imports)] +use glib::{gboolean, gconstpointer, gpointer, GType, Volatile}; + +// Constants +pub const GST_NET_TIME_PACKET_SIZE: c_int = 16; +pub const GST_PTP_CLOCK_ID_NONE: u64 = 18446744073709551615; +pub const GST_PTP_STATISTICS_BEST_MASTER_CLOCK_SELECTED: *const c_char = b"GstPtpStatisticsBestMasterClockSelected\0" as *const u8 as *const c_char; +pub const GST_PTP_STATISTICS_NEW_DOMAIN_FOUND: *const c_char = b"GstPtpStatisticsNewDomainFound\0" as *const u8 as *const c_char; +pub const GST_PTP_STATISTICS_PATH_DELAY_MEASURED: *const c_char = b"GstPtpStatisticsPathDelayMeasured\0" as *const u8 as *const c_char; +pub const GST_PTP_STATISTICS_TIME_UPDATED: *const c_char = b"GstPtpStatisticsTimeUpdated\0" as *const u8 as *const c_char; + +// Callbacks +pub type GstPtpStatisticsCallback = Option gboolean>; + +// Records +#[repr(C)] +pub struct GstNetAddressMeta { + pub meta: gst::GstMeta, + pub addr: *mut gio::GSocketAddress, +} + +impl ::std::fmt::Debug for GstNetAddressMeta { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstNetAddressMeta @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstNetClientClockClass { + pub parent_class: gst::GstSystemClockClass, + pub _gst_reserved: [gpointer; 4], +} + +impl ::std::fmt::Debug for GstNetClientClockClass { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstNetClientClockClass @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstNetClientClockPrivate(c_void); + +impl ::std::fmt::Debug for GstNetClientClockPrivate { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstNetClientClockPrivate @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstNetControlMessageMeta { + pub meta: gst::GstMeta, + pub message: *mut gio::GSocketControlMessage, +} + +impl ::std::fmt::Debug for GstNetControlMessageMeta { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstNetControlMessageMeta @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstNetTimePacket { + pub local_time: gst::GstClockTime, + pub remote_time: gst::GstClockTime, +} + +impl ::std::fmt::Debug for GstNetTimePacket { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstNetTimePacket @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstNetTimeProviderClass { + pub parent_class: gst::GstObjectClass, + pub _gst_reserved: [gpointer; 4], +} + +impl ::std::fmt::Debug for GstNetTimeProviderClass { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstNetTimeProviderClass @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstNetTimeProviderPrivate(c_void); + +impl ::std::fmt::Debug for GstNetTimeProviderPrivate { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstNetTimeProviderPrivate @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstNtpClockClass { + pub parent_class: gst::GstSystemClockClass, + pub _gst_reserved: [gpointer; 4], +} + +impl ::std::fmt::Debug for GstNtpClockClass { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstNtpClockClass @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstPtpClockClass { + pub parent_class: gst::GstSystemClockClass, + pub _gst_reserved: [gpointer; 4], +} + +impl ::std::fmt::Debug for GstPtpClockClass { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstPtpClockClass @ {:?}", self as *const _) + } +} + +#[repr(C)] +pub struct GstPtpClockPrivate(c_void); + +impl ::std::fmt::Debug for GstPtpClockPrivate { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstPtpClockPrivate @ {:?}", self as *const _) + } +} + +// Classes +#[repr(C)] +pub struct GstNetClientClock { + pub clock: gst::GstSystemClock, + pub priv_: *mut GstNetClientClockPrivate, + pub _gst_reserved: [gpointer; 4], +} + +impl ::std::fmt::Debug for GstNetClientClock { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstNetClientClock @ {:?}", self as *const _)) + .field("clock", &self.clock) + .field("priv_", &self.priv_) + .field("_gst_reserved", &self._gst_reserved) + .finish() + } +} + +#[repr(C)] +pub struct GstNetTimeProvider { + pub parent: gst::GstObject, + pub priv_: *mut GstNetTimeProviderPrivate, + pub _gst_reserved: [gpointer; 4], +} + +impl ::std::fmt::Debug for GstNetTimeProvider { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstNetTimeProvider @ {:?}", self as *const _)) + .field("parent", &self.parent) + .field("priv_", &self.priv_) + .field("_gst_reserved", &self._gst_reserved) + .finish() + } +} + +#[repr(C)] +pub struct GstNtpClock { + pub clock: gst::GstSystemClock, + pub priv_: *mut GstNetClientClockPrivate, + pub _gst_reserved: [gpointer; 4], +} + +impl ::std::fmt::Debug for GstNtpClock { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstNtpClock @ {:?}", self as *const _)) + .field("clock", &self.clock) + .field("priv_", &self.priv_) + .field("_gst_reserved", &self._gst_reserved) + .finish() + } +} + +#[repr(C)] +pub struct GstPtpClock { + pub clock: gst::GstSystemClock, + pub priv_: *mut GstPtpClockPrivate, + pub _gst_reserved: [gpointer; 4], +} + +impl ::std::fmt::Debug for GstPtpClock { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPtpClock @ {:?}", self as *const _)) + .field("clock", &self.clock) + .field("priv_", &self.priv_) + .field("_gst_reserved", &self._gst_reserved) + .finish() + } +} + +extern "C" { + + //========================================================================= + // GstNetAddressMeta + //========================================================================= + pub fn gst_net_address_meta_get_info() -> *const gst::GstMetaInfo; + + //========================================================================= + // GstNetControlMessageMeta + //========================================================================= + pub fn gst_net_control_message_meta_get_info() -> *const gst::GstMetaInfo; + + //========================================================================= + // GstNetTimePacket + //========================================================================= + pub fn gst_net_time_packet_get_type() -> GType; + pub fn gst_net_time_packet_new(buffer: *mut u8) -> *mut GstNetTimePacket; + pub fn gst_net_time_packet_copy(packet: *const GstNetTimePacket) -> *mut GstNetTimePacket; + pub fn gst_net_time_packet_free(packet: *mut GstNetTimePacket); + pub fn gst_net_time_packet_send(packet: *const GstNetTimePacket, socket: *mut gio::GSocket, dest_address: *mut gio::GSocketAddress, error: *mut *mut glib::GError) -> gboolean; + pub fn gst_net_time_packet_serialize(packet: *const GstNetTimePacket) -> *mut u8; + pub fn gst_net_time_packet_receive(socket: *mut gio::GSocket, src_address: *mut *mut gio::GSocketAddress, error: *mut *mut glib::GError) -> *mut GstNetTimePacket; + + //========================================================================= + // GstNetClientClock + //========================================================================= + pub fn gst_net_client_clock_get_type() -> GType; + pub fn gst_net_client_clock_new(name: *const c_char, remote_address: *const c_char, remote_port: c_int, base_time: gst::GstClockTime) -> *mut gst::GstClock; + + //========================================================================= + // GstNetTimeProvider + //========================================================================= + pub fn gst_net_time_provider_get_type() -> GType; + pub fn gst_net_time_provider_new(clock: *mut gst::GstClock, address: *const c_char, port: c_int) -> *mut GstNetTimeProvider; + + //========================================================================= + // GstNtpClock + //========================================================================= + pub fn gst_ntp_clock_get_type() -> GType; + #[cfg(any(feature = "v1_6", feature = "dox"))] + pub fn gst_ntp_clock_new(name: *const c_char, remote_address: *const c_char, remote_port: c_int, base_time: gst::GstClockTime) -> *mut gst::GstClock; + + //========================================================================= + // GstPtpClock + //========================================================================= + pub fn gst_ptp_clock_get_type() -> GType; + #[cfg(any(feature = "v1_6", feature = "dox"))] + pub fn gst_ptp_clock_new(name: *const c_char, domain: c_uint) -> *mut gst::GstClock; + + //========================================================================= + // Other functions + //========================================================================= + pub fn gst_buffer_add_net_address_meta(buffer: *mut gst::GstBuffer, addr: *mut gio::GSocketAddress) -> *mut GstNetAddressMeta; + pub fn gst_buffer_add_net_control_message_meta(buffer: *mut gst::GstBuffer, message: *mut gio::GSocketControlMessage) -> *mut GstNetControlMessageMeta; + pub fn gst_buffer_get_net_address_meta(buffer: *mut gst::GstBuffer) -> *mut GstNetAddressMeta; + pub fn gst_net_address_meta_api_get_type() -> GType; + pub fn gst_net_control_message_meta_api_get_type() -> GType; + #[cfg(any(feature = "v1_6", feature = "dox"))] + pub fn gst_ptp_deinit(); + #[cfg(any(feature = "v1_6", feature = "dox"))] + pub fn gst_ptp_init(clock_id: u64, interfaces: *mut *mut c_char) -> gboolean; + #[cfg(any(feature = "v1_6", feature = "dox"))] + pub fn gst_ptp_is_initialized() -> gboolean; + #[cfg(any(feature = "v1_6", feature = "dox"))] + pub fn gst_ptp_is_supported() -> gboolean; + #[cfg(any(feature = "v1_6", feature = "dox"))] + pub fn gst_ptp_statistics_callback_add(callback: GstPtpStatisticsCallback, user_data: gpointer, destroy_data: glib::GDestroyNotify) -> c_ulong; + #[cfg(any(feature = "v1_6", feature = "dox"))] + pub fn gst_ptp_statistics_callback_remove(id: c_ulong); + +}