From 20a493ee491a9840eca84deb97e361c1c6f2abb3 Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Wed, 4 May 2022 14:45:39 +0200 Subject: [PATCH] Implement MpegTs safe bindings Adds safe bindings generated from Gir for the MpegTS library. Not all object bindings are generated. This contains a subset of the library that allows to use it's basic functionality. Part of the API is written manually to add some extra methods like setting struct field values and other useful features. --- Cargo.toml | 2 + gstreamer-mpegts/Cargo.toml | 33 +++++ gstreamer-mpegts/Gir.toml | 68 +++++++++++ gstreamer-mpegts/src/auto/mod.rs | 11 ++ gstreamer-mpegts/src/auto/section.rs | 159 +++++++++++++++++++++++++ gstreamer-mpegts/src/auto/versions.txt | 3 + gstreamer-mpegts/src/lib.rs | 32 +++++ gstreamer-mpegts/sys/Cargo.toml | 64 +++++----- 8 files changed, 340 insertions(+), 32 deletions(-) create mode 100644 gstreamer-mpegts/Cargo.toml create mode 100644 gstreamer-mpegts/Gir.toml create mode 100644 gstreamer-mpegts/src/auto/mod.rs create mode 100644 gstreamer-mpegts/src/auto/section.rs create mode 100644 gstreamer-mpegts/src/auto/versions.txt create mode 100644 gstreamer-mpegts/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 449238a86..e9f3d68f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ default-members = [ "gstreamer-check", "gstreamer-controller", "gstreamer-editing-services", + "gstreamer-mpegts", "gstreamer-net", "gstreamer-pbutils", "gstreamer-play", @@ -78,6 +79,7 @@ members = [ "gstreamer-gl/egl", "gstreamer-gl/wayland", "gstreamer-gl/x11", + "gstreamer-mpegts", "gstreamer-net", "gstreamer-pbutils", "gstreamer-play", diff --git a/gstreamer-mpegts/Cargo.toml b/gstreamer-mpegts/Cargo.toml new file mode 100644 index 000000000..3b7eccf37 --- /dev/null +++ b/gstreamer-mpegts/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "gstreamer-mpegts" +version = "0.19.0" +authors = ["Sebastian Dröge ", "Rafael Caricio "] +categories = ["api-bindings", "multimedia"] +description = "Rust bindings for GStreamer MpegTs library" +repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" +license = "MIT OR Apache-2.0" +readme = "README.md" +homepage = "https://gstreamer.freedesktop.org" +documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_mpegts/" +keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"] +edition = "2021" +rust-version = "1.63" + +[dependencies] +ffi = { package = "gstreamer-mpegts-sys", path = "sys" } +glib = { git = "https://github.com/gtk-rs/gtk-rs-core" } +gst = { package = "gstreamer", path = "../gstreamer" } + +[dev-dependencies] +gir-format-check = "0.1" + +[features] +default = [] +v1_16 = ["gst/v1_16", "ffi/v1_16"] +v1_18 = ["gst/v1_18", "ffi/v1_18", "v1_16"] +v1_20 = ["gst/v1_20", "ffi/v1_20", "v1_18"] +v1_22 = ["gst/v1_22", "ffi/v1_22", "v1_20"] +dox = ["ffi/dox", "glib/dox", "gst/dox"] + +[package.metadata.docs.rs] +features = ["dox"] diff --git a/gstreamer-mpegts/Gir.toml b/gstreamer-mpegts/Gir.toml new file mode 100644 index 000000000..ab0b7b4b6 --- /dev/null +++ b/gstreamer-mpegts/Gir.toml @@ -0,0 +1,68 @@ +[options] +girs_directories = ["../gir-files", "../gst-gir-files"] +library = "GstMpegts" +version = "1.0" +min_cfg_version = "1.14" +work_mode = "normal" +target_path = "." +concurrency = "send+sync" +generate_safety_asserts = true +single_version_file = true +generate_display_trait = false +deprecate_by_min_version = true +trust_return_value_nullability = true + +external_libraries = [ + "GLib", + "GObject", + "Gst", +] + +generate = [] + +manual = [ + "GLib.Bytes", + "Gst.Element", +] + +[[object]] +name = "GstMpegts.Section" +status = "generate" +version = "1.20" + [[object.function]] + name = "new" + ignore = true + + [[object.function]] + name = "get_scte_sit" + ignore = true + + [[object.function]] + name = "packetize" + # Invalid code generation for this function + ignore = true + + [[object.function]] + name = "from_scte_sit" + # Invalid code generation for this function + ignore = true + + [[object.function]] + name = "data" + [object.function.return] + nullable = true + nullable_return_is_error = "Failed to create section" + + [[object.function]] + name = "get_tsdt" + # Invalid code generation for this function + ignore = true + + [[object.function]] + name = "get_cat" + # Invalid code generation for this function + ignore = true + + [[object.function]] + name = "send_event" + ignore = true \ No newline at end of file diff --git a/gstreamer-mpegts/src/auto/mod.rs b/gstreamer-mpegts/src/auto/mod.rs new file mode 100644 index 000000000..dfcf3be8a --- /dev/null +++ b/gstreamer-mpegts/src/auto/mod.rs @@ -0,0 +1,11 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_20", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] +mod section; +#[cfg(any(feature = "v1_20", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] +pub use self::section::Section; diff --git a/gstreamer-mpegts/src/auto/section.rs b/gstreamer-mpegts/src/auto/section.rs new file mode 100644 index 000000000..641dd0915 --- /dev/null +++ b/gstreamer-mpegts/src/auto/section.rs @@ -0,0 +1,159 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git) +// DO NOT EDIT + +use glib::translate::*; + +glib::wrapper! { + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct Section(Boxed); + + match fn { + copy => |ptr| glib::gobject_ffi::g_boxed_copy(ffi::gst_mpegts_section_get_type(), ptr as *mut _) as *mut ffi::GstMpegtsSection, + free => |ptr| glib::gobject_ffi::g_boxed_free(ffi::gst_mpegts_section_get_type(), ptr as *mut _), + type_ => || ffi::gst_mpegts_section_get_type(), + } +} + +impl Section { + //#[doc(alias = "gst_mpegts_section_get_atsc_cvct")] + //#[doc(alias = "get_atsc_cvct")] + //pub fn atsc_cvct(&mut self) -> /*Ignored*/AtscVCT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_atsc_cvct() } + //} + + //#[doc(alias = "gst_mpegts_section_get_atsc_eit")] + //#[doc(alias = "get_atsc_eit")] + //pub fn atsc_eit(&mut self) -> /*Ignored*/AtscEIT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_atsc_eit() } + //} + + //#[doc(alias = "gst_mpegts_section_get_atsc_ett")] + //#[doc(alias = "get_atsc_ett")] + //pub fn atsc_ett(&mut self) -> /*Ignored*/AtscETT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_atsc_ett() } + //} + + //#[doc(alias = "gst_mpegts_section_get_atsc_mgt")] + //#[doc(alias = "get_atsc_mgt")] + //pub fn atsc_mgt(&mut self) -> /*Ignored*/AtscMGT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_atsc_mgt() } + //} + + //#[doc(alias = "gst_mpegts_section_get_atsc_rrt")] + //#[doc(alias = "get_atsc_rrt")] + //pub fn atsc_rrt(&mut self) -> /*Ignored*/AtscRRT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_atsc_rrt() } + //} + + //#[doc(alias = "gst_mpegts_section_get_atsc_stt")] + //#[doc(alias = "get_atsc_stt")] + //pub fn atsc_stt(&mut self) -> /*Ignored*/AtscSTT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_atsc_stt() } + //} + + //#[doc(alias = "gst_mpegts_section_get_atsc_tvct")] + //#[doc(alias = "get_atsc_tvct")] + //pub fn atsc_tvct(&mut self) -> /*Ignored*/AtscVCT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_atsc_tvct() } + //} + + //#[doc(alias = "gst_mpegts_section_get_bat")] + //#[doc(alias = "get_bat")] + //pub fn bat(&mut self) -> /*Ignored*/BAT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_bat() } + //} + + #[doc(alias = "gst_mpegts_section_get_data")] + #[doc(alias = "get_data")] + pub fn data(&mut self) -> glib::Bytes { + unsafe { from_glib_full(ffi::gst_mpegts_section_get_data(self.to_glib_none_mut().0)) } + } + + //#[doc(alias = "gst_mpegts_section_get_eit")] + //#[doc(alias = "get_eit")] + //pub fn eit(&mut self) -> /*Ignored*/EIT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_eit() } + //} + + //#[doc(alias = "gst_mpegts_section_get_nit")] + //#[doc(alias = "get_nit")] + //pub fn nit(&mut self) -> /*Ignored*/NIT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_nit() } + //} + + //#[doc(alias = "gst_mpegts_section_get_pat")] + //#[doc(alias = "get_pat")] + //pub fn pat(&mut self) -> /*Ignored*/Vec { + // unsafe { TODO: call ffi:gst_mpegts_section_get_pat() } + //} + + //#[doc(alias = "gst_mpegts_section_get_pmt")] + //#[doc(alias = "get_pmt")] + //pub fn pmt(&mut self) -> /*Ignored*/PMT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_pmt() } + //} + + //#[doc(alias = "gst_mpegts_section_get_sdt")] + //#[doc(alias = "get_sdt")] + //pub fn sdt(&mut self) -> /*Ignored*/SDT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_sdt() } + //} + + //#[doc(alias = "gst_mpegts_section_get_sit")] + //#[doc(alias = "get_sit")] + //pub fn sit(&mut self) -> /*Ignored*/SIT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_sit() } + //} + + //#[doc(alias = "gst_mpegts_section_get_tdt")] + //#[doc(alias = "get_tdt")] + //pub fn tdt(&mut self) -> /*Ignored*/gst::DateTime { + // unsafe { TODO: call ffi:gst_mpegts_section_get_tdt() } + //} + + //#[doc(alias = "gst_mpegts_section_get_tot")] + //#[doc(alias = "get_tot")] + //pub fn tot(&mut self) -> /*Ignored*/TOT { + // unsafe { TODO: call ffi:gst_mpegts_section_get_tot() } + //} + + //#[doc(alias = "gst_mpegts_section_from_atsc_mgt")] + //pub fn from_atsc_mgt(mgt: /*Ignored*/&mut AtscMGT) -> Section { + // unsafe { TODO: call ffi:gst_mpegts_section_from_atsc_mgt() } + //} + + //#[doc(alias = "gst_mpegts_section_from_atsc_rrt")] + //pub fn from_atsc_rrt(rrt: /*Ignored*/&mut AtscRRT) -> Section { + // unsafe { TODO: call ffi:gst_mpegts_section_from_atsc_rrt() } + //} + + //#[doc(alias = "gst_mpegts_section_from_atsc_stt")] + //pub fn from_atsc_stt(stt: /*Ignored*/&mut AtscSTT) -> Section { + // unsafe { TODO: call ffi:gst_mpegts_section_from_atsc_stt() } + //} + + //#[doc(alias = "gst_mpegts_section_from_nit")] + //pub fn from_nit(nit: /*Ignored*/&mut NIT) -> Section { + // unsafe { TODO: call ffi:gst_mpegts_section_from_nit() } + //} + + //#[doc(alias = "gst_mpegts_section_from_pat")] + //pub fn from_pat(programs: /*Ignored*/&[PatProgram], ts_id: u16) -> Section { + // unsafe { TODO: call ffi:gst_mpegts_section_from_pat() } + //} + + //#[doc(alias = "gst_mpegts_section_from_pmt")] + //pub fn from_pmt(pmt: /*Ignored*/&mut PMT, pid: u16) -> Section { + // unsafe { TODO: call ffi:gst_mpegts_section_from_pmt() } + //} + + //#[doc(alias = "gst_mpegts_section_from_sdt")] + //pub fn from_sdt(sdt: /*Ignored*/&mut SDT) -> Section { + // unsafe { TODO: call ffi:gst_mpegts_section_from_sdt() } + //} +} + +unsafe impl Send for Section {} +unsafe impl Sync for Section {} diff --git a/gstreamer-mpegts/src/auto/versions.txt b/gstreamer-mpegts/src/auto/versions.txt new file mode 100644 index 000000000..4133cf20b --- /dev/null +++ b/gstreamer-mpegts/src/auto/versions.txt @@ -0,0 +1,3 @@ +Generated by gir (https://github.com/gtk-rs/gir @ b3147f2b6043) +from gir-files (https://github.com/gtk-rs/gir-files @ 7fa401e3ee5d) +from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 2860909848fa) diff --git a/gstreamer-mpegts/src/lib.rs b/gstreamer-mpegts/src/lib.rs new file mode 100644 index 000000000..a83882989 --- /dev/null +++ b/gstreamer-mpegts/src/lib.rs @@ -0,0 +1,32 @@ +#![cfg_attr(feature = "dox", feature(doc_cfg))] +#![allow(clippy::missing_safety_doc)] +#![allow(clippy::non_send_fields_in_send_ty)] + +pub use ffi::*; +pub use glib; +pub use gst; + +use std::sync::Once; + +static MPEGTS_INIT: Once = Once::new(); + +macro_rules! assert_initialized_main_thread { + () => { + if !gst::INITIALIZED.load(std::sync::atomic::Ordering::SeqCst) { + #[allow(unused_unsafe)] + if unsafe { gst::ffi::gst_is_initialized() } != glib::ffi::GTRUE { + panic!("GStreamer has not been initialized. Call `gst::init` first."); + } else { + gst::INITIALIZED.store(true, std::sync::atomic::Ordering::SeqCst); + } + } + crate::MPEGTS_INIT.call_once(|| unsafe { ffi::gst_mpegts_initialize() }); + }; +} + +pub fn init() { + assert_initialized_main_thread!(); +} + +mod auto; +pub use crate::auto::*; diff --git a/gstreamer-mpegts/sys/Cargo.toml b/gstreamer-mpegts/sys/Cargo.toml index 72488d181..4ad79fc72 100644 --- a/gstreamer-mpegts/sys/Cargo.toml +++ b/gstreamer-mpegts/sys/Cargo.toml @@ -1,35 +1,3 @@ -[build-dependencies] -system-deps = "6" - -[dependencies] -libc = "0.2" - -[dependencies.glib] -package = "glib-sys" -git = "https://github.com/gtk-rs/gtk-rs-core" - -[dependencies.gst_base] -package = "gstreamer-base-sys" -path = "../../gstreamer-base/sys" - -[dependencies.gst] -package = "gstreamer-sys" -path = "../../gstreamer/sys" - -[dev-dependencies] -shell-words = "1.0.0" -tempfile = "3" - -[features] -v1_16 = [] -v1_18 = ["v1_16"] -v1_20 = ["v1_18"] -v1_22 = ["v1_20"] -dox = [] - -[lib] -name = "gstreamer_mpegts_sys" - [package] authors = ["Russel Winder ", "Sebastian Dröge "] build = "build.rs" @@ -61,3 +29,35 @@ version = "1.20" [package.metadata.system-deps.gstreamer_mpegts_1_0.v1_22] version = "1.21" + +[lib] +name = "gstreamer_mpegts_sys" + +[build-dependencies] +system-deps = "6" + +[dependencies] +libc = "0.2" + +[dependencies.glib] +package = "glib-sys" +git = "https://github.com/gtk-rs/gtk-rs-core" + +[dependencies.gst_base] +package = "gstreamer-base-sys" +path = "../../gstreamer-base/sys" + +[dependencies.gst] +package = "gstreamer-sys" +path = "../../gstreamer/sys" + +[dev-dependencies] +shell-words = "1.0.0" +tempfile = "3" + +[features] +v1_16 = [] +v1_18 = ["v1_16"] +v1_20 = ["v1_18"] +v1_22 = ["v1_20"] +dox = []