Code Monkey home page Code Monkey logo

gstreamer-rs's Introduction

gstreamer-rs crates.io pipeline status

GStreamer bindings for Rust. Documentation can be found here.

These bindings are providing a safe API that can be used to interface with GStreamer, e.g. for writing GStreamer-based applications and GStreamer plugins.

The bindings are mostly autogenerated with gir based on the GObject-Introspection API metadata provided by the GStreamer project.

Table of Contents

  1. Installation
    1. Linux/BSDs
    2. macOS
    3. Windows
  2. Getting Started
  3. License
  4. Contribution

To build the GStreamer bindings or anything depending on them, you need to have at least GStreamer 1.14 and gst-plugins-base 1.14 installed. In addition, some of the examples/tutorials require various GStreamer plugins to be available, which can be found in gst-plugins-base, gst-plugins-good, gst-plugins-bad, gst-plugins-ugly and/or gst-libav.

You need to install the above mentioned packages with your distributions package manager, or build them from source.

On Debian/Ubuntu they can be installed with

$ apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
      gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
      gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
      gstreamer1.0-libav libgstrtspserver-1.0-dev libges-1.0-dev

The minimum required version of the above libraries is >= 1.14. If you build the gstreamer-player sub-crate, or any of the examples that depend on gstreamer-player, you must ensure that in addition to the above packages, libgstreamer-plugins-bad1.0-dev is installed. See the Cargo.toml files for the full details,

$ apt-get install libgstreamer-plugins-bad1.0-dev

Package names on other distributions should be similar. Please submit a pull request with instructions for yours.

You can install GStreamer and the plugins via Homebrew or by installing the binaries provided by the GStreamer project.

We recommend using the official GStreamer binaries over Homebrew, especially as GStreamer in Homebrew is currently broken.

GStreamer Binaries

You need to download the two .pkg files from the GStreamer website and install them, e.g. gstreamer-1.0-1.20.4-universal.pkg and gstreamer-1.0-devel-1.20.4-universal.pkg.

After installation, you also need to set the PATH environment variable as follows

$ export PATH="/Library/Frameworks/GStreamer.framework/Versions/1.0/bin${PATH:+:$PATH}"

Also note that the pkg-config from GStreamer should be the first one in the PATH as other versions have all kinds of quirks that will cause problems.

Homebrew

Homebrew only installs various plugins if explicitly enabled, so some extra --with-* flags may be required.

$ brew install gstreamer gst-plugins-base gst-plugins-good \
      gst-plugins-bad gst-plugins-ugly gst-libav gst-rtsp-server \
      gst-editing-services --with-orc --with-libogg --with-opus \
      --with-pango --with-theora --with-libvorbis --with-libvpx \
      --enable-gtk3

Make sure the version of these libraries is >= 1.14.

You can install GStreamer and the plugins via MSYS2 with pacman or by installing the binaries provided by the GStreamer project.

We recommend using the official GStreamer binaries over MSYS2.

GStreamer Binaries

You need to download the two .msi files for your platform from the GStreamer website and install them, e.g. gstreamer-1.0-x86_64-1.20.4.msi and gstreamer-1.0-devel-x86_64-1.20.4.msi. Make sure to select the version that matches your Rust toolchain, i.e. MinGW or MSVC.

After installation set the ``PATH` environment variable as follows:

# For a UNIX-style shell:
$ export PATH="c:/gstreamer/1.0/msvc_x86_64/bin${PATH:+:$PATH}"

# For cmd.exe:
$ set PATH=C:\gstreamer\1.0\msvc_x86_64\bin;%PATH%

Make sure to update the path to where you have actually installed GStreamer and for the corresponding toolchain.

Also note that the pkg-config.exe from GStreamer should be the first one in the PATH as other versions have all kinds of quirks that will cause problems.

MSYS2 / pacman

$ pacman -S glib2-devel pkg-config \
      mingw-w64-x86_64-gstreamer mingw-w64-x86_64-gst-plugins-base \
      mingw-w64-x86_64-gst-plugins-good mingw-w64-x86_64-gst-plugins-bad \
      mingw-w64-x86_64-gst-plugins-ugly mingw-w64-x86_64-gst-libav \
      mingw-w64-x86_64-gst-rtsp-server

Make sure the version of these libraries is >= 1.14.

Note that the version of pkg-config included in MSYS2 is known to have problems compiling GStreamer, so you may need to install another version. One option would be pkg-config-lite.

The API reference can be found here, however it is only the Rust API reference and does not explain any of the concepts.

For getting started with GStreamer development, the best would be to follow the documentation on the GStreamer website, especially the Application Development Manual. While being C-centric, it explains all the fundamental concepts of GStreamer and the code examples should be relatively easily translatable to Rust. The API is basically the same, function/struct names are the same and everything is only more convenient (hopefully) and safer.

In addition there are tutorials on the GStreamer website. Many of them were ported to Rust already and the code can be found in the tutorials directory.

Some further examples for various aspects of GStreamer and how to use it from Rust can be found in the examples directory.

Various GStreamer plugins written in Rust can be found in the gst-plugins-rs repository.

gstreamer-rs and all crates contained in here are licensed under either of

at your option.

GStreamer itself is licensed under the Lesser General Public License version 2.1 or (at your option) any later version: https://www.gnu.org/licenses/lgpl-2.1.html

Any kinds of contributions are welcome as a pull request.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in gstreamer-rs by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

gstreamer-rs's People

Contributors

alatiera avatar bilelmoussaoui avatar ceyusa avatar cmeissl avatar fengalin avatar ferjm avatar filnet avatar ford-prefect avatar guillaumegomez avatar heftig avatar jplatte avatar lovebug356 avatar lucab avatar marijns95 avatar mathieuduponchelle avatar nagisa avatar ocrete avatar philn avatar sdroege avatar seadve avatar seungha-yang avatar sophie-h avatar thaytan avatar thewildtree avatar thiagoss avatar thiblahute avatar tony-jinwoo-ahn avatar tp-m avatar vivia avatar vivienne-w avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gstreamer-rs's Issues

Linking statically?

Hello,

Is there any way to produce completely static binaries with gstreamer-rs?

Thanks :)

Tutorials don't work on macOS due to not running a NSRunLoop on the main thread, as required for OpenGL on macOS

gstreamer-rs/tutorials$ cargo run --bin basic-tutorial-1

couldn't load TLS file database: Failed to open file '/Library/Frameworks/GStreamer.framework/Versions/1.0/etc/ssl/certs/ca-certificates.crt': No such file or directory

I've installed gstreamer-1.0-devel-1.12.3-x86_64.pkg, gstreamer-1.0-1.12.3-x86_64.pkg, and the dmg with a ton of installer packages (base-crypto-1.12.3-x86_64.pkg, base-system-1.0-1.12.3-x86_64.pkg, gstreamer-1.0-capture-1.12.3-x86_64.pkg, gstreamer-1.0-codecs-1.12.3-x86_64.pkg, gstreamer-1.0-codecs-gpl-1.12.3-x86_64.pkg, gstreamer-1.0-codecs-restricted-1.12.3-x86_64.pkg, gstreamer-1.0-core-1.12.3-x86_64.pkg, gstreamer-1.0-devtools-1.12.3-x86_64.pkg, gstreamer-1.0-dvd-1.12.3-x86_64.pkg, gstreamer-1.0-editing-1.12.3-x86_64.pkg, gstreamer-1.0-effects-1.12.3-x86_64.pkg, gstreamer-1.0-encoding-1.12.3-x86_64.pkg, gstreamer-1.0-libav-1.12.3-x86_64.pkg, gstreamer-1.0-net-1.12.3-x86_64.pkg, gstreamer-1.0-net-restricted-1.12.3-x86_64.pkg, gstreamer-1.0-playback-1.12.3-x86_64.pkg, gstreamer-1.0-system-1.12.3-x86_64.pkg, gstreamer-1.0-visualizers-1.12.3-x86_64.pkg, osx-framework-1.12.3-x86_64.pkg).

and yet, the directory "/Library/Frameworks/GStreamer.framework/Versions/1.0/etc/ssl/" is missing (there's only "fonts" in "etc").

Add GstMemory/GstAllocator/GstBufferPool/GstVideoBufferPool bindings

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMemory.html
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstAllocator.html
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBufferPool.html

GstMemory needs to be manually generated (because miniobject). See caps.rs, tags.rs, sample.rs. Support for it needs to be added to buffer.rs.

The others should be possible to mostly autogenerate.

Add bindings for libgstaudio

See https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gstreamer-audio.html

There are multiple steps here:

  • Add a Gir_Gst*.toml and autogenerate all relevant types, see https://github.com/gtk-rs/gir/
  • Make sure the autogenerated code is correct, add manual code as needed
  • Write manual bindings for anything that can't be automatically generated (macros, miniobjects, GstAudioInfo/Frame, ...)
  • Add src/lib.rs for re-exporting, Cargo.toml, etc

Depends on
#7

undefined reference to gst_stream_type_get_type

What I did:

  • Install Rust with rustup-init.exe and choose x86_64-pc-windows-gnu as default triple.
  • Install MSYS2
  • Inside the msys2-mingw64 shell run the command from here
  • Create a new Rust project with cargo new --bin test
  • Add gstreamer = "0.10.0" to my Cargo.toml dependencies
  • Create main.rs:
extern crate gstreamer as gst;

fn main() {
    gst::init().unwrap();
}

Now, because I got an error ld: cannot find -lgstreamer-1.0 (and the same for gobject-2.0, glib-2.0 and gobject-2.0) I tried setting environment variables:

set PKG_CONFIG_PATH=C:\dev\msys64\mingw64\lib\pkgconfig
set LIBRARY_PATH=C:\dev\msys64\mingw64\lib

After I set LIBRARY_PATH, the error changed to:

C:\dev-projects\rust-test\test\target\debug\deps\libgstreamer-70220f7014e9955f.rlib(gstreamer-70220f7014e9955f.gstreamer8.rust-cgu.o): In function gstreamer::auto::flags::{{impl}}::static_type': c:\dev\rust\cargo\registry\src\github.com-1ecc6299db9ec823\gstreamer-0.10.0\src\auto/flags.rs:807: undefined reference to gst_stream_type_get_type'

Compiling tutorials on windows

Hey there, I cloned repo and installed gstreamer but getting this error on compiling tutorials:

ld: cannot find -lgstaudio-1.0
ld: cannot find -lgstapp-1.0
ld: cannot find -lgstbase-1.0
ld: cannot find -lgstreamer-1.0
ld: cannot find -lgobject-2.0
ld: cannot find -lglib-2.0
ld: cannot find -lgobject-2.0

Also, i didnt't really understand pkf-config part from readme: should PKG_CONFIG_PATH point to pkg-config.exe OR it should it point to some c:/gstreamer path?

Bug in GStreamer, mark MessageRef::get_src() unsafe?

When running a playbin, It turns out that messages exist on the bus where the message src pointer is invalid. (already freed or something)

Checking if msg.get_src() == pipeline sometimes causes memory corruption that will crash the program at a later time.

This is of course not a problem with this excellent library, but possibly MessageRef::get_src() should be unsafe with a warning until this gets fixed in GStreamer?

This is the reason for the bug that i filed earlier:
#70

I managed to work around this limitation in the following way:

// let msg_from_pipeline = msg.get_src().unwrap() == pipeline; // DON'T DO THIS
let msg_from_pipeline = unsafe { // WORKAROUND
  use glib::translate::ToGlibPtr;
  use gstreamer_sys::{GstElement, GstPipeline};
  let pipeline_ptr: *const GstPipeline = pipeline.to_glib_none().0;
  let msg_src_ptr = (*msg.as_ptr()).src as *const GstElement;
  pipeline_ptr as *const GstElement == msg_src_ptr
};

With the workaround, all problems go away and it works flawlessly.

Tested on Fedora 27 with:
[karlri@localhost ~]$ gst-launch-1.0 --version
gst-launch-1.0 version 1.12.4
GStreamer 1.12.4
http://download.fedoraproject.org

Building on Windows x64 with MSVC not working

Hello,

I wanted to write a simple program that just reports the linked gstreamer version. It looks like this:

fn main() {
    let version = gstreamer::version_string();
    println!("Hello, world! You're using {}", version);
}

The build fails with:

error: failed to run custom build command for `glib-sys v0.5.0`
process didn't exit successfully: `C:\Users\waved\Desktop\devel\projects\gst-print-version\target\debug\build\glib-sys-04fcb8127bd3b7bb\build-script-build` (exit code: 1)
--- stderr
MSVC target detected. If you are using the MSVC ABI rust build, please use the GNU ABI build instead.

Now, this is not a gstreamer bug per se, but I'm curious why I can't build this with the recommended default toolchain for my platform.

Add bindings for libgstplayer

See https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/player.html

Main trickyness here is that it's still unstable API. We should only support the latest stable release here (1.12 at this time).

There are multiple steps here:

  • Add a Gir_Gst*.toml and autogenerate all relevant types, see https://github.com/gtk-rs/gir/
  • Make sure the autogenerated code is correct, add manual code as needed
  • Write manual bindings for anything that can't be automatically generated (macros, miniobjects, ...)
  • Add src/lib.rs for re-exporting, Cargo.toml, etc

Question: tee, appsink and offset

I tried implementing the tee as you suggested and I'm nearly done. I have two problems left that are probably related.

For easier reference, this is the pipeline (for an audio only media):

             --- queue (visualization) --- audioconvert --- appsink (-> callback to visualization)
src --- tee /
            \
             --- queue (playback) --- audioconvert --- audioresample --- autoaudiosink

In my visualization, I want to display 1 sec of samples ahead of current position and 1 sec behind (this might change depending on the zoom factor). See this screenshot as an illustration. I read the tutorials on multithreading, cutting the pipeline and streaming and ended up setting:

  • source element (uridecodebin): "buffer-duration" property to 3 sec (as nano).
  • visualization queue: "max-size-time" property to 3 sec (as nano). I believe the defaults for the other properties should be good as is ("max-size-bytes" being 10MB and "max-size-buffers" 200).
  • visualization queue: offset to -1 sec (as nano).
  • appsink: offset to -1 sec (as nano).

I checked the appsink example and implemented appsink.set_callbacks to get the samples. I first start my pipeline in the Paused state, so I defined both the new_preroll and new_sample closures.

Problem # 1

After the pipeline is set to Paused, I only get the first sample in the new_preroll closure. I also defined a pad probe on the queue sink which gives me the expected many buffers. So I guess the appsink doesn't pull the buffers during preroll even though they are available. I checked the properties for appsink, but the defaults seem to fit my needs.

What am I missing or doing wrong? I guess I would be better off implementing the visualization as a plugin, but it is supposed to be interactive and will be really tied up to the application.

Problem # 2

When I define the offset for the visualization queue and appsink to a value less than -1 sec (so further than 1 sec from 0), I no longer can get the state of the pipeline using let (_, current, _) = self.pipeline.get_state(10_000_000);. I tried larger values than 10 ms, but it didn't help.

Observation

Finally, not a show stopper but rather an observation. In the callbacks for pad probe or those from the appsink, the buffers' offset and offset_end are always equal and constant. According to this page, I was expecting to be able to rely on them to get the position of the buffer in the stream. I searched in gstreamer-rs's code, but found nothing suspicious there.

Tutorial 2 on macOS doesn't appear to do anything

cargo run --bin basic-tutorial-2
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `/www/gstreamer-rs/target/debug/basic-tutorial-2`

and it stays like that. I don't see any output, files, windows or any side effects of it running.

Tutorial 3 & 4 on macOS: g_param_spec_pool_lookup: assertion 'pool != NULL' failed

 cargo run --bin basic-tutorial-3

(process:74622): GLib-GObject-CRITICAL **: g_param_spec_pool_lookup: assertion 'pool != NULL' failed
thread 'main' panicked at 'Can't set uri property on uridecodebin: BoolError("Invalid property name")', src/libcore/result.rs:906:4

backtrace points to src/bin/basic-tutorial-3.rs:28:

    source
        .set_property("uri", &uri)
        .expect("Can't set uri property on uridecodebin");

g_signal_emit_by_name won't accept correct argument type

This fails with BoolError("Incompatible argument types")

let opus_caps = gst::Caps::from_str(&rtp_caps_opus).unwrap();
webrtc
    .emit("add-transceiver", &[&3i32, &opus_caps])
    .unwrap();

add-transceiver accepts direction and caps.

I've tried a few values for the direction:

gstreamer_webrtc_sys::GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY
&(gstreamer_webrtc_sys::GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY).to_value()
&(gstreamer_webrtc_sys::GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY
    as gstreamer_webrtc_sys::GstWebRTCRTPTransceiverDirection)
    .to_value(),
// etc....

Wondering if I'm missing a way to pass the type.

Add channel based helper for GstPlayer

This would be instead of signals and, like GstBus allow polling in some thread to get an enum of all possibilities.

Should account for cancellation or injection of custom app messages, maybe tokio based?

@philn might this also be useful for you? I wanted to do something like this also in the C API but it's inconvenient to implement such things in C :p

Tutorial 3 does not work on OSX

Tutorial 3 does not play any audio and breaks with this output on OSX:

❯ ./target/debug/basic-tutorial-3
Pipeline state changed from Null to Ready
Received new pad src_0 from test-pipeline
It has type video/x-raw which is not raw audio. Ignoring.
Error received from element Some("/GstPipeline:test-pipeline/GstURIDecodeBin:source/GstSoupHTTPSrc:source") Internal data stream error.
Debugging information: Some("gstbasesrc.c(2939): void gst_base_src_loop(GstPad *) (): /GstPipeline:test-pipeline/GstURIDecodeBin:source/GstSoupHTTPSrc:source:\nstreaming stopped, reason not-linked (-1)")

It works perfectly fine on Linux.

EXC_BAD_ACCESS AppSink destroying callback

Probably doing something very bad here. But getting errors upon killing pipeline.

EXC_BAD_ACCESS (code=1, address=0x1)

    appsink.set_callbacks(gst_app::AppSinkCallbacks::new(
        /* eos */
        |_| {},
        /* new_preroll */
        |_| gst::FlowReturn::Ok,
        /* new_samples */
        move |appsink| {

            // if this line is commented it wont crash
            let p = appsink.pull_sample();

Callstack:

core::ptr::drop_in_place<gstreamer_app::app_sink::AppSinkCallbacks> (rust-lang/rust/src/libcore/ptr.rs:59)
core::ptr::drop_in_place<alloc::boxed::Box<gstreamer_app::app_sink::AppSinkCallbacks>> (rust-lang/rust/src/libcore/ptr.rs:59)
core::ptr::drop_in_place<alloc::boxed::Box<alloc::boxed::Box<gstreamer_app::app_sink::AppSinkCallbacks>>> (rust-lang/rust/src/libcore/ptr.rs:59)
gstreamer_app::app_sink::destroy_callbacks (gstreamer-rs-8719441e7bb90fbc/2f7ee30/gstreamer-app/src/app_sink.rs:82)
gst_app_sink_dispose (@1017d6b6f..1017d6c37:24)
g_object_unref (@10194dacf..10194dc8d:64)
gst_bin_remove_func (@10184436c..101844cc5:425)
gst_bin_remove (@101840eb2..10184113a:88)
gst_bin_dispose (@101841d0e..101841df5:40)
g_object_unref (@10194dacf..10194dc8d:64)
glib::object::{{impl}}::unref (glib-928cf7b282977403/a51dc67/src/object.rs:182)
glib::shared::{{impl}}::drop<gobject_sys::GObject,glib::object::MemoryManager> (glib-928cf7b282977403/a51dc67/src/shared.rs:276)
core::ptr::drop_in_place<glib::shared::Shared<gobject_sys::GObject, glib::object::MemoryManager>> (rust-lang/rust/src/libcore/ptr.rs:59)
core::ptr::drop_in_place<glib::object::ObjectRef> (rust-lang/rust/src/libcore/ptr.rs:59)
core::ptr::drop_in_place<gstreamer::auto::pipeline::Pipeline> (rust-lang/rust/src/libcore/ptr.rs:59)
mumblebot::gst::sink_loop (mumble-bot/src/gst.rs:156)
mumblebot::gst::sink_main::{{closure}} (mumble-bot/src/gst.rs:164)
std::sys_common::backtrace::__rust_begin_short_backtrace<closure,()> (rust-lang/rust/src/libstd/sys_common/backtrace.rs:134)
std::thread::{{impl}}::spawn::{{closure}}::{{closure}}<closure,()> (rust-lang/rust/src/libstd/thread/mod.rs:406)

Context:

pub fn sink_main(vox_out_tx: futures::sync::mpsc::Sender<Vec<u8>>) -> impl Fn() -> () {
    let pipeline = sink_pipeline(vox_out_tx).unwrap();
    let p = pipeline.clone();

    thread::spawn(move || {
        println!("start thread sink_loop");
        sink_loop(pipeline);
        println!("stop thread sink_loop");
    });

    // kill switch
    move|| {
        let ev = gst::Event::new_eos().build();
        p.send_event(ev);
    }
}

Segfault on gstreamer_sdp::SDPMessage::parse_buffer

Example code:

let ret = gstreamer_sdp::SDPMessage::parse_buffer(b"t=0 0\r\n").unwrap();

Valgrind output:

==5178== Invalid read of size 4
==5178==    at 0x58E94D9: gst_sdp_message_emails_len (gstsdpmessage.c:897)
==5178==    by 0x58ED356: gst_sdp_message_as_text (gstsdpmessage.c:499)
==5178==    by 0x2D2920: gstreamer_sdp::sdp_message::SDPMessage::as_text (sdp_message.rs:134)
==5178==    by 0x19A9CA: <gst_rust::WsClient as ws::handler::Handler>::on_message (main.rs:239)
==5178==    by 0x146C75: <ws::connection::Connection<H>>::read_frames (connection.rs:658)
==5178==    by 0x150020: <ws::connection::Connection<H>>::read (connection.rs:602)
==5178==    by 0x16BECB: <ws::io::Handler<F>>::handle_event (io.rs:548)
==5178==    by 0x169A46: <ws::io::Handler<F>>::event_loop (io.rs:429)
==5178==    by 0x175502: <ws::io::Handler<F>>::run (io.rs:396)
==5178==    by 0x120042: <ws::WebSocket<F>>::run (lib.rs:331)
==5178==    by 0x11FC73: ws::connect (lib.rs:121)
==5178==    by 0x19ACA3: gst_rust::connect_to_websocket_server_async (main.rs:264)
==5178==  Address 0x8 is not stack'd, malloc'd or (recently) free'd

Digging into this a little bit more now, but hoping I might be missing something obvious.

I simplified the buffer value to hopefully provide a more concise failure example, but it also segfaults with a full SDP offer.

Proper error handling in examples

All the unwrap()s are ugly and we can easily do better.

Idea would be to have main be a function that just calls run or a couple of other functions returning a Result<_,_> and it's only job is to destructure that and print any possible errors.

For each example we would then define an error enum (that implements Display, Error and what else) like

enum MyLittleError {
    MissingElement(&str),
    LinkingFailed(&str, &str),
    Other(&str),
}

and return those from the functions, ideally making use of the ?-operator and various Option<_> / Result<_, _> combinators, e.g. gst::ElementFactory::make("appsrc", None).ok_or(MyLittleError::MissingElement("appsrc"))?;.

How to run examples on macOS?

I've tried installing gstreamer via Homebrew, but Homebrew only has a generic "gstreamer" package, and not specific "gstreamer-video-1.0", etc.

I've also tried installing everything from https://gstreamer.freedesktop.org/data/pkg/osx/1.12.3/gstreamer-1.0-1.12.3-x86_64-packages.dmg and https://gstreamer.freedesktop.org/data/pkg/osx/1.12.3/gstreamer-1.0-1.12.3-x86_64.pkg

but in both cases gstreamer-rs can't find packages it needs:

/gstreamer-rs/examples$ cargo run --bin playbin
Compiling gstreamer-audio-sys v0.3.0 (https://github.com/sdroege/gstreamer-sys#4b228f5f)
Compiling gstreamer-app-sys v0.3.0 (https://github.com/sdroege/gstreamer-sys#4b228f5f)
Compiling gstreamer-video-sys v0.3.0 (https://github.com/sdroege/gstreamer-sys#4b228f5f)
error: failed to run custom build command for gstreamer-app-sys v0.3.0 (https://github.com/sdroege/gstreamer-sys#4b228f5f)
process didn't exit successfully: /www/gstreamer-rs/target/debug/build/gstreamer-app-sys-5e59631e4f8c2493/build-script-build (exit code: 1)
--- stderr
"pkg-config" "--libs" "--cflags" "gstreamer-app-1.0 >= 1.8" did not exit successfully: exit code: 1

"pkg-config" "--libs" "--cflags" "gstreamer-audio-1.0 >= 1.8" did not exit successfully: exit code: 1

"pkg-config" "--libs" "--cflags" "gstreamer-video-1.0 >= 1.8" did not exit successfully: exit code: 1

Add bindings for libgstvideo

See https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gstreamer-video.html

There are multiple steps here:

  • Add a Gir_Gst*.toml and autogenerate all relevant types, see https://github.com/gtk-rs/gir/
  • Make sure the autogenerated code is correct, add manual code as needed
  • Write manual bindings for anything that can't be automatically generated (macros, miniobjects, GstVideoInfo/Frame, ...)
  • Add src/lib.rs for re-exporting, Cargo.toml, etc

Depends on
#7
#12

Add bindings for GstControlBinding and related API

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstControlBinding.html and https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstControlSource.html in core, and some GstObject API.

Plus a new crate for https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/gstreamer-control.html:

  • Add a Gir_Gst*.toml and autogenerate all relevant types, see https://github.com/gtk-rs/gir/
  • Make sure the autogenerated code is correct, add manual code as needed
  • Write manual bindings for anything that can't be automatically generated (macros, miniobjects, ...)
  • Add src/lib.rs for re-exporting, Cargo.toml, etc

Add bindings for gst_element_class*() and similar class functions

I'm following this tutorial in order to implement a tee in my audio pipeline.

To get the src pads from the tee, the tutorial proposes using:

  tee_src_pad_template = gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (tee), "src_%d");
  tee_audio_pad = gst_element_request_pad (tee, tee_src_pad_template, NULL, NULL);

ElementClass is not generated, but I found get_compatible_pad_template on Element. So I tried this in the connect_pad_added callback (my source is a uridecodebin):

    [...]
    let tee = gst::ElementFactory::make("tee", None).unwrap();
    pipeline.add(&tee).unwrap();

    let tee_sink = tee.get_static_pad("sink").unwrap();
    assert_eq!(src_pad.link(&tee_sink), gst::PadLinkReturn::Ok);

    let pad_tmpl = PadTemplate::new("src_%d",
        PadDirection::Src,
        PadPresence::Request,
        &Caps::new_any()
    );
    let tee_src_pad_tmpl = tee.get_compatible_pad_template(&pad_tmpl).unwrap();
    let tee_src_pad = tee.request_pad(&tee_src_pad_tmpl, None, None)
        .expect("Couldn't get src pad from gst tee");

Which fails on tee.request_pad() with the following message:

(.:8073): GStreamer-CRITICAL **: gst_element_request_pad: assertion 'templ->presence == GST_PAD_REQUEST' failed

I can continue investigating, but if you tell me that this isn't going to work, I'd implement the binding to ElementClass instead.

Tutorial 6 on macOS: 'G_IS_VALUE (value)' failed

cargo run --bin basic-tutorial-6

Pad Template for Audio test source:
SRC template: 'src'
Availability: Always
Capabilities:
audio/x-raw

(process:78002): GLib-GObject-CRITICAL **: g_strdup_value_contents: assertion 'G_IS_VALUE (value)' failed
thread 'main' panicked at 'assertion failed: !ptr.is_null()', /Users/porneL/.cargo/git/checkouts/glib-928cf7b282977403/4356d43/src/translate.rs:872:8

Backtrace points to src/bin/basic-tutorial-6.rs:20

        for (field, value) in structure.iter() {
            println!("{}  {}:{:?}", prefix, field, value);
        }

Memory corruption playbin no unsafe

A combination of bus.timed_pop(), msg.get_src(), and playbin.set_state() causes a GStreamer-CRITICAL error which makes no sense when looking at the code. The error is followed by lots of memory corruption (lots of errors in valgrind). No unsafe code is needed. The bug cannot be reliably triggered, but repeatedly changing the state does the trick. The shortest example I could come up with to make it occur is attached, and valgrind output obtained with:
valgrind ./target/debug/binary > valgrind-output.txt 2>&1

corruption-example.zip

Tested on latest stable Fedora and Debian, same result. Deleted Cargo.lock, used:
"gstreamer 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
Used:
stable-x86_64-unknown-linux-gnu (default)
rustc 1.23.0 (766bd11c8 2018-01-01)

Panic in gtksink example

$ RUST_BACKTRACE=1 ./gtksink.exe
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src\libcore\option.rs:335:20
stack backtrace:
   0: std::sys_common::backtrace::_print
   1: std::panicking::default_hook::{{closure}}
   2: std::panicking::default_hook
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic
   5: std::panicking::begin_panic_fmt
   6: rust_begin_unwind
   7: core::panicking::panic_fmt
   8: core::panicking::panic
   9: <core::option::Option<T>>::unwrap
             at C:\projects\rust\src\libcore/macros.rs:22
  10: gtksink::create_ui
             at src\bin/gtksink.rs:29
  11: core::ops::function::Fn::call
             at C:\projects\rust\src\libcore\ops/function.rs:48
  12: gio::auto::application::activate_trampoline
             at C:\Users\xx\.cargo\git\checkouts\gio-a4b825b310a073b9\4c69584\src\auto/application.rs:491
  13: unit_addrs_search
  14: unit_addrs_search
  15: unit_addrs_search
  16: unit_addrs_search
  17: unit_addrs_search
  18: unit_addrs_search
  19: <O as gio::auto::application::ApplicationExt>::run
             at C:\Users\xx\.cargo\git\checkouts\gio-a4b825b310a073b9\4c69584\src\auto/application.rs:297
  20: gtksink::main
             at src\bin/gtksink.rs:123
  21: _rust_maybe_catch_panic
  22: std::rt::lang_start
  23: main
  24: _tmainCRTStartup
  25: mainCRTStartup
  26: unit_addrs_search

Am I missing something obvious here?

nightly-x86_64-pc-windows-gnu is the target.

Add bindings for libgstpbutils

See https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gstreamer-base-utils.html

There are multiple steps here:

  • Add a Gir_Gst*.toml and autogenerate all relevant types, see https://github.com/gtk-rs/gir/
  • Make sure the autogenerated code is correct, add manual code as needed
  • Write manual bindings for anything that can't be automatically generated (macros, miniobjects, ...)
  • Add src/lib.rs for re-exporting, Cargo.toml, etc

Depends on
#7
#5
#4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.