From 7326377f5f99e7b248048c76cecc60d97f9b6854 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Fri, 4 Aug 2017 10:54:11 +0100 Subject: [PATCH] examples: app*: refactor error enum to a utils module The module also contains create_element, link_elements and set_state functions to help reduce boilerplate. --- examples/src/bin/appsink.rs | 61 ++++++-------------------------- examples/src/bin/appsrc.rs | 66 ++++++++--------------------------- examples/src/bin/utils/mod.rs | 58 ++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 102 deletions(-) create mode 100644 examples/src/bin/utils/mod.rs diff --git a/examples/src/bin/appsink.rs b/examples/src/bin/appsink.rs index 7753fa570..f3ad11ac0 100644 --- a/examples/src/bin/appsink.rs +++ b/examples/src/bin/appsink.rs @@ -5,56 +5,23 @@ use gst_app::*; extern crate glib; -use std::fmt; use std::u64; use std::i16; use std::i32; -#[derive(Debug)] -enum AppSinkExError { - InitFailed(glib::Error), - ElementNotFound(&'static str), - ElementLinkFailed(&'static str, &'static str), - SetStateError(&'static str), - ElementError(std::string::String, glib::Error, std::string::String), -} +pub mod utils; -impl fmt::Display for AppSinkExError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - AppSinkExError::InitFailed(ref e) => { - write!(f, "GStreamer initialization failed: {:?}", e) - } - AppSinkExError::ElementNotFound(ref e) => write!(f, "Element {} not found", e), - AppSinkExError::ElementLinkFailed(ref e1, ref e2) => { - write!(f, "Link failed between {} and {}", e1, e2) - } - AppSinkExError::SetStateError(ref state) => { - write!(f, "Pipeline failed to switch to state {}", state) - } - AppSinkExError::ElementError(ref element, ref err, ref debug) => { - write!(f, "Error from {}: {} ({:?})", element, err, debug) - } - } - } -} - -fn create_pipeline() -> Result { - gst::init().map_err(|e| AppSinkExError::InitFailed(e))?; +fn create_pipeline() -> Result { + gst::init().map_err(|e| utils::ExampleError::InitFailed(e))?; let pipeline = gst::Pipeline::new(None); - let src = gst::ElementFactory::make("audiotestsrc", None) - .ok_or(AppSinkExError::ElementNotFound("audiotestsrc"))?; - let sink = gst::ElementFactory::make("appsink", None) - .ok_or(AppSinkExError::ElementNotFound("appsink"))?; + let src = utils::create_element("audiotestsrc")?; + let sink = utils::create_element("appsink")?; pipeline .add_many(&[&src, &sink]) .expect("Unable to add elements in the pipeline"); - gst::Element::link(&src, &sink) - .map_err(|_| { - AppSinkExError::ElementLinkFailed("audiotestsrc", "appsink") - })?; + utils::link_elements(&src, &sink)?; let appsink = sink.clone() .dynamic_cast::() @@ -105,12 +72,10 @@ fn create_pipeline() -> Result { Ok(pipeline) } -fn main_loop() -> Result<(), AppSinkExError> { +fn main_loop() -> Result<(), utils::ExampleError> { let pipeline = create_pipeline()?; - if let gst::StateChangeReturn::Failure = pipeline.set_state(gst::State::Playing) { - return Err(AppSinkExError::SetStateError("playing")); - } + utils::set_state(&pipeline, gst::State::Playing)?; let bus = pipeline .get_bus() @@ -125,10 +90,8 @@ fn main_loop() -> Result<(), AppSinkExError> { match msg.view() { MessageView::Eos(..) => break, MessageView::Error(err) => { - if let gst::StateChangeReturn::Failure = pipeline.set_state(gst::State::Null) { - return Err(AppSinkExError::SetStateError("null")); - } - return Err(AppSinkExError::ElementError( + 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(), @@ -138,9 +101,7 @@ fn main_loop() -> Result<(), AppSinkExError> { } } - if let gst::StateChangeReturn::Failure = pipeline.set_state(gst::State::Null) { - return Err(AppSinkExError::SetStateError("null")); - } + utils::set_state(&pipeline, gst::State::Null)?; Ok(()) } diff --git a/examples/src/bin/appsrc.rs b/examples/src/bin/appsrc.rs index d8b1a6345..724954749 100644 --- a/examples/src/bin/appsrc.rs +++ b/examples/src/bin/appsrc.rs @@ -5,61 +5,27 @@ use gst_app::*; extern crate glib; -use std::fmt; use std::u64; use std::thread; +pub mod utils; + const WIDTH: usize = 320; const HEIGHT: usize = 240; -#[derive(Debug)] -enum AppSrcExError { - InitFailed(glib::Error), - ElementNotFound(&'static str), - ElementLinkFailed(&'static str, &'static str), - SetStateError(&'static str), - ElementError(std::string::String, glib::Error, std::string::String), -} - -impl fmt::Display for AppSrcExError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - AppSrcExError::InitFailed(ref e) => { - write!(f, "GStreamer initialization failed: {:?}", e) - } - AppSrcExError::ElementNotFound(ref e) => write!(f, "Element {} not found", e), - AppSrcExError::ElementLinkFailed(ref e1, ref e2) => { - write!(f, "Link failed between {} and {}", e1, e2) - } - AppSrcExError::SetStateError(ref state) => { - write!(f, "Pipeline failed to switch to state {}", state) - } - AppSrcExError::ElementError(ref element, ref err, ref debug) => { - write!(f, "Error from {}: {} ({:?})", element, err, debug) - } - } - } -} - -fn create_pipeline() -> Result<(Pipeline, AppSrc), AppSrcExError> { - gst::init().map_err(|e| AppSrcExError::InitFailed(e))?; +fn create_pipeline() -> Result<(Pipeline, AppSrc), utils::ExampleError> { + gst::init().map_err(|e| utils::ExampleError::InitFailed(e))?; let pipeline = gst::Pipeline::new(None); - let src = gst::ElementFactory::make("appsrc", None) - .ok_or(AppSrcExError::ElementNotFound("appsrc"))?; - - let videoconvert = gst::ElementFactory::make("videoconvert", None) - .ok_or(AppSrcExError::ElementNotFound("videoconvert"))?; - let sink = gst::ElementFactory::make("autovideosink", None) - .ok_or(AppSrcExError::ElementNotFound("autovideosink"))?; + let src = utils::create_element("appsrc")?; + let videoconvert = utils::create_element("videoconvert")?; + let sink = utils::create_element("autovideosink")?; pipeline .add_many(&[&src, &videoconvert, &sink]) .expect("Unable to add elements in the pipeline"); - gst::Element::link(&src, &videoconvert) - .map_err(|_| AppSrcExError::ElementLinkFailed("src", "videoconvert"))?; - gst::Element::link(&videoconvert, &sink) - .map_err(|_| AppSrcExError::ElementLinkFailed("videoconvert", "sink"))?; + utils::link_elements(&src, &videoconvert)?; + utils::link_elements(&videoconvert, &sink)?; let appsrc = src.clone() .dynamic_cast::() @@ -80,7 +46,7 @@ fn create_pipeline() -> Result<(Pipeline, AppSrc), AppSrcExError> { Ok((pipeline, appsrc)) } -fn main_loop() -> Result<(), AppSrcExError> { +fn main_loop() -> Result<(), utils::ExampleError> { let (pipeline, appsrc) = create_pipeline()?; thread::spawn(move || { @@ -111,9 +77,7 @@ fn main_loop() -> Result<(), AppSrcExError> { appsrc.end_of_stream(); }); - if let gst::StateChangeReturn::Failure = pipeline.set_state(gst::State::Playing) { - return Err(AppSrcExError::SetStateError("playing")); - } + utils::set_state(&pipeline, gst::State::Playing)?; let bus = pipeline .get_bus() @@ -128,8 +92,8 @@ fn main_loop() -> Result<(), AppSrcExError> { match msg.view() { MessageView::Eos(..) => break, MessageView::Error(err) => { - pipeline.set_state(gst::State::Null); - return Err(AppSrcExError::ElementError( + 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(), @@ -139,9 +103,7 @@ fn main_loop() -> Result<(), AppSrcExError> { } } - if let gst::StateChangeReturn::Failure = pipeline.set_state(gst::State::Null) { - return Err(AppSrcExError::SetStateError("null")); - } + utils::set_state(&pipeline, gst::State::Null)?; Ok(()) } diff --git a/examples/src/bin/utils/mod.rs b/examples/src/bin/utils/mod.rs new file mode 100644 index 000000000..6c1cb2007 --- /dev/null +++ b/examples/src/bin/utils/mod.rs @@ -0,0 +1,58 @@ + +extern crate gstreamer as gst; +use gst::*; + +extern crate glib; +use std::fmt; + +#[derive(Debug)] +pub enum ExampleError { + InitFailed(glib::Error), + ElementNotFound(&'static str), + ElementLinkFailed(::std::string::String, ::std::string::String), + SetStateError(::std::string::String), + ElementError(::std::string::String, glib::Error, ::std::string::String), +} + +impl fmt::Display for ExampleError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ExampleError::InitFailed(ref e) => { + write!(f, "GStreamer initialization failed: {:?}", e) + } + ExampleError::ElementNotFound(ref e) => write!(f, "Element {} not found", e), + ExampleError::ElementLinkFailed(ref e1, ref e2) => { + write!(f, "Link failed between {} and {}", e1, e2) + } + ExampleError::SetStateError(ref state) => { + write!(f, "Pipeline failed to switch to state {}", state) + } + ExampleError::ElementError(ref element, ref err, ref debug) => { + write!(f, "Error from {}: {} ({:?})", element, err, debug) + } + } + } +} + +pub fn create_element(name: &'static str) -> Result { + gst::ElementFactory::make(name, None).ok_or(ExampleError::ElementNotFound(name)) +} + +pub fn link_elements(e1: &gst::Element, e2: &gst::Element) -> Result<(), ExampleError> { + match gst::Element::link(e1, e2) { + Ok(o) => Ok(o), + Err(_) => Err(ExampleError::ElementLinkFailed( + e1.get_name(), + e2.get_name(), + )), + } +} + +pub fn set_state(e: &gst::Pipeline, state: gst::State) -> Result<(), ExampleError> { + if let gst::StateChangeReturn::Failure = e.set_state(state) { + return Err(ExampleError::SetStateError( + gst::Element::state_get_name(state).unwrap(), + )); + } + Ok(()) +}