// Copyright (C) 2019 Guillaume Desmottes // // 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 gstreamer as gst; extern crate gstreamer_app as gst_app; use gst::prelude::*; use std::path::PathBuf; fn init() { use std::sync::Once; static INIT: Once = Once::new(); INIT.call_once(|| { gst::init().unwrap(); gstcdg::plugin_register_static().expect("cdgdec tests"); }); } #[test] fn test_cdgdec() { init(); let pipeline = gst::Pipeline::new(Some("cdgdec-test")); let input_path = { let mut r = PathBuf::new(); r.push(env!("CARGO_MANIFEST_DIR")); r.push("tests"); r.push("BrotherJohn"); r.set_extension("cdg"); r }; let filesrc = gst::ElementFactory::make("filesrc", None).unwrap(); filesrc .set_property("location", &input_path.to_str().unwrap()) .expect("failed to set 'location' property"); filesrc .set_property("num-buffers", &1) .expect("failed to set 'num-buffers' property"); let blocksize: u32 = 24; // One CDG instruction filesrc .set_property("blocksize", &blocksize) .expect("failed to set 'blocksize' property"); let parse = gst::ElementFactory::make("cdgparse", None).unwrap(); let dec = gst::ElementFactory::make("cdgdec", None).unwrap(); let sink = gst::ElementFactory::make("appsink", None).unwrap(); pipeline .add_many(&[&filesrc, &parse, &dec, &sink]) .expect("failed to add elements to the pipeline"); gst::Element::link_many(&[&filesrc, &parse, &dec, &sink]).expect("failed to link the elements"); let sink = sink.downcast::().unwrap(); sink.set_callbacks( gst_app::AppSinkCallbacks::new() // Add a handler to the "new-sample" signal. .new_sample(move |appsink| { // Pull the sample in question out of the appsink's buffer. let sample = appsink.pull_sample().map_err(|_| gst::FlowError::Eos)?; let buffer = sample.get_buffer().ok_or(gst::FlowError::Error)?; let map = buffer.map_readable().map_err(|_| gst::FlowError::Error)?; // First frame fully blue map.as_slice() .chunks_exact(4) .for_each(|p| assert_eq!(p, [0, 0, 136, 255])); Ok(gst::FlowSuccess::Ok) }) .build(), ); pipeline .set_state(gst::State::Playing) .expect("Unable to set the pipeline to the `Playing` state"); let bus = pipeline.get_bus().unwrap(); for msg in bus.iter_timed(gst::CLOCK_TIME_NONE) { use gst::MessageView; match msg.view() { MessageView::Error(err) => { eprintln!( "Error received from element {:?}: {}", err.get_src().map(|s| s.get_path_string()), err.get_error() ); eprintln!("Debugging information: {:?}", err.get_debug()); unreachable!(); } MessageView::Eos(..) => break, _ => (), } } pipeline .set_state(gst::State::Null) .expect("Unable to set the pipeline to the `Null` state"); }