From 35aff36c618d04d7f0a0b7e8c74e34d549f04c94 Mon Sep 17 00:00:00 2001 From: Philippe Renon Date: Sun, 15 May 2022 18:13:37 +0200 Subject: [PATCH] Introduce gstreamer-play --- Cargo.toml | 4 + gstreamer-play/CHANGELOG.md | 1 + gstreamer-play/COPYRIGHT | 1 + gstreamer-play/Cargo.toml | 33 + gstreamer-play/Gir.toml | 247 +++++ gstreamer-play/LICENSE-APACHE | 1 + gstreamer-play/LICENSE-MIT | 1 + gstreamer-play/README.md | 195 ++++ gstreamer-play/src/auto/enums.rs | 632 ++++++++++++ gstreamer-play/src/auto/mod.rs | 47 + gstreamer-play/src/auto/play.rs | 899 ++++++++++++++++++ gstreamer-play/src/auto/play_audio_info.rs | 51 + gstreamer-play/src/auto/play_media_info.rs | 142 +++ .../src/auto/play_signal_adapter.rs | 378 ++++++++ gstreamer-play/src/auto/play_stream_info.rs | 85 ++ gstreamer-play/src/auto/play_subtitle_info.rs | 31 + gstreamer-play/src/auto/play_video_info.rs | 45 + .../auto/play_video_overlay_video_renderer.rs | 140 +++ .../src/auto/play_video_renderer.rs | 26 + gstreamer-play/src/auto/play_visualization.rs | 18 + gstreamer-play/src/auto/versions.txt | 3 + gstreamer-play/src/config.rs | 103 ++ gstreamer-play/src/lib.rs | 48 + gstreamer-play/src/play.rs | 22 + gstreamer-play/src/play_message.rs | 105 ++ gstreamer-play/src/play_signal_adapter.rs | 105 ++ gstreamer-play/src/play_video_info.rs | 37 + .../src/play_video_overlay_video_renderer.rs | 56 ++ gstreamer-play/src/play_visualization.rs | 24 + gstreamer-play/src/subclass/mod.rs | 10 + .../src/subclass/play_video_renderer.rs | 85 ++ gstreamer-play/sys/CHANGELOG.md | 1 + gstreamer-play/sys/COPYRIGHT | 1 + gstreamer-play/sys/Cargo.toml | 55 ++ gstreamer-play/sys/Gir.toml | 17 + gstreamer-play/sys/LICENSE | 1 + gstreamer-play/sys/README.md | 31 + gstreamer-play/sys/build.rs | 18 + gstreamer-play/sys/src/lib.rs | 569 +++++++++++ gstreamer-play/sys/tests/abi.rs | 295 ++++++ gstreamer-play/sys/tests/constant.c | 60 ++ gstreamer-play/sys/tests/layout.c | 19 + gstreamer-play/sys/tests/manual.h | 3 + gstreamer-play/tests/check_gir.rs | 8 + gstreamer-play/tests/manual.h | 3 + 45 files changed, 4656 insertions(+) create mode 100644 gstreamer-play/CHANGELOG.md create mode 100644 gstreamer-play/COPYRIGHT create mode 100644 gstreamer-play/Cargo.toml create mode 100644 gstreamer-play/Gir.toml create mode 100644 gstreamer-play/LICENSE-APACHE create mode 100644 gstreamer-play/LICENSE-MIT create mode 100644 gstreamer-play/README.md create mode 100644 gstreamer-play/src/auto/enums.rs create mode 100644 gstreamer-play/src/auto/mod.rs create mode 100644 gstreamer-play/src/auto/play.rs create mode 100644 gstreamer-play/src/auto/play_audio_info.rs create mode 100644 gstreamer-play/src/auto/play_media_info.rs create mode 100644 gstreamer-play/src/auto/play_signal_adapter.rs create mode 100644 gstreamer-play/src/auto/play_stream_info.rs create mode 100644 gstreamer-play/src/auto/play_subtitle_info.rs create mode 100644 gstreamer-play/src/auto/play_video_info.rs create mode 100644 gstreamer-play/src/auto/play_video_overlay_video_renderer.rs create mode 100644 gstreamer-play/src/auto/play_video_renderer.rs create mode 100644 gstreamer-play/src/auto/play_visualization.rs create mode 100644 gstreamer-play/src/auto/versions.txt create mode 100644 gstreamer-play/src/config.rs create mode 100644 gstreamer-play/src/lib.rs create mode 100644 gstreamer-play/src/play.rs create mode 100644 gstreamer-play/src/play_message.rs create mode 100644 gstreamer-play/src/play_signal_adapter.rs create mode 100644 gstreamer-play/src/play_video_info.rs create mode 100644 gstreamer-play/src/play_video_overlay_video_renderer.rs create mode 100644 gstreamer-play/src/play_visualization.rs create mode 100644 gstreamer-play/src/subclass/mod.rs create mode 100644 gstreamer-play/src/subclass/play_video_renderer.rs create mode 100644 gstreamer-play/sys/CHANGELOG.md create mode 100644 gstreamer-play/sys/COPYRIGHT create mode 100644 gstreamer-play/sys/Cargo.toml create mode 100644 gstreamer-play/sys/Gir.toml create mode 100644 gstreamer-play/sys/LICENSE create mode 100644 gstreamer-play/sys/README.md create mode 100644 gstreamer-play/sys/build.rs create mode 100644 gstreamer-play/sys/src/lib.rs create mode 100644 gstreamer-play/sys/tests/abi.rs create mode 100644 gstreamer-play/sys/tests/constant.c create mode 100644 gstreamer-play/sys/tests/layout.c create mode 100644 gstreamer-play/sys/tests/manual.h create mode 100644 gstreamer-play/tests/check_gir.rs create mode 100644 gstreamer-play/tests/manual.h diff --git a/Cargo.toml b/Cargo.toml index bb5fd688a..bfecd54ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ default-members = [ "gstreamer-mpegts/sys", "gstreamer-net/sys", "gstreamer-pbutils/sys", + "gstreamer-play/sys", "gstreamer-player/sys", "gstreamer-rtp/sys", "gstreamer-rtsp/sys", @@ -28,6 +29,7 @@ default-members = [ "gstreamer-editing-services", "gstreamer-net", "gstreamer-pbutils", + "gstreamer-play", "gstreamer-player", "gstreamer-rtp", "gstreamer-rtsp", @@ -54,6 +56,7 @@ members = [ "gstreamer-mpegts/sys", "gstreamer-net/sys", "gstreamer-pbutils/sys", + "gstreamer-play/sys", "gstreamer-player/sys", "gstreamer-rtp/sys", "gstreamer-rtsp/sys", @@ -76,6 +79,7 @@ members = [ "gstreamer-gl/x11", "gstreamer-net", "gstreamer-pbutils", + "gstreamer-play", "gstreamer-player", "gstreamer-rtp", "gstreamer-rtsp", diff --git a/gstreamer-play/CHANGELOG.md b/gstreamer-play/CHANGELOG.md new file mode 100644 index 000000000..670919a56 --- /dev/null +++ b/gstreamer-play/CHANGELOG.md @@ -0,0 +1 @@ +../gstreamer/CHANGELOG.md \ No newline at end of file diff --git a/gstreamer-play/COPYRIGHT b/gstreamer-play/COPYRIGHT new file mode 100644 index 000000000..dc5f40a22 --- /dev/null +++ b/gstreamer-play/COPYRIGHT @@ -0,0 +1 @@ +../COPYRIGHT \ No newline at end of file diff --git a/gstreamer-play/Cargo.toml b/gstreamer-play/Cargo.toml new file mode 100644 index 000000000..55c78501c --- /dev/null +++ b/gstreamer-play/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "gstreamer-play" +version = "0.19.0" +authors = ["Sebastian Dröge "] +categories = ["api-bindings", "multimedia"] +description = "Rust bindings for GStreamer Play 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_play/" +keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"] +edition = "2021" +rust-version = "1.57" + +[dependencies] +bitflags = "1.0" +libc = "0.2" +ffi = { package = "gstreamer-play-sys", path = "sys" } +glib = { git = "https://github.com/gtk-rs/gtk-rs-core" } +gst = { package = "gstreamer", path = "../gstreamer", features = ["v1_20"] } +gst-video = { package = "gstreamer-video", path = "../gstreamer-video", features = ["v1_20"] } +once_cell = "1.0" + +[dev-dependencies] +gir-format-check = "0.1" + +[features] +v1_22 = ["gst/v1_22", "gst-video/v1_22", "ffi/v1_22"] +dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-video/dox"] + +[package.metadata.docs.rs] +features = ["dox"] diff --git a/gstreamer-play/Gir.toml b/gstreamer-play/Gir.toml new file mode 100644 index 000000000..824b8581d --- /dev/null +++ b/gstreamer-play/Gir.toml @@ -0,0 +1,247 @@ +[options] +girs_directories = ["../gir-files", "../gst-gir-files"] +library = "GstPlay" +version = "1.0" +min_cfg_version = "1.20" +work_mode = "normal" +concurrency = "send+sync" +generate_safety_asserts = true +single_version_file = true +generate_display_trait = false +trust_return_value_nullability = true + +external_libraries = [ + "GLib", + "GObject", + "Gst", +] + +generate = [ + "GstPlay.PlayColorBalanceType", + "GstPlay.PlayError", + "GstPlay.PlayMediaInfo", + "GstPlay.PlaySnapshotFormat", + "GstPlay.PlayState", + "GstPlay.PlayStreamInfo", + "GstPlay.PlayVideoRenderer", + "GstPlay.PlayVisualization", +] + +manual = [ + "GLib.Error", + "GLib.MainContext", + "GObject.Object", + "Gst.Element", + "Gst.Object", + "GstVideo.VideoMultiviewFlags", + "GstVideo.VideoMultiviewFramePacking", +] + +[[object]] +name = "Gst.Bus" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Caps" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.ClockTime" +status = "manual" +conversion_type = "Option" + +[[object]] +name = "Gst.Message" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Sample" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Structure" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.TagList" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "GstPlay.Play" +status = "generate" +final_type = true + + [[object.function]] + name = "visualizations_free" + # correct mutability + ignore = true + + [[object.function]] + name = "set_config" + # Custom type + manual = true + + [[object.function]] + name = "get_config" + # Custom type + manual = true + + [[object.function]] + pattern = "config_.*" + # Custom type + ignore = true + + [[object.function]] + name = "seek" + [[object.function.parameter]] + name = "position" + mandatory = true + + [[object.function]] + name = "set_audio_track" + [object.function.return] + bool_return_is_error = "Failed to set audio track" + + [[object.function]] + name = "set_subtitle_track" + [object.function.return] + bool_return_is_error = "Failed to set subtitle track" + + [[object.function]] + name = "set_video_track" + [object.function.return] + bool_return_is_error = "Failed to set video track" + + [[object.function]] + name = "set_visualization" + [object.function.return] + bool_return_is_error = "Failed to set visualization" + +[[object]] +name = "GstPlay.PlayAudioInfo" +status = "generate" +final_type = true + +[[object]] +name = "GstPlay.PlayMessage" +status = "generate" +final_type = true +visibility = "crate" + +[[object]] +name = "GstPlay.PlaySignalAdapter" +status = "generate" +final_type = true + + [[object.signal]] + name = "buffering" + concurrency = "send" + + [[object.signal]] + name = "duration-changed" + concurrency = "send" + # Pass ClockTime instead of u64 + manual = true + + [[object.signal]] + name = "end-of-stream" + concurrency = "send" + + [[object.signal]] + name = "error" + concurrency = "send" + [[object.signal.parameter]] + name = "p0" + nullable = true + + [[object.signal]] + name = "media-info-updated" + concurrency = "send" + + [[object.signal]] + name = "mute-changed" + concurrency = "send" + + [[object.signal]] + name = "position-updated" + concurrency = "send" + # Pass ClockTime instead of u64 + manual = true + + [[object.signal]] + name = "seek-done" + concurrency = "send" + # Pass ClockTime instead of u64 + manual = true + + [[object.signal]] + name = "state-changed" + concurrency = "send" + + [[object.signal]] + name = "uri-loaded" + concurrency = "send" + + [[object.signal]] + name = "video-dimensions-changed" + concurrency = "send" + + [[object.signal]] + name = "volume-changed" + concurrency = "send" + + [[object.signal]] + name = "warning" + concurrency = "send" + [[object.signal.parameter]] + name = "p0" + nullable = true + +[[object]] +name = "GstPlay.PlaySubtitleInfo" +status = "generate" +final_type = true + +[[object]] +name = "GstPlay.PlayVideoInfo" +status = "generate" +final_type = true + + [[object.function]] + name = "get_framerate" + # Fraction + manual = true + + [[object.function]] + name = "get_pixel_aspect_ratio" + # Fraction + manual = true + +[[object]] +name = "GstPlay.PlayVideoOverlayVideoRenderer" +status = "generate" +final_type = true + + [[object.function]] + name = "new" + manual = true + + [[object.function]] + name = "new_with_sink" + # with_handle_and_sink() also calls this. + rename = "with_sink" + manual = true + + [[object.function]] + name = "get_window_handle" + manual = true + + [[object.function]] + name = "set_window_handle" + manual = true diff --git a/gstreamer-play/LICENSE-APACHE b/gstreamer-play/LICENSE-APACHE new file mode 100644 index 000000000..965b606f3 --- /dev/null +++ b/gstreamer-play/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/gstreamer-play/LICENSE-MIT b/gstreamer-play/LICENSE-MIT new file mode 100644 index 000000000..76219eb72 --- /dev/null +++ b/gstreamer-play/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/gstreamer-play/README.md b/gstreamer-play/README.md new file mode 100644 index 000000000..26ef422ad --- /dev/null +++ b/gstreamer-play/README.md @@ -0,0 +1,195 @@ +# gstreamer-rs [![crates.io](https://img.shields.io/crates/v/gstreamer-play.svg)](https://crates.io/crates/gstreamer-play) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/main/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/main) + +[GStreamer](https://gstreamer.freedesktop.org/) (Play library) bindings for Rust. +Documentation can be found [here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_play/). + +These bindings are providing a safe API that can be used to interface with +GStreamer, e.g. for writing GStreamer-based applications and GStreamer plugins. + +The bindings are mostly 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. + +## Table of Contents +1. [Installation](#installation) + 1. [Linux/BSDs](#installation-linux) + 1. [macOS](#installation-macos) + 1. [Windows](#installation-windows) +1. [Getting Started](#getting-started) +1. [License](#license) +1. [Contribution](#contribution) + + + +## Installation + +To build the GStreamer bindings or anything depending on them, you need to +have at least GStreamer 1.14 and gst-plugins-base 1.14 installed. In addition, +some of the examples/tutorials require various GStreamer plugins to be +available, which can be found in gst-plugins-base, gst-plugins-good, +gst-plugins-bad, gst-plugins-ugly and/or gst-libav. + + + +### Linux/BSDs + +You need to install the above mentioned packages with your distributions +package manager, or build them from source. + +On Debian/Ubuntu they can be installed with + +```console +$ apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ + gstreamer1.0-plugins-base gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \ + gstreamer1.0-libav libgstrtspserver-1.0-dev libges-1.0-dev +``` + +The minimum required version of the above libraries is >= 1.14. If you +build the gstreamer-play sub-crate, or any of the examples that +depend on gstreamer-play, you must ensure that in addition to the above +packages, `libgstreamer-plugins-bad1.0-dev` is installed. See the `Cargo.toml` +files for the full details, + +```console +$ apt-get install libgstreamer-plugins-bad1.0-dev +``` + +Package names on other distributions should be similar. +Please submit a pull request with instructions for yours. + + + +### macOS + +You can install GStreamer and the plugins via [Homebrew](https://brew.sh/) or +by installing the [binaries](https://gstreamer.freedesktop.org/data/pkg/osx/) +provided by the GStreamer project. + +#### Homebrew + +Homebrew only installs various plugins if explicitly enabled, so some extra +`--with-*` flags may be required. + +```console +$ brew install gstreamer gst-plugins-base gst-plugins-good \ + gst-plugins-bad gst-plugins-ugly gst-libav gst-rtsp-server \ + gst-editing-services --with-orc --with-libogg --with-opus \ + --with-pango --with-theora --with-libvorbis --with-libvpx \ + --enable-gtk3 +``` + +Make sure the version of these libraries is >= 1.14. + +#### GStreamer Binaries + +You need to download the *two* `.pkg` files from the GStreamer website and +install them, e.g. `gstreamer-1.0-1.14.0-x86_64.pkg` and +`gstreamer-1.0-devel-1.14.0-x86_64.pkg`. + +After installation, you also need to install `pkg-config` (e.g. via Homebrew) +and set the `PKG_CONFIG_PATH` environment variable + +```console +$ export PKG_CONFIG_PATH="/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" +``` + + + +### Windows + +You can install GStreamer and the plugins via [MSYS2](http://www.msys2.org/) +with `pacman` or by installing the +[binaries](https://gstreamer.freedesktop.org/data/pkg/windows/) provided by +the GStreamer project. + +#### MSYS2 / pacman + +```console +$ pacman -S glib2-devel pkg-config \ + mingw-w64-x86_64-gstreamer mingw-w64-x86_64-gst-plugins-base \ + mingw-w64-x86_64-gst-plugins-good mingw-w64-x86_64-gst-plugins-bad \ + mingw-w64-x86_64-gst-plugins-ugly mingw-w64-x86_64-gst-libav \ + mingw-w64-x86_64-gst-rtsp-server +``` + +Make sure the version of these libraries is >= 1.14. + +Note that the version of `pkg-config` included in `MSYS2` is +[known to have problems](https://github.com/rust-lang/pkg-config-rs/issues/51#issuecomment-346300858) +compiling GStreamer, so you may need to install another version. One option +would be [`pkg-config-lite`](https://sourceforge.net/projects/pkgconfiglite/). + +#### GStreamer Binaries + +You need to download the *two* `.msi` files for your platform from the +GStreamer website and install them, e.g. `gstreamer-1.0-x86_64-1.14.0.msi` and +`gstreamer-1.0-devel-x86_64-1.14.0.msi`. + +After installation, you also need to install `pkg-config` (e.g. via MSYS2 or +from [here](https://sourceforge.net/projects/pkgconfiglite/)) +and set the `PKG_CONFIG_PATH` environment variable + +```console +$ export PKG_CONFIG_PATH="c:\\gstreamer\\1.0\\x86_64\\lib\\pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" +``` + + + +## Getting Started + +The API reference can be found +[here](https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer/), however it is +only the Rust API reference and does not explain any of the concepts. + +For getting started with GStreamer development, the best would be to follow +the [documentation](https://gstreamer.freedesktop.org/documentation/) on the +GStreamer website, especially the [Application Development +Manual](https://gstreamer.freedesktop.org/documentation/application-development/). +While being C-centric, it explains all the fundamental concepts of GStreamer +and the code examples should be relatively easily translatable to Rust. The +API is basically the same, function/struct names are the same and everything +is only more convenient (hopefully) and safer. + +In addition there are +[tutorials](https://gstreamer.freedesktop.org/documentation/tutorials/) on the +GStreamer website. Many of them were ported to Rust already and the code can +be found in the +[tutorials](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/tree/main/tutorials) +directory. + +Some further examples for various aspects of GStreamer and how to use it from +Rust can be found in the +[examples](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/tree/main/examples) +directory. + +Various GStreamer plugins written in Rust can be found in the +[gst-plugins-rs](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs) +repository. + + + +## LICENSE + +gstreamer-rs and all crates contained in here are licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +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, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/gstreamer-play/src/auto/enums.rs b/gstreamer-play/src/auto/enums.rs new file mode 100644 index 000000000..fe3d655cd --- /dev/null +++ b/gstreamer-play/src/auto/enums.rs @@ -0,0 +1,632 @@ +// 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 crate::PlayMediaInfo; +use glib::error::ErrorDomain; +use glib::translate::*; +use glib::value::FromValue; +use glib::value::ToValue; +use glib::Quark; +use glib::StaticType; +use glib::Type; +use std::ffi::CStr; +use std::fmt; +use std::mem; +use std::ptr; + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "GstPlayColorBalanceType")] +pub enum PlayColorBalanceType { + #[doc(alias = "GST_PLAY_COLOR_BALANCE_HUE")] + Hue, + #[doc(alias = "GST_PLAY_COLOR_BALANCE_BRIGHTNESS")] + Brightness, + #[doc(alias = "GST_PLAY_COLOR_BALANCE_SATURATION")] + Saturation, + #[doc(alias = "GST_PLAY_COLOR_BALANCE_CONTRAST")] + Contrast, + #[doc(hidden)] + __Unknown(i32), +} + +impl PlayColorBalanceType { + pub fn name<'a>(self) -> &'a str { + unsafe { + CStr::from_ptr( + ffi::gst_play_color_balance_type_get_name(self.into_glib()) + .as_ref() + .expect("gst_play_color_balance_type_get_name returned NULL"), + ) + .to_str() + .expect("gst_play_color_balance_type_get_name returned an invalid string") + } + } +} + +impl fmt::Display for PlayColorBalanceType { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.name()) + } +} + +#[doc(hidden)] +impl IntoGlib for PlayColorBalanceType { + type GlibType = ffi::GstPlayColorBalanceType; + + fn into_glib(self) -> ffi::GstPlayColorBalanceType { + match self { + Self::Hue => ffi::GST_PLAY_COLOR_BALANCE_HUE, + Self::Brightness => ffi::GST_PLAY_COLOR_BALANCE_BRIGHTNESS, + Self::Saturation => ffi::GST_PLAY_COLOR_BALANCE_SATURATION, + Self::Contrast => ffi::GST_PLAY_COLOR_BALANCE_CONTRAST, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for PlayColorBalanceType { + unsafe fn from_glib(value: ffi::GstPlayColorBalanceType) -> Self { + skip_assert_initialized!(); + match value { + ffi::GST_PLAY_COLOR_BALANCE_HUE => Self::Hue, + ffi::GST_PLAY_COLOR_BALANCE_BRIGHTNESS => Self::Brightness, + ffi::GST_PLAY_COLOR_BALANCE_SATURATION => Self::Saturation, + ffi::GST_PLAY_COLOR_BALANCE_CONTRAST => Self::Contrast, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for PlayColorBalanceType { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_play_color_balance_type_get_type()) } + } +} + +impl glib::value::ValueType for PlayColorBalanceType { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for PlayColorBalanceType { + type Checker = glib::value::GenericValueTypeChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for PlayColorBalanceType { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "GstPlayError")] +pub enum PlayError { + #[doc(alias = "GST_PLAY_ERROR_FAILED")] + Failed, + #[doc(hidden)] + __Unknown(i32), +} + +impl PlayError { + pub fn name<'a>(self) -> &'a str { + unsafe { + CStr::from_ptr( + ffi::gst_play_error_get_name(self.into_glib()) + .as_ref() + .expect("gst_play_error_get_name returned NULL"), + ) + .to_str() + .expect("gst_play_error_get_name returned an invalid string") + } + } +} + +impl fmt::Display for PlayError { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.name()) + } +} + +#[doc(hidden)] +impl IntoGlib for PlayError { + type GlibType = ffi::GstPlayError; + + fn into_glib(self) -> ffi::GstPlayError { + match self { + Self::Failed => ffi::GST_PLAY_ERROR_FAILED, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for PlayError { + unsafe fn from_glib(value: ffi::GstPlayError) -> Self { + skip_assert_initialized!(); + match value { + ffi::GST_PLAY_ERROR_FAILED => Self::Failed, + value => Self::__Unknown(value), + } + } +} + +impl ErrorDomain for PlayError { + fn domain() -> Quark { + skip_assert_initialized!(); + + unsafe { from_glib(ffi::gst_play_error_quark()) } + } + + fn code(self) -> i32 { + self.into_glib() + } + + fn from(code: i32) -> Option { + skip_assert_initialized!(); + match code { + ffi::GST_PLAY_ERROR_FAILED => Some(Self::Failed), + _ => Some(Self::Failed), + } + } +} + +impl StaticType for PlayError { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_play_error_get_type()) } + } +} + +impl glib::value::ValueType for PlayError { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for PlayError { + type Checker = glib::value::GenericValueTypeChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for PlayError { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "GstPlayMessage")] +pub(crate) enum PlayMessage { + #[doc(alias = "GST_PLAY_MESSAGE_URI_LOADED")] + UriLoaded, + #[doc(alias = "GST_PLAY_MESSAGE_POSITION_UPDATED")] + PositionUpdated, + #[doc(alias = "GST_PLAY_MESSAGE_DURATION_CHANGED")] + DurationChanged, + #[doc(alias = "GST_PLAY_MESSAGE_STATE_CHANGED")] + StateChanged, + #[doc(alias = "GST_PLAY_MESSAGE_BUFFERING")] + Buffering, + #[doc(alias = "GST_PLAY_MESSAGE_END_OF_STREAM")] + EndOfStream, + #[doc(alias = "GST_PLAY_MESSAGE_ERROR")] + Error, + #[doc(alias = "GST_PLAY_MESSAGE_WARNING")] + Warning, + #[doc(alias = "GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED")] + VideoDimensionsChanged, + #[doc(alias = "GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED")] + MediaInfoUpdated, + #[doc(alias = "GST_PLAY_MESSAGE_VOLUME_CHANGED")] + VolumeChanged, + #[doc(alias = "GST_PLAY_MESSAGE_MUTE_CHANGED")] + MuteChanged, + #[doc(alias = "GST_PLAY_MESSAGE_SEEK_DONE")] + SeekDone, + #[doc(hidden)] + __Unknown(i32), +} + +impl PlayMessage { + pub fn name<'a>(self) -> &'a str { + unsafe { + CStr::from_ptr( + ffi::gst_play_message_get_name(self.into_glib()) + .as_ref() + .expect("gst_play_message_get_name returned NULL"), + ) + .to_str() + .expect("gst_play_message_get_name returned an invalid string") + } + } + + #[doc(alias = "gst_play_message_parse_buffering_percent")] + pub fn parse_buffering_percent(msg: &gst::Message) -> u32 { + assert_initialized_main_thread!(); + unsafe { + let mut percent = mem::MaybeUninit::uninit(); + ffi::gst_play_message_parse_buffering_percent( + msg.to_glib_none().0, + percent.as_mut_ptr(), + ); + percent.assume_init() + } + } + + #[doc(alias = "gst_play_message_parse_duration_updated")] + pub fn parse_duration_updated(msg: &gst::Message) -> Option { + assert_initialized_main_thread!(); + unsafe { + let mut duration = mem::MaybeUninit::uninit(); + ffi::gst_play_message_parse_duration_updated( + msg.to_glib_none().0, + duration.as_mut_ptr(), + ); + from_glib(duration.assume_init()) + } + } + + #[doc(alias = "gst_play_message_parse_error")] + pub fn parse_error(msg: &gst::Message) -> (glib::Error, Option) { + assert_initialized_main_thread!(); + unsafe { + let mut error = ptr::null_mut(); + let mut details = ptr::null_mut(); + ffi::gst_play_message_parse_error(msg.to_glib_none().0, &mut error, &mut details); + (from_glib_full(error), from_glib_full(details)) + } + } + + #[doc(alias = "gst_play_message_parse_media_info_updated")] + pub fn parse_media_info_updated(msg: &gst::Message) -> PlayMediaInfo { + assert_initialized_main_thread!(); + unsafe { + let mut info = ptr::null_mut(); + ffi::gst_play_message_parse_media_info_updated(msg.to_glib_none().0, &mut info); + from_glib_full(info) + } + } + + #[doc(alias = "gst_play_message_parse_muted_changed")] + pub fn parse_muted_changed(msg: &gst::Message) -> bool { + assert_initialized_main_thread!(); + unsafe { + let mut muted = mem::MaybeUninit::uninit(); + ffi::gst_play_message_parse_muted_changed(msg.to_glib_none().0, muted.as_mut_ptr()); + from_glib(muted.assume_init()) + } + } + + #[doc(alias = "gst_play_message_parse_position_updated")] + pub fn parse_position_updated(msg: &gst::Message) -> Option { + assert_initialized_main_thread!(); + unsafe { + let mut position = mem::MaybeUninit::uninit(); + ffi::gst_play_message_parse_position_updated( + msg.to_glib_none().0, + position.as_mut_ptr(), + ); + from_glib(position.assume_init()) + } + } + + #[doc(alias = "gst_play_message_parse_state_changed")] + pub fn parse_state_changed(msg: &gst::Message) -> PlayState { + assert_initialized_main_thread!(); + unsafe { + let mut state = mem::MaybeUninit::uninit(); + ffi::gst_play_message_parse_state_changed(msg.to_glib_none().0, state.as_mut_ptr()); + from_glib(state.assume_init()) + } + } + + #[doc(alias = "gst_play_message_parse_type")] + pub fn parse_type(msg: &gst::Message) -> PlayMessage { + assert_initialized_main_thread!(); + unsafe { + let mut type_ = mem::MaybeUninit::uninit(); + ffi::gst_play_message_parse_type(msg.to_glib_none().0, type_.as_mut_ptr()); + from_glib(type_.assume_init()) + } + } + + #[doc(alias = "gst_play_message_parse_video_dimensions_changed")] + pub fn parse_video_dimensions_changed(msg: &gst::Message) -> (u32, u32) { + assert_initialized_main_thread!(); + unsafe { + let mut width = mem::MaybeUninit::uninit(); + let mut height = mem::MaybeUninit::uninit(); + ffi::gst_play_message_parse_video_dimensions_changed( + msg.to_glib_none().0, + width.as_mut_ptr(), + height.as_mut_ptr(), + ); + (width.assume_init(), height.assume_init()) + } + } + + #[doc(alias = "gst_play_message_parse_volume_changed")] + pub fn parse_volume_changed(msg: &gst::Message) -> f64 { + assert_initialized_main_thread!(); + unsafe { + let mut volume = mem::MaybeUninit::uninit(); + ffi::gst_play_message_parse_volume_changed(msg.to_glib_none().0, volume.as_mut_ptr()); + volume.assume_init() + } + } + + #[doc(alias = "gst_play_message_parse_warning")] + pub fn parse_warning(msg: &gst::Message) -> (glib::Error, Option) { + assert_initialized_main_thread!(); + unsafe { + let mut error = ptr::null_mut(); + let mut details = ptr::null_mut(); + ffi::gst_play_message_parse_warning(msg.to_glib_none().0, &mut error, &mut details); + (from_glib_full(error), from_glib_full(details)) + } + } +} + +impl fmt::Display for PlayMessage { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.name()) + } +} + +#[doc(hidden)] +impl IntoGlib for PlayMessage { + type GlibType = ffi::GstPlayMessage; + + fn into_glib(self) -> ffi::GstPlayMessage { + match self { + Self::UriLoaded => ffi::GST_PLAY_MESSAGE_URI_LOADED, + Self::PositionUpdated => ffi::GST_PLAY_MESSAGE_POSITION_UPDATED, + Self::DurationChanged => ffi::GST_PLAY_MESSAGE_DURATION_CHANGED, + Self::StateChanged => ffi::GST_PLAY_MESSAGE_STATE_CHANGED, + Self::Buffering => ffi::GST_PLAY_MESSAGE_BUFFERING, + Self::EndOfStream => ffi::GST_PLAY_MESSAGE_END_OF_STREAM, + Self::Error => ffi::GST_PLAY_MESSAGE_ERROR, + Self::Warning => ffi::GST_PLAY_MESSAGE_WARNING, + Self::VideoDimensionsChanged => ffi::GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED, + Self::MediaInfoUpdated => ffi::GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED, + Self::VolumeChanged => ffi::GST_PLAY_MESSAGE_VOLUME_CHANGED, + Self::MuteChanged => ffi::GST_PLAY_MESSAGE_MUTE_CHANGED, + Self::SeekDone => ffi::GST_PLAY_MESSAGE_SEEK_DONE, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for PlayMessage { + unsafe fn from_glib(value: ffi::GstPlayMessage) -> Self { + skip_assert_initialized!(); + match value { + ffi::GST_PLAY_MESSAGE_URI_LOADED => Self::UriLoaded, + ffi::GST_PLAY_MESSAGE_POSITION_UPDATED => Self::PositionUpdated, + ffi::GST_PLAY_MESSAGE_DURATION_CHANGED => Self::DurationChanged, + ffi::GST_PLAY_MESSAGE_STATE_CHANGED => Self::StateChanged, + ffi::GST_PLAY_MESSAGE_BUFFERING => Self::Buffering, + ffi::GST_PLAY_MESSAGE_END_OF_STREAM => Self::EndOfStream, + ffi::GST_PLAY_MESSAGE_ERROR => Self::Error, + ffi::GST_PLAY_MESSAGE_WARNING => Self::Warning, + ffi::GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED => Self::VideoDimensionsChanged, + ffi::GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED => Self::MediaInfoUpdated, + ffi::GST_PLAY_MESSAGE_VOLUME_CHANGED => Self::VolumeChanged, + ffi::GST_PLAY_MESSAGE_MUTE_CHANGED => Self::MuteChanged, + ffi::GST_PLAY_MESSAGE_SEEK_DONE => Self::SeekDone, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for PlayMessage { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_play_message_get_type()) } + } +} + +impl glib::value::ValueType for PlayMessage { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for PlayMessage { + type Checker = glib::value::GenericValueTypeChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for PlayMessage { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "GstPlaySnapshotFormat")] +pub enum PlaySnapshotFormat { + #[doc(alias = "GST_PLAY_THUMBNAIL_RAW_NATIVE")] + RawNative, + #[doc(alias = "GST_PLAY_THUMBNAIL_RAW_xRGB")] + RawXrgb, + #[doc(alias = "GST_PLAY_THUMBNAIL_RAW_BGRx")] + RawBgrx, + #[doc(alias = "GST_PLAY_THUMBNAIL_JPG")] + Jpg, + #[doc(alias = "GST_PLAY_THUMBNAIL_PNG")] + Png, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl IntoGlib for PlaySnapshotFormat { + type GlibType = ffi::GstPlaySnapshotFormat; + + fn into_glib(self) -> ffi::GstPlaySnapshotFormat { + match self { + Self::RawNative => ffi::GST_PLAY_THUMBNAIL_RAW_NATIVE, + Self::RawXrgb => ffi::GST_PLAY_THUMBNAIL_RAW_xRGB, + Self::RawBgrx => ffi::GST_PLAY_THUMBNAIL_RAW_BGRx, + Self::Jpg => ffi::GST_PLAY_THUMBNAIL_JPG, + Self::Png => ffi::GST_PLAY_THUMBNAIL_PNG, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for PlaySnapshotFormat { + unsafe fn from_glib(value: ffi::GstPlaySnapshotFormat) -> Self { + skip_assert_initialized!(); + match value { + ffi::GST_PLAY_THUMBNAIL_RAW_NATIVE => Self::RawNative, + ffi::GST_PLAY_THUMBNAIL_RAW_xRGB => Self::RawXrgb, + ffi::GST_PLAY_THUMBNAIL_RAW_BGRx => Self::RawBgrx, + ffi::GST_PLAY_THUMBNAIL_JPG => Self::Jpg, + ffi::GST_PLAY_THUMBNAIL_PNG => Self::Png, + value => Self::__Unknown(value), + } + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "GstPlayState")] +pub enum PlayState { + #[doc(alias = "GST_PLAY_STATE_STOPPED")] + Stopped, + #[doc(alias = "GST_PLAY_STATE_BUFFERING")] + Buffering, + #[doc(alias = "GST_PLAY_STATE_PAUSED")] + Paused, + #[doc(alias = "GST_PLAY_STATE_PLAYING")] + Playing, + #[doc(hidden)] + __Unknown(i32), +} + +impl PlayState { + pub fn name<'a>(self) -> &'a str { + unsafe { + CStr::from_ptr( + ffi::gst_play_state_get_name(self.into_glib()) + .as_ref() + .expect("gst_play_state_get_name returned NULL"), + ) + .to_str() + .expect("gst_play_state_get_name returned an invalid string") + } + } +} + +impl fmt::Display for PlayState { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.name()) + } +} + +#[doc(hidden)] +impl IntoGlib for PlayState { + type GlibType = ffi::GstPlayState; + + fn into_glib(self) -> ffi::GstPlayState { + match self { + Self::Stopped => ffi::GST_PLAY_STATE_STOPPED, + Self::Buffering => ffi::GST_PLAY_STATE_BUFFERING, + Self::Paused => ffi::GST_PLAY_STATE_PAUSED, + Self::Playing => ffi::GST_PLAY_STATE_PLAYING, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for PlayState { + unsafe fn from_glib(value: ffi::GstPlayState) -> Self { + skip_assert_initialized!(); + match value { + ffi::GST_PLAY_STATE_STOPPED => Self::Stopped, + ffi::GST_PLAY_STATE_BUFFERING => Self::Buffering, + ffi::GST_PLAY_STATE_PAUSED => Self::Paused, + ffi::GST_PLAY_STATE_PLAYING => Self::Playing, + value => Self::__Unknown(value), + } + } +} + +impl StaticType for PlayState { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_play_state_get_type()) } + } +} + +impl glib::value::ValueType for PlayState { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for PlayState { + type Checker = glib::value::GenericValueTypeChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for PlayState { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} diff --git a/gstreamer-play/src/auto/mod.rs b/gstreamer-play/src/auto/mod.rs new file mode 100644 index 000000000..a35a85ae9 --- /dev/null +++ b/gstreamer-play/src/auto/mod.rs @@ -0,0 +1,47 @@ +// 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 + +mod play; +pub use self::play::Play; + +mod play_audio_info; +pub use self::play_audio_info::PlayAudioInfo; + +mod play_media_info; +pub use self::play_media_info::PlayMediaInfo; + +mod play_signal_adapter; +pub use self::play_signal_adapter::PlaySignalAdapter; + +mod play_stream_info; +pub use self::play_stream_info::PlayStreamInfo; + +mod play_subtitle_info; +pub use self::play_subtitle_info::PlaySubtitleInfo; + +mod play_video_info; +pub use self::play_video_info::PlayVideoInfo; + +mod play_video_overlay_video_renderer; +pub use self::play_video_overlay_video_renderer::PlayVideoOverlayVideoRenderer; + +mod play_video_renderer; +pub use self::play_video_renderer::PlayVideoRenderer; + +mod play_visualization; +pub use self::play_visualization::PlayVisualization; + +mod enums; +pub use self::enums::PlayColorBalanceType; +pub use self::enums::PlayError; +pub(crate) use self::enums::PlayMessage; +pub use self::enums::PlaySnapshotFormat; +pub use self::enums::PlayState; + +#[doc(hidden)] +pub mod traits { + pub use super::play_stream_info::PlayStreamInfoExt; + pub use super::play_video_renderer::PlayVideoRendererExt; +} diff --git a/gstreamer-play/src/auto/play.rs b/gstreamer-play/src/auto/play.rs new file mode 100644 index 000000000..6e0b5c36d --- /dev/null +++ b/gstreamer-play/src/auto/play.rs @@ -0,0 +1,899 @@ +// 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 crate::PlayAudioInfo; +use crate::PlayColorBalanceType; +use crate::PlayMediaInfo; +use crate::PlaySnapshotFormat; +use crate::PlaySubtitleInfo; +use crate::PlayVideoInfo; +use crate::PlayVideoRenderer; +use crate::PlayVisualization; +use glib::object::IsA; +use glib::object::ObjectType as ObjectType_; +use glib::signal::connect_raw; +use glib::signal::SignalHandlerId; +use glib::translate::*; +use glib::StaticType; +use glib::ToValue; +use std::boxed::Box as Box_; +use std::mem::transmute; + +glib::wrapper! { + #[doc(alias = "GstPlay")] + pub struct Play(Object) @extends gst::Object; + + match fn { + type_ => || ffi::gst_play_get_type(), + } +} + +impl Play { + #[doc(alias = "gst_play_new")] + pub fn new(video_renderer: Option<&impl IsA>) -> Play { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gst_play_new( + video_renderer.map(|p| p.as_ref()).to_glib_full(), + )) + } + } + + #[doc(alias = "gst_play_get_audio_video_offset")] + #[doc(alias = "get_audio_video_offset")] + pub fn audio_video_offset(&self) -> i64 { + unsafe { ffi::gst_play_get_audio_video_offset(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_get_color_balance")] + #[doc(alias = "get_color_balance")] + pub fn color_balance(&self, type_: PlayColorBalanceType) -> f64 { + unsafe { ffi::gst_play_get_color_balance(self.to_glib_none().0, type_.into_glib()) } + } + + #[doc(alias = "gst_play_get_current_audio_track")] + #[doc(alias = "get_current_audio_track")] + pub fn current_audio_track(&self) -> Option { + unsafe { from_glib_full(ffi::gst_play_get_current_audio_track(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_current_subtitle_track")] + #[doc(alias = "get_current_subtitle_track")] + pub fn current_subtitle_track(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_play_get_current_subtitle_track( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_get_current_video_track")] + #[doc(alias = "get_current_video_track")] + pub fn current_video_track(&self) -> Option { + unsafe { from_glib_full(ffi::gst_play_get_current_video_track(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_current_visualization")] + #[doc(alias = "get_current_visualization")] + pub fn current_visualization(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_play_get_current_visualization( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_get_duration")] + #[doc(alias = "get_duration")] + pub fn duration(&self) -> Option { + unsafe { from_glib(ffi::gst_play_get_duration(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_media_info")] + #[doc(alias = "get_media_info")] + pub fn media_info(&self) -> Option { + unsafe { from_glib_full(ffi::gst_play_get_media_info(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_message_bus")] + #[doc(alias = "get_message_bus")] + pub fn message_bus(&self) -> gst::Bus { + unsafe { from_glib_full(ffi::gst_play_get_message_bus(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_multiview_flags")] + #[doc(alias = "get_multiview_flags")] + pub fn multiview_flags(&self) -> gst_video::VideoMultiviewFlags { + unsafe { from_glib(ffi::gst_play_get_multiview_flags(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_multiview_mode")] + #[doc(alias = "get_multiview_mode")] + pub fn multiview_mode(&self) -> gst_video::VideoMultiviewFramePacking { + unsafe { from_glib(ffi::gst_play_get_multiview_mode(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_mute")] + #[doc(alias = "get_mute")] + pub fn is_muted(&self) -> bool { + unsafe { from_glib(ffi::gst_play_get_mute(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_pipeline")] + #[doc(alias = "get_pipeline")] + pub fn pipeline(&self) -> gst::Element { + unsafe { from_glib_full(ffi::gst_play_get_pipeline(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_position")] + #[doc(alias = "get_position")] + pub fn position(&self) -> Option { + unsafe { from_glib(ffi::gst_play_get_position(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_rate")] + #[doc(alias = "get_rate")] + pub fn rate(&self) -> f64 { + unsafe { ffi::gst_play_get_rate(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_get_subtitle_uri")] + #[doc(alias = "get_subtitle_uri")] + pub fn subtitle_uri(&self) -> Option { + unsafe { from_glib_full(ffi::gst_play_get_subtitle_uri(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_subtitle_video_offset")] + #[doc(alias = "get_subtitle_video_offset")] + pub fn subtitle_video_offset(&self) -> i64 { + unsafe { ffi::gst_play_get_subtitle_video_offset(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_get_uri")] + #[doc(alias = "get_uri")] + pub fn uri(&self) -> Option { + unsafe { from_glib_full(ffi::gst_play_get_uri(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_get_video_snapshot")] + #[doc(alias = "get_video_snapshot")] + pub fn video_snapshot( + &self, + format: PlaySnapshotFormat, + config: Option<&gst::Structure>, + ) -> Option { + unsafe { + from_glib_full(ffi::gst_play_get_video_snapshot( + self.to_glib_none().0, + format.into_glib(), + config.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_get_volume")] + #[doc(alias = "get_volume")] + pub fn volume(&self) -> f64 { + unsafe { ffi::gst_play_get_volume(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_has_color_balance")] + pub fn has_color_balance(&self) -> bool { + unsafe { from_glib(ffi::gst_play_has_color_balance(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_pause")] + pub fn pause(&self) { + unsafe { + ffi::gst_play_pause(self.to_glib_none().0); + } + } + + #[doc(alias = "gst_play_play")] + pub fn play(&self) { + unsafe { + ffi::gst_play_play(self.to_glib_none().0); + } + } + + #[doc(alias = "gst_play_seek")] + pub fn seek(&self, position: gst::ClockTime) { + unsafe { + ffi::gst_play_seek(self.to_glib_none().0, position.into_glib()); + } + } + + #[doc(alias = "gst_play_set_audio_track")] + pub fn set_audio_track(&self, stream_index: i32) -> Result<(), glib::error::BoolError> { + unsafe { + glib::result_from_gboolean!( + ffi::gst_play_set_audio_track(self.to_glib_none().0, stream_index), + "Failed to set audio track" + ) + } + } + + #[doc(alias = "gst_play_set_audio_track_enabled")] + pub fn set_audio_track_enabled(&self, enabled: bool) { + unsafe { + ffi::gst_play_set_audio_track_enabled(self.to_glib_none().0, enabled.into_glib()); + } + } + + #[doc(alias = "gst_play_set_audio_video_offset")] + pub fn set_audio_video_offset(&self, offset: i64) { + unsafe { + ffi::gst_play_set_audio_video_offset(self.to_glib_none().0, offset); + } + } + + #[doc(alias = "gst_play_set_color_balance")] + pub fn set_color_balance(&self, type_: PlayColorBalanceType, value: f64) { + unsafe { + ffi::gst_play_set_color_balance(self.to_glib_none().0, type_.into_glib(), value); + } + } + + #[doc(alias = "gst_play_set_multiview_flags")] + pub fn set_multiview_flags(&self, flags: gst_video::VideoMultiviewFlags) { + unsafe { + ffi::gst_play_set_multiview_flags(self.to_glib_none().0, flags.into_glib()); + } + } + + #[doc(alias = "gst_play_set_multiview_mode")] + pub fn set_multiview_mode(&self, mode: gst_video::VideoMultiviewFramePacking) { + unsafe { + ffi::gst_play_set_multiview_mode(self.to_glib_none().0, mode.into_glib()); + } + } + + #[doc(alias = "gst_play_set_mute")] + pub fn set_mute(&self, val: bool) { + unsafe { + ffi::gst_play_set_mute(self.to_glib_none().0, val.into_glib()); + } + } + + #[doc(alias = "gst_play_set_rate")] + pub fn set_rate(&self, rate: f64) { + unsafe { + ffi::gst_play_set_rate(self.to_glib_none().0, rate); + } + } + + #[doc(alias = "gst_play_set_subtitle_track")] + pub fn set_subtitle_track(&self, stream_index: i32) -> Result<(), glib::error::BoolError> { + unsafe { + glib::result_from_gboolean!( + ffi::gst_play_set_subtitle_track(self.to_glib_none().0, stream_index), + "Failed to set subtitle track" + ) + } + } + + #[doc(alias = "gst_play_set_subtitle_track_enabled")] + pub fn set_subtitle_track_enabled(&self, enabled: bool) { + unsafe { + ffi::gst_play_set_subtitle_track_enabled(self.to_glib_none().0, enabled.into_glib()); + } + } + + #[doc(alias = "gst_play_set_subtitle_uri")] + pub fn set_subtitle_uri(&self, uri: Option<&str>) { + unsafe { + ffi::gst_play_set_subtitle_uri(self.to_glib_none().0, uri.to_glib_none().0); + } + } + + #[doc(alias = "gst_play_set_subtitle_video_offset")] + pub fn set_subtitle_video_offset(&self, offset: i64) { + unsafe { + ffi::gst_play_set_subtitle_video_offset(self.to_glib_none().0, offset); + } + } + + #[doc(alias = "gst_play_set_uri")] + pub fn set_uri(&self, uri: Option<&str>) { + unsafe { + ffi::gst_play_set_uri(self.to_glib_none().0, uri.to_glib_none().0); + } + } + + #[doc(alias = "gst_play_set_video_track")] + pub fn set_video_track(&self, stream_index: i32) -> Result<(), glib::error::BoolError> { + unsafe { + glib::result_from_gboolean!( + ffi::gst_play_set_video_track(self.to_glib_none().0, stream_index), + "Failed to set video track" + ) + } + } + + #[doc(alias = "gst_play_set_video_track_enabled")] + pub fn set_video_track_enabled(&self, enabled: bool) { + unsafe { + ffi::gst_play_set_video_track_enabled(self.to_glib_none().0, enabled.into_glib()); + } + } + + #[doc(alias = "gst_play_set_visualization")] + pub fn set_visualization(&self, name: Option<&str>) -> Result<(), glib::error::BoolError> { + unsafe { + glib::result_from_gboolean!( + ffi::gst_play_set_visualization(self.to_glib_none().0, name.to_glib_none().0), + "Failed to set visualization" + ) + } + } + + #[doc(alias = "gst_play_set_visualization_enabled")] + pub fn set_visualization_enabled(&self, enabled: bool) { + unsafe { + ffi::gst_play_set_visualization_enabled(self.to_glib_none().0, enabled.into_glib()); + } + } + + #[doc(alias = "gst_play_set_volume")] + pub fn set_volume(&self, val: f64) { + unsafe { + ffi::gst_play_set_volume(self.to_glib_none().0, val); + } + } + + #[doc(alias = "gst_play_stop")] + pub fn stop(&self) { + unsafe { + ffi::gst_play_stop(self.to_glib_none().0); + } + } + + pub fn suburi(&self) -> Option { + glib::ObjectExt::property(self, "suburi") + } + + pub fn set_suburi(&self, suburi: Option<&str>) { + glib::ObjectExt::set_property(self, "suburi", &suburi) + } + + #[doc(alias = "video-multiview-flags")] + pub fn video_multiview_flags(&self) -> gst_video::VideoMultiviewFlags { + glib::ObjectExt::property(self, "video-multiview-flags") + } + + #[doc(alias = "video-multiview-flags")] + pub fn set_video_multiview_flags(&self, video_multiview_flags: gst_video::VideoMultiviewFlags) { + glib::ObjectExt::set_property(self, "video-multiview-flags", &video_multiview_flags) + } + + #[doc(alias = "video-multiview-mode")] + pub fn video_multiview_mode(&self) -> gst_video::VideoMultiviewFramePacking { + glib::ObjectExt::property(self, "video-multiview-mode") + } + + #[doc(alias = "video-multiview-mode")] + pub fn set_video_multiview_mode( + &self, + video_multiview_mode: gst_video::VideoMultiviewFramePacking, + ) { + glib::ObjectExt::set_property(self, "video-multiview-mode", &video_multiview_mode) + } + + #[doc(alias = "video-renderer")] + pub fn video_renderer(&self) -> Option { + glib::ObjectExt::property(self, "video-renderer") + } + + #[doc(alias = "video-renderer")] + pub fn set_video_renderer>(&self, video_renderer: Option<&P>) { + glib::ObjectExt::set_property(self, "video-renderer", &video_renderer) + } + + #[doc(alias = "gst_play_get_audio_streams")] + #[doc(alias = "get_audio_streams")] + pub fn audio_streams(info: &PlayMediaInfo) -> Vec { + skip_assert_initialized!(); + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::gst_play_get_audio_streams( + info.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_get_subtitle_streams")] + #[doc(alias = "get_subtitle_streams")] + pub fn subtitle_streams(info: &PlayMediaInfo) -> Vec { + skip_assert_initialized!(); + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::gst_play_get_subtitle_streams( + info.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_get_video_streams")] + #[doc(alias = "get_video_streams")] + pub fn video_streams(info: &PlayMediaInfo) -> Vec { + skip_assert_initialized!(); + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::gst_play_get_video_streams( + info.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_is_play_message")] + pub fn is_play_message(msg: &gst::Message) -> bool { + assert_initialized_main_thread!(); + unsafe { from_glib(ffi::gst_play_is_play_message(msg.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_visualizations_get")] + pub fn visualizations_get() -> Vec { + assert_initialized_main_thread!(); + unsafe { FromGlibPtrContainer::from_glib_full(ffi::gst_play_visualizations_get()) } + } + + #[doc(alias = "audio-video-offset")] + pub fn connect_audio_video_offset_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_audio_video_offset_trampoline< + F: Fn(&Play) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::audio-video-offset\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_audio_video_offset_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "current-audio-track")] + pub fn connect_current_audio_track_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_current_audio_track_trampoline< + F: Fn(&Play) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::current-audio-track\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_current_audio_track_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "current-subtitle-track")] + pub fn connect_current_subtitle_track_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_current_subtitle_track_trampoline< + F: Fn(&Play) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::current-subtitle-track\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_current_subtitle_track_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "current-video-track")] + pub fn connect_current_video_track_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_current_video_track_trampoline< + F: Fn(&Play) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::current-video-track\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_current_video_track_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "duration")] + pub fn connect_duration_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_duration_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::duration\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_duration_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "media-info")] + pub fn connect_media_info_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_media_info_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::media-info\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_media_info_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "mute")] + pub fn connect_mute_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_mute_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::mute\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_mute_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "pipeline")] + pub fn connect_pipeline_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_pipeline_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::pipeline\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_pipeline_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "position")] + pub fn connect_position_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_position_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::position\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_position_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "rate")] + pub fn connect_rate_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_rate_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::rate\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_rate_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "subtitle-video-offset")] + pub fn connect_subtitle_video_offset_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_subtitle_video_offset_trampoline< + F: Fn(&Play) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::subtitle-video-offset\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_subtitle_video_offset_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "suburi")] + pub fn connect_suburi_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_suburi_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::suburi\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_suburi_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "uri")] + pub fn connect_uri_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_uri_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::uri\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_uri_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "video-multiview-flags")] + pub fn connect_video_multiview_flags_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_video_multiview_flags_trampoline< + F: Fn(&Play) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::video-multiview-flags\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_video_multiview_flags_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "video-multiview-mode")] + pub fn connect_video_multiview_mode_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_video_multiview_mode_trampoline< + F: Fn(&Play) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::video-multiview-mode\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_video_multiview_mode_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "video-renderer")] + pub fn connect_video_renderer_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_video_renderer_trampoline< + F: Fn(&Play) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::video-renderer\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_video_renderer_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "volume")] + pub fn connect_volume_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_volume_trampoline( + this: *mut ffi::GstPlay, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::volume\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_volume_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +unsafe impl Send for Play {} +unsafe impl Sync for Play {} diff --git a/gstreamer-play/src/auto/play_audio_info.rs b/gstreamer-play/src/auto/play_audio_info.rs new file mode 100644 index 000000000..68b802bac --- /dev/null +++ b/gstreamer-play/src/auto/play_audio_info.rs @@ -0,0 +1,51 @@ +// 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 crate::PlayStreamInfo; +use glib::translate::*; + +glib::wrapper! { + #[doc(alias = "GstPlayAudioInfo")] + pub struct PlayAudioInfo(Object) @extends PlayStreamInfo; + + match fn { + type_ => || ffi::gst_play_audio_info_get_type(), + } +} + +impl PlayAudioInfo { + #[doc(alias = "gst_play_audio_info_get_bitrate")] + #[doc(alias = "get_bitrate")] + pub fn bitrate(&self) -> i32 { + unsafe { ffi::gst_play_audio_info_get_bitrate(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_audio_info_get_channels")] + #[doc(alias = "get_channels")] + pub fn channels(&self) -> i32 { + unsafe { ffi::gst_play_audio_info_get_channels(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_audio_info_get_language")] + #[doc(alias = "get_language")] + pub fn language(&self) -> Option { + unsafe { from_glib_none(ffi::gst_play_audio_info_get_language(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_audio_info_get_max_bitrate")] + #[doc(alias = "get_max_bitrate")] + pub fn max_bitrate(&self) -> i32 { + unsafe { ffi::gst_play_audio_info_get_max_bitrate(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_audio_info_get_sample_rate")] + #[doc(alias = "get_sample_rate")] + pub fn sample_rate(&self) -> i32 { + unsafe { ffi::gst_play_audio_info_get_sample_rate(self.to_glib_none().0) } + } +} + +unsafe impl Send for PlayAudioInfo {} +unsafe impl Sync for PlayAudioInfo {} diff --git a/gstreamer-play/src/auto/play_media_info.rs b/gstreamer-play/src/auto/play_media_info.rs new file mode 100644 index 000000000..a6df5bbcb --- /dev/null +++ b/gstreamer-play/src/auto/play_media_info.rs @@ -0,0 +1,142 @@ +// 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 crate::PlayAudioInfo; +use crate::PlayStreamInfo; +use crate::PlaySubtitleInfo; +use crate::PlayVideoInfo; +use glib::translate::*; + +glib::wrapper! { + #[doc(alias = "GstPlayMediaInfo")] + pub struct PlayMediaInfo(Object); + + match fn { + type_ => || ffi::gst_play_media_info_get_type(), + } +} + +impl PlayMediaInfo { + #[doc(alias = "gst_play_media_info_get_audio_streams")] + #[doc(alias = "get_audio_streams")] + pub fn audio_streams(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::gst_play_media_info_get_audio_streams( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_media_info_get_container_format")] + #[doc(alias = "get_container_format")] + pub fn container_format(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_play_media_info_get_container_format( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_media_info_get_duration")] + #[doc(alias = "get_duration")] + pub fn duration(&self) -> Option { + unsafe { from_glib(ffi::gst_play_media_info_get_duration(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_media_info_get_image_sample")] + #[doc(alias = "get_image_sample")] + pub fn image_sample(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_play_media_info_get_image_sample( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_media_info_get_number_of_audio_streams")] + #[doc(alias = "get_number_of_audio_streams")] + pub fn number_of_audio_streams(&self) -> u32 { + unsafe { ffi::gst_play_media_info_get_number_of_audio_streams(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_media_info_get_number_of_streams")] + #[doc(alias = "get_number_of_streams")] + pub fn number_of_streams(&self) -> u32 { + unsafe { ffi::gst_play_media_info_get_number_of_streams(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_media_info_get_number_of_subtitle_streams")] + #[doc(alias = "get_number_of_subtitle_streams")] + pub fn number_of_subtitle_streams(&self) -> u32 { + unsafe { ffi::gst_play_media_info_get_number_of_subtitle_streams(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_media_info_get_number_of_video_streams")] + #[doc(alias = "get_number_of_video_streams")] + pub fn number_of_video_streams(&self) -> u32 { + unsafe { ffi::gst_play_media_info_get_number_of_video_streams(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_media_info_get_stream_list")] + #[doc(alias = "get_stream_list")] + pub fn stream_list(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::gst_play_media_info_get_stream_list( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_media_info_get_subtitle_streams")] + #[doc(alias = "get_subtitle_streams")] + pub fn subtitle_streams(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::gst_play_media_info_get_subtitle_streams( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_media_info_get_tags")] + #[doc(alias = "get_tags")] + pub fn tags(&self) -> Option { + unsafe { from_glib_none(ffi::gst_play_media_info_get_tags(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_media_info_get_title")] + #[doc(alias = "get_title")] + pub fn title(&self) -> Option { + unsafe { from_glib_none(ffi::gst_play_media_info_get_title(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_media_info_get_uri")] + #[doc(alias = "get_uri")] + pub fn uri(&self) -> glib::GString { + unsafe { from_glib_none(ffi::gst_play_media_info_get_uri(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_media_info_get_video_streams")] + #[doc(alias = "get_video_streams")] + pub fn video_streams(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::gst_play_media_info_get_video_streams( + self.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_media_info_is_live")] + pub fn is_live(&self) -> bool { + unsafe { from_glib(ffi::gst_play_media_info_is_live(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_media_info_is_seekable")] + pub fn is_seekable(&self) -> bool { + unsafe { from_glib(ffi::gst_play_media_info_is_seekable(self.to_glib_none().0)) } + } +} + +unsafe impl Send for PlayMediaInfo {} +unsafe impl Sync for PlayMediaInfo {} diff --git a/gstreamer-play/src/auto/play_signal_adapter.rs b/gstreamer-play/src/auto/play_signal_adapter.rs new file mode 100644 index 000000000..d2c82da00 --- /dev/null +++ b/gstreamer-play/src/auto/play_signal_adapter.rs @@ -0,0 +1,378 @@ +// 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 crate::Play; +use crate::PlayMediaInfo; +use crate::PlayState; +use glib::object::ObjectType as ObjectType_; +use glib::signal::connect_raw; +use glib::signal::SignalHandlerId; +use glib::translate::*; +use std::boxed::Box as Box_; +use std::mem::transmute; + +glib::wrapper! { + #[doc(alias = "GstPlaySignalAdapter")] + pub struct PlaySignalAdapter(Object); + + match fn { + type_ => || ffi::gst_play_signal_adapter_get_type(), + } +} + +impl PlaySignalAdapter { + #[doc(alias = "gst_play_signal_adapter_new")] + pub fn new(play: &Play) -> PlaySignalAdapter { + skip_assert_initialized!(); + unsafe { from_glib_full(ffi::gst_play_signal_adapter_new(play.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_signal_adapter_new_sync_emit")] + pub fn new_sync_emit(play: &Play) -> PlaySignalAdapter { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::gst_play_signal_adapter_new_sync_emit( + play.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_signal_adapter_new_with_main_context")] + #[doc(alias = "new_with_main_context")] + pub fn with_main_context(play: &Play, context: &glib::MainContext) -> PlaySignalAdapter { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::gst_play_signal_adapter_new_with_main_context( + play.to_glib_none().0, + context.to_glib_none().0, + )) + } + } + + #[doc(alias = "gst_play_signal_adapter_get_play")] + #[doc(alias = "get_play")] + pub fn play(&self) -> Play { + unsafe { from_glib_none(ffi::gst_play_signal_adapter_get_play(self.to_glib_none().0)) } + } + + #[doc(alias = "buffering")] + pub fn connect_buffering(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn buffering_trampoline< + F: Fn(&PlaySignalAdapter, i32) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: libc::c_int, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), object) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"buffering\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + buffering_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "end-of-stream")] + pub fn connect_end_of_stream(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn end_of_stream_trampoline< + F: Fn(&PlaySignalAdapter) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"end-of-stream\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + end_of_stream_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "error")] + pub fn connect_error) + Send + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn error_trampoline< + F: Fn(&PlaySignalAdapter, &glib::Error, Option<&gst::Structure>) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: *mut glib::ffi::GError, + p0: *mut gst::ffi::GstStructure, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + &from_glib_borrow(object), + Option::::from_glib_borrow(p0) + .as_ref() + .as_ref(), + ) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"error\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + error_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "media-info-updated")] + pub fn connect_media_info_updated( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn media_info_updated_trampoline< + F: Fn(&PlaySignalAdapter, &PlayMediaInfo) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: *mut ffi::GstPlayMediaInfo, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), &from_glib_borrow(object)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"media-info-updated\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + media_info_updated_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "mute-changed")] + pub fn connect_mute_changed( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn mute_changed_trampoline< + F: Fn(&PlaySignalAdapter, bool) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: glib::ffi::gboolean, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), from_glib(object)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"mute-changed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + mute_changed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "state-changed")] + pub fn connect_state_changed( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn state_changed_trampoline< + F: Fn(&PlaySignalAdapter, PlayState) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: ffi::GstPlayState, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), from_glib(object)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"state-changed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + state_changed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "uri-loaded")] + pub fn connect_uri_loaded(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn uri_loaded_trampoline< + F: Fn(&PlaySignalAdapter, &str) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: *mut libc::c_char, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + &glib::GString::from_glib_borrow(object), + ) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"uri-loaded\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + uri_loaded_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "video-dimensions-changed")] + pub fn connect_video_dimensions_changed( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn video_dimensions_changed_trampoline< + F: Fn(&PlaySignalAdapter, u32, u32) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: libc::c_uint, + p0: libc::c_uint, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), object, p0) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"video-dimensions-changed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + video_dimensions_changed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "volume-changed")] + pub fn connect_volume_changed( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn volume_changed_trampoline< + F: Fn(&PlaySignalAdapter, f64) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: libc::c_double, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), object) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"volume-changed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + volume_changed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "warning")] + pub fn connect_warning) + Send + 'static>( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn warning_trampoline< + F: Fn(&PlaySignalAdapter, &glib::Error, Option<&gst::Structure>) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: *mut glib::ffi::GError, + p0: *mut gst::ffi::GstStructure, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + &from_glib_borrow(object), + Option::::from_glib_borrow(p0) + .as_ref() + .as_ref(), + ) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"warning\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + warning_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "play")] + pub fn connect_play_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_play_trampoline< + F: Fn(&PlaySignalAdapter) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::play\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_play_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +unsafe impl Send for PlaySignalAdapter {} +unsafe impl Sync for PlaySignalAdapter {} diff --git a/gstreamer-play/src/auto/play_stream_info.rs b/gstreamer-play/src/auto/play_stream_info.rs new file mode 100644 index 000000000..13a0ea67e --- /dev/null +++ b/gstreamer-play/src/auto/play_stream_info.rs @@ -0,0 +1,85 @@ +// 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::object::IsA; +use glib::translate::*; + +glib::wrapper! { + #[doc(alias = "GstPlayStreamInfo")] + pub struct PlayStreamInfo(Object); + + match fn { + type_ => || ffi::gst_play_stream_info_get_type(), + } +} + +impl PlayStreamInfo { + pub const NONE: Option<&'static PlayStreamInfo> = None; +} + +unsafe impl Send for PlayStreamInfo {} +unsafe impl Sync for PlayStreamInfo {} + +pub trait PlayStreamInfoExt: 'static { + #[doc(alias = "gst_play_stream_info_get_caps")] + #[doc(alias = "get_caps")] + fn caps(&self) -> Option; + + #[doc(alias = "gst_play_stream_info_get_codec")] + #[doc(alias = "get_codec")] + fn codec(&self) -> Option; + + #[doc(alias = "gst_play_stream_info_get_index")] + #[doc(alias = "get_index")] + fn index(&self) -> i32; + + #[doc(alias = "gst_play_stream_info_get_stream_type")] + #[doc(alias = "get_stream_type")] + fn stream_type(&self) -> glib::GString; + + #[doc(alias = "gst_play_stream_info_get_tags")] + #[doc(alias = "get_tags")] + fn tags(&self) -> Option; +} + +impl> PlayStreamInfoExt for O { + fn caps(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_play_stream_info_get_caps(const_override( + self.as_ref().to_glib_none().0, + ))) + } + } + + fn codec(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_play_stream_info_get_codec(const_override( + self.as_ref().to_glib_none().0, + ))) + } + } + + fn index(&self) -> i32 { + unsafe { + ffi::gst_play_stream_info_get_index(const_override(self.as_ref().to_glib_none().0)) + } + } + + fn stream_type(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::gst_play_stream_info_get_stream_type(const_override( + self.as_ref().to_glib_none().0, + ))) + } + } + + fn tags(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_play_stream_info_get_tags(const_override( + self.as_ref().to_glib_none().0, + ))) + } + } +} diff --git a/gstreamer-play/src/auto/play_subtitle_info.rs b/gstreamer-play/src/auto/play_subtitle_info.rs new file mode 100644 index 000000000..292ae8bfd --- /dev/null +++ b/gstreamer-play/src/auto/play_subtitle_info.rs @@ -0,0 +1,31 @@ +// 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 crate::PlayStreamInfo; +use glib::translate::*; + +glib::wrapper! { + #[doc(alias = "GstPlaySubtitleInfo")] + pub struct PlaySubtitleInfo(Object) @extends PlayStreamInfo; + + match fn { + type_ => || ffi::gst_play_subtitle_info_get_type(), + } +} + +impl PlaySubtitleInfo { + #[doc(alias = "gst_play_subtitle_info_get_language")] + #[doc(alias = "get_language")] + pub fn language(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_play_subtitle_info_get_language( + self.to_glib_none().0, + )) + } + } +} + +unsafe impl Send for PlaySubtitleInfo {} +unsafe impl Sync for PlaySubtitleInfo {} diff --git a/gstreamer-play/src/auto/play_video_info.rs b/gstreamer-play/src/auto/play_video_info.rs new file mode 100644 index 000000000..72b0d0c98 --- /dev/null +++ b/gstreamer-play/src/auto/play_video_info.rs @@ -0,0 +1,45 @@ +// 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 crate::PlayStreamInfo; +use glib::translate::*; + +glib::wrapper! { + #[doc(alias = "GstPlayVideoInfo")] + pub struct PlayVideoInfo(Object) @extends PlayStreamInfo; + + match fn { + type_ => || ffi::gst_play_video_info_get_type(), + } +} + +impl PlayVideoInfo { + #[doc(alias = "gst_play_video_info_get_bitrate")] + #[doc(alias = "get_bitrate")] + pub fn bitrate(&self) -> i32 { + unsafe { ffi::gst_play_video_info_get_bitrate(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_video_info_get_height")] + #[doc(alias = "get_height")] + pub fn height(&self) -> i32 { + unsafe { ffi::gst_play_video_info_get_height(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_video_info_get_max_bitrate")] + #[doc(alias = "get_max_bitrate")] + pub fn max_bitrate(&self) -> i32 { + unsafe { ffi::gst_play_video_info_get_max_bitrate(self.to_glib_none().0) } + } + + #[doc(alias = "gst_play_video_info_get_width")] + #[doc(alias = "get_width")] + pub fn width(&self) -> i32 { + unsafe { ffi::gst_play_video_info_get_width(self.to_glib_none().0) } + } +} + +unsafe impl Send for PlayVideoInfo {} +unsafe impl Sync for PlayVideoInfo {} diff --git a/gstreamer-play/src/auto/play_video_overlay_video_renderer.rs b/gstreamer-play/src/auto/play_video_overlay_video_renderer.rs new file mode 100644 index 000000000..49568a36c --- /dev/null +++ b/gstreamer-play/src/auto/play_video_overlay_video_renderer.rs @@ -0,0 +1,140 @@ +// 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 crate::PlayVideoRenderer; +use glib::object::IsA; +use glib::object::ObjectType as ObjectType_; +use glib::signal::connect_raw; +use glib::signal::SignalHandlerId; +use glib::translate::*; +use glib::StaticType; +use glib::ToValue; +use std::boxed::Box as Box_; +use std::mem; +use std::mem::transmute; + +glib::wrapper! { + #[doc(alias = "GstPlayVideoOverlayVideoRenderer")] + pub struct PlayVideoOverlayVideoRenderer(Object) @implements PlayVideoRenderer; + + match fn { + type_ => || ffi::gst_play_video_overlay_video_renderer_get_type(), + } +} + +impl PlayVideoOverlayVideoRenderer { + #[doc(alias = "gst_play_video_overlay_video_renderer_expose")] + pub fn expose(&self) { + unsafe { + ffi::gst_play_video_overlay_video_renderer_expose(self.to_glib_none().0); + } + } + + #[doc(alias = "gst_play_video_overlay_video_renderer_get_render_rectangle")] + #[doc(alias = "get_render_rectangle")] + pub fn render_rectangle(&self) -> (i32, i32, i32, i32) { + unsafe { + let mut x = mem::MaybeUninit::uninit(); + let mut y = mem::MaybeUninit::uninit(); + let mut width = mem::MaybeUninit::uninit(); + let mut height = mem::MaybeUninit::uninit(); + ffi::gst_play_video_overlay_video_renderer_get_render_rectangle( + self.to_glib_none().0, + x.as_mut_ptr(), + y.as_mut_ptr(), + width.as_mut_ptr(), + height.as_mut_ptr(), + ); + ( + x.assume_init(), + y.assume_init(), + width.assume_init(), + height.assume_init(), + ) + } + } + + #[doc(alias = "gst_play_video_overlay_video_renderer_set_render_rectangle")] + pub fn set_render_rectangle(&self, x: i32, y: i32, width: i32, height: i32) { + unsafe { + ffi::gst_play_video_overlay_video_renderer_set_render_rectangle( + self.to_glib_none().0, + x, + y, + width, + height, + ); + } + } + + #[doc(alias = "video-sink")] + pub fn video_sink(&self) -> Option { + glib::ObjectExt::property(self, "video-sink") + } + + #[doc(alias = "video-sink")] + pub fn set_video_sink>(&self, video_sink: Option<&P>) { + glib::ObjectExt::set_property(self, "video-sink", &video_sink) + } + + #[doc(alias = "video-sink")] + pub fn connect_video_sink_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_video_sink_trampoline< + F: Fn(&PlayVideoOverlayVideoRenderer) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlayVideoOverlayVideoRenderer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::video-sink\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_video_sink_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "window-handle")] + pub fn connect_window_handle_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_window_handle_trampoline< + F: Fn(&PlayVideoOverlayVideoRenderer) + Send + Sync + 'static, + >( + this: *mut ffi::GstPlayVideoOverlayVideoRenderer, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this)) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::window-handle\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_window_handle_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} + +unsafe impl Send for PlayVideoOverlayVideoRenderer {} +unsafe impl Sync for PlayVideoOverlayVideoRenderer {} diff --git a/gstreamer-play/src/auto/play_video_renderer.rs b/gstreamer-play/src/auto/play_video_renderer.rs new file mode 100644 index 000000000..a27cd8dc7 --- /dev/null +++ b/gstreamer-play/src/auto/play_video_renderer.rs @@ -0,0 +1,26 @@ +// 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::object::IsA; + +glib::wrapper! { + #[doc(alias = "GstPlayVideoRenderer")] + pub struct PlayVideoRenderer(Interface); + + match fn { + type_ => || ffi::gst_play_video_renderer_get_type(), + } +} + +impl PlayVideoRenderer { + pub const NONE: Option<&'static PlayVideoRenderer> = None; +} + +unsafe impl Send for PlayVideoRenderer {} +unsafe impl Sync for PlayVideoRenderer {} + +pub trait PlayVideoRendererExt: 'static {} + +impl> PlayVideoRendererExt for O {} diff --git a/gstreamer-play/src/auto/play_visualization.rs b/gstreamer-play/src/auto/play_visualization.rs new file mode 100644 index 000000000..a93221bc8 --- /dev/null +++ b/gstreamer-play/src/auto/play_visualization.rs @@ -0,0 +1,18 @@ +// 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 + +glib::wrapper! { + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct PlayVisualization(Boxed); + + match fn { + copy => |ptr| ffi::gst_play_visualization_copy(ptr), + free => |ptr| ffi::gst_play_visualization_free(ptr), + type_ => || ffi::gst_play_visualization_get_type(), + } +} + +unsafe impl Send for PlayVisualization {} +unsafe impl Sync for PlayVisualization {} diff --git a/gstreamer-play/src/auto/versions.txt b/gstreamer-play/src/auto/versions.txt new file mode 100644 index 000000000..0e5d6057c --- /dev/null +++ b/gstreamer-play/src/auto/versions.txt @@ -0,0 +1,3 @@ +Generated by gir (https://github.com/gtk-rs/gir @ c063b4567de5) +from gir-files (https://github.com/gtk-rs/gir-files @ 7ebd4478b4a5) +from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 654191eba8d7) diff --git a/gstreamer-play/src/config.rs b/gstreamer-play/src/config.rs new file mode 100644 index 000000000..85ce84d5d --- /dev/null +++ b/gstreamer-play/src/config.rs @@ -0,0 +1,103 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use glib::translate::*; + +use std::mem; +use std::ops; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PlayConfig(gst::Structure); + +impl ops::Deref for PlayConfig { + type Target = gst::StructureRef; + + fn deref(&self) -> &gst::StructureRef { + self.0.deref() + } +} + +impl ops::DerefMut for PlayConfig { + fn deref_mut(&mut self) -> &mut gst::StructureRef { + self.0.deref_mut() + } +} + +impl AsRef for PlayConfig { + fn as_ref(&self) -> &gst::StructureRef { + self.0.as_ref() + } +} + +impl AsMut for PlayConfig { + fn as_mut(&mut self) -> &mut gst::StructureRef { + self.0.as_mut() + } +} + +impl PlayConfig { + #[doc(alias = "get_position_update_interval")] + #[doc(alias = "gst_play_config_get_position_update_interval")] + pub fn position_update_interval(&self) -> u32 { + assert_initialized_main_thread!(); + unsafe { ffi::gst_play_config_get_position_update_interval(self.0.to_glib_none().0) } + } + + #[doc(alias = "get_seek_accurate")] + pub fn is_seek_accurate(&self) -> bool { + assert_initialized_main_thread!(); + unsafe { + from_glib(ffi::gst_play_config_get_seek_accurate( + self.0.to_glib_none().0, + )) + } + } + + #[doc(alias = "get_user_agent")] + #[doc(alias = "gst_play_config_get_user_agent")] + pub fn user_agent(&self) -> Option { + assert_initialized_main_thread!(); + unsafe { from_glib_full(ffi::gst_play_config_get_user_agent(self.0.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_config_set_position_update_interval")] + pub fn set_position_update_interval(&mut self, interval: u32) { + assert_initialized_main_thread!(); + unsafe { + ffi::gst_play_config_set_position_update_interval( + self.0.to_glib_none_mut().0, + interval, + ); + } + } + + pub fn set_seek_accurate(&mut self, accurate: bool) { + assert_initialized_main_thread!(); + // FIXME: Work-around for + // http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=cc58bd6ae071dec4ea7b4be626034accd0372755 + self.set("accurate-seek", &accurate); + } + + #[doc(alias = "gst_play_config_set_user_agent")] + pub fn set_user_agent(&mut self, agent: &str) { + assert_initialized_main_thread!(); + unsafe { + ffi::gst_play_config_set_user_agent( + self.0.to_glib_none_mut().0, + agent.to_glib_none().0, + ); + } + } +} + +impl IntoGlibPtr<*mut gst::ffi::GstStructure> for PlayConfig { + unsafe fn into_glib_ptr(self) -> *mut gst::ffi::GstStructure { + let mut s = mem::ManuallyDrop::new(self); + s.0.to_glib_none_mut().0 + } +} + +impl FromGlibPtrFull<*mut gst::ffi::GstStructure> for PlayConfig { + unsafe fn from_glib_full(ptr: *mut gst::ffi::GstStructure) -> Self { + PlayConfig(from_glib_full(ptr)) + } +} diff --git a/gstreamer-play/src/lib.rs b/gstreamer-play/src/lib.rs new file mode 100644 index 000000000..809f05010 --- /dev/null +++ b/gstreamer-play/src/lib.rs @@ -0,0 +1,48 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +#![cfg_attr(feature = "dox", feature(doc_cfg))] +#![allow(clippy::missing_safety_doc)] +#![allow(clippy::non_send_fields_in_send_ty)] +#![doc = include_str!("../README.md")] + +pub use ffi; +pub use gst; +pub use gst_video; + +macro_rules! skip_assert_initialized { + () => {}; +} + +macro_rules! assert_initialized_main_thread { + () => {}; +} + +#[allow(clippy::needless_borrow)] +#[allow(unused_imports)] +mod auto; +pub(crate) use crate::auto::PlayMessage as PlayMessageType; +pub use crate::auto::*; + +pub mod subclass; + +mod config; +mod play; +pub use crate::config::*; + +mod play_video_info; + +mod play_signal_adapter; +mod play_video_overlay_video_renderer; +mod play_visualization; + +pub mod play_message; +pub use crate::play_message::PlayMessage; + +// Re-export all the traits in a prelude module, so that applications +// can always "use gst_player::prelude::*" without getting conflicts +pub mod prelude { + #[doc(hidden)] + pub use gst_video::prelude::*; + + pub use crate::auto::traits::*; +} diff --git a/gstreamer-play/src/play.rs b/gstreamer-play/src/play.rs new file mode 100644 index 000000000..b2272337b --- /dev/null +++ b/gstreamer-play/src/play.rs @@ -0,0 +1,22 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::Play; +use glib::translate::*; + +impl Play { + #[doc(alias = "get_config")] + #[doc(alias = "gst_play_get_config")] + pub fn config(&self) -> crate::PlayConfig { + unsafe { from_glib_full(ffi::gst_play_get_config(self.to_glib_none().0)) } + } + + #[doc(alias = "gst_play_set_config")] + pub fn set_config(&self, config: crate::PlayConfig) -> Result<(), glib::error::BoolError> { + unsafe { + glib::result_from_gboolean!( + ffi::gst_play_set_config(self.to_glib_none().0, config.into_glib_ptr()), + "Failed to set config", + ) + } + } +} diff --git a/gstreamer-play/src/play_message.rs b/gstreamer-play/src/play_message.rs new file mode 100644 index 000000000..4a5528f2d --- /dev/null +++ b/gstreamer-play/src/play_message.rs @@ -0,0 +1,105 @@ +use crate::PlayMessageType; +use crate::{PlayMediaInfo, PlayState}; + +#[derive(Clone, PartialEq, Debug)] +#[non_exhaustive] +#[doc(alias = "GstPlayMessage")] +pub enum PlayMessage { + #[doc(alias = "GST_PLAY_MESSAGE_URI_LOADED")] + UriLoaded, + #[doc(alias = "GST_PLAY_MESSAGE_POSITION_UPDATED")] + PositionUpdated { position: Option }, + #[doc(alias = "GST_PLAY_MESSAGE_DURATION_CHANGED")] + DurationChanged { duration: Option }, + #[doc(alias = "GST_PLAY_MESSAGE_STATE_CHANGED")] + StateChanged { state: PlayState }, + #[doc(alias = "GST_PLAY_MESSAGE_BUFFERING")] + Buffering { percent: u32 }, + #[doc(alias = "GST_PLAY_MESSAGE_END_OF_STREAM")] + EndOfStream, + #[doc(alias = "GST_PLAY_MESSAGE_ERROR")] + Error { + error: glib::Error, + details: Option, + }, + #[doc(alias = "GST_PLAY_MESSAGE_WARNING")] + Warning { + error: glib::Error, + details: Option, + }, + #[doc(alias = "GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED")] + VideoDimensionsChanged { width: u32, height: u32 }, + #[doc(alias = "GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED")] + MediaInfoUpdated { info: PlayMediaInfo }, + #[doc(alias = "GST_PLAY_MESSAGE_VOLUME_CHANGED")] + VolumeChanged { volume: f64 }, + #[doc(alias = "GST_PLAY_MESSAGE_MUTE_CHANGED")] + MuteChanged { muted: bool }, + #[doc(alias = "GST_PLAY_MESSAGE_SEEK_DONE")] + SeekDone, +} + +impl PlayMessage { + #[doc(alias = "gst_play_message_parse_position_updated")] + #[doc(alias = "gst_play_message_parse_duration_updated")] + #[doc(alias = "gst_play_message_parse_state_changed")] + #[doc(alias = "gst_play_message_parse_buffering_percent")] + #[doc(alias = "gst_play_message_parse_error")] + #[doc(alias = "gst_play_message_parse_warning")] + #[doc(alias = "gst_play_message_parse_video_dimensions_changed")] + #[doc(alias = "gst_play_message_parse_media_info_updated")] + #[doc(alias = "gst_play_message_parse_muted_changed")] + #[doc(alias = "gst_play_message_parse_volume_changed")] + pub fn parse(msg: &gst::Message) -> Result { + skip_assert_initialized!(); + if msg.type_() != gst::MessageType::Application { + return Err(glib::bool_error!("Invalid play message")); + } + match PlayMessageType::parse_type(msg) { + PlayMessageType::UriLoaded => Ok(Self::UriLoaded), + PlayMessageType::PositionUpdated => { + let position = PlayMessageType::parse_position_updated(msg); + Ok(Self::PositionUpdated { position }) + } + PlayMessageType::DurationChanged => { + let duration = PlayMessageType::parse_duration_updated(msg); + Ok(Self::DurationChanged { duration }) + } + PlayMessageType::StateChanged => { + let state = PlayMessageType::parse_state_changed(msg); + Ok(Self::StateChanged { state }) + } + PlayMessageType::Buffering => { + let percent = PlayMessageType::parse_buffering_percent(msg); + Ok(Self::Buffering { percent }) + } + PlayMessageType::EndOfStream => Ok(Self::EndOfStream), + PlayMessageType::Error => { + let (error, details) = PlayMessageType::parse_error(msg); + Ok(Self::Error { error, details }) + } + PlayMessageType::Warning => { + let (error, details) = PlayMessageType::parse_warning(msg); + Ok(Self::Warning { error, details }) + } + PlayMessageType::VideoDimensionsChanged => { + let (width, height) = PlayMessageType::parse_video_dimensions_changed(msg); + Ok(Self::VideoDimensionsChanged { width, height }) + } + PlayMessageType::MediaInfoUpdated => { + let info = PlayMessageType::parse_media_info_updated(msg); + Ok(Self::MediaInfoUpdated { info }) + } + PlayMessageType::VolumeChanged => { + let volume = PlayMessageType::parse_volume_changed(msg); + Ok(Self::VolumeChanged { volume }) + } + PlayMessageType::MuteChanged => { + let muted = PlayMessageType::parse_muted_changed(msg); + Ok(Self::MuteChanged { muted }) + } + PlayMessageType::SeekDone => Ok(Self::SeekDone), + _ => Err(glib::bool_error!("Invalid play message")), + } + } +} diff --git a/gstreamer-play/src/play_signal_adapter.rs b/gstreamer-play/src/play_signal_adapter.rs new file mode 100644 index 000000000..97b5b240b --- /dev/null +++ b/gstreamer-play/src/play_signal_adapter.rs @@ -0,0 +1,105 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::PlaySignalAdapter; +use glib::signal::connect_raw; +use glib::signal::SignalHandlerId; +use glib::translate::*; +use glib::ObjectType; +use std::boxed::Box as Box_; +use std::mem::transmute; + +impl PlaySignalAdapter { + #[doc(alias = "duration-changed")] + pub fn connect_duration_changed< + F: Fn(&PlaySignalAdapter, Option) + Send + 'static, + >( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn duration_changed_trampoline< + F: Fn(&PlaySignalAdapter, Option) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: u64, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), FromGlib::from_glib(object)) + } + #[allow(clippy::cast_ptr_alignment)] + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"duration-changed\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + duration_changed_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "position-updated")] + pub fn connect_position_updated< + F: Fn(&PlaySignalAdapter, Option) + Send + 'static, + >( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn position_updated_trampoline< + F: Fn(&PlaySignalAdapter, Option) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: u64, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(&from_glib_borrow(this), FromGlib::from_glib(object)) + } + #[allow(clippy::cast_ptr_alignment)] + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"position-updated\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + position_updated_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[doc(alias = "seek-done")] + pub fn connect_seek_done( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn seek_done_trampoline< + F: Fn(&PlaySignalAdapter, gst::ClockTime) + Send + 'static, + >( + this: *mut ffi::GstPlaySignalAdapter, + object: u64, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f( + &from_glib_borrow(this), + try_from_glib(object).expect("undefined seek position"), + ) + } + #[allow(clippy::cast_ptr_alignment)] + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"seek-done\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + seek_done_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} diff --git a/gstreamer-play/src/play_video_info.rs b/gstreamer-play/src/play_video_info.rs new file mode 100644 index 000000000..3270066cc --- /dev/null +++ b/gstreamer-play/src/play_video_info.rs @@ -0,0 +1,37 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::PlayVideoInfo; +use glib::translate::*; +use std::mem; + +impl PlayVideoInfo { + #[doc(alias = "get_framerate")] + #[doc(alias = "gst_play_video_info_get_framerate")] + pub fn framerate(&self) -> gst::Fraction { + unsafe { + let mut fps_n = mem::MaybeUninit::uninit(); + let mut fps_d = mem::MaybeUninit::uninit(); + ffi::gst_play_video_info_get_framerate( + self.to_glib_none().0, + fps_n.as_mut_ptr(), + fps_d.as_mut_ptr(), + ); + (fps_n.assume_init() as i32, fps_d.as_mut_ptr() as i32).into() + } + } + + #[doc(alias = "get_pixel_aspect_ratio")] + #[doc(alias = "gst_play_video_info_get_pixel_aspect_ratio")] + pub fn pixel_aspect_ratio(&self) -> gst::Fraction { + unsafe { + let mut par_n = mem::MaybeUninit::uninit(); + let mut par_d = mem::MaybeUninit::uninit(); + ffi::gst_play_video_info_get_pixel_aspect_ratio( + self.to_glib_none().0, + par_n.as_mut_ptr(), + par_d.as_mut_ptr(), + ); + (par_n.assume_init() as i32, par_d.assume_init() as i32).into() + } + } +} diff --git a/gstreamer-play/src/play_video_overlay_video_renderer.rs b/gstreamer-play/src/play_video_overlay_video_renderer.rs new file mode 100644 index 000000000..70fee3b7f --- /dev/null +++ b/gstreamer-play/src/play_video_overlay_video_renderer.rs @@ -0,0 +1,56 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::PlayVideoOverlayVideoRenderer; +use glib::prelude::*; +use glib::translate::*; + +use std::ptr; + +use libc::uintptr_t; + +impl PlayVideoOverlayVideoRenderer { + pub unsafe fn new(window_handle: uintptr_t) -> PlayVideoOverlayVideoRenderer { + assert_initialized_main_thread!(); + + from_glib_full( + ffi::gst_play_video_overlay_video_renderer_new(window_handle as *mut _) as *mut _, + ) + } + + pub unsafe fn with_handle_and_sink>( + window_handle: uintptr_t, + video_sink: &P, + ) -> PlayVideoOverlayVideoRenderer { + assert_initialized_main_thread!(); + + from_glib_full(ffi::gst_play_video_overlay_video_renderer_new_with_sink( + window_handle as *mut _, + video_sink.as_ref().to_glib_none().0, + ) as *mut _) + } + + #[doc(alias = "gst_play_video_overlay_video_renderer_new_with_sink")] + pub fn with_sink>(video_sink: &P) -> PlayVideoOverlayVideoRenderer { + assert_initialized_main_thread!(); + + unsafe { + from_glib_full(ffi::gst_play_video_overlay_video_renderer_new_with_sink( + ptr::null_mut(), + video_sink.as_ref().to_glib_none().0, + ) as *mut _) + } + } + + #[doc(alias = "get_window_handle")] + pub unsafe fn window_handle(&self) -> uintptr_t { + ffi::gst_play_video_overlay_video_renderer_get_window_handle(self.to_glib_none().0) + as uintptr_t + } + + pub unsafe fn set_window_handle(&self, window_handle: uintptr_t) { + ffi::gst_play_video_overlay_video_renderer_set_window_handle( + self.to_glib_none().0, + window_handle as *mut _, + ) + } +} diff --git a/gstreamer-play/src/play_visualization.rs b/gstreamer-play/src/play_visualization.rs new file mode 100644 index 000000000..4f26deb54 --- /dev/null +++ b/gstreamer-play/src/play_visualization.rs @@ -0,0 +1,24 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use glib::translate::*; +use std::ffi::CStr; + +use crate::PlayVisualization; + +impl PlayVisualization { + pub fn name(&self) -> &str { + unsafe { + CStr::from_ptr((*self.to_glib_none().0).name) + .to_str() + .unwrap() + } + } + + pub fn description(&self) -> &str { + unsafe { + CStr::from_ptr((*self.to_glib_none().0).description) + .to_str() + .unwrap() + } + } +} diff --git a/gstreamer-play/src/subclass/mod.rs b/gstreamer-play/src/subclass/mod.rs new file mode 100644 index 000000000..562214148 --- /dev/null +++ b/gstreamer-play/src/subclass/mod.rs @@ -0,0 +1,10 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +mod play_video_renderer; + +pub mod prelude { + #[doc(hidden)] + pub use gst::subclass::prelude::*; + + pub use super::play_video_renderer::{PlayVideoRendererImpl, PlayVideoRendererImplExt}; +} diff --git a/gstreamer-play/src/subclass/play_video_renderer.rs b/gstreamer-play/src/subclass/play_video_renderer.rs new file mode 100644 index 000000000..1f163c6b8 --- /dev/null +++ b/gstreamer-play/src/subclass/play_video_renderer.rs @@ -0,0 +1,85 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::{Play, PlayVideoRenderer}; + +use glib::prelude::*; +use glib::subclass::prelude::*; +use glib::translate::*; + +pub trait PlayVideoRendererImpl: ObjectImpl { + fn create_video_sink(&self, video_renderer: &Self::Type, play: &Play) -> gst::Element; +} + +unsafe impl IsImplementable for PlayVideoRenderer { + fn interface_init(iface: &mut glib::Interface) { + let iface = iface.as_mut(); + + iface.create_video_sink = Some(video_renderer_create_video_sink::); + } +} + +pub trait PlayVideoRendererImplExt: ObjectSubclass { + fn parent_create_video_sink(&self, video_renderer: &Self::Type, play: &Play) -> gst::Element; +} + +impl PlayVideoRendererImplExt for T { + fn parent_create_video_sink(&self, video_renderer: &Self::Type, play: &Play) -> gst::Element { + unsafe { + let type_data = Self::type_data(); + let parent_iface = type_data.as_ref().parent_interface::() + as *const ffi::GstPlayVideoRendererInterface; + + let func = (*parent_iface) + .create_video_sink + .expect("no parent \"create_video_sink\" implementation"); + let ret = func( + video_renderer + .unsafe_cast_ref::() + .to_glib_none() + .0, + play.to_glib_none().0, + ); + from_glib_none(ret) + } + } +} + +unsafe extern "C" fn video_renderer_create_video_sink( + video_renderer: *mut ffi::GstPlayVideoRenderer, + play: *mut ffi::GstPlay, +) -> *mut gst::ffi::GstElement { + use once_cell::sync::Lazy; + static VIDEO_SINK_QUARK: Lazy = + Lazy::new(|| glib::Quark::from_str("gstreamer-rs-play-video-sink")); + + let instance = &*(video_renderer as *mut T::Instance); + let imp = instance.imp(); + + let sink = imp.create_video_sink( + from_glib_borrow::<_, PlayVideoRenderer>(video_renderer).unsafe_cast_ref(), + &Play::from_glib_borrow(play), + ); + + let sink_ptr: *mut gst::ffi::GstElement = sink.to_glib_none().0; + + let old_sink_ptr = glib::gobject_ffi::g_object_get_qdata( + video_renderer as *mut _, + VIDEO_SINK_QUARK.into_glib(), + ) as *mut gst::ffi::GstElement; + if !old_sink_ptr.is_null() && old_sink_ptr != sink_ptr { + panic!("Video sink must not change"); + } + + unsafe extern "C" fn unref(ptr: glib::ffi::gpointer) { + glib::gobject_ffi::g_object_unref(ptr as *mut _); + } + + glib::gobject_ffi::g_object_set_qdata_full( + video_renderer as *mut _, + VIDEO_SINK_QUARK.into_glib(), + glib::gobject_ffi::g_object_ref(sink_ptr as *mut _) as *mut _, + Some(unref), + ); + + sink_ptr +} diff --git a/gstreamer-play/sys/CHANGELOG.md b/gstreamer-play/sys/CHANGELOG.md new file mode 100644 index 000000000..d6a7bdb06 --- /dev/null +++ b/gstreamer-play/sys/CHANGELOG.md @@ -0,0 +1 @@ +../../gstreamer/CHANGELOG.md \ No newline at end of file diff --git a/gstreamer-play/sys/COPYRIGHT b/gstreamer-play/sys/COPYRIGHT new file mode 100644 index 000000000..8b0161cc9 --- /dev/null +++ b/gstreamer-play/sys/COPYRIGHT @@ -0,0 +1 @@ +../../COPYRIGHT \ No newline at end of file diff --git a/gstreamer-play/sys/Cargo.toml b/gstreamer-play/sys/Cargo.toml new file mode 100644 index 000000000..85be89144 --- /dev/null +++ b/gstreamer-play/sys/Cargo.toml @@ -0,0 +1,55 @@ +[build-dependencies] +system-deps = "6" + +[dependencies] +libc = "0.2" + +[dependencies.glib] +package = "glib-sys" +git = "https://github.com/gtk-rs/gtk-rs-core" + +[dependencies.gobject] +package = "gobject-sys" +git = "https://github.com/gtk-rs/gtk-rs-core" + +[dependencies.gst] +package = "gstreamer-sys" +path = "../../gstreamer/sys" + +[dependencies.gst_video] +package = "gstreamer-video-sys" +path = "../../gstreamer-video/sys" + +[dev-dependencies] +shell-words = "1.0.0" +tempfile = "3" + +[features] +v1_22 = [] +dox = [] + +[lib] +name = "gstreamer_play_sys" + +[package] +authors = ["Sebastian Dröge "] +build = "build.rs" +description = "FFI bindings to libgstplay-1.0" +documentation = "https://gstreamer.pages.freedesktop.org/gstreamer-rs/stable/latest/docs/gstreamer_play_sys/" +homepage = "https://gstreamer.freedesktop.org" +keywords = ["ffi", "gstreamer", "gnome", "multimedia"] +license = "MIT" +name = "gstreamer-play-sys" +readme = "README.md" +repository = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" +version = "0.19.0" +edition = "2021" +rust-version = "1.57" +[package.metadata.docs.rs] +features = ["dox"] +[package.metadata.system-deps.gstreamer_play_1_0] +name = "gstreamer-play-1.0" +version = "1.20" + +[package.metadata.system-deps.gstreamer_play_1_0.v1_22] +version = "1.21" diff --git a/gstreamer-play/sys/Gir.toml b/gstreamer-play/sys/Gir.toml new file mode 100644 index 000000000..4777c6271 --- /dev/null +++ b/gstreamer-play/sys/Gir.toml @@ -0,0 +1,17 @@ +[options] +girs_directories = ["../../gir-files", "../../gst-gir-files"] +library = "GstPlay" +version = "1.0" +min_cfg_version = "1.20" +work_mode = "sys" + +extra_versions = ["1.22"] + +external_libraries = [ + "GLib", + "GObject", +] + +[external_libraries] +gstreamer="Gst" +gstreamer_video="GstVideo" diff --git a/gstreamer-play/sys/LICENSE b/gstreamer-play/sys/LICENSE new file mode 100644 index 000000000..b2cfbdc7b --- /dev/null +++ b/gstreamer-play/sys/LICENSE @@ -0,0 +1 @@ +../../LICENSE-MIT \ No newline at end of file diff --git a/gstreamer-play/sys/README.md b/gstreamer-play/sys/README.md new file mode 100644 index 000000000..b5b92bc9d --- /dev/null +++ b/gstreamer-play/sys/README.md @@ -0,0 +1,31 @@ +# gstreamer-sys [![crates.io](https://img.shields.io/crates/v/gstreamer-play-sys.svg)](https://crates.io/crates/gstreamer-play-sys) [![pipeline status](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/badges/main/pipeline.svg)](https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/commits/main) + +[GStreamer](https://gstreamer.freedesktop.org/) (Play 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: + + * Bindings for GStreamer applications and plugins: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs + * Various GStreamer plugins written in Rust: https://gitlab.freedesktop.org/gstreamer/gst-plugins-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-play/sys/build.rs b/gstreamer-play/sys/build.rs new file mode 100644 index 000000000..a0858d4dd --- /dev/null +++ b/gstreamer-play/sys/build.rs @@ -0,0 +1,18 @@ +// Generated by gir (https://github.com/gtk-rs/gir @ c063b4567de5) +// from gir-files (https://github.com/gtk-rs/gir-files @ 7ebd4478b4a5) +// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 654191eba8d7) +// DO NOT EDIT + +#[cfg(not(feature = "dox"))] +use std::process; + +#[cfg(feature = "dox")] +fn main() {} // prevent linking libraries to avoid documentation failure + +#[cfg(not(feature = "dox"))] +fn main() { + if let Err(s) = system_deps::Config::new().probe() { + println!("cargo:warning={}", s); + process::exit(1); + } +} diff --git a/gstreamer-play/sys/src/lib.rs b/gstreamer-play/sys/src/lib.rs new file mode 100644 index 000000000..ae9d9dbe0 --- /dev/null +++ b/gstreamer-play/sys/src/lib.rs @@ -0,0 +1,569 @@ +// Generated by gir (https://github.com/gtk-rs/gir @ c063b4567de5) +// from gir-files (https://github.com/gtk-rs/gir-files @ 7ebd4478b4a5) +// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 654191eba8d7) +// DO NOT EDIT + +#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)] +#![allow( + clippy::approx_constant, + clippy::type_complexity, + clippy::unreadable_literal, + clippy::upper_case_acronyms +)] +#![cfg_attr(feature = "dox", feature(doc_cfg))] + +#[allow(unused_imports)] +use libc::{ + c_char, c_double, c_float, c_int, c_long, c_short, c_uchar, c_uint, c_ulong, c_ushort, c_void, + intptr_t, size_t, ssize_t, uintptr_t, FILE, +}; + +#[allow(unused_imports)] +use glib::{gboolean, gconstpointer, gpointer, GType}; + +// Enums +pub type GstPlayColorBalanceType = c_int; +pub const GST_PLAY_COLOR_BALANCE_HUE: GstPlayColorBalanceType = 3; +pub const GST_PLAY_COLOR_BALANCE_BRIGHTNESS: GstPlayColorBalanceType = 0; +pub const GST_PLAY_COLOR_BALANCE_SATURATION: GstPlayColorBalanceType = 2; +pub const GST_PLAY_COLOR_BALANCE_CONTRAST: GstPlayColorBalanceType = 1; + +pub type GstPlayError = c_int; +pub const GST_PLAY_ERROR_FAILED: GstPlayError = 0; + +pub type GstPlayMessage = c_int; +pub const GST_PLAY_MESSAGE_URI_LOADED: GstPlayMessage = 0; +pub const GST_PLAY_MESSAGE_POSITION_UPDATED: GstPlayMessage = 1; +pub const GST_PLAY_MESSAGE_DURATION_CHANGED: GstPlayMessage = 2; +pub const GST_PLAY_MESSAGE_STATE_CHANGED: GstPlayMessage = 3; +pub const GST_PLAY_MESSAGE_BUFFERING: GstPlayMessage = 4; +pub const GST_PLAY_MESSAGE_END_OF_STREAM: GstPlayMessage = 5; +pub const GST_PLAY_MESSAGE_ERROR: GstPlayMessage = 6; +pub const GST_PLAY_MESSAGE_WARNING: GstPlayMessage = 7; +pub const GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED: GstPlayMessage = 8; +pub const GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED: GstPlayMessage = 9; +pub const GST_PLAY_MESSAGE_VOLUME_CHANGED: GstPlayMessage = 10; +pub const GST_PLAY_MESSAGE_MUTE_CHANGED: GstPlayMessage = 11; +pub const GST_PLAY_MESSAGE_SEEK_DONE: GstPlayMessage = 12; + +pub type GstPlaySnapshotFormat = c_int; +pub const GST_PLAY_THUMBNAIL_RAW_NATIVE: GstPlaySnapshotFormat = 0; +pub const GST_PLAY_THUMBNAIL_RAW_xRGB: GstPlaySnapshotFormat = 1; +pub const GST_PLAY_THUMBNAIL_RAW_BGRx: GstPlaySnapshotFormat = 2; +pub const GST_PLAY_THUMBNAIL_JPG: GstPlaySnapshotFormat = 3; +pub const GST_PLAY_THUMBNAIL_PNG: GstPlaySnapshotFormat = 4; + +pub type GstPlayState = c_int; +pub const GST_PLAY_STATE_STOPPED: GstPlayState = 0; +pub const GST_PLAY_STATE_BUFFERING: GstPlayState = 1; +pub const GST_PLAY_STATE_PAUSED: GstPlayState = 2; +pub const GST_PLAY_STATE_PLAYING: GstPlayState = 3; + +// Records +#[repr(C)] +pub struct _GstPlayAudioInfoClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GstPlayAudioInfoClass = *mut _GstPlayAudioInfoClass; + +#[repr(C)] +pub struct _GstPlayClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GstPlayClass = *mut _GstPlayClass; + +#[repr(C)] +pub struct _GstPlayMediaInfoClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GstPlayMediaInfoClass = *mut _GstPlayMediaInfoClass; + +#[repr(C)] +pub struct _GstPlaySignalAdapterClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GstPlaySignalAdapterClass = *mut _GstPlaySignalAdapterClass; + +#[repr(C)] +pub struct _GstPlayStreamInfoClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GstPlayStreamInfoClass = *mut _GstPlayStreamInfoClass; + +#[repr(C)] +pub struct _GstPlaySubtitleInfoClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GstPlaySubtitleInfoClass = *mut _GstPlaySubtitleInfoClass; + +#[repr(C)] +pub struct _GstPlayVideoInfoClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GstPlayVideoInfoClass = *mut _GstPlayVideoInfoClass; + +#[repr(C)] +pub struct _GstPlayVideoOverlayVideoRendererClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GstPlayVideoOverlayVideoRendererClass = *mut _GstPlayVideoOverlayVideoRendererClass; + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct GstPlayVideoRendererInterface { + pub parent_iface: gobject::GTypeInterface, + pub create_video_sink: Option< + unsafe extern "C" fn(*mut GstPlayVideoRenderer, *mut GstPlay) -> *mut gst::GstElement, + >, +} + +impl ::std::fmt::Debug for GstPlayVideoRendererInterface { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlayVideoRendererInterface @ {:p}", self)) + .field("parent_iface", &self.parent_iface) + .field("create_video_sink", &self.create_video_sink) + .finish() + } +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct GstPlayVisualization { + pub name: *mut c_char, + pub description: *mut c_char, +} + +impl ::std::fmt::Debug for GstPlayVisualization { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlayVisualization @ {:p}", self)) + .field("name", &self.name) + .field("description", &self.description) + .finish() + } +} + +// Classes +#[repr(C)] +pub struct GstPlay { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlay { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlay @ {:p}", self)).finish() + } +} + +#[repr(C)] +pub struct GstPlayAudioInfo { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlayAudioInfo { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlayAudioInfo @ {:p}", self)) + .finish() + } +} + +#[repr(C)] +pub struct GstPlayMediaInfo { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlayMediaInfo { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlayMediaInfo @ {:p}", self)) + .finish() + } +} + +#[repr(C)] +pub struct GstPlaySignalAdapter { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlaySignalAdapter { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlaySignalAdapter @ {:p}", self)) + .finish() + } +} + +#[repr(C)] +pub struct GstPlayStreamInfo { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlayStreamInfo { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlayStreamInfo @ {:p}", self)) + .finish() + } +} + +#[repr(C)] +pub struct GstPlaySubtitleInfo { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlaySubtitleInfo { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlaySubtitleInfo @ {:p}", self)) + .finish() + } +} + +#[repr(C)] +pub struct GstPlayVideoInfo { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlayVideoInfo { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlayVideoInfo @ {:p}", self)) + .finish() + } +} + +#[repr(C)] +pub struct GstPlayVideoOverlayVideoRenderer { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlayVideoOverlayVideoRenderer { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GstPlayVideoOverlayVideoRenderer @ {:p}", self)) + .finish() + } +} + +// Interfaces +#[repr(C)] +pub struct GstPlayVideoRenderer { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GstPlayVideoRenderer { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "GstPlayVideoRenderer @ {:p}", self) + } +} + +#[link(name = "gstplay-1.0")] +extern "C" { + + //========================================================================= + // GstPlayColorBalanceType + //========================================================================= + pub fn gst_play_color_balance_type_get_type() -> GType; + pub fn gst_play_color_balance_type_get_name(type_: GstPlayColorBalanceType) -> *const c_char; + + //========================================================================= + // GstPlayError + //========================================================================= + pub fn gst_play_error_get_type() -> GType; + pub fn gst_play_error_get_name(error: GstPlayError) -> *const c_char; + pub fn gst_play_error_quark() -> glib::GQuark; + + //========================================================================= + // GstPlayMessage + //========================================================================= + pub fn gst_play_message_get_type() -> GType; + pub fn gst_play_message_get_name(message_type: GstPlayMessage) -> *const c_char; + pub fn gst_play_message_parse_buffering_percent( + msg: *mut gst::GstMessage, + percent: *mut c_uint, + ); + pub fn gst_play_message_parse_duration_updated( + msg: *mut gst::GstMessage, + duration: *mut gst::GstClockTime, + ); + pub fn gst_play_message_parse_error( + msg: *mut gst::GstMessage, + error: *mut *mut glib::GError, + details: *mut *mut gst::GstStructure, + ); + pub fn gst_play_message_parse_media_info_updated( + msg: *mut gst::GstMessage, + info: *mut *mut GstPlayMediaInfo, + ); + pub fn gst_play_message_parse_muted_changed(msg: *mut gst::GstMessage, muted: *mut gboolean); + pub fn gst_play_message_parse_position_updated( + msg: *mut gst::GstMessage, + position: *mut gst::GstClockTime, + ); + pub fn gst_play_message_parse_state_changed( + msg: *mut gst::GstMessage, + state: *mut GstPlayState, + ); + pub fn gst_play_message_parse_type(msg: *mut gst::GstMessage, type_: *mut GstPlayMessage); + pub fn gst_play_message_parse_video_dimensions_changed( + msg: *mut gst::GstMessage, + width: *mut c_uint, + height: *mut c_uint, + ); + pub fn gst_play_message_parse_volume_changed(msg: *mut gst::GstMessage, volume: *mut c_double); + pub fn gst_play_message_parse_warning( + msg: *mut gst::GstMessage, + error: *mut *mut glib::GError, + details: *mut *mut gst::GstStructure, + ); + + //========================================================================= + // GstPlayState + //========================================================================= + pub fn gst_play_state_get_type() -> GType; + pub fn gst_play_state_get_name(state: GstPlayState) -> *const c_char; + + //========================================================================= + // GstPlayVisualization + //========================================================================= + pub fn gst_play_visualization_get_type() -> GType; + pub fn gst_play_visualization_copy( + vis: *const GstPlayVisualization, + ) -> *mut GstPlayVisualization; + pub fn gst_play_visualization_free(vis: *mut GstPlayVisualization); + + //========================================================================= + // GstPlay + //========================================================================= + pub fn gst_play_get_type() -> GType; + pub fn gst_play_new(video_renderer: *mut GstPlayVideoRenderer) -> *mut GstPlay; + pub fn gst_play_config_get_position_update_interval(config: *const gst::GstStructure) + -> c_uint; + pub fn gst_play_config_get_seek_accurate(config: *const gst::GstStructure) -> gboolean; + pub fn gst_play_config_get_user_agent(config: *const gst::GstStructure) -> *mut c_char; + pub fn gst_play_config_set_position_update_interval( + config: *mut gst::GstStructure, + interval: c_uint, + ); + pub fn gst_play_config_set_seek_accurate(config: *mut gst::GstStructure, accurate: gboolean); + pub fn gst_play_config_set_user_agent(config: *mut gst::GstStructure, agent: *const c_char); + pub fn gst_play_get_audio_streams(info: *const GstPlayMediaInfo) -> *mut glib::GList; + pub fn gst_play_get_subtitle_streams(info: *const GstPlayMediaInfo) -> *mut glib::GList; + pub fn gst_play_get_video_streams(info: *const GstPlayMediaInfo) -> *mut glib::GList; + pub fn gst_play_is_play_message(msg: *mut gst::GstMessage) -> gboolean; + pub fn gst_play_visualizations_free(viss: *mut *mut GstPlayVisualization); + pub fn gst_play_visualizations_get() -> *mut *mut GstPlayVisualization; + pub fn gst_play_get_audio_video_offset(play: *mut GstPlay) -> i64; + pub fn gst_play_get_color_balance( + play: *mut GstPlay, + type_: GstPlayColorBalanceType, + ) -> c_double; + pub fn gst_play_get_config(play: *mut GstPlay) -> *mut gst::GstStructure; + pub fn gst_play_get_current_audio_track(play: *mut GstPlay) -> *mut GstPlayAudioInfo; + pub fn gst_play_get_current_subtitle_track(play: *mut GstPlay) -> *mut GstPlaySubtitleInfo; + pub fn gst_play_get_current_video_track(play: *mut GstPlay) -> *mut GstPlayVideoInfo; + pub fn gst_play_get_current_visualization(play: *mut GstPlay) -> *mut c_char; + pub fn gst_play_get_duration(play: *mut GstPlay) -> gst::GstClockTime; + pub fn gst_play_get_media_info(play: *mut GstPlay) -> *mut GstPlayMediaInfo; + pub fn gst_play_get_message_bus(play: *mut GstPlay) -> *mut gst::GstBus; + pub fn gst_play_get_multiview_flags(play: *mut GstPlay) -> gst_video::GstVideoMultiviewFlags; + pub fn gst_play_get_multiview_mode( + play: *mut GstPlay, + ) -> gst_video::GstVideoMultiviewFramePacking; + pub fn gst_play_get_mute(play: *mut GstPlay) -> gboolean; + pub fn gst_play_get_pipeline(play: *mut GstPlay) -> *mut gst::GstElement; + pub fn gst_play_get_position(play: *mut GstPlay) -> gst::GstClockTime; + pub fn gst_play_get_rate(play: *mut GstPlay) -> c_double; + pub fn gst_play_get_subtitle_uri(play: *mut GstPlay) -> *mut c_char; + pub fn gst_play_get_subtitle_video_offset(play: *mut GstPlay) -> i64; + pub fn gst_play_get_uri(play: *mut GstPlay) -> *mut c_char; + pub fn gst_play_get_video_snapshot( + play: *mut GstPlay, + format: GstPlaySnapshotFormat, + config: *const gst::GstStructure, + ) -> *mut gst::GstSample; + pub fn gst_play_get_volume(play: *mut GstPlay) -> c_double; + pub fn gst_play_has_color_balance(play: *mut GstPlay) -> gboolean; + pub fn gst_play_pause(play: *mut GstPlay); + pub fn gst_play_play(play: *mut GstPlay); + pub fn gst_play_seek(play: *mut GstPlay, position: gst::GstClockTime); + pub fn gst_play_set_audio_track(play: *mut GstPlay, stream_index: c_int) -> gboolean; + pub fn gst_play_set_audio_track_enabled(play: *mut GstPlay, enabled: gboolean); + pub fn gst_play_set_audio_video_offset(play: *mut GstPlay, offset: i64); + pub fn gst_play_set_color_balance( + play: *mut GstPlay, + type_: GstPlayColorBalanceType, + value: c_double, + ); + pub fn gst_play_set_config(play: *mut GstPlay, config: *mut gst::GstStructure) -> gboolean; + pub fn gst_play_set_multiview_flags( + play: *mut GstPlay, + flags: gst_video::GstVideoMultiviewFlags, + ); + pub fn gst_play_set_multiview_mode( + play: *mut GstPlay, + mode: gst_video::GstVideoMultiviewFramePacking, + ); + pub fn gst_play_set_mute(play: *mut GstPlay, val: gboolean); + pub fn gst_play_set_rate(play: *mut GstPlay, rate: c_double); + pub fn gst_play_set_subtitle_track(play: *mut GstPlay, stream_index: c_int) -> gboolean; + pub fn gst_play_set_subtitle_track_enabled(play: *mut GstPlay, enabled: gboolean); + pub fn gst_play_set_subtitle_uri(play: *mut GstPlay, uri: *const c_char); + pub fn gst_play_set_subtitle_video_offset(play: *mut GstPlay, offset: i64); + pub fn gst_play_set_uri(play: *mut GstPlay, uri: *const c_char); + pub fn gst_play_set_video_track(play: *mut GstPlay, stream_index: c_int) -> gboolean; + pub fn gst_play_set_video_track_enabled(play: *mut GstPlay, enabled: gboolean); + pub fn gst_play_set_visualization(play: *mut GstPlay, name: *const c_char) -> gboolean; + pub fn gst_play_set_visualization_enabled(play: *mut GstPlay, enabled: gboolean); + pub fn gst_play_set_volume(play: *mut GstPlay, val: c_double); + pub fn gst_play_stop(play: *mut GstPlay); + + //========================================================================= + // GstPlayAudioInfo + //========================================================================= + pub fn gst_play_audio_info_get_type() -> GType; + pub fn gst_play_audio_info_get_bitrate(info: *const GstPlayAudioInfo) -> c_int; + pub fn gst_play_audio_info_get_channels(info: *const GstPlayAudioInfo) -> c_int; + pub fn gst_play_audio_info_get_language(info: *const GstPlayAudioInfo) -> *const c_char; + pub fn gst_play_audio_info_get_max_bitrate(info: *const GstPlayAudioInfo) -> c_int; + pub fn gst_play_audio_info_get_sample_rate(info: *const GstPlayAudioInfo) -> c_int; + + //========================================================================= + // GstPlayMediaInfo + //========================================================================= + pub fn gst_play_media_info_get_type() -> GType; + pub fn gst_play_media_info_get_audio_streams(info: *const GstPlayMediaInfo) + -> *mut glib::GList; + pub fn gst_play_media_info_get_container_format(info: *const GstPlayMediaInfo) + -> *const c_char; + pub fn gst_play_media_info_get_duration(info: *const GstPlayMediaInfo) -> gst::GstClockTime; + pub fn gst_play_media_info_get_image_sample( + info: *const GstPlayMediaInfo, + ) -> *mut gst::GstSample; + pub fn gst_play_media_info_get_number_of_audio_streams(info: *const GstPlayMediaInfo) + -> c_uint; + pub fn gst_play_media_info_get_number_of_streams(info: *const GstPlayMediaInfo) -> c_uint; + pub fn gst_play_media_info_get_number_of_subtitle_streams( + info: *const GstPlayMediaInfo, + ) -> c_uint; + pub fn gst_play_media_info_get_number_of_video_streams(info: *const GstPlayMediaInfo) + -> c_uint; + pub fn gst_play_media_info_get_stream_list(info: *const GstPlayMediaInfo) -> *mut glib::GList; + pub fn gst_play_media_info_get_subtitle_streams( + info: *const GstPlayMediaInfo, + ) -> *mut glib::GList; + pub fn gst_play_media_info_get_tags(info: *const GstPlayMediaInfo) -> *mut gst::GstTagList; + pub fn gst_play_media_info_get_title(info: *const GstPlayMediaInfo) -> *const c_char; + pub fn gst_play_media_info_get_uri(info: *const GstPlayMediaInfo) -> *const c_char; + pub fn gst_play_media_info_get_video_streams(info: *const GstPlayMediaInfo) + -> *mut glib::GList; + pub fn gst_play_media_info_is_live(info: *const GstPlayMediaInfo) -> gboolean; + pub fn gst_play_media_info_is_seekable(info: *const GstPlayMediaInfo) -> gboolean; + + //========================================================================= + // GstPlaySignalAdapter + //========================================================================= + pub fn gst_play_signal_adapter_get_type() -> GType; + pub fn gst_play_signal_adapter_new(play: *mut GstPlay) -> *mut GstPlaySignalAdapter; + pub fn gst_play_signal_adapter_new_sync_emit(play: *mut GstPlay) -> *mut GstPlaySignalAdapter; + pub fn gst_play_signal_adapter_new_with_main_context( + play: *mut GstPlay, + context: *mut glib::GMainContext, + ) -> *mut GstPlaySignalAdapter; + pub fn gst_play_signal_adapter_get_play(adapter: *mut GstPlaySignalAdapter) -> *mut GstPlay; + + //========================================================================= + // GstPlayStreamInfo + //========================================================================= + pub fn gst_play_stream_info_get_type() -> GType; + pub fn gst_play_stream_info_get_caps(info: *const GstPlayStreamInfo) -> *mut gst::GstCaps; + pub fn gst_play_stream_info_get_codec(info: *const GstPlayStreamInfo) -> *const c_char; + pub fn gst_play_stream_info_get_index(info: *const GstPlayStreamInfo) -> c_int; + pub fn gst_play_stream_info_get_stream_type(info: *const GstPlayStreamInfo) -> *const c_char; + pub fn gst_play_stream_info_get_tags(info: *const GstPlayStreamInfo) -> *mut gst::GstTagList; + + //========================================================================= + // GstPlaySubtitleInfo + //========================================================================= + pub fn gst_play_subtitle_info_get_type() -> GType; + pub fn gst_play_subtitle_info_get_language(info: *const GstPlaySubtitleInfo) -> *const c_char; + + //========================================================================= + // GstPlayVideoInfo + //========================================================================= + pub fn gst_play_video_info_get_type() -> GType; + pub fn gst_play_video_info_get_bitrate(info: *const GstPlayVideoInfo) -> c_int; + pub fn gst_play_video_info_get_framerate( + info: *const GstPlayVideoInfo, + fps_n: *mut c_int, + fps_d: *mut c_int, + ); + pub fn gst_play_video_info_get_height(info: *const GstPlayVideoInfo) -> c_int; + pub fn gst_play_video_info_get_max_bitrate(info: *const GstPlayVideoInfo) -> c_int; + pub fn gst_play_video_info_get_pixel_aspect_ratio( + info: *const GstPlayVideoInfo, + par_n: *mut c_uint, + par_d: *mut c_uint, + ); + pub fn gst_play_video_info_get_width(info: *const GstPlayVideoInfo) -> c_int; + + //========================================================================= + // GstPlayVideoOverlayVideoRenderer + //========================================================================= + pub fn gst_play_video_overlay_video_renderer_get_type() -> GType; + pub fn gst_play_video_overlay_video_renderer_new( + window_handle: gpointer, + ) -> *mut GstPlayVideoRenderer; + pub fn gst_play_video_overlay_video_renderer_new_with_sink( + window_handle: gpointer, + video_sink: *mut gst::GstElement, + ) -> *mut GstPlayVideoRenderer; + pub fn gst_play_video_overlay_video_renderer_expose( + self_: *mut GstPlayVideoOverlayVideoRenderer, + ); + pub fn gst_play_video_overlay_video_renderer_get_render_rectangle( + self_: *mut GstPlayVideoOverlayVideoRenderer, + x: *mut c_int, + y: *mut c_int, + width: *mut c_int, + height: *mut c_int, + ); + pub fn gst_play_video_overlay_video_renderer_get_window_handle( + self_: *mut GstPlayVideoOverlayVideoRenderer, + ) -> gpointer; + pub fn gst_play_video_overlay_video_renderer_set_render_rectangle( + self_: *mut GstPlayVideoOverlayVideoRenderer, + x: c_int, + y: c_int, + width: c_int, + height: c_int, + ); + pub fn gst_play_video_overlay_video_renderer_set_window_handle( + self_: *mut GstPlayVideoOverlayVideoRenderer, + window_handle: gpointer, + ); + + //========================================================================= + // GstPlayVideoRenderer + //========================================================================= + pub fn gst_play_video_renderer_get_type() -> GType; + +} diff --git a/gstreamer-play/sys/tests/abi.rs b/gstreamer-play/sys/tests/abi.rs new file mode 100644 index 000000000..a1bb8885c --- /dev/null +++ b/gstreamer-play/sys/tests/abi.rs @@ -0,0 +1,295 @@ +// Generated by gir (https://github.com/gtk-rs/gir @ c063b4567de5) +// from gir-files (https://github.com/gtk-rs/gir-files @ 7ebd4478b4a5) +// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 654191eba8d7) +// DO NOT EDIT + +use gstreamer_play_sys::*; +use std::env; +use std::error::Error; +use std::ffi::OsString; +use std::mem::{align_of, size_of}; +use std::path::Path; +use std::process::Command; +use std::str; +use tempfile::Builder; + +static PACKAGES: &[&str] = &["gstreamer-play-1.0"]; + +#[derive(Clone, Debug)] +struct Compiler { + pub args: Vec, +} + +impl Compiler { + pub fn new() -> Result> { + let mut args = get_var("CC", "cc")?; + args.push("-Wno-deprecated-declarations".to_owned()); + // For _Generic + args.push("-std=c11".to_owned()); + // For %z support in printf when using MinGW. + args.push("-D__USE_MINGW_ANSI_STDIO".to_owned()); + args.extend(get_var("CFLAGS", "")?); + args.extend(get_var("CPPFLAGS", "")?); + args.extend(pkg_config_cflags(PACKAGES)?); + Ok(Self { args }) + } + + pub fn compile(&self, src: &Path, out: &Path) -> Result<(), Box> { + let mut cmd = self.to_command(); + cmd.arg(src); + cmd.arg("-o"); + cmd.arg(out); + let status = cmd.spawn()?.wait()?; + if !status.success() { + return Err(format!("compilation command {:?} failed, {}", &cmd, status).into()); + } + Ok(()) + } + + fn to_command(&self) -> Command { + let mut cmd = Command::new(&self.args[0]); + cmd.args(&self.args[1..]); + cmd + } +} + +fn get_var(name: &str, default: &str) -> Result, Box> { + match env::var(name) { + Ok(value) => Ok(shell_words::split(&value)?), + Err(env::VarError::NotPresent) => Ok(shell_words::split(default)?), + Err(err) => Err(format!("{} {}", name, err).into()), + } +} + +fn pkg_config_cflags(packages: &[&str]) -> Result, Box> { + if packages.is_empty() { + return Ok(Vec::new()); + } + let pkg_config = env::var_os("PKG_CONFIG").unwrap_or_else(|| OsString::from("pkg-config")); + let mut cmd = Command::new(pkg_config); + cmd.arg("--cflags"); + cmd.args(packages); + let out = cmd.output()?; + if !out.status.success() { + return Err(format!("command {:?} returned {}", &cmd, out.status).into()); + } + let stdout = str::from_utf8(&out.stdout)?; + Ok(shell_words::split(stdout.trim())?) +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +struct Layout { + size: usize, + alignment: usize, +} + +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +struct Results { + /// Number of successfully completed tests. + passed: usize, + /// Total number of failed tests (including those that failed to compile). + failed: usize, +} + +impl Results { + fn record_passed(&mut self) { + self.passed += 1; + } + fn record_failed(&mut self) { + self.failed += 1; + } + fn summary(&self) -> String { + format!("{} passed; {} failed", self.passed, self.failed) + } + fn expect_total_success(&self) { + if self.failed == 0 { + println!("OK: {}", self.summary()); + } else { + panic!("FAILED: {}", self.summary()); + }; + } +} + +#[test] +#[cfg(target_os = "linux")] +fn cross_validate_constants_with_c() { + let mut c_constants: Vec<(String, String)> = Vec::new(); + + for l in get_c_output("constant").unwrap().lines() { + let mut words = l.trim().split(';'); + let name = words.next().expect("Failed to parse name").to_owned(); + let value = words + .next() + .and_then(|s| s.parse().ok()) + .expect("Failed to parse value"); + c_constants.push((name, value)); + } + + let mut results = Results::default(); + + for ((rust_name, rust_value), (c_name, c_value)) in + RUST_CONSTANTS.iter().zip(c_constants.iter()) + { + if rust_name != c_name { + results.record_failed(); + eprintln!("Name mismatch:\nRust: {:?}\nC: {:?}", rust_name, c_name,); + continue; + } + + if rust_value != c_value { + results.record_failed(); + eprintln!( + "Constant value mismatch for {}\nRust: {:?}\nC: {:?}", + rust_name, rust_value, &c_value + ); + continue; + } + + results.record_passed(); + } + + results.expect_total_success(); +} + +#[test] +#[cfg(target_os = "linux")] +fn cross_validate_layout_with_c() { + let mut c_layouts = Vec::new(); + + for l in get_c_output("layout").unwrap().lines() { + let mut words = l.trim().split(';'); + let name = words.next().expect("Failed to parse name").to_owned(); + let size = words + .next() + .and_then(|s| s.parse().ok()) + .expect("Failed to parse size"); + let alignment = words + .next() + .and_then(|s| s.parse().ok()) + .expect("Failed to parse alignment"); + c_layouts.push((name, Layout { size, alignment })); + } + + let mut results = Results::default(); + + for ((rust_name, rust_layout), (c_name, c_layout)) in RUST_LAYOUTS.iter().zip(c_layouts.iter()) + { + if rust_name != c_name { + results.record_failed(); + eprintln!("Name mismatch:\nRust: {:?}\nC: {:?}", rust_name, c_name,); + continue; + } + + if rust_layout != c_layout { + results.record_failed(); + eprintln!( + "Layout mismatch for {}\nRust: {:?}\nC: {:?}", + rust_name, rust_layout, &c_layout + ); + continue; + } + + results.record_passed(); + } + + results.expect_total_success(); +} + +fn get_c_output(name: &str) -> Result> { + let tmpdir = Builder::new().prefix("abi").tempdir()?; + let exe = tmpdir.path().join(name); + let c_file = Path::new("tests").join(name).with_extension("c"); + + let cc = Compiler::new().expect("configured compiler"); + cc.compile(&c_file, &exe)?; + + let mut abi_cmd = Command::new(exe); + let output = abi_cmd.output()?; + if !output.status.success() { + return Err(format!("command {:?} failed, {:?}", &abi_cmd, &output).into()); + } + + Ok(String::from_utf8(output.stdout)?) +} + +const RUST_LAYOUTS: &[(&str, Layout)] = &[ + ( + "GstPlayColorBalanceType", + Layout { + size: size_of::(), + alignment: align_of::(), + }, + ), + ( + "GstPlayError", + Layout { + size: size_of::(), + alignment: align_of::(), + }, + ), + ( + "GstPlayMessage", + Layout { + size: size_of::(), + alignment: align_of::(), + }, + ), + ( + "GstPlaySnapshotFormat", + Layout { + size: size_of::(), + alignment: align_of::(), + }, + ), + ( + "GstPlayState", + Layout { + size: size_of::(), + alignment: align_of::(), + }, + ), + ( + "GstPlayVideoRendererInterface", + Layout { + size: size_of::(), + alignment: align_of::(), + }, + ), + ( + "GstPlayVisualization", + Layout { + size: size_of::(), + alignment: align_of::(), + }, + ), +]; + +const RUST_CONSTANTS: &[(&str, &str)] = &[ + ("(gint) GST_PLAY_COLOR_BALANCE_BRIGHTNESS", "0"), + ("(gint) GST_PLAY_COLOR_BALANCE_CONTRAST", "1"), + ("(gint) GST_PLAY_COLOR_BALANCE_HUE", "3"), + ("(gint) GST_PLAY_COLOR_BALANCE_SATURATION", "2"), + ("(gint) GST_PLAY_ERROR_FAILED", "0"), + ("(gint) GST_PLAY_MESSAGE_BUFFERING", "4"), + ("(gint) GST_PLAY_MESSAGE_DURATION_CHANGED", "2"), + ("(gint) GST_PLAY_MESSAGE_END_OF_STREAM", "5"), + ("(gint) GST_PLAY_MESSAGE_ERROR", "6"), + ("(gint) GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED", "9"), + ("(gint) GST_PLAY_MESSAGE_MUTE_CHANGED", "11"), + ("(gint) GST_PLAY_MESSAGE_POSITION_UPDATED", "1"), + ("(gint) GST_PLAY_MESSAGE_SEEK_DONE", "12"), + ("(gint) GST_PLAY_MESSAGE_STATE_CHANGED", "3"), + ("(gint) GST_PLAY_MESSAGE_URI_LOADED", "0"), + ("(gint) GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED", "8"), + ("(gint) GST_PLAY_MESSAGE_VOLUME_CHANGED", "10"), + ("(gint) GST_PLAY_MESSAGE_WARNING", "7"), + ("(gint) GST_PLAY_STATE_BUFFERING", "1"), + ("(gint) GST_PLAY_STATE_PAUSED", "2"), + ("(gint) GST_PLAY_STATE_PLAYING", "3"), + ("(gint) GST_PLAY_STATE_STOPPED", "0"), + ("(gint) GST_PLAY_THUMBNAIL_JPG", "3"), + ("(gint) GST_PLAY_THUMBNAIL_PNG", "4"), + ("(gint) GST_PLAY_THUMBNAIL_RAW_BGRx", "2"), + ("(gint) GST_PLAY_THUMBNAIL_RAW_NATIVE", "0"), + ("(gint) GST_PLAY_THUMBNAIL_RAW_xRGB", "1"), +]; diff --git a/gstreamer-play/sys/tests/constant.c b/gstreamer-play/sys/tests/constant.c new file mode 100644 index 000000000..5ce567260 --- /dev/null +++ b/gstreamer-play/sys/tests/constant.c @@ -0,0 +1,60 @@ +// Generated by gir (https://github.com/gtk-rs/gir @ c063b4567de5) +// from gir-files (https://github.com/gtk-rs/gir-files @ 7ebd4478b4a5) +// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 654191eba8d7) +// DO NOT EDIT + +#include "manual.h" +#include + +#define PRINT_CONSTANT(CONSTANT_NAME) \ + printf("%s;", #CONSTANT_NAME); \ + printf(_Generic((CONSTANT_NAME), \ + char *: "%s", \ + const char *: "%s", \ + char: "%c", \ + signed char: "%hhd", \ + unsigned char: "%hhu", \ + short int: "%hd", \ + unsigned short int: "%hu", \ + int: "%d", \ + unsigned int: "%u", \ + long: "%ld", \ + unsigned long: "%lu", \ + long long: "%lld", \ + unsigned long long: "%llu", \ + float: "%f", \ + double: "%f", \ + long double: "%ld"), \ + CONSTANT_NAME); \ + printf("\n"); + +int main() { + PRINT_CONSTANT((gint) GST_PLAY_COLOR_BALANCE_BRIGHTNESS); + PRINT_CONSTANT((gint) GST_PLAY_COLOR_BALANCE_CONTRAST); + PRINT_CONSTANT((gint) GST_PLAY_COLOR_BALANCE_HUE); + PRINT_CONSTANT((gint) GST_PLAY_COLOR_BALANCE_SATURATION); + PRINT_CONSTANT((gint) GST_PLAY_ERROR_FAILED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_BUFFERING); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_DURATION_CHANGED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_END_OF_STREAM); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_ERROR); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_MUTE_CHANGED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_POSITION_UPDATED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_SEEK_DONE); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_STATE_CHANGED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_URI_LOADED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_VOLUME_CHANGED); + PRINT_CONSTANT((gint) GST_PLAY_MESSAGE_WARNING); + PRINT_CONSTANT((gint) GST_PLAY_STATE_BUFFERING); + PRINT_CONSTANT((gint) GST_PLAY_STATE_PAUSED); + PRINT_CONSTANT((gint) GST_PLAY_STATE_PLAYING); + PRINT_CONSTANT((gint) GST_PLAY_STATE_STOPPED); + PRINT_CONSTANT((gint) GST_PLAY_THUMBNAIL_JPG); + PRINT_CONSTANT((gint) GST_PLAY_THUMBNAIL_PNG); + PRINT_CONSTANT((gint) GST_PLAY_THUMBNAIL_RAW_BGRx); + PRINT_CONSTANT((gint) GST_PLAY_THUMBNAIL_RAW_NATIVE); + PRINT_CONSTANT((gint) GST_PLAY_THUMBNAIL_RAW_xRGB); + return 0; +} diff --git a/gstreamer-play/sys/tests/layout.c b/gstreamer-play/sys/tests/layout.c new file mode 100644 index 000000000..e82340fc9 --- /dev/null +++ b/gstreamer-play/sys/tests/layout.c @@ -0,0 +1,19 @@ +// Generated by gir (https://github.com/gtk-rs/gir @ c063b4567de5) +// from gir-files (https://github.com/gtk-rs/gir-files @ 7ebd4478b4a5) +// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git @ 654191eba8d7) +// DO NOT EDIT + +#include "manual.h" +#include +#include + +int main() { + printf("%s;%zu;%zu\n", "GstPlayColorBalanceType", sizeof(GstPlayColorBalanceType), alignof(GstPlayColorBalanceType)); + printf("%s;%zu;%zu\n", "GstPlayError", sizeof(GstPlayError), alignof(GstPlayError)); + printf("%s;%zu;%zu\n", "GstPlayMessage", sizeof(GstPlayMessage), alignof(GstPlayMessage)); + printf("%s;%zu;%zu\n", "GstPlaySnapshotFormat", sizeof(GstPlaySnapshotFormat), alignof(GstPlaySnapshotFormat)); + printf("%s;%zu;%zu\n", "GstPlayState", sizeof(GstPlayState), alignof(GstPlayState)); + printf("%s;%zu;%zu\n", "GstPlayVideoRendererInterface", sizeof(GstPlayVideoRendererInterface), alignof(GstPlayVideoRendererInterface)); + printf("%s;%zu;%zu\n", "GstPlayVisualization", sizeof(GstPlayVisualization), alignof(GstPlayVisualization)); + return 0; +} diff --git a/gstreamer-play/sys/tests/manual.h b/gstreamer-play/sys/tests/manual.h new file mode 100644 index 000000000..fcd37961c --- /dev/null +++ b/gstreamer-play/sys/tests/manual.h @@ -0,0 +1,3 @@ +// Feel free to edit this file, it won't be regenerated by gir generator unless removed. + +#include diff --git a/gstreamer-play/tests/check_gir.rs b/gstreamer-play/tests/check_gir.rs new file mode 100644 index 000000000..b095c0444 --- /dev/null +++ b/gstreamer-play/tests/check_gir.rs @@ -0,0 +1,8 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +#[test] +fn check_gir_file() { + let res = gir_format_check::check_gir_file("Gir.toml"); + println!("{}", res); + assert_eq!(res.nb_errors, 0); +} diff --git a/gstreamer-play/tests/manual.h b/gstreamer-play/tests/manual.h new file mode 100644 index 000000000..fcd37961c --- /dev/null +++ b/gstreamer-play/tests/manual.h @@ -0,0 +1,3 @@ +// Feel free to edit this file, it won't be regenerated by gir generator unless removed. + +#include