Why sometime parse_launch pipeline will report StateChangeError if set_state afterward (in gstreamer-rs)

Hello all:) I’m using gstreamer-rs rust bindings and trying to run the pipeline which I can run successfully with gst-launh-1.0, and it always fails with error.

I cant be sure whether there is something I dont know about the usage for gstreamer parse_launch or there could be issue in gstreamer-rs?

rust code:

#[cfg(test)]
mod tests {
    use gst::prelude::*;

    #[test]
    fn gstreamer_push() {
        gst::init().unwrap();

        let pipeline = gst::parse_launch("flvmux name=mux ! rtmpsink location='rtmp://localhost/live/test' filesrc location='D:/Download/test.mkv' ! decodebin3 name=d d. ! queue ! videoconvert ! x264enc tune=zerolatency ! mux. d. ! queue ! audioconvert ! voaacenc ! mux.").unwrap();

        // pipeline.set_state(gst::State::Paused).expect("Unable to prepare pipeline for paused");
        pipeline.set_state(gst::State::Playing).expect("Unable to prepare pipeline for playing");

        let bus = pipeline.bus().unwrap();

        for msg in bus.iter_timed(gst::ClockTime::NONE) {
            use gst::MessageView;

            match msg.view() {
                MessageView::Eos(..) => break,
                MessageView::StateChanged(s) => {
                    dbg!(s.old(), s.current());
                },
                MessageView::Error(err) => {
                    dbg!(err.src().map(|s| s.path_string()), err.error(), err.debug());
                },
                _ => (),
            }
        }

        // Terminating player and close all pipepline sources by setting state to null.
        pipeline.set_state(gst::State::Null).unwrap();
    }
}

It alway fail with StateChangeError.

When I run a simple pipeline like let pipeline = gst::parse_launch(&format!("playbin uri={uri}")).unwrap();, it works fine though.

Expected Behavior

According to the gstreamer documentation, parse_launch should support gst-launch-1.0 commands and run successfully.

Observed Behavior

Unable to prepare pipeline for playing: StateChangeError
thread 'tests::gstreamer_push' panicked at stream\src\main.rs:27:49:
Unable to prepare pipeline for playing: StateChangeError
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library\std\src\panicking.rs:595
   1: core::panicking::panic_fmt
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library\core\src\panicking.rs:67
   2: core::result::unwrap_failed
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library\core\src\result.rs:1652
   3: enum2$<core::result::Result<gstreamer::enums::StateChangeSuccess,gstreamer::enums::StateChangeError> >::expect<gstreamer::enums::StateChangeSuccess,gstreamer::enums::StateChangeError>
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33\library\core\src\result.rs:1034
   4: stream::tests::gstreamer_push
             at .\src\main.rs:27
   5: stream::tests::gstreamer_push::closure$0
             at .\src\main.rs:21

Setup

  • Operating System: Windows 11
  • Device: Computer
  • gstreamer-rs Version: 0.21.1
  • GStreamer Version: 1.22.5
  • Command line: gst-launch-1.0 flvmux name=mux ! rtmpsink location='rtmp://localhost/live/test' filesrc location='D:/Download/test.mkv' ! decodebin3 name=d d. ! queue ! videoconvert ! x264enc tune=zerolatency ! mux. d. ! queue ! audioconvert ! voaacenc ! mux.

Have you tried without the single apostrophes - those are for the shell usually, I don’t know if parse_launch() will parse them.

Perhaps don’t check for the result of the state change, but instead look for error messages on the bus, which will also have more information.

1 Like

Can you get a debug log with GST_DEBUG=6 of both your code and the gst-launch-1.0 pipeline?

As both pipeline strings are the same they should theoretically also behave the same so there’s probably some difference in the environment that would be visible from the logs.

You are right, removing those single apostrophes makes the code compiles and runs succesfully. This is really tricky for me. Thanks a lot for your hint and suggestion!

Thanks for your attention. After being reminded of the single apostrophes used in parse_launch, I remove them and the code works good. A tricky problem.

1 Like

Double quotes is supported in parse_launch though. And using double quotes will support blanks in path.

True. I use " in my pipeline string.

location=\"rtmp://localhost/live/test\"