From c81e177cfb745d434c778dd021d09dcd8691a3b2 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Mon, 19 Feb 2018 12:15:52 -0800 Subject: [PATCH] pbutils: add discoverer APIs Fixes https://github.com/sdroege/gstreamer-rs/pull/84 --- Cargo.toml | 1 + Gir_GstPbutils.toml | 142 +++++ docs/gstreamer-pbutils/docs.md | 487 ++++++++++++++++++ examples/Cargo.toml | 1 + examples/src/bin/discoverer.rs | 98 ++++ gir-files/GstPbutils-1.0.gir | 38 +- gstreamer-pbutils/Cargo.toml | 38 ++ gstreamer-pbutils/build.rs | 34 ++ gstreamer-pbutils/src/auto/discoverer.rs | 119 +++++ .../src/auto/discoverer_audio_info.rs | 60 +++ .../src/auto/discoverer_container_info.rs | 30 ++ gstreamer-pbutils/src/auto/discoverer_info.rs | 176 +++++++ .../src/auto/discoverer_stream_info.rs | 91 ++++ .../src/auto/discoverer_subtitle_info.rs | 30 ++ .../src/auto/discoverer_video_info.rs | 66 +++ gstreamer-pbutils/src/auto/enums.rs | 83 +++ gstreamer-pbutils/src/auto/flags.rs | 65 +++ gstreamer-pbutils/src/auto/mod.rs | 38 ++ gstreamer-pbutils/src/discoverer.rs | 58 +++ .../src/discoverer_stream_info.rs | 52 ++ .../src/discoverer_video_info.rs | 32 ++ gstreamer-pbutils/src/lib.rs | 76 +++ 22 files changed, 1804 insertions(+), 11 deletions(-) create mode 100644 Gir_GstPbutils.toml create mode 100644 docs/gstreamer-pbutils/docs.md create mode 100644 examples/src/bin/discoverer.rs create mode 100644 gstreamer-pbutils/Cargo.toml create mode 100644 gstreamer-pbutils/build.rs create mode 100644 gstreamer-pbutils/src/auto/discoverer.rs create mode 100644 gstreamer-pbutils/src/auto/discoverer_audio_info.rs create mode 100644 gstreamer-pbutils/src/auto/discoverer_container_info.rs create mode 100644 gstreamer-pbutils/src/auto/discoverer_info.rs create mode 100644 gstreamer-pbutils/src/auto/discoverer_stream_info.rs create mode 100644 gstreamer-pbutils/src/auto/discoverer_subtitle_info.rs create mode 100644 gstreamer-pbutils/src/auto/discoverer_video_info.rs create mode 100644 gstreamer-pbutils/src/auto/enums.rs create mode 100644 gstreamer-pbutils/src/auto/flags.rs create mode 100644 gstreamer-pbutils/src/auto/mod.rs create mode 100644 gstreamer-pbutils/src/discoverer.rs create mode 100644 gstreamer-pbutils/src/discoverer_stream_info.rs create mode 100644 gstreamer-pbutils/src/discoverer_video_info.rs create mode 100644 gstreamer-pbutils/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index b3c358272..49ba025f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "gstreamer-rtsp-server", "gstreamer-sdp", "gstreamer-video", + "gstreamer-pbutils", "examples", "tutorials", ] diff --git a/Gir_GstPbutils.toml b/Gir_GstPbutils.toml new file mode 100644 index 000000000..c783f22d0 --- /dev/null +++ b/Gir_GstPbutils.toml @@ -0,0 +1,142 @@ +[options] +girs_dir = "gir-files" +library = "GstPbutils" +version = "1.0" +min_cfg_version = "1.8" +target_path = "gstreamer-pbutils" +work_mode = "normal" +concurrency = "send+sync" +generate_safety_asserts = true + +external_libraries = [ + "GLib", + "GObject", + "Gst", +] + +generate = [ + "GstPbutils.DiscovererResult", + "GstPbutils.DiscovererSerializeFlags", +] + +manual = [ + "GLib.Error", + "GLib.Source", + "GLib.DateTime", + "GLib.Variant", + "GObject.Object", + "Gst.Object", + "Gst.Element", +] + +[[object]] +name = "Gst.Toc" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Caps" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Message" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Buffer" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Event" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.TagList" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Structure" +status = "manual" +ref_mode = "ref-mut" + +[[object]] +name = "Gst.ClockTime" +status = "manual" +conversion_type = "scalar" + +[[object]] +name = "GstPbutils.Discoverer" +status = "generate" +trait = false + + [[object.function]] + name = "discover_uri_async" + [object.function.return] + bool_return_is_error = "Failed to add URI to list of discovers" + + # Manually implemented to use ClockTime + [[object.property]] + name = "timeout" + ignore = true + +[[object]] +name = "GstPbutils.DiscovererInfo" +status = "generate" + + [[object.function]] + name = "copy" + [object.function.return] + nullable = false + +[[object]] +name = "GstPbutils.DiscovererStreamInfo" +status = "generate" + + # Not useful + [[object.function]] + name = "list_free" + ignore = true + + [[object.function]] + name = "get_stream_type_nick" + [object.function.return] + nullable = false + +[[object]] +name = "GstPbutils.DiscovererAudioInfo" +status = "generate" +trait = false + +[[object]] +name = "GstPbutils.DiscovererVideoInfo" +status = "generate" +trait = false + + # Implement manually to expose as gst::Fraction + [[object.function]] + name = "get_framerate_num" + ignore = true + [[object.function]] + name = "get_framerate_denom" + ignore = true + [[object.function]] + name = "get_par_num" + ignore = true + [[object.function]] + name = "get_par_denom" + ignore = true + +[[object]] +name = "GstPbutils.DiscovererSubtitleInfo" +status = "generate" +trait = false + +[[object]] +name = "GstPbutils.DiscovererContainerInfo" +status = "generate" +trait = false diff --git a/docs/gstreamer-pbutils/docs.md b/docs/gstreamer-pbutils/docs.md new file mode 100644 index 000000000..b573f47af --- /dev/null +++ b/docs/gstreamer-pbutils/docs.md @@ -0,0 +1,487 @@ + + +The `Discoverer` is a utility object which allows to get as much +information as possible from one or many URIs. + +It provides two APIs, allowing usage in blocking or non-blocking mode. + +The blocking mode just requires calling `DiscovererExt::discover_uri` +with the URI one wishes to discover. + +The non-blocking mode requires a running `glib::MainLoop` iterating a +`glib::MainContext`, where one connects to the various signals, appends the +URIs to be processed (through `DiscovererExt::discover_uri_async`) and then +asks for the discovery to begin (through `DiscovererExt::start`). +By default this will use the GLib default main context unless you have +set a custom context using `glib::MainContext::push_thread_default`. + +All the information is returned in a `DiscovererInfo` structure. + +# Implements + +[`DiscovererExt`](trait.DiscovererExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Trait containing all `Discoverer` methods. + +# Implementors + +[`Discoverer`](struct.Discoverer.html) + +Creates a new `Discoverer` with the provided timeout. +## `timeout` +timeout per file, in nanoseconds. Allowed are values between + one second (`GST_SECOND`) and one hour (3600 * `GST_SECOND`) + +# Returns + +The new `Discoverer`. +If an error occurred when creating the discoverer, `err` will be set +accordingly and `None` will be returned. If `err` is set, the caller must +free it when no longer needed using `glib::Error::free`. + +Synchronously discovers the given `uri`. + +A copy of `uri` will be made internally, so the caller can safely `g_free` +afterwards. +## `uri` +The URI to run on. + +# Returns + +the result of the scanning. Can be `None` if an +error occurred. + +Appends the given `uri` to the list of URIs to discoverer. The actual +discovery of the `uri` will only take place if `DiscovererExt::start` has +been called. + +A copy of `uri` will be made internally, so the caller can safely `g_free` +afterwards. +## `uri` +the URI to add. + +# Returns + +`true` if the `uri` was successfully appended to the list of pending +uris, else `false` + +Allow asynchronous discovering of URIs to take place. +A `glib::MainLoop` must be available for `Discoverer` to properly work in +asynchronous mode. + +Stop the discovery of any pending URIs and clears the list of +pending URIS (if any). + +Will be emitted in async mode when all information on a URI could be +discovered, or an error occurred. + +When an error occurs, `info` might still contain some partial information, +depending on the circumstances of the error. +## `info` +the results `DiscovererInfo` +## `error` +`glib::Error`, which will be non-NULL if an error + occurred during discovery. You must not + free this `glib::Error`, it will be freed by + the discoverer. + +Will be emitted in async mode when all pending URIs have been processed. + +This signal is emitted after the source element has been created for, so +the URI being discovered, so it can be configured by setting additional +properties (e.g. set a proxy server for an http source, or set the device +and read speed for an audio cd source). + +This signal is usually emitted from the context of a GStreamer streaming +thread. +## `source` +source element + +Will be emitted when the discover starts analyzing the pending URIs + +The duration (in nanoseconds) after which the discovery of an individual +URI will timeout. + +If the discovery of a URI times out, the `DiscovererResult::Timeout` will be +set on the result flags. + +The duration (in nanoseconds) after which the discovery of an individual +URI will timeout. + +If the discovery of a URI times out, the `DiscovererResult::Timeout` will be +set on the result flags. + +`DiscovererStreamInfo` specific to audio streams. + +# Implements + +[`DiscovererStreamInfoExt`](trait.DiscovererStreamInfoExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + + +# Returns + +the average or nominal bitrate of the stream in bits/second. + + +# Returns + +the number of channels in the stream. + + +# Returns + +the number of bits used per sample in each channel. + + +# Returns + +the language of the stream, or NULL if unknown. + + +# Returns + +the maximum bitrate of the stream in bits/second. + + +# Returns + +the sample rate of the stream in Hertz. + +`DiscovererStreamInfo` specific to container streams. + +# Implements + +[`DiscovererStreamInfoExt`](trait.DiscovererStreamInfoExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + + +# Returns + +the list of +`DiscovererStreamInfo` this container stream offers. +Free with `DiscovererStreamInfo::list_free` after usage. + +Structure containing the information of a URI analyzed by `Discoverer`. + +# Implements + +[`DiscovererInfoExt`](trait.DiscovererInfoExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Trait containing all `DiscovererInfo` methods. + +# Implementors + +[`DiscovererInfo`](struct.DiscovererInfo.html) + +Parses a `glib::Variant` as produced by `DiscovererInfoExt::to_variant` +back to a `DiscovererInfo`. +## `variant` +A `glib::Variant` to deserialize into a `DiscovererInfo`. + +# Returns + +A newly-allocated `DiscovererInfo`. + + +# Returns + +A copy of the `DiscovererInfo` + +Finds all the `DiscovererAudioInfo` contained in `self` + +# Returns + +A `glib::List` of +matching `DiscovererStreamInfo`. The caller should free it with +`DiscovererStreamInfo::list_free`. + +Finds all the `DiscovererContainerInfo` contained in `self` + +# Returns + +A `glib::List` of +matching `DiscovererStreamInfo`. The caller should free it with +`DiscovererStreamInfo::list_free`. + + +# Returns + +the duration of the URI in `gst::ClockTime` (nanoseconds). + + +# Deprecated + +This functions is deprecated since version 1.4, use +`DiscovererInfoExt::get_missing_elements_installer_details` + +# Returns + +Miscellaneous information stored as a `gst::Structure` +(for example: information about missing plugins). If you wish to use the +`gst::Structure` after the life-time of `self`, you will need to copy it. + +Get the installer details for missing elements + +# Returns + +An array of strings +containing informations about how to install the various missing elements +for `self` to be usable. If you wish to use the strings after the life-time +of `self`, you will need to copy them. + + +# Returns + +the result of the discovery as a `DiscovererResult`. + + +# Returns + +the whether the URI is seekable. + + +# Returns + +the structure (or topology) of the URI as a +`DiscovererStreamInfo`. +This structure can be traversed to see the original hierarchy. Unref with +`gst_discoverer_stream_info_unref` after usage. + + +# Returns + +the list of +all streams contained in the `info`. Free after usage +with `DiscovererStreamInfo::list_free`. + +Finds the `DiscovererStreamInfo` contained in `self` that match the +given `streamtype`. +## `streamtype` +a `glib::Type` derived from `DiscovererStreamInfo` + +# Returns + +A `glib::List` of +matching `DiscovererStreamInfo`. The caller should free it with +`DiscovererStreamInfo::list_free`. + +Finds all the `DiscovererSubtitleInfo` contained in `self` + +# Returns + +A `glib::List` of +matching `DiscovererStreamInfo`. The caller should free it with +`DiscovererStreamInfo::list_free`. + + +# Returns + +all tags contained in the URI. If you wish to use +the tags after the life-time of `self`, you will need to copy them. + + +# Returns + +TOC contained in the URI. If you wish to use +the TOC after the life-time of `self`, you will need to copy it. + + +# Returns + +the URI to which this information corresponds to. +Copy it if you wish to use it after the life-time of `self`. + +Finds all the `DiscovererVideoInfo` contained in `self` + +# Returns + +A `glib::List` of +matching `DiscovererStreamInfo`. The caller should free it with +`DiscovererStreamInfo::list_free`. + +Serializes `self` to a `glib::Variant` that can be parsed again +through `DiscovererInfo::from_variant`. + +Note that any `gst::Toc` (s) that might have been discovered will not be serialized +for now. +## `flags` +A combination of `DiscovererSerializeFlags` to specify +what needs to be serialized. + +# Returns + +A newly-allocated `glib::Variant` representing `self`. + +Result values for the discovery process. + +The discovery was successful + +the URI is invalid + +an error happened and the GError is set + +the discovery timed-out + +the discoverer was already discovering a file + +Some plugins are missing for full discovery + +Base structure for information concerning a media stream. Depending on the +stream type, one can find more media-specific information in +`DiscovererAudioInfo`, `DiscovererVideoInfo`, and +`DiscovererContainerInfo`. + +The `DiscovererStreamInfo` represents the topology of the stream. Siblings +can be iterated over with `DiscovererStreamInfoExt::get_next` and +`DiscovererStreamInfoExt::get_previous`. Children (sub-streams) of a +stream can be accessed using the `DiscovererContainerInfo` API. + +As a simple example, if you run `Discoverer` on an AVI file with one audio +and one video stream, you will get a `DiscovererContainerInfo` +corresponding to the AVI container, which in turn will have a +`DiscovererAudioInfo` sub-stream and a `DiscovererVideoInfo` sub-stream +for the audio and video streams respectively. + +# Implements + +[`DiscovererStreamInfoExt`](trait.DiscovererStreamInfoExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Trait containing all `DiscovererStreamInfo` methods. + +# Implementors + +[`DiscovererAudioInfo`](struct.DiscovererAudioInfo.html), [`DiscovererContainerInfo`](struct.DiscovererContainerInfo.html), [`DiscovererStreamInfo`](struct.DiscovererStreamInfo.html), [`DiscovererSubtitleInfo`](struct.DiscovererSubtitleInfo.html), [`DiscovererVideoInfo`](struct.DiscovererVideoInfo.html) + +Decrements the reference count of all contained `DiscovererStreamInfo` +and fress the `glib::List`. +## `infos` +a `glib::List` of `DiscovererStreamInfo` + + +# Returns + +the `gst::Caps` of the stream. Unref with +`gst_caps_unref` after usage. + + +# Deprecated + +This functions is deprecated since version 1.4, use +`DiscovererInfoExt::get_missing_elements_installer_details` + +# Returns + +additional information regarding the stream (for +example codec version, profile, etc..). If you wish to use the `gst::Structure` +after the life-time of `self` you will need to copy it. + + +# Returns + +the next `DiscovererStreamInfo` in a chain. `None` +for final streams. +Unref with `gst_discoverer_stream_info_unref` after usage. + + +# Returns + +the previous `DiscovererStreamInfo` in a chain. +`None` for starting points. Unref with `gst_discoverer_stream_info_unref` +after usage. + + +# Returns + +the stream ID of this stream. If you wish to +use the stream ID after the life-time of `self` you will need to copy it. + + +# Returns + +a human readable name for the stream type of the given `self` (ex : "audio", +"container",...). + + +# Returns + +the tags contained in this stream. If you wish to +use the tags after the life-time of `self` you will need to copy them. + + +# Returns + +the TOC contained in this stream. If you wish to +use the TOC after the life-time of `self` you will need to copy it. + +`DiscovererStreamInfo` specific to subtitle streams (this includes text and +image based ones). + +# Implements + +[`DiscovererStreamInfoExt`](trait.DiscovererStreamInfoExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + + +# Returns + +the language of the stream, or NULL if unknown. + +`DiscovererStreamInfo` specific to video streams (this includes images). + +# Implements + +[`DiscovererStreamInfoExt`](trait.DiscovererStreamInfoExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + + +# Returns + +the average or nominal bitrate of the video stream in bits/second. + + +# Returns + +the depth in bits of the video stream. + + +# Returns + +the framerate of the video stream (denominator). + + +# Returns + +the framerate of the video stream (numerator). + + +# Returns + +the height of the video stream in pixels. + + +# Returns + +the maximum bitrate of the video stream in bits/second. + + +# Returns + +the Pixel Aspect Ratio (PAR) of the video stream (denominator). + + +# Returns + +the Pixel Aspect Ratio (PAR) of the video stream (numerator). + + +# Returns + +the width of the video stream in pixels. + + +# Returns + +`true` if the video stream corresponds to an image (i.e. only contains +one frame). + + +# Returns + +`true` if the stream is interlaced, else `false`. diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 5c0465acf..b738064cd 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -9,6 +9,7 @@ gstreamer = { path = "../gstreamer" } gstreamer-app = { path = "../gstreamer-app" } gstreamer-audio = { path = "../gstreamer-audio" } gstreamer-video = { path = "../gstreamer-video" } +gstreamer-pbutils = { path = "../gstreamer-pbutils" } gstreamer-player = { path = "../gstreamer-player", optional = true } gstreamer-rtsp = { path = "../gstreamer-rtsp", optional = true } gstreamer-rtsp-server = { path = "../gstreamer-rtsp-server", optional = true } diff --git a/examples/src/bin/discoverer.rs b/examples/src/bin/discoverer.rs new file mode 100644 index 000000000..0f1cf0d74 --- /dev/null +++ b/examples/src/bin/discoverer.rs @@ -0,0 +1,98 @@ +extern crate gstreamer as gst; + +extern crate gstreamer_pbutils as pbutils; +use pbutils::prelude::*; + +use pbutils::DiscovererStreamInfo; +use pbutils::DiscovererInfo; + +extern crate glib; + +extern crate failure; +use failure::Error; + +#[macro_use] +extern crate failure_derive; + +use std::env; + +#[path = "../examples-common.rs"] +mod examples_common; + +#[derive(Debug, Fail)] +#[fail(display = "Discoverer error {}", _0)] +struct DiscovererError(&'static str); + +fn print_tags(info: &DiscovererInfo) { + println!("Tags:"); + + let tags = info.get_tags(); + match tags { + Some(taglist) => { + println!(" {}", taglist.to_string()); // FIXME use an iterator + } + None => { + println!(" no tags"); + } + } +} + +fn print_stream_info(stream: &DiscovererStreamInfo) { + println!("Stream: "); + match stream.get_stream_id() { + Some(id) => println!(" Stream id: {}", id), + None => {} + } + let caps_str = match stream.get_caps() { + Some(caps) => caps.to_string(), + None => String::from("--") + }; + println!(" Format: {}", caps_str); +} + +fn print_discoverer_info(info: &DiscovererInfo) -> Result<(), Error> { + let uri = info.get_uri().ok_or(DiscovererError("URI should not be null"))?; + println!("URI: {}", uri); + println!("Duration: {}", info.get_duration()); + print_tags(info); + print_stream_info(&info.get_stream_info().ok_or(DiscovererError("Error while obtaining stream info"))?); + + let children = info.get_stream_list(); + println!("Children streams:"); + for child in children { + print_stream_info(&child); + } + + Ok(()) +} + +fn run_discoverer() -> Result<(), Error> { + gst::init()?; + + let args: Vec<_> = env::args().collect(); + let uri: &str = if args.len() == 2 { + args[1].as_ref() + } else { + println!("Usage: discoverer uri"); + std::process::exit(-1) + }; + + let timeout: gst::ClockTime = gst::ClockTime::from_seconds(15); + let discoverer = pbutils::Discoverer::new(timeout)?; + let info = discoverer.discover_uri(uri)?; + print_discoverer_info(&info)?; + Ok(()) +} + +fn example_main() { + match run_discoverer() { + Ok(_) => (), + Err(e) => eprintln!("Error: {}", e) + } +} + +fn main() { + // tutorials_common::run is only required to set up the application environent on macOS + // (but not necessary in normal Cocoa applications where this is set up autmatically) + examples_common::run(example_main); +} diff --git a/gir-files/GstPbutils-1.0.gir b/gir-files/GstPbutils-1.0.gir index 8ce604dd7..4094eba6d 100644 --- a/gir-files/GstPbutils-1.0.gir +++ b/gir-files/GstPbutils-1.0.gir @@ -458,11 +458,15 @@ depending on the circumstances of the error. the results #GstDiscovererInfo - - #GError, which will be non-NULL if an error - occurred during discovery. You must not - free this #GError, it will be freed by - the discoverer. + + #GError, which will be non-NULL + if an error occurred during + discovery. You must not free + this #GError, it will be freed by + the discoverer. @@ -1903,7 +1907,10 @@ during the encoding a #GstEncodingProfile - + the description to set on the profile @@ -1953,7 +1960,10 @@ internally. a #GstEncodingProfile - + the name to set on the profile @@ -2009,7 +2019,10 @@ This is the name that has been set when saving the preset. a #GstEncodingProfile - + The name of the preset to use in this @profile. @@ -2028,7 +2041,10 @@ for more about restrictions. Does not apply to #GstEncodingContainerProfile.a #GstEncodingProfile - + the restriction to apply @@ -2132,7 +2148,7 @@ valid for target names). The file location to load the #GstEncodingTarget from - + @@ -2259,7 +2275,7 @@ count. the location to store the @target at. - + diff --git a/gstreamer-pbutils/Cargo.toml b/gstreamer-pbutils/Cargo.toml new file mode 100644 index 000000000..275814882 --- /dev/null +++ b/gstreamer-pbutils/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "gstreamer-pbutils" +version = "0.11.0" +authors = ["Sebastian Dröge "] +categories = ["api-bindings", "multimedia"] +description = "Rust bindings for GStreamer Base Utils library" +repository = "https://github.com/sdroege/gstreamer-rs" +license = "MIT/Apache-2.0" +readme = "README.md" +homepage = "https://gstreamer.freedesktop.org" +documentation = "https://sdroege.github.io/rustdoc/gstreamer/gstreamer_pbutils" +keywords = ["gstreamer", "multimedia", "audio", "pbutils", "gnome"] +build = "build.rs" + +[dependencies] +bitflags = "1.0" +libc = "0.2" +glib-sys = { git = "https://github.com/gtk-rs/sys" } +gobject-sys = { git = "https://github.com/gtk-rs/sys" } +gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] } +gstreamer-pbutils-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] } +glib = { git = "https://github.com/gtk-rs/glib" } +gstreamer = { path = "../gstreamer" } + +[build-dependencies.rustdoc-stripper] +version = "0.1" +optional = true + +[features] +v1_10 = ["gstreamer-sys/v1_10", "gstreamer-pbutils-sys/v1_10"] +v1_12 = ["gstreamer-sys/v1_12", "gstreamer-pbutils-sys/v1_12", "v1_10"] +embed-lgpl-docs = ["rustdoc-stripper"] +purge-lgpl-docs = ["rustdoc-stripper"] +dox = ["gstreamer-pbutils-sys/dox"] +default-features = [] + +[badges] +travis-ci = { repository = "sdroege/gstreamer-rs", branch = "master" } diff --git a/gstreamer-pbutils/build.rs b/gstreamer-pbutils/build.rs new file mode 100644 index 000000000..91a9745e4 --- /dev/null +++ b/gstreamer-pbutils/build.rs @@ -0,0 +1,34 @@ +fn main() { + manage_docs(); +} + +#[cfg(any(feature = "embed-lgpl-docs", feature = "purge-lgpl-docs"))] +fn manage_docs() { + extern crate stripper_lib; + use std::io; + + let path = "src"; + let ignores: &[&str] = &[]; + + stripper_lib::loop_over_files( + path.as_ref(), + &mut |w, s| stripper_lib::strip_comments(w, s, &mut io::sink(), true), + &ignores, + false, + ); + + #[cfg(feature = "embed-lgpl-docs")] + { + let docs = include_str!("../docs/gstreamer-pbutils/docs.md"); + let mut infos = stripper_lib::parse_cmts(docs.lines(), true); + stripper_lib::loop_over_files( + path.as_ref(), + &mut |w, s| stripper_lib::regenerate_comments(w, s, &mut infos, true, true), + &ignores, + false, + ); + } +} + +#[cfg(not(any(feature = "embed-lgpl-docs", feature = "purge-lgpl-docs")))] +fn manage_docs() {} diff --git a/gstreamer-pbutils/src/auto/discoverer.rs b/gstreamer-pbutils/src/auto/discoverer.rs new file mode 100644 index 000000000..8ab89037f --- /dev/null +++ b/gstreamer-pbutils/src/auto/discoverer.rs @@ -0,0 +1,119 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use DiscovererInfo; +use Error; +use ffi; +use glib; +use glib::signal::SignalHandlerId; +use glib::signal::connect; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::boxed::Box as Box_; +use std::mem; +use std::mem::transmute; +use std::ptr; + +glib_wrapper! { + pub struct Discoverer(Object); + + match fn { + get_type => || ffi::gst_discoverer_get_type(), + } +} + +impl Discoverer { + pub fn new(timeout: gst::ClockTime) -> Result { + assert_initialized_main_thread!(); + unsafe { + let mut error = ptr::null_mut(); + let ret = ffi::gst_discoverer_new(timeout.to_glib(), &mut error); + if error.is_null() { Ok(from_glib_full(ret)) } else { Err(from_glib_full(error)) } + } + } + + pub fn discover_uri(&self, uri: &str) -> Result { + unsafe { + let mut error = ptr::null_mut(); + let ret = ffi::gst_discoverer_discover_uri(self.to_glib_none().0, uri.to_glib_none().0, &mut error); + if error.is_null() { Ok(from_glib_full(ret)) } else { Err(from_glib_full(error)) } + } + } + + pub fn discover_uri_async(&self, uri: &str) -> Result<(), glib::error::BoolError> { + unsafe { + glib::error::BoolError::from_glib(ffi::gst_discoverer_discover_uri_async(self.to_glib_none().0, uri.to_glib_none().0), "Failed to add URI to list of discovers") + } + } + + pub fn start(&self) { + unsafe { + ffi::gst_discoverer_start(self.to_glib_none().0); + } + } + + pub fn stop(&self) { + unsafe { + ffi::gst_discoverer_stop(self.to_glib_none().0); + } + } + + pub fn connect_discovered) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_) + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "discovered", + transmute(discovered_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } + + pub fn connect_finished(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "finished", + transmute(finished_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } + + pub fn connect_source_setup(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "source-setup", + transmute(source_setup_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } + + pub fn connect_starting(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "starting", + transmute(starting_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } +} + +unsafe impl Send for Discoverer {} +unsafe impl Sync for Discoverer {} + +unsafe extern "C" fn discovered_trampoline(this: *mut ffi::GstDiscoverer, info: *mut ffi::GstDiscovererInfo, error: *mut glib_ffi::GError, f: glib_ffi::gpointer) { + let f: &&(Fn(&Discoverer, &DiscovererInfo, &Option) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this), &from_glib_borrow(info), &from_glib_borrow(error)) +} + +unsafe extern "C" fn finished_trampoline(this: *mut ffi::GstDiscoverer, f: glib_ffi::gpointer) { + let f: &&(Fn(&Discoverer) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this)) +} + +unsafe extern "C" fn source_setup_trampoline(this: *mut ffi::GstDiscoverer, source: *mut gst_ffi::GstElement, f: glib_ffi::gpointer) { + let f: &&(Fn(&Discoverer, &gst::Element) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this), &from_glib_borrow(source)) +} + +unsafe extern "C" fn starting_trampoline(this: *mut ffi::GstDiscoverer, f: glib_ffi::gpointer) { + let f: &&(Fn(&Discoverer) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this)) +} diff --git a/gstreamer-pbutils/src/auto/discoverer_audio_info.rs b/gstreamer-pbutils/src/auto/discoverer_audio_info.rs new file mode 100644 index 000000000..84a8dbd4c --- /dev/null +++ b/gstreamer-pbutils/src/auto/discoverer_audio_info.rs @@ -0,0 +1,60 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use DiscovererStreamInfo; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct DiscovererAudioInfo(Object): DiscovererStreamInfo; + + match fn { + get_type => || ffi::gst_discoverer_audio_info_get_type(), + } +} + +impl DiscovererAudioInfo { + pub fn get_bitrate(&self) -> u32 { + unsafe { + ffi::gst_discoverer_audio_info_get_bitrate(self.to_glib_none().0) + } + } + + pub fn get_channels(&self) -> u32 { + unsafe { + ffi::gst_discoverer_audio_info_get_channels(self.to_glib_none().0) + } + } + + pub fn get_depth(&self) -> u32 { + unsafe { + ffi::gst_discoverer_audio_info_get_depth(self.to_glib_none().0) + } + } + + pub fn get_language(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_audio_info_get_language(self.to_glib_none().0)) + } + } + + pub fn get_max_bitrate(&self) -> u32 { + unsafe { + ffi::gst_discoverer_audio_info_get_max_bitrate(self.to_glib_none().0) + } + } + + pub fn get_sample_rate(&self) -> u32 { + unsafe { + ffi::gst_discoverer_audio_info_get_sample_rate(self.to_glib_none().0) + } + } +} + +unsafe impl Send for DiscovererAudioInfo {} +unsafe impl Sync for DiscovererAudioInfo {} diff --git a/gstreamer-pbutils/src/auto/discoverer_container_info.rs b/gstreamer-pbutils/src/auto/discoverer_container_info.rs new file mode 100644 index 000000000..e45d2a75d --- /dev/null +++ b/gstreamer-pbutils/src/auto/discoverer_container_info.rs @@ -0,0 +1,30 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use DiscovererStreamInfo; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct DiscovererContainerInfo(Object): DiscovererStreamInfo; + + match fn { + get_type => || ffi::gst_discoverer_container_info_get_type(), + } +} + +impl DiscovererContainerInfo { + pub fn get_streams(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_full(ffi::gst_discoverer_container_info_get_streams(self.to_glib_none().0)) + } + } +} + +unsafe impl Send for DiscovererContainerInfo {} +unsafe impl Sync for DiscovererContainerInfo {} diff --git a/gstreamer-pbutils/src/auto/discoverer_info.rs b/gstreamer-pbutils/src/auto/discoverer_info.rs new file mode 100644 index 000000000..4b94801f5 --- /dev/null +++ b/gstreamer-pbutils/src/auto/discoverer_info.rs @@ -0,0 +1,176 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use DiscovererResult; +use DiscovererSerializeFlags; +use DiscovererStreamInfo; +use ffi; +use glib; +use glib::object::IsA; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct DiscovererInfo(Object); + + match fn { + get_type => || ffi::gst_discoverer_info_get_type(), + } +} + +impl DiscovererInfo { + pub fn from_variant(variant: &glib::Variant) -> Option { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gst_discoverer_info_from_variant(variant.to_glib_none().0)) + } + } +} + +unsafe impl Send for DiscovererInfo {} +unsafe impl Sync for DiscovererInfo {} + +pub trait DiscovererInfoExt { + fn copy(&self) -> DiscovererInfo; + + fn get_audio_streams(&self) -> Vec; + + fn get_container_streams(&self) -> Vec; + + fn get_duration(&self) -> gst::ClockTime; + + fn get_misc(&self) -> Option; + + fn get_missing_elements_installer_details(&self) -> Vec; + + fn get_result(&self) -> DiscovererResult; + + fn get_seekable(&self) -> bool; + + fn get_stream_info(&self) -> Option; + + fn get_stream_list(&self) -> Vec; + + fn get_streams(&self, streamtype: glib::types::Type) -> Vec; + + fn get_subtitle_streams(&self) -> Vec; + + fn get_tags(&self) -> Option; + + fn get_toc(&self) -> Option; + + fn get_uri(&self) -> Option; + + fn get_video_streams(&self) -> Vec; + + fn to_variant(&self, flags: DiscovererSerializeFlags) -> Option; +} + +impl> DiscovererInfoExt for O { + fn copy(&self) -> DiscovererInfo { + unsafe { + from_glib_full(ffi::gst_discoverer_info_copy(self.to_glib_none().0)) + } + } + + fn get_audio_streams(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_full(ffi::gst_discoverer_info_get_audio_streams(self.to_glib_none().0)) + } + } + + fn get_container_streams(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_full(ffi::gst_discoverer_info_get_container_streams(self.to_glib_none().0)) + } + } + + fn get_duration(&self) -> gst::ClockTime { + unsafe { + from_glib(ffi::gst_discoverer_info_get_duration(const_override(self.to_glib_none().0))) + } + } + + fn get_misc(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_info_get_misc(const_override(self.to_glib_none().0))) + } + } + + fn get_missing_elements_installer_details(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_none(ffi::gst_discoverer_info_get_missing_elements_installer_details(const_override(self.to_glib_none().0))) + } + } + + fn get_result(&self) -> DiscovererResult { + unsafe { + from_glib(ffi::gst_discoverer_info_get_result(const_override(self.to_glib_none().0))) + } + } + + fn get_seekable(&self) -> bool { + unsafe { + from_glib(ffi::gst_discoverer_info_get_seekable(const_override(self.to_glib_none().0))) + } + } + + fn get_stream_info(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_discoverer_info_get_stream_info(self.to_glib_none().0)) + } + } + + fn get_stream_list(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_full(ffi::gst_discoverer_info_get_stream_list(self.to_glib_none().0)) + } + } + + fn get_streams(&self, streamtype: glib::types::Type) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_full(ffi::gst_discoverer_info_get_streams(self.to_glib_none().0, streamtype.to_glib())) + } + } + + fn get_subtitle_streams(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_full(ffi::gst_discoverer_info_get_subtitle_streams(self.to_glib_none().0)) + } + } + + fn get_tags(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_info_get_tags(const_override(self.to_glib_none().0))) + } + } + + fn get_toc(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_info_get_toc(const_override(self.to_glib_none().0))) + } + } + + fn get_uri(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_info_get_uri(const_override(self.to_glib_none().0))) + } + } + + fn get_video_streams(&self) -> Vec { + unsafe { + FromGlibPtrContainer::from_glib_full(ffi::gst_discoverer_info_get_video_streams(self.to_glib_none().0)) + } + } + + fn to_variant(&self, flags: DiscovererSerializeFlags) -> Option { + unsafe { + from_glib_full(ffi::gst_discoverer_info_to_variant(self.to_glib_none().0, flags.to_glib())) + } + } +} diff --git a/gstreamer-pbutils/src/auto/discoverer_stream_info.rs b/gstreamer-pbutils/src/auto/discoverer_stream_info.rs new file mode 100644 index 000000000..1ff1e40db --- /dev/null +++ b/gstreamer-pbutils/src/auto/discoverer_stream_info.rs @@ -0,0 +1,91 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use ffi; +use glib::object::IsA; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct DiscovererStreamInfo(Object); + + match fn { + get_type => || ffi::gst_discoverer_stream_info_get_type(), + } +} + +unsafe impl Send for DiscovererStreamInfo {} +unsafe impl Sync for DiscovererStreamInfo {} + +pub trait DiscovererStreamInfoExt { + fn get_caps(&self) -> Option; + + fn get_misc(&self) -> Option; + + fn get_next(&self) -> Option; + + fn get_previous(&self) -> Option; + + fn get_stream_id(&self) -> Option; + + fn get_stream_type_nick(&self) -> String; + + fn get_tags(&self) -> Option; + + fn get_toc(&self) -> Option; +} + +impl> DiscovererStreamInfoExt for O { + fn get_caps(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_discoverer_stream_info_get_caps(self.to_glib_none().0)) + } + } + + fn get_misc(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_stream_info_get_misc(self.to_glib_none().0)) + } + } + + fn get_next(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_discoverer_stream_info_get_next(self.to_glib_none().0)) + } + } + + fn get_previous(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_discoverer_stream_info_get_previous(self.to_glib_none().0)) + } + } + + fn get_stream_id(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_stream_info_get_stream_id(self.to_glib_none().0)) + } + } + + fn get_stream_type_nick(&self) -> String { + unsafe { + from_glib_none(ffi::gst_discoverer_stream_info_get_stream_type_nick(self.to_glib_none().0)) + } + } + + fn get_tags(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_stream_info_get_tags(self.to_glib_none().0)) + } + } + + fn get_toc(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_stream_info_get_toc(self.to_glib_none().0)) + } + } +} diff --git a/gstreamer-pbutils/src/auto/discoverer_subtitle_info.rs b/gstreamer-pbutils/src/auto/discoverer_subtitle_info.rs new file mode 100644 index 000000000..f9bcc32a2 --- /dev/null +++ b/gstreamer-pbutils/src/auto/discoverer_subtitle_info.rs @@ -0,0 +1,30 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use DiscovererStreamInfo; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct DiscovererSubtitleInfo(Object): DiscovererStreamInfo; + + match fn { + get_type => || ffi::gst_discoverer_subtitle_info_get_type(), + } +} + +impl DiscovererSubtitleInfo { + pub fn get_language(&self) -> Option { + unsafe { + from_glib_none(ffi::gst_discoverer_subtitle_info_get_language(self.to_glib_none().0)) + } + } +} + +unsafe impl Send for DiscovererSubtitleInfo {} +unsafe impl Sync for DiscovererSubtitleInfo {} diff --git a/gstreamer-pbutils/src/auto/discoverer_video_info.rs b/gstreamer-pbutils/src/auto/discoverer_video_info.rs new file mode 100644 index 000000000..edff05bbd --- /dev/null +++ b/gstreamer-pbutils/src/auto/discoverer_video_info.rs @@ -0,0 +1,66 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use DiscovererStreamInfo; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct DiscovererVideoInfo(Object): DiscovererStreamInfo; + + match fn { + get_type => || ffi::gst_discoverer_video_info_get_type(), + } +} + +impl DiscovererVideoInfo { + pub fn get_bitrate(&self) -> u32 { + unsafe { + ffi::gst_discoverer_video_info_get_bitrate(self.to_glib_none().0) + } + } + + pub fn get_depth(&self) -> u32 { + unsafe { + ffi::gst_discoverer_video_info_get_depth(self.to_glib_none().0) + } + } + + pub fn get_height(&self) -> u32 { + unsafe { + ffi::gst_discoverer_video_info_get_height(self.to_glib_none().0) + } + } + + pub fn get_max_bitrate(&self) -> u32 { + unsafe { + ffi::gst_discoverer_video_info_get_max_bitrate(self.to_glib_none().0) + } + } + + pub fn get_width(&self) -> u32 { + unsafe { + ffi::gst_discoverer_video_info_get_width(self.to_glib_none().0) + } + } + + pub fn is_image(&self) -> bool { + unsafe { + from_glib(ffi::gst_discoverer_video_info_is_image(self.to_glib_none().0)) + } + } + + pub fn is_interlaced(&self) -> bool { + unsafe { + from_glib(ffi::gst_discoverer_video_info_is_interlaced(self.to_glib_none().0)) + } + } +} + +unsafe impl Send for DiscovererVideoInfo {} +unsafe impl Sync for DiscovererVideoInfo {} diff --git a/gstreamer-pbutils/src/auto/enums.rs b/gstreamer-pbutils/src/auto/enums.rs new file mode 100644 index 000000000..ab0a46c77 --- /dev/null +++ b/gstreamer-pbutils/src/auto/enums.rs @@ -0,0 +1,83 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use ffi; +use glib::StaticType; +use glib::Type; +use glib::translate::*; +use glib::value::FromValue; +use glib::value::FromValueOptional; +use glib::value::SetValue; +use glib::value::Value; +use gobject_ffi; + +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub enum DiscovererResult { + Ok, + UriInvalid, + Error, + Timeout, + Busy, + MissingPlugins, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for DiscovererResult { + type GlibType = ffi::GstDiscovererResult; + + fn to_glib(&self) -> ffi::GstDiscovererResult { + match *self { + DiscovererResult::Ok => ffi::GST_DISCOVERER_OK, + DiscovererResult::UriInvalid => ffi::GST_DISCOVERER_URI_INVALID, + DiscovererResult::Error => ffi::GST_DISCOVERER_ERROR, + DiscovererResult::Timeout => ffi::GST_DISCOVERER_TIMEOUT, + DiscovererResult::Busy => ffi::GST_DISCOVERER_BUSY, + DiscovererResult::MissingPlugins => ffi::GST_DISCOVERER_MISSING_PLUGINS, + DiscovererResult::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for DiscovererResult { + fn from_glib(value: ffi::GstDiscovererResult) -> Self { + skip_assert_initialized!(); + match value { + 0 => DiscovererResult::Ok, + 1 => DiscovererResult::UriInvalid, + 2 => DiscovererResult::Error, + 3 => DiscovererResult::Timeout, + 4 => DiscovererResult::Busy, + 5 => DiscovererResult::MissingPlugins, + value => DiscovererResult::__Unknown(value), + } + } +} + +impl StaticType for DiscovererResult { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_discoverer_result_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for DiscovererResult { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for DiscovererResult { + unsafe fn from_value(value: &Value) -> Self { + from_glib(gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl SetValue for DiscovererResult { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib()) + } +} + diff --git a/gstreamer-pbutils/src/auto/flags.rs b/gstreamer-pbutils/src/auto/flags.rs new file mode 100644 index 000000000..92cfb8018 --- /dev/null +++ b/gstreamer-pbutils/src/auto/flags.rs @@ -0,0 +1,65 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +use ffi; +use glib::StaticType; +use glib::Type; +use glib::translate::*; +use glib::value::FromValue; +use glib::value::FromValueOptional; +use glib::value::SetValue; +use glib::value::Value; +use gobject_ffi; + +bitflags! { + pub struct DiscovererSerializeFlags: u32 { + const BASIC = 0; + const CAPS = 1; + const TAGS = 2; + const MISC = 4; + const ALL = 7; + } +} + +#[doc(hidden)] +impl ToGlib for DiscovererSerializeFlags { + type GlibType = ffi::GstDiscovererSerializeFlags; + + fn to_glib(&self) -> ffi::GstDiscovererSerializeFlags { + ffi::GstDiscovererSerializeFlags::from_bits_truncate(self.bits()) + } +} + +#[doc(hidden)] +impl FromGlib for DiscovererSerializeFlags { + fn from_glib(value: ffi::GstDiscovererSerializeFlags) -> DiscovererSerializeFlags { + skip_assert_initialized!(); + DiscovererSerializeFlags::from_bits_truncate(value.bits()) + } +} + +impl StaticType for DiscovererSerializeFlags { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_discoverer_serialize_flags_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for DiscovererSerializeFlags { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for DiscovererSerializeFlags { + unsafe fn from_value(value: &Value) -> Self { + from_glib(ffi::GstDiscovererSerializeFlags::from_bits_truncate(gobject_ffi::g_value_get_flags(value.to_glib_none().0))) + } +} + +impl SetValue for DiscovererSerializeFlags { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib().bits()) + } +} + diff --git a/gstreamer-pbutils/src/auto/mod.rs b/gstreamer-pbutils/src/auto/mod.rs new file mode 100644 index 000000000..e0d2343fe --- /dev/null +++ b/gstreamer-pbutils/src/auto/mod.rs @@ -0,0 +1,38 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir @ bd67955) +// from gir-files (https://github.com/gtk-rs/gir-files @ ???) +// DO NOT EDIT + +mod discoverer; +pub use self::discoverer::Discoverer; + +mod discoverer_audio_info; +pub use self::discoverer_audio_info::DiscovererAudioInfo; + +mod discoverer_container_info; +pub use self::discoverer_container_info::DiscovererContainerInfo; + +mod discoverer_info; +pub use self::discoverer_info::DiscovererInfo; +pub use self::discoverer_info::DiscovererInfoExt; + +mod discoverer_stream_info; +pub use self::discoverer_stream_info::DiscovererStreamInfo; +pub use self::discoverer_stream_info::DiscovererStreamInfoExt; + +mod discoverer_subtitle_info; +pub use self::discoverer_subtitle_info::DiscovererSubtitleInfo; + +mod discoverer_video_info; +pub use self::discoverer_video_info::DiscovererVideoInfo; + +mod enums; +pub use self::enums::DiscovererResult; + +mod flags; +pub use self::flags::DiscovererSerializeFlags; + +#[doc(hidden)] +pub mod traits { + pub use super::DiscovererInfoExt; + pub use super::DiscovererStreamInfoExt; +} diff --git a/gstreamer-pbutils/src/discoverer.rs b/gstreamer-pbutils/src/discoverer.rs new file mode 100644 index 000000000..5515fb369 --- /dev/null +++ b/gstreamer-pbutils/src/discoverer.rs @@ -0,0 +1,58 @@ +// Copyright (C) 2018 Thiago Santos +// Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use gst; + +use auto::Discoverer; + +use glib::Value; +use glib::IsA; +use glib::signal::connect; +use glib::signal::SignalHandlerId; +use glib::translate::*; +use glib::object::Downcast; + +use ffi; +use glib_ffi; +use gobject_ffi; + +use std::mem::transmute; +use std::boxed::Box as Box_; + +impl Discoverer { + pub fn set_property_timeout(&self, timeout: gst::ClockTime) { + unsafe { + gobject_ffi::g_object_set_property(self.to_glib_none().0, + "timeout".to_glib_none().0, Value::from(&timeout).to_glib_none().0); + } + } + + pub fn get_property_timeout(&self) -> gst::ClockTime { + let mut value = Value::from(&0u64); + unsafe { + gobject_ffi::g_object_get_property(self.to_glib_none().0, "timeout".to_glib_none().0, value.to_glib_none_mut().0); + } + value.get().unwrap() + } + + pub fn connect_property_timeout_notify(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "notify::timeout", + transmute(notify_timeout_trampoline:: as usize), Box_::into_raw(f) as *mut _) + } + } +} + +unsafe extern "C" fn notify_timeout_trampoline

(this: *mut ffi::GstDiscoverer, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer) +where P: IsA { + callback_guard!(); + let f: &&(Fn(&P) + Send + Sync + 'static) = transmute(f); + f(&Discoverer::from_glib_borrow(this).downcast_unchecked()) +} diff --git a/gstreamer-pbutils/src/discoverer_stream_info.rs b/gstreamer-pbutils/src/discoverer_stream_info.rs new file mode 100644 index 000000000..94705dab3 --- /dev/null +++ b/gstreamer-pbutils/src/discoverer_stream_info.rs @@ -0,0 +1,52 @@ +// Copyright (C) 2018 Thiago Santos +// Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use DiscovererStreamInfo; +use DiscovererStreamInfoExt; + +pub struct DiscovererStreamInfoIter { + stream_info: Option, + direction_forward: bool +} + +impl Iterator for DiscovererStreamInfoIter { + type Item = DiscovererStreamInfo; + + fn next(&mut self) -> Option { + let current = self.stream_info.take(); + self.stream_info = match ¤t { + &Some(ref c) => { + // Decide on the direction + if self.direction_forward { + c.get_next() + } else { + c.get_previous() + } + }, + &None => None + }; + current + } +} + +impl DiscovererStreamInfo { + pub fn next_iter(&self) -> DiscovererStreamInfoIter { + DiscovererStreamInfoIter { + stream_info: self.get_next(), + direction_forward: true + } + } + + pub fn previous_iter(&self) -> DiscovererStreamInfoIter { + DiscovererStreamInfoIter { + stream_info: self.get_previous(), + direction_forward: false + } + } +} diff --git a/gstreamer-pbutils/src/discoverer_video_info.rs b/gstreamer-pbutils/src/discoverer_video_info.rs new file mode 100644 index 000000000..44f9964d3 --- /dev/null +++ b/gstreamer-pbutils/src/discoverer_video_info.rs @@ -0,0 +1,32 @@ +// Copyright (C) 2018 Thiago Santos +// Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use DiscovererVideoInfo; + +use gst; +use ffi; +use glib::translate::*; + +impl DiscovererVideoInfo { + pub fn get_framerate(&self) -> gst::Fraction { + unsafe { + gst::Fraction::new( + ffi::gst_discoverer_video_info_get_framerate_num(self.to_glib_none().0) as i32, + ffi::gst_discoverer_video_info_get_framerate_denom(self.to_glib_none().0) as i32) + } + } + + pub fn get_par(&self) -> gst::Fraction { + unsafe { + gst::Fraction::new( + ffi::gst_discoverer_video_info_get_par_num(self.to_glib_none().0) as i32, + ffi::gst_discoverer_video_info_get_par_denom(self.to_glib_none().0) as i32) + } + } +} diff --git a/gstreamer-pbutils/src/lib.rs b/gstreamer-pbutils/src/lib.rs new file mode 100644 index 000000000..b90245cad --- /dev/null +++ b/gstreamer-pbutils/src/lib.rs @@ -0,0 +1,76 @@ +// Copyright (C) 2017 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate bitflags; +extern crate libc; + +use std::sync::{Once, ONCE_INIT}; + +#[macro_use] +extern crate glib; +extern crate glib_sys as glib_ffi; +extern crate gobject_sys as gobject_ffi; +extern crate gstreamer as gst; +extern crate gstreamer_sys as gst_ffi; +extern crate gstreamer_pbutils_sys as ffi; + +static PBUTILS_INIT: Once = ONCE_INIT; + +macro_rules! callback_guard { + () => ( + let _guard = ::glib::CallbackGuard::new(); + ) +} + +macro_rules! assert_initialized_main_thread { + () => ( + if unsafe {::gst_ffi::gst_is_initialized()} != ::glib_ffi::GTRUE { + panic!("GStreamer has not been initialized. Call `gst::init` first."); + } + ::PBUTILS_INIT.call_once(|| { + unsafe{::ffi::gst_pb_utils_init()}; + }); + ) +} + +macro_rules! skip_assert_initialized { + () => ( + ) +} + +pub use glib::{Cast, Continue, Error, IsA, StaticType, ToValue, Type, TypedValue, Value}; + +#[cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))] +#[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))] +#[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] +#[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))] +mod auto; +pub use auto::*; + +mod discoverer; +pub use discoverer::*; + +mod discoverer_stream_info; +pub use discoverer_stream_info::*; + +mod discoverer_video_info; +pub use discoverer_video_info::*; + +// Re-export all the traits in a prelude module, so that applications +// can always "use gst::prelude::*" without getting conflicts +pub mod prelude { + pub use glib::prelude::*; + pub use gst::prelude::*; + + pub use discoverer::*; + pub use discoverer_stream_info::*; + pub use discoverer_video_info::*; + + pub use auto::traits::*; +}