diff --git a/Cargo.lock b/Cargo.lock index 3c2cfcbf8..b6a12442f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,15 +1,15 @@ [root] -name = "gstreamer" +name = "gstreamer-app" version = "0.1.0" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "glib 0.1.3 (git+https://github.com/gtk-rs/glib)", "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", + "gstreamer 0.1.0", + "gstreamer-app-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)", "gstreamer-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)", - "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "rustdoc-stripper 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -210,6 +210,48 @@ dependencies = [ "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "gstreamer" +version = "0.1.0" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "glib 0.1.3 (git+https://github.com/gtk-rs/glib)", + "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", + "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", + "gstreamer-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "rustdoc-stripper 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gstreamer-app-sys" +version = "0.1.1" +source = "git+https://github.com/sdroege/gstreamer-sys#8c0b6e6605ed614c03fa99c406aabd9c1c42f70b" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", + "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", + "gstreamer-base-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)", + "gstreamer-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)", + "libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gstreamer-base-sys" +version = "0.1.1" +source = "git+https://github.com/sdroege/gstreamer-sys#8c0b6e6605ed614c03fa99c406aabd9c1c42f70b" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", + "gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)", + "gstreamer-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)", + "libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gstreamer-sys" version = "0.1.1" @@ -469,6 +511,8 @@ dependencies = [ "checksum glib 0.1.3 (git+https://github.com/gtk-rs/glib)" = "" "checksum glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "" "checksum gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "" +"checksum gstreamer-app-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)" = "" +"checksum gstreamer-base-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)" = "" "checksum gstreamer-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)" = "" "checksum gtk 0.1.3 (git+https://github.com/gtk-rs/gtk)" = "" "checksum gtk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "" diff --git a/Cargo.toml b/Cargo.toml index 8eee8f672..4f543e6cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,5 +2,6 @@ members = [ "gstreamer", + "gstreamer-app", "examples", ] diff --git a/Gir_GstApp.toml b/Gir_GstApp.toml index f878ab911..732b8e4f6 100644 --- a/Gir_GstApp.toml +++ b/Gir_GstApp.toml @@ -11,21 +11,32 @@ generate_safety_asserts = true external_libraries = [ "GLib", "GObject", + "Gst", ] generate = [ - "GstApp.AppSink", - "GstApp.AppSrc", "GstApp.AppStreamType", ] manual = [ "GObject.Object", + "Gst.Object", + "Gst.Element", "Gst.ClockTime", "Gst.FlowReturn", "Gst.Format", ] +[[object]] +name = "GstApp.AppSink" +status = "generate" +trait = false + +[[object]] +name = "GstApp.AppSrc" +status = "generate" +trait = false + [[object]] name = "Gst.Caps" status = "manual" diff --git a/docs/gstreamer-app/docs.md b/docs/gstreamer-app/docs.md new file mode 100644 index 000000000..7ccd313da --- /dev/null +++ b/docs/gstreamer-app/docs.md @@ -0,0 +1,483 @@ + + +Appsink is a sink plugin that supports many different methods for making +the application get a handle on the GStreamer data in a pipeline. Unlike +most GStreamer elements, Appsink provides external API functions. + +appsink can be used by linking to the gstappsink.h header file to access the +methods or by using the appsink action signals and properties. + +The normal way of retrieving samples from appsink is by using the +`AppSinkExt::pull_sample` and `AppSinkExt::pull_preroll` methods. +These methods block until a sample becomes available in the sink or when the +sink is shut down or reaches EOS. There are also timed variants of these +methods, `AppSinkExt::try_pull_sample` and `AppSinkExt::try_pull_preroll`, +which accept a timeout parameter to limit the amount of time to wait. + +Appsink will internally use a queue to collect buffers from the streaming +thread. If the application is not pulling samples fast enough, this queue +will consume a lot of memory over time. The "max-buffers" property can be +used to limit the queue size. The "drop" property controls whether the +streaming thread blocks or if older buffers are dropped when the maximum +queue size is reached. Note that blocking the streaming thread can negatively +affect real-time performance and should be avoided. + +If a blocking behaviour is not desirable, setting the "emit-signals" property +to `true` will make appsink emit the "new-sample" and "new-preroll" signals +when a sample can be pulled without blocking. + +The "caps" property on appsink can be used to control the formats that +appsink can receive. This property can contain non-fixed caps, the format of +the pulled samples can be obtained by getting the sample caps. + +If one of the pull-preroll or pull-sample methods return `None`, the appsink +is stopped or in the EOS state. You can check for the EOS state with the +"eos" property or with the `AppSinkExt::is_eos` method. + +The eos signal can also be used to be informed when the EOS state is reached +to avoid polling. + +# Implements + +[`AppSinkExt`](trait.AppSinkExt.html), [`ObjectExt`](trait.ObjectExt.html) + +Trait containing all `AppSink` methods. + +# Implementors + +[`AppSink`](struct.AppSink.html) + +Check if `self` supports buffer lists. + +Feature: `v1_12` + + +# Returns + +`true` if `self` supports buffer lists. + +Get the configured caps on `self`. + +# Returns + +the `gst::Caps` accepted by the sink. `gst_caps_unref` after usage. + +Check if `self` will drop old buffers when the maximum amount of queued +buffers is reached. + +# Returns + +`true` if `self` is dropping old buffers when the queue is +filled. + +Check if appsink will emit the "new-preroll" and "new-sample" signals. + +# Returns + +`true` if `self` is emiting the "new-preroll" and "new-sample" +signals. + +Get the maximum amount of buffers that can be queued in `self`. + +# Returns + +The maximum amount of buffers that can be queued. + +Check if `self` will wait for all buffers to be consumed when an EOS is +received. + +# Returns + +`true` if `self` will wait for all buffers to be consumed when an +EOS is received. + +Check if `self` is EOS, which is when no more samples can be pulled because +an EOS event was received. + +This function also returns `true` when the appsink is not in the PAUSED or +PLAYING state. + +# Returns + +`true` if no more samples can be pulled and the appsink is EOS. + +Get the last preroll sample in `self`. This was the sample that caused the +appsink to preroll in the PAUSED state. This sample can be pulled many times +and remains available to the application even after EOS. + +This function is typically used when dealing with a pipeline in the PAUSED +state. Calling this function after doing a seek will give the sample right +after the seek position. + +Note that the preroll sample will also be returned as the first sample +when calling `AppSinkExt::pull_sample`. + +If an EOS event was received before any buffers, this function returns +`None`. Use gst_app_sink_is_eos () to check for the EOS condition. + +This function blocks until a preroll sample or EOS is received or the appsink +element is set to the READY/NULL state. + +# Returns + +a `gst::Sample` or NULL when the appsink is stopped or EOS. + Call `gst_sample_unref` after usage. + +This function blocks until a sample or EOS becomes available or the appsink +element is set to the READY/NULL state. + +This function will only return samples when the appsink is in the PLAYING +state. All rendered buffers will be put in a queue so that the application +can pull samples at its own rate. Note that when the application does not +pull samples fast enough, the queued buffers could consume a lot of memory, +especially when dealing with raw video frames. + +If an EOS event was received before any buffers, this function returns +`None`. Use gst_app_sink_is_eos () to check for the EOS condition. + +# Returns + +a `gst::Sample` or NULL when the appsink is stopped or EOS. + Call `gst_sample_unref` after usage. + +Instruct `self` to enable or disable buffer list support. + +For backwards-compatibility reasons applications need to opt in +to indicate that they will be able to handle buffer lists. + +Feature: `v1_12` + +## `enable_lists` +enable or disable buffer list support + +Set callbacks which will be executed for each new preroll, new sample and eos. +This is an alternative to using the signals, it has lower overhead and is thus +less expensive, but also less flexible. + +If callbacks are installed, no signals will be emitted for performance +reasons. +## `callbacks` +the callbacks +## `user_data` +a user_data argument for the callbacks +## `notify` +a destroy notify function + +Set the capabilities on the appsink element. This function takes +a copy of the caps structure. After calling this method, the sink will only +accept caps that match `caps`. If `caps` is non-fixed, or incomplete, +you must check the caps on the samples to get the actual used caps. +## `caps` +caps to set + +Instruct `self` to drop old buffers when the maximum amount of queued +buffers is reached. +## `drop` +the new state + +Make appsink emit the "new-preroll" and "new-sample" signals. This option is +by default disabled because signal emission is expensive and unneeded when +the application prefers to operate in pull mode. +## `emit` +the new state + +Set the maximum amount of buffers that can be queued in `self`. After this +amount of buffers are queued in appsink, any more buffers will block upstream +elements until a sample is pulled from `self`. +## `max` +the maximum number of buffers to queue + +Instruct `self` to wait for all buffers to be consumed when an EOS is received. +## `wait` +the new state + +Get the last preroll sample in `self`. This was the sample that caused the +appsink to preroll in the PAUSED state. This sample can be pulled many times +and remains available to the application even after EOS. + +This function is typically used when dealing with a pipeline in the PAUSED +state. Calling this function after doing a seek will give the sample right +after the seek position. + +Note that the preroll sample will also be returned as the first sample +when calling `AppSinkExt::pull_sample`. + +If an EOS event was received before any buffers or the timeout expires, +this function returns `None`. Use gst_app_sink_is_eos () to check for the EOS +condition. + +This function blocks until a preroll sample or EOS is received, the appsink +element is set to the READY/NULL state, or the timeout expires. + +Feature: `v1_10` + +## `timeout` +the maximum amount of time to wait for the preroll sample + +# Returns + +a `gst::Sample` or NULL when the appsink is stopped or EOS or the timeout expires. + Call `gst_sample_unref` after usage. + +This function blocks until a sample or EOS becomes available or the appsink +element is set to the READY/NULL state or the timeout expires. + +This function will only return samples when the appsink is in the PLAYING +state. All rendered buffers will be put in a queue so that the application +can pull samples at its own rate. Note that when the application does not +pull samples fast enough, the queued buffers could consume a lot of memory, +especially when dealing with raw video frames. + +If an EOS event was received before any buffers or the timeout expires, +this function returns `None`. Use gst_app_sink_is_eos () to check for the EOS +condition. + +Feature: `v1_10` + +## `timeout` +the maximum amount of time to wait for a sample + +# Returns + +a `gst::Sample` or NULL when the appsink is stopped or EOS or the timeout expires. +Call `gst_sample_unref` after usage. + +The appsrc element can be used by applications to insert data into a +GStreamer pipeline. Unlike most GStreamer elements, appsrc provides +external API functions. + +appsrc can be used by linking with the libgstapp library to access the +methods directly or by using the appsrc action signals. + +Before operating appsrc, the caps property must be set to fixed caps +describing the format of the data that will be pushed with appsrc. An +exception to this is when pushing buffers with unknown caps, in which case no +caps should be set. This is typically true of file-like sources that push raw +byte buffers. If you don't want to explicitly set the caps, you can use +gst_app_src_push_sample. This method gets the caps associated with the +sample and sets them on the appsrc replacing any previously set caps (if +different from sample's caps). + +The main way of handing data to the appsrc element is by calling the +`AppSrcExt::push_buffer` method or by emitting the push-buffer action signal. +This will put the buffer onto a queue from which appsrc will read from in its +streaming thread. It is important to note that data transport will not happen +from the thread that performed the push-buffer call. + +The "max-bytes" property controls how much data can be queued in appsrc +before appsrc considers the queue full. A filled internal queue will always +signal the "enough-data" signal, which signals the application that it should +stop pushing data into appsrc. The "block" property will cause appsrc to +block the push-buffer method until free data becomes available again. + +When the internal queue is running out of data, the "need-data" signal is +emitted, which signals the application that it should start pushing more data +into appsrc. + +In addition to the "need-data" and "enough-data" signals, appsrc can emit the +"seek-data" signal when the "stream-mode" property is set to "seekable" or +"random-access". The signal argument will contain the new desired position in +the stream expressed in the unit set with the "format" property. After +receiving the seek-data signal, the application should push-buffers from the +new position. + +These signals allow the application to operate the appsrc in two different +ways: + +The push mode, in which the application repeatedly calls the push-buffer/push-sample +method with a new buffer/sample. Optionally, the queue size in the appsrc +can be controlled with the enough-data and need-data signals by respectively +stopping/starting the push-buffer/push-sample calls. This is a typical +mode of operation for the stream-type "stream" and "seekable". Use this +mode when implementing various network protocols or hardware devices. + +The pull mode, in which the need-data signal triggers the next push-buffer call. +This mode is typically used in the "random-access" stream-type. Use this +mode for file access or other randomly accessable sources. In this mode, a +buffer of exactly the amount of bytes given by the need-data signal should be +pushed into appsrc. + +In all modes, the size property on appsrc should contain the total stream +size in bytes. Setting this property is mandatory in the random-access mode. +For the stream and seekable modes, setting this property is optional but +recommended. + +When the application has finished pushing data into appsrc, it should call +`AppSrcExt::end_of_stream` or emit the end-of-stream action signal. After +this call, no more buffers can be pushed into appsrc until a flushing seek +occurs or the state of the appsrc has gone through READY. + +# Implements + +[`AppSrcExt`](trait.AppSrcExt.html), [`ObjectExt`](trait.ObjectExt.html) + +Trait containing all `AppSrc` methods. + +# Implementors + +[`AppSrc`](struct.AppSrc.html) + +Indicates to the appsrc element that the last buffer queued in the +element is the last buffer of the stream. + +# Returns + +`gst::FlowReturn::Ok` when the EOS was successfuly queued. +`gst::FlowReturn::Flushing` when `self` is not PAUSED or PLAYING. + +Get the configured caps on `self`. + +# Returns + +the `gst::Caps` produced by the source. `gst_caps_unref` after usage. + +Get the number of currently queued bytes inside `self`. + +# Returns + +The number of currently queued bytes. + +Get the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is +not known. + +Feature: `v1_10` + + +# Returns + +the duration of the stream previously set with `AppSrcExt::set_duration`; + +Check if appsrc will emit the "new-preroll" and "new-buffer" signals. + +# Returns + +`true` if `self` is emitting the "new-preroll" and "new-buffer" +signals. + +Retrieve the min and max latencies in `min` and `max` respectively. +## `min` +the min latency +## `max` +the min latency + +Get the maximum amount of bytes that can be queued in `self`. + +# Returns + +The maximum amount of bytes that can be queued. + +Get the size of the stream in bytes. A value of -1 means that the size is +not known. + +# Returns + +the size of the stream previously set with `AppSrcExt::set_size`; + +Get the stream type. Control the stream type of `self` +with `AppSrcExt::set_stream_type`. + +# Returns + +the stream type. + +Adds a buffer to the queue of buffers that the appsrc element will +push to its source pad. This function takes ownership of the buffer. + +When the block property is TRUE, this function can block until free +space becomes available in the queue. +## `buffer` +a `gst::Buffer` to push + +# Returns + +`gst::FlowReturn::Ok` when the buffer was successfuly queued. +`gst::FlowReturn::Flushing` when `self` is not PAUSED or PLAYING. +`gst::FlowReturn::Eos` when EOS occured. + +Extract a buffer from the provided sample and adds it to the queue of +buffers that the appsrc element will push to its source pad. Any +previous caps that were set on appsrc will be replaced by the caps +associated with the sample if not equal. + +When the block property is TRUE, this function can block until free +space becomes available in the queue. +## `sample` +a `gst::Sample` from which buffer and caps may be +extracted + +# Returns + +`gst::FlowReturn::Ok` when the buffer was successfuly queued. +`gst::FlowReturn::Flushing` when `self` is not PAUSED or PLAYING. +`gst::FlowReturn::Eos` when EOS occured. + +Set callbacks which will be executed when data is needed, enough data has +been collected or when a seek should be performed. +This is an alternative to using the signals, it has lower overhead and is thus +less expensive, but also less flexible. + +If callbacks are installed, no signals will be emitted for performance +reasons. +## `callbacks` +the callbacks +## `user_data` +a user_data argument for the callbacks +## `notify` +a destroy notify function + +Set the capabilities on the appsrc element. This function takes +a copy of the caps structure. After calling this method, the source will +only produce caps that match `caps`. `caps` must be fixed and the caps on the +buffers must match the caps or left NULL. +## `caps` +caps to set + +Set the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is +not known. + +Feature: `v1_10` + +## `duration` +the duration to set + +Make appsrc emit the "new-preroll" and "new-buffer" signals. This option is +by default disabled because signal emission is expensive and unneeded when +the application prefers to operate in pull mode. +## `emit` +the new state + +Configure the `min` and `max` latency in `src`. If `min` is set to -1, the +default latency calculations for pseudo-live sources will be used. +## `min` +the min latency +## `max` +the min latency + +Set the maximum amount of bytes that can be queued in `self`. +After the maximum amount of bytes are queued, `self` will emit the +"enough-data" signal. +## `max` +the maximum number of bytes to queue + +Set the size of the stream in bytes. A value of -1 means that the size is +not known. +## `size` +the size to set + +Set the stream type on `self`. For seekable streams, the "seek" signal must +be connected to. + +A stream_type stream +## `type_` +the new state + +The stream type. + +No seeking is supported in the stream, such as a +live stream. + +The stream is seekable but seeking might not +be very fast, such as data from a webserver. + +The stream is seekable and seeking is fast, +such as in a local file. diff --git a/gir-files/GstApp-1.0.gir b/gir-files/GstApp-1.0.gir index 433d83685..8b08d528b 100644 --- a/gir-files/GstApp-1.0.gir +++ b/gir-files/GstApp-1.0.gir @@ -1198,11 +1198,17 @@ signals. a #GstAppSrc - + the min latency - + the min latency diff --git a/gstreamer-app/Cargo.toml b/gstreamer-app/Cargo.toml new file mode 100644 index 000000000..f3e86963a --- /dev/null +++ b/gstreamer-app/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "gstreamer-app" +version = "0.1.0" +authors = ["Sebastian Dröge "] +categories = ["api-bindings", "multimedia"] +description = "Rust bindings for GStreamer App library" +repository = "https://github.com/sdroege/gstreamer-rs" +license = "MIT" +documentation = "https://gstreamer.freedesktop.org" +keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"] +build = "build.rs" + +[dependencies] +bitflags = "0.9" +libc = "0.2" +glib-sys = { version = "0.3.4", git = "https://github.com/gtk-rs/sys" } +gobject-sys = { version = "0.3.4", git = "https://github.com/gtk-rs/sys" } +gstreamer-sys = { version = "0.1.1", git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] } +gstreamer-app-sys = { version = "0.1.1", git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] } +glib = { version = "0.1.3", git = "https://github.com/gtk-rs/glib" } +gstreamer = { version = "0.1.0", path = "../gstreamer" } + +[build-dependencies.rustdoc-stripper] +version = "0.1" +optional = true + +[features] +v1_10 = ["gstreamer-sys/v1_10"] +v1_12 = ["gstreamer-sys/v1_12", "v1_10"] +embed-lgpl-docs = ["rustdoc-stripper"] +purge-lgpl-docs = ["rustdoc-stripper"] +default-features = [] diff --git a/gstreamer-app/build.rs b/gstreamer-app/build.rs new file mode 100644 index 000000000..2f6587d82 --- /dev/null +++ b/gstreamer-app/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-app/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-app/src/auto/app_sink.rs b/gstreamer-app/src/auto/app_sink.rs index e92636c5e..7896be02b 100644 --- a/gstreamer-app/src/auto/app_sink.rs +++ b/gstreamer-app/src/auto/app_sink.rs @@ -2,10 +2,7 @@ // DO NOT EDIT use ffi; -use glib; use glib::Value; -use glib::object::Downcast; -use glib::object::IsA; use glib::signal::connect; use glib::translate::*; use glib_ffi; @@ -18,192 +15,128 @@ use std::mem::transmute; use std::ptr; glib_wrapper! { - pub struct AppSink(Object); + pub struct AppSink(Object): [ + gst::Element => gst_ffi::GstElement, + gst::Object => gst_ffi::GstObject, + ]; match fn { get_type => || ffi::gst_app_sink_get_type(), } } -unsafe impl Send for AppSink {} -unsafe impl Sync for AppSink {} - -pub trait AppSinkExt { +impl AppSink { #[cfg(feature = "v1_12")] - fn get_buffer_list_support(&self) -> bool; - - fn get_caps(&self) -> Option; - - fn get_drop(&self) -> bool; - - fn get_emit_signals(&self) -> bool; - - fn get_max_buffers(&self) -> u32; - - fn get_wait_on_eos(&self) -> bool; - - fn is_eos(&self) -> bool; - - fn pull_preroll(&self) -> Option; - - fn pull_sample(&self) -> Option; - - #[cfg(feature = "v1_12")] - fn set_buffer_list_support(&self, enable_lists: bool); - - //fn set_callbacks>>(&self, callbacks: /*Ignored*/&mut AppSinkCallbacks, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify); - - fn set_caps(&self, caps: &gst::Caps); - - fn set_drop(&self, drop: bool); - - fn set_emit_signals(&self, emit: bool); - - fn set_max_buffers(&self, max: u32); - - fn set_wait_on_eos(&self, wait: bool); - - #[cfg(feature = "v1_10")] - fn try_pull_preroll(&self, timeout: gst::ClockTime) -> Option; - - #[cfg(feature = "v1_10")] - fn try_pull_sample(&self, timeout: gst::ClockTime) -> Option; - - fn get_property_buffer_list(&self) -> bool; - - fn set_property_buffer_list(&self, buffer_list: bool); - - fn get_property_eos(&self) -> bool; - - fn connect_eos(&self, f: F) -> u64; - - fn connect_new_preroll gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64; - - fn connect_new_sample gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64; - - fn connect_pull_preroll gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64; - - fn connect_pull_sample gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64; - - #[cfg(feature = "v1_10")] - fn connect_try_pull_preroll gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64; - - #[cfg(feature = "v1_10")] - fn connect_try_pull_sample gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64; -} - -impl + IsA> AppSinkExt for O { - #[cfg(feature = "v1_12")] - fn get_buffer_list_support(&self) -> bool { + pub fn get_buffer_list_support(&self) -> bool { unsafe { from_glib(ffi::gst_app_sink_get_buffer_list_support(self.to_glib_none().0)) } } - fn get_caps(&self) -> Option { + pub fn get_caps(&self) -> Option { unsafe { from_glib_full(ffi::gst_app_sink_get_caps(self.to_glib_none().0)) } } - fn get_drop(&self) -> bool { + pub fn get_drop(&self) -> bool { unsafe { from_glib(ffi::gst_app_sink_get_drop(self.to_glib_none().0)) } } - fn get_emit_signals(&self) -> bool { + pub fn get_emit_signals(&self) -> bool { unsafe { from_glib(ffi::gst_app_sink_get_emit_signals(self.to_glib_none().0)) } } - fn get_max_buffers(&self) -> u32 { + pub fn get_max_buffers(&self) -> u32 { unsafe { ffi::gst_app_sink_get_max_buffers(self.to_glib_none().0) } } - fn get_wait_on_eos(&self) -> bool { + pub fn get_wait_on_eos(&self) -> bool { unsafe { from_glib(ffi::gst_app_sink_get_wait_on_eos(self.to_glib_none().0)) } } - fn is_eos(&self) -> bool { + pub fn is_eos(&self) -> bool { unsafe { from_glib(ffi::gst_app_sink_is_eos(self.to_glib_none().0)) } } - fn pull_preroll(&self) -> Option { + pub fn pull_preroll(&self) -> Option { unsafe { from_glib_full(ffi::gst_app_sink_pull_preroll(self.to_glib_none().0)) } } - fn pull_sample(&self) -> Option { + pub fn pull_sample(&self) -> Option { unsafe { from_glib_full(ffi::gst_app_sink_pull_sample(self.to_glib_none().0)) } } #[cfg(feature = "v1_12")] - fn set_buffer_list_support(&self, enable_lists: bool) { + pub fn set_buffer_list_support(&self, enable_lists: bool) { unsafe { ffi::gst_app_sink_set_buffer_list_support(self.to_glib_none().0, enable_lists.to_glib()); } } - //fn set_callbacks>>(&self, callbacks: /*Ignored*/&mut AppSinkCallbacks, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify) { + //pub fn set_callbacks>>(&self, callbacks: /*Ignored*/&mut AppSinkCallbacks, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify) { // unsafe { TODO: call ffi::gst_app_sink_set_callbacks() } //} - fn set_caps(&self, caps: &gst::Caps) { + pub fn set_caps(&self, caps: &gst::Caps) { unsafe { ffi::gst_app_sink_set_caps(self.to_glib_none().0, caps.to_glib_none().0); } } - fn set_drop(&self, drop: bool) { + pub fn set_drop(&self, drop: bool) { unsafe { ffi::gst_app_sink_set_drop(self.to_glib_none().0, drop.to_glib()); } } - fn set_emit_signals(&self, emit: bool) { + pub fn set_emit_signals(&self, emit: bool) { unsafe { ffi::gst_app_sink_set_emit_signals(self.to_glib_none().0, emit.to_glib()); } } - fn set_max_buffers(&self, max: u32) { + pub fn set_max_buffers(&self, max: u32) { unsafe { ffi::gst_app_sink_set_max_buffers(self.to_glib_none().0, max); } } - fn set_wait_on_eos(&self, wait: bool) { + pub fn set_wait_on_eos(&self, wait: bool) { unsafe { ffi::gst_app_sink_set_wait_on_eos(self.to_glib_none().0, wait.to_glib()); } } #[cfg(feature = "v1_10")] - fn try_pull_preroll(&self, timeout: gst::ClockTime) -> Option { + pub fn try_pull_preroll(&self, timeout: gst::ClockTime) -> Option { unsafe { from_glib_full(ffi::gst_app_sink_try_pull_preroll(self.to_glib_none().0, timeout)) } } #[cfg(feature = "v1_10")] - fn try_pull_sample(&self, timeout: gst::ClockTime) -> Option { + pub fn try_pull_sample(&self, timeout: gst::ClockTime) -> Option { unsafe { from_glib_full(ffi::gst_app_sink_try_pull_sample(self.to_glib_none().0, timeout)) } } - fn get_property_buffer_list(&self) -> bool { + pub fn get_property_buffer_list(&self) -> bool { let mut value = Value::from(&false); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "buffer-list".to_glib_none().0, value.to_glib_none_mut().0); @@ -211,13 +144,13 @@ impl + IsA> AppSinkExt for O { value.get().unwrap() } - fn set_property_buffer_list(&self, buffer_list: bool) { + pub fn set_property_buffer_list(&self, buffer_list: bool) { unsafe { gobject_ffi::g_object_set_property(self.to_glib_none().0, "buffer-list".to_glib_none().0, Value::from(&buffer_list).to_glib_none().0); } } - fn get_property_eos(&self) -> bool { + pub fn get_property_eos(&self) -> bool { let mut value = Value::from(&false); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "eos".to_glib_none().0, value.to_glib_none_mut().0); @@ -225,112 +158,108 @@ impl + IsA> AppSinkExt for O { value.get().unwrap() } - fn connect_eos(&self, f: F) -> u64 { + pub fn connect_eos(&self, f: F) -> u64 { unsafe { - let f: Box_> = Box_::new(Box_::new(f)); + let f: Box_> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "eos", - transmute(eos_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(eos_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_new_preroll gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_new_preroll gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "new-preroll", - transmute(new_preroll_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(new_preroll_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_new_sample gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_new_sample gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "new-sample", - transmute(new_sample_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(new_sample_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_pull_preroll gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_pull_preroll gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::Sample + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::Sample + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "pull-preroll", - transmute(pull_preroll_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(pull_preroll_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_pull_sample gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_pull_sample gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::Sample + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::Sample + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "pull-sample", - transmute(pull_sample_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(pull_sample_trampoline as usize), Box_::into_raw(f) as *mut _) } } #[cfg(feature = "v1_10")] - fn connect_try_pull_preroll gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_try_pull_preroll gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::Sample + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::Sample + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "try-pull-preroll", - transmute(try_pull_preroll_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(try_pull_preroll_trampoline as usize), Box_::into_raw(f) as *mut _) } } #[cfg(feature = "v1_10")] - fn connect_try_pull_sample gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_try_pull_sample gst::Sample + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::Sample + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::Sample + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "try-pull-sample", - transmute(try_pull_sample_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(try_pull_sample_trampoline as usize), Box_::into_raw(f) as *mut _) } } } -unsafe extern "C" fn eos_trampoline

(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -where P: IsA { +unsafe impl Send for AppSink {} +unsafe impl Sync for AppSink {} + +unsafe extern "C" fn eos_trampoline(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) { callback_guard!(); - let f: &Box_ = transmute(f); - f(&AppSink::from_glib_none(this).downcast_unchecked()) + let f: &Box_ = transmute(f); + f(&from_glib_none(this)) } -unsafe extern "C" fn new_preroll_trampoline

(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn -where P: IsA { +unsafe extern "C" fn new_preroll_trampoline(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn { callback_guard!(); - let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); - f(&AppSink::from_glib_none(this).downcast_unchecked()).to_glib() + let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this)).to_glib() } -unsafe extern "C" fn new_sample_trampoline

(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn -where P: IsA { +unsafe extern "C" fn new_sample_trampoline(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn { callback_guard!(); - let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); - f(&AppSink::from_glib_none(this).downcast_unchecked()).to_glib() + let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this)).to_glib() } -unsafe extern "C" fn pull_preroll_trampoline

(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -> *mut gst_ffi::GstSample -where P: IsA { +unsafe extern "C" fn pull_preroll_trampoline(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -> *mut gst_ffi::GstSample { callback_guard!(); - let f: &Box_ gst::Sample + Send + Sync + 'static> = transmute(f); - f(&AppSink::from_glib_none(this).downcast_unchecked()).to_glib_full() + let f: &Box_ gst::Sample + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this)).to_glib_full() } -unsafe extern "C" fn pull_sample_trampoline

(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -> *mut gst_ffi::GstSample -where P: IsA { +unsafe extern "C" fn pull_sample_trampoline(this: *mut ffi::GstAppSink, f: glib_ffi::gpointer) -> *mut gst_ffi::GstSample { callback_guard!(); - let f: &Box_ gst::Sample + Send + Sync + 'static> = transmute(f); - f(&AppSink::from_glib_none(this).downcast_unchecked()).to_glib_full() + let f: &Box_ gst::Sample + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this)).to_glib_full() } #[cfg(feature = "v1_10")] -unsafe extern "C" fn try_pull_preroll_trampoline

(this: *mut ffi::GstAppSink, timeout: u64, f: glib_ffi::gpointer) -> *mut gst_ffi::GstSample -where P: IsA { +unsafe extern "C" fn try_pull_preroll_trampoline(this: *mut ffi::GstAppSink, timeout: u64, f: glib_ffi::gpointer) -> *mut gst_ffi::GstSample { callback_guard!(); - let f: &Box_ gst::Sample + Send + Sync + 'static> = transmute(f); - f(&AppSink::from_glib_none(this).downcast_unchecked(), timeout).to_glib_full() + let f: &Box_ gst::Sample + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this), timeout).to_glib_full() } #[cfg(feature = "v1_10")] -unsafe extern "C" fn try_pull_sample_trampoline

(this: *mut ffi::GstAppSink, timeout: u64, f: glib_ffi::gpointer) -> *mut gst_ffi::GstSample -where P: IsA { +unsafe extern "C" fn try_pull_sample_trampoline(this: *mut ffi::GstAppSink, timeout: u64, f: glib_ffi::gpointer) -> *mut gst_ffi::GstSample { callback_guard!(); - let f: &Box_ gst::Sample + Send + Sync + 'static> = transmute(f); - f(&AppSink::from_glib_none(this).downcast_unchecked(), timeout).to_glib_full() + let f: &Box_ gst::Sample + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this), timeout).to_glib_full() } diff --git a/gstreamer-app/src/auto/app_src.rs b/gstreamer-app/src/auto/app_src.rs index 6019ab742..765148960 100644 --- a/gstreamer-app/src/auto/app_src.rs +++ b/gstreamer-app/src/auto/app_src.rs @@ -3,10 +3,7 @@ use AppStreamType; use ffi; -use glib; use glib::Value; -use glib::object::Downcast; -use glib::object::IsA; use glib::signal::connect; use glib::translate::*; use glib_ffi; @@ -20,216 +17,135 @@ use std::mem::transmute; use std::ptr; glib_wrapper! { - pub struct AppSrc(Object); + pub struct AppSrc(Object): [ + gst::Element => gst_ffi::GstElement, + gst::Object => gst_ffi::GstObject, + ]; match fn { get_type => || ffi::gst_app_src_get_type(), } } -unsafe impl Send for AppSrc {} -unsafe impl Sync for AppSrc {} - -pub trait AppSrcExt { - fn end_of_stream(&self) -> gst::FlowReturn; - - fn get_caps(&self) -> Option; - - fn get_current_level_bytes(&self) -> u64; - - #[cfg(feature = "v1_10")] - fn get_duration(&self) -> gst::ClockTime; - - fn get_emit_signals(&self) -> bool; - - fn get_latency(&self, min: u64, max: u64); - - fn get_max_bytes(&self) -> u64; - - fn get_size(&self) -> i64; - - fn get_stream_type(&self) -> AppStreamType; - - fn push_buffer(&self, buffer: &gst::Buffer) -> gst::FlowReturn; - - fn push_sample(&self, sample: &gst::Sample) -> gst::FlowReturn; - - //fn set_callbacks>>(&self, callbacks: /*Ignored*/&mut AppSrcCallbacks, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify); - - fn set_caps(&self, caps: &gst::Caps); - - #[cfg(feature = "v1_10")] - fn set_duration(&self, duration: gst::ClockTime); - - fn set_emit_signals(&self, emit: bool); - - fn set_latency(&self, min: u64, max: u64); - - fn set_max_bytes(&self, max: u64); - - fn set_size(&self, size: i64); - - fn set_stream_type(&self, type_: AppStreamType); - - fn get_property_block(&self) -> bool; - - fn set_property_block(&self, block: bool); - - fn get_property_current_level_bytes(&self) -> u64; - - fn get_property_duration(&self) -> u64; - - fn set_property_duration(&self, duration: u64); - - fn get_property_format(&self) -> gst::Format; - - fn set_property_format(&self, format: gst::Format); - - fn get_property_is_live(&self) -> bool; - - fn set_property_is_live(&self, is_live: bool); - - fn get_property_max_latency(&self) -> i64; - - fn set_property_max_latency(&self, max_latency: i64); - - fn get_property_min_latency(&self) -> i64; - - fn set_property_min_latency(&self, min_latency: i64); - - fn get_property_min_percent(&self) -> u32; - - fn set_property_min_percent(&self, min_percent: u32); - - fn connect_end_of_stream gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64; - - fn connect_enough_data(&self, f: F) -> u64; - - fn connect_need_data(&self, f: F) -> u64; - - fn connect_push_buffer gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64; - - fn connect_push_sample gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64; - - fn connect_seek_data bool + Send + Sync + 'static>(&self, f: F) -> u64; -} - -impl + IsA> AppSrcExt for O { - fn end_of_stream(&self) -> gst::FlowReturn { +impl AppSrc { + pub fn end_of_stream(&self) -> gst::FlowReturn { unsafe { from_glib(ffi::gst_app_src_end_of_stream(self.to_glib_none().0)) } } - fn get_caps(&self) -> Option { + pub fn get_caps(&self) -> Option { unsafe { from_glib_full(ffi::gst_app_src_get_caps(self.to_glib_none().0)) } } - fn get_current_level_bytes(&self) -> u64 { + pub fn get_current_level_bytes(&self) -> u64 { unsafe { ffi::gst_app_src_get_current_level_bytes(self.to_glib_none().0) } } #[cfg(feature = "v1_10")] - fn get_duration(&self) -> gst::ClockTime { + pub fn get_duration(&self) -> gst::ClockTime { unsafe { ffi::gst_app_src_get_duration(self.to_glib_none().0) } } - fn get_emit_signals(&self) -> bool { + pub fn get_emit_signals(&self) -> bool { unsafe { from_glib(ffi::gst_app_src_get_emit_signals(self.to_glib_none().0)) } } - fn get_latency(&self, min: u64, max: u64) { + pub fn get_latency(&self) -> (u64, u64) { unsafe { - ffi::gst_app_src_get_latency(self.to_glib_none().0, min, max); + let mut min = mem::uninitialized(); + let mut max = mem::uninitialized(); + ffi::gst_app_src_get_latency(self.to_glib_none().0, &mut min, &mut max); + (min, max) } } - fn get_max_bytes(&self) -> u64 { + pub fn get_max_bytes(&self) -> u64 { unsafe { ffi::gst_app_src_get_max_bytes(self.to_glib_none().0) } } - fn get_size(&self) -> i64 { + pub fn get_size(&self) -> i64 { unsafe { ffi::gst_app_src_get_size(self.to_glib_none().0) } } - fn get_stream_type(&self) -> AppStreamType { + pub fn get_stream_type(&self) -> AppStreamType { unsafe { from_glib(ffi::gst_app_src_get_stream_type(self.to_glib_none().0)) } } - fn push_buffer(&self, buffer: &gst::Buffer) -> gst::FlowReturn { + pub fn push_buffer(&self, buffer: &gst::Buffer) -> gst::FlowReturn { unsafe { from_glib(ffi::gst_app_src_push_buffer(self.to_glib_none().0, buffer.to_glib_full())) } } - fn push_sample(&self, sample: &gst::Sample) -> gst::FlowReturn { + pub fn push_sample(&self, sample: &gst::Sample) -> gst::FlowReturn { unsafe { from_glib(ffi::gst_app_src_push_sample(self.to_glib_none().0, sample.to_glib_none().0)) } } - //fn set_callbacks>>(&self, callbacks: /*Ignored*/&mut AppSrcCallbacks, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify) { + //pub fn set_callbacks>>(&self, callbacks: /*Ignored*/&mut AppSrcCallbacks, user_data: P, notify: /*Unknown conversion*//*Unimplemented*/DestroyNotify) { // unsafe { TODO: call ffi::gst_app_src_set_callbacks() } //} - fn set_caps(&self, caps: &gst::Caps) { + pub fn set_caps(&self, caps: &gst::Caps) { unsafe { ffi::gst_app_src_set_caps(self.to_glib_none().0, caps.to_glib_none().0); } } #[cfg(feature = "v1_10")] - fn set_duration(&self, duration: gst::ClockTime) { + pub fn set_duration(&self, duration: gst::ClockTime) { unsafe { ffi::gst_app_src_set_duration(self.to_glib_none().0, duration); } } - fn set_emit_signals(&self, emit: bool) { + pub fn set_emit_signals(&self, emit: bool) { unsafe { ffi::gst_app_src_set_emit_signals(self.to_glib_none().0, emit.to_glib()); } } - fn set_latency(&self, min: u64, max: u64) { + pub fn set_latency(&self, min: u64, max: u64) { unsafe { ffi::gst_app_src_set_latency(self.to_glib_none().0, min, max); } } - fn set_max_bytes(&self, max: u64) { + pub fn set_max_bytes(&self, max: u64) { unsafe { ffi::gst_app_src_set_max_bytes(self.to_glib_none().0, max); } } - fn set_size(&self, size: i64) { + pub fn set_size(&self, size: i64) { unsafe { ffi::gst_app_src_set_size(self.to_glib_none().0, size); } } - fn set_stream_type(&self, type_: AppStreamType) { + pub fn set_stream_type(&self, type_: AppStreamType) { unsafe { ffi::gst_app_src_set_stream_type(self.to_glib_none().0, type_.to_glib()); } } - fn get_property_block(&self) -> bool { + pub fn get_property_block(&self) -> bool { let mut value = Value::from(&false); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "block".to_glib_none().0, value.to_glib_none_mut().0); @@ -237,13 +153,13 @@ impl + IsA> AppSrcExt for O { value.get().unwrap() } - fn set_property_block(&self, block: bool) { + pub fn set_property_block(&self, block: bool) { unsafe { gobject_ffi::g_object_set_property(self.to_glib_none().0, "block".to_glib_none().0, Value::from(&block).to_glib_none().0); } } - fn get_property_current_level_bytes(&self) -> u64 { + pub fn get_property_current_level_bytes(&self) -> u64 { let mut value = Value::from(&0u64); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "current-level-bytes".to_glib_none().0, value.to_glib_none_mut().0); @@ -251,7 +167,7 @@ impl + IsA> AppSrcExt for O { value.get().unwrap() } - fn get_property_duration(&self) -> u64 { + pub fn get_property_duration(&self) -> u64 { let mut value = Value::from(&0u64); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "duration".to_glib_none().0, value.to_glib_none_mut().0); @@ -259,13 +175,13 @@ impl + IsA> AppSrcExt for O { value.get().unwrap() } - fn set_property_duration(&self, duration: u64) { + pub fn set_property_duration(&self, duration: u64) { unsafe { gobject_ffi::g_object_set_property(self.to_glib_none().0, "duration".to_glib_none().0, Value::from(&duration).to_glib_none().0); } } - fn get_property_format(&self) -> gst::Format { + pub fn get_property_format(&self) -> gst::Format { let mut value = Value::from(&0); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "format".to_glib_none().0, value.to_glib_none_mut().0); @@ -273,14 +189,14 @@ impl + IsA> AppSrcExt for O { } } - fn set_property_format(&self, format: gst::Format) { + pub fn set_property_format(&self, format: gst::Format) { let format = format.to_glib() as i32; unsafe { gobject_ffi::g_object_set_property(self.to_glib_none().0, "format".to_glib_none().0, Value::from(&format).to_glib_none().0); } } - fn get_property_is_live(&self) -> bool { + pub fn get_property_is_live(&self) -> bool { let mut value = Value::from(&false); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "is-live".to_glib_none().0, value.to_glib_none_mut().0); @@ -288,13 +204,13 @@ impl + IsA> AppSrcExt for O { value.get().unwrap() } - fn set_property_is_live(&self, is_live: bool) { + pub fn set_property_is_live(&self, is_live: bool) { unsafe { gobject_ffi::g_object_set_property(self.to_glib_none().0, "is-live".to_glib_none().0, Value::from(&is_live).to_glib_none().0); } } - fn get_property_max_latency(&self) -> i64 { + pub fn get_property_max_latency(&self) -> i64 { let mut value = Value::from(&0i64); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "max-latency".to_glib_none().0, value.to_glib_none_mut().0); @@ -302,13 +218,13 @@ impl + IsA> AppSrcExt for O { value.get().unwrap() } - fn set_property_max_latency(&self, max_latency: i64) { + pub fn set_property_max_latency(&self, max_latency: i64) { unsafe { gobject_ffi::g_object_set_property(self.to_glib_none().0, "max-latency".to_glib_none().0, Value::from(&max_latency).to_glib_none().0); } } - fn get_property_min_latency(&self) -> i64 { + pub fn get_property_min_latency(&self) -> i64 { let mut value = Value::from(&0i64); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "min-latency".to_glib_none().0, value.to_glib_none_mut().0); @@ -316,13 +232,13 @@ impl + IsA> AppSrcExt for O { value.get().unwrap() } - fn set_property_min_latency(&self, min_latency: i64) { + pub fn set_property_min_latency(&self, min_latency: i64) { unsafe { gobject_ffi::g_object_set_property(self.to_glib_none().0, "min-latency".to_glib_none().0, Value::from(&min_latency).to_glib_none().0); } } - fn get_property_min_percent(&self) -> u32 { + pub fn get_property_min_percent(&self) -> u32 { let mut value = Value::from(&0u32); unsafe { gobject_ffi::g_object_get_property(self.to_glib_none().0, "min-percent".to_glib_none().0, value.to_glib_none_mut().0); @@ -330,99 +246,96 @@ impl + IsA> AppSrcExt for O { value.get().unwrap() } - fn set_property_min_percent(&self, min_percent: u32) { + pub fn set_property_min_percent(&self, min_percent: u32) { unsafe { gobject_ffi::g_object_set_property(self.to_glib_none().0, "min-percent".to_glib_none().0, Value::from(&min_percent).to_glib_none().0); } } - fn connect_end_of_stream gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_end_of_stream gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "end-of-stream", - transmute(end_of_stream_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(end_of_stream_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_enough_data(&self, f: F) -> u64 { + pub fn connect_enough_data(&self, f: F) -> u64 { unsafe { - let f: Box_> = Box_::new(Box_::new(f)); + let f: Box_> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "enough-data", - transmute(enough_data_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(enough_data_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_need_data(&self, f: F) -> u64 { + pub fn connect_need_data(&self, f: F) -> u64 { unsafe { - let f: Box_> = Box_::new(Box_::new(f)); + let f: Box_> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "need-data", - transmute(need_data_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(need_data_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_push_buffer gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_push_buffer gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "push-buffer", - transmute(push_buffer_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(push_buffer_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_push_sample gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_push_sample gst::FlowReturn + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ gst::FlowReturn + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "push-sample", - transmute(push_sample_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(push_sample_trampoline as usize), Box_::into_raw(f) as *mut _) } } - fn connect_seek_data bool + Send + Sync + 'static>(&self, f: F) -> u64 { + pub fn connect_seek_data bool + Send + Sync + 'static>(&self, f: F) -> u64 { unsafe { - let f: Box_ bool + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + let f: Box_ bool + Send + Sync + 'static>> = Box_::new(Box_::new(f)); connect(self.to_glib_none().0, "seek-data", - transmute(seek_data_trampoline:: as usize), Box_::into_raw(f) as *mut _) + transmute(seek_data_trampoline as usize), Box_::into_raw(f) as *mut _) } } } -unsafe extern "C" fn end_of_stream_trampoline

(this: *mut ffi::GstAppSrc, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn -where P: IsA { +unsafe impl Send for AppSrc {} +unsafe impl Sync for AppSrc {} + +unsafe extern "C" fn end_of_stream_trampoline(this: *mut ffi::GstAppSrc, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn { callback_guard!(); - let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); - f(&AppSrc::from_glib_none(this).downcast_unchecked()).to_glib() + let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this)).to_glib() } -unsafe extern "C" fn enough_data_trampoline

(this: *mut ffi::GstAppSrc, f: glib_ffi::gpointer) -where P: IsA { +unsafe extern "C" fn enough_data_trampoline(this: *mut ffi::GstAppSrc, f: glib_ffi::gpointer) { callback_guard!(); - let f: &Box_ = transmute(f); - f(&AppSrc::from_glib_none(this).downcast_unchecked()) + let f: &Box_ = transmute(f); + f(&from_glib_none(this)) } -unsafe extern "C" fn need_data_trampoline

(this: *mut ffi::GstAppSrc, length: libc::c_uint, f: glib_ffi::gpointer) -where P: IsA { +unsafe extern "C" fn need_data_trampoline(this: *mut ffi::GstAppSrc, length: libc::c_uint, f: glib_ffi::gpointer) { callback_guard!(); - let f: &Box_ = transmute(f); - f(&AppSrc::from_glib_none(this).downcast_unchecked(), length) + let f: &Box_ = transmute(f); + f(&from_glib_none(this), length) } -unsafe extern "C" fn push_buffer_trampoline

(this: *mut ffi::GstAppSrc, buffer: *mut gst_ffi::GstBuffer, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn -where P: IsA { +unsafe extern "C" fn push_buffer_trampoline(this: *mut ffi::GstAppSrc, buffer: *mut gst_ffi::GstBuffer, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn { callback_guard!(); - let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); - f(&AppSrc::from_glib_none(this).downcast_unchecked(), &from_glib_none(buffer)).to_glib() + let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this), &from_glib_none(buffer)).to_glib() } -unsafe extern "C" fn push_sample_trampoline

(this: *mut ffi::GstAppSrc, sample: *mut gst_ffi::GstSample, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn -where P: IsA { +unsafe extern "C" fn push_sample_trampoline(this: *mut ffi::GstAppSrc, sample: *mut gst_ffi::GstSample, f: glib_ffi::gpointer) -> gst_ffi::GstFlowReturn { callback_guard!(); - let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); - f(&AppSrc::from_glib_none(this).downcast_unchecked(), &from_glib_none(sample)).to_glib() + let f: &Box_ gst::FlowReturn + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this), &from_glib_none(sample)).to_glib() } -unsafe extern "C" fn seek_data_trampoline

(this: *mut ffi::GstAppSrc, offset: u64, f: glib_ffi::gpointer) -> glib_ffi::gboolean -where P: IsA { +unsafe extern "C" fn seek_data_trampoline(this: *mut ffi::GstAppSrc, offset: u64, f: glib_ffi::gpointer) -> glib_ffi::gboolean { callback_guard!(); - let f: &Box_ bool + Send + Sync + 'static> = transmute(f); - f(&AppSrc::from_glib_none(this).downcast_unchecked(), offset).to_glib() + let f: &Box_ bool + Send + Sync + 'static> = transmute(f); + f(&from_glib_none(this), offset).to_glib() } diff --git a/gstreamer-app/src/auto/mod.rs b/gstreamer-app/src/auto/mod.rs index 0b382b0ef..7720eceae 100644 --- a/gstreamer-app/src/auto/mod.rs +++ b/gstreamer-app/src/auto/mod.rs @@ -3,17 +3,13 @@ mod app_sink; pub use self::app_sink::AppSink; -pub use self::app_sink::AppSinkExt; mod app_src; pub use self::app_src::AppSrc; -pub use self::app_src::AppSrcExt; mod enums; pub use self::enums::AppStreamType; #[doc(hidden)] pub mod traits { - pub use super::AppSinkExt; - pub use super::AppSrcExt; } diff --git a/gstreamer-app/src/lib.rs b/gstreamer-app/src/lib.rs new file mode 100644 index 000000000..3af0f16c2 --- /dev/null +++ b/gstreamer-app/src/lib.rs @@ -0,0 +1,36 @@ +// 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. + +extern crate libc; + +extern crate glib_sys as glib_ffi; +extern crate gobject_sys as gobject_ffi; +extern crate gstreamer_sys as gst_ffi; +extern crate gstreamer_app_sys as ffi; +extern crate gstreamer as gst; + +#[macro_use] +extern crate glib; + +macro_rules! callback_guard { + () => ( + let _guard = ::glib::CallbackGuard::new(); + ) +} + +macro_rules! skip_assert_initialized { + () => ( + ) +} + +pub use glib::{Cast, Continue, Error, IsA, StaticType, ToValue, Type, TypedValue, Value}; + +mod auto; +pub use auto::*; +pub use auto::traits::*; +