From c9027fb24471ace293e61cad6bb61aff1fc40ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 12 Nov 2017 10:15:37 +0100 Subject: [PATCH] Switch appsrc example to failure based error handling --- examples/src/bin/appsink.rs | 4 +-- examples/src/bin/appsrc.rs | 67 ++++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/examples/src/bin/appsink.rs b/examples/src/bin/appsink.rs index a8899bd9f..2c6ec7131 100644 --- a/examples/src/bin/appsink.rs +++ b/examples/src/bin/appsink.rs @@ -14,13 +14,11 @@ use std::i32; use std::error::Error as StdError; extern crate failure; +use failure::Error; #[macro_use] extern crate failure_derive; -#[allow(unused_imports)] -use failure::{Error, Fail}; - #[derive(Debug, Fail)] #[fail(display = "Missing element {}", _0)] struct MissingElement(&'static str); diff --git a/examples/src/bin/appsrc.rs b/examples/src/bin/appsrc.rs index 97c903041..f632ed8c3 100644 --- a/examples/src/bin/appsrc.rs +++ b/examples/src/bin/appsrc.rs @@ -3,26 +3,46 @@ use gst::prelude::*; extern crate gstreamer_app as gst_app; extern crate gstreamer_video as gst_video; +extern crate glib; + use std::thread; -pub mod utils; +use std::error::Error as StdError; + +extern crate failure; +use failure::Error; + +#[macro_use] +extern crate failure_derive; + +#[derive(Debug, Fail)] +#[fail(display = "Missing element {}", _0)] +struct MissingElement(&'static str); + +#[derive(Debug, Fail)] +#[fail(display = "Received error from {}: {} (debug: {:?})", src, error, debug)] +struct ErrorMessage { + src: String, + error: String, + debug: Option, + #[cause] cause: glib::Error, +} const WIDTH: usize = 320; const HEIGHT: usize = 240; -fn create_pipeline() -> Result<(gst::Pipeline, gst_app::AppSrc), utils::ExampleError> { - gst::init().map_err(utils::ExampleError::InitFailed)?; +fn create_pipeline() -> Result<(gst::Pipeline, gst_app::AppSrc), Error> { + gst::init()?; let pipeline = gst::Pipeline::new(None); - let src = utils::create_element("appsrc")?; - let videoconvert = utils::create_element("videoconvert")?; - let sink = utils::create_element("autovideosink")?; + let src = gst::ElementFactory::make("appsrc", None).ok_or(MissingElement("appsrc"))?; + let videoconvert = + gst::ElementFactory::make("videoconvert", None).ok_or(MissingElement("videoconvert"))?; + let sink = + gst::ElementFactory::make("autovideosink", None).ok_or(MissingElement("autovideosink"))?; - pipeline - .add_many(&[&src, &videoconvert, &sink]) - .expect("Unable to add elements in the pipeline"); - utils::link_elements(&src, &videoconvert)?; - utils::link_elements(&videoconvert, &sink)?; + pipeline.add_many(&[&src, &videoconvert, &sink])?; + gst::Element::link_many(&[&src, &videoconvert, &sink])?; let appsrc = src.clone() .dynamic_cast::() @@ -31,7 +51,7 @@ fn create_pipeline() -> Result<(gst::Pipeline, gst_app::AppSrc), utils::ExampleE let info = gst_video::VideoInfo::new(gst_video::VideoFormat::Bgrx, WIDTH as u32, HEIGHT as u32) .fps(gst::Fraction::new(2, 1)) .build() - .unwrap(); + .expect("Failed to create video info"); appsrc.set_caps(&info.to_caps().unwrap()); appsrc.set_property_format(gst::Format::Time); @@ -41,9 +61,7 @@ fn create_pipeline() -> Result<(gst::Pipeline, gst_app::AppSrc), utils::ExampleE Ok((pipeline, appsrc)) } -fn main_loop() -> Result<(), utils::ExampleError> { - let (pipeline, appsrc) = create_pipeline()?; - +fn main_loop(pipeline: gst::Pipeline, appsrc: gst_app::AppSrc) -> Result<(), Error> { thread::spawn(move || { for i in 0..100 { println!("Producing frame {}", i); @@ -76,7 +94,7 @@ fn main_loop() -> Result<(), utils::ExampleError> { let _ = appsrc.end_of_stream(); }); - utils::set_state(&pipeline, gst::State::Playing)?; + pipeline.set_state(gst::State::Playing).into_result()?; let bus = pipeline .get_bus() @@ -88,24 +106,25 @@ fn main_loop() -> Result<(), utils::ExampleError> { match msg.view() { MessageView::Eos(..) => break, MessageView::Error(err) => { - utils::set_state(&pipeline, gst::State::Null)?; - return Err(utils::ExampleError::ElementError( - msg.get_src().get_path_string(), - err.get_error(), - err.get_debug().unwrap(), - )); + pipeline.set_state(gst::State::Null).into_result()?; + Err(ErrorMessage { + src: msg.get_src().get_path_string(), + error: err.get_error().description().into(), + debug: err.get_debug(), + cause: err.get_error(), + })?; } _ => (), } } - utils::set_state(&pipeline, gst::State::Null)?; + pipeline.set_state(gst::State::Null).into_result()?; Ok(()) } fn main() { - match main_loop() { + match create_pipeline().and_then(|(pipeline, appsrc)| main_loop(pipeline, appsrc)) { Ok(r) => r, Err(e) => eprintln!("Error! {}", e), }