forked from mirrors/gstreamer-rs
Change appsrc example to directly push data from the need-data callback
There's no need to start yet another thread just to push data in this case, we can simply use the callback and store the frame counter in the mutable environment of the closure.
This commit is contained in:
parent
a10532c379
commit
7734725da1
1 changed files with 45 additions and 40 deletions
|
@ -5,8 +5,6 @@ extern crate gstreamer_video as gst_video;
|
||||||
|
|
||||||
extern crate glib;
|
extern crate glib;
|
||||||
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
|
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
|
@ -35,7 +33,7 @@ struct ErrorMessage {
|
||||||
const WIDTH: usize = 320;
|
const WIDTH: usize = 320;
|
||||||
const HEIGHT: usize = 240;
|
const HEIGHT: usize = 240;
|
||||||
|
|
||||||
fn create_pipeline() -> Result<(gst::Pipeline, gst_app::AppSrc), Error> {
|
fn create_pipeline() -> Result<gst::Pipeline, Error> {
|
||||||
gst::init()?;
|
gst::init()?;
|
||||||
|
|
||||||
let pipeline = gst::Pipeline::new(None);
|
let pipeline = gst::Pipeline::new(None);
|
||||||
|
@ -59,15 +57,18 @@ fn create_pipeline() -> Result<(gst::Pipeline, gst_app::AppSrc), Error> {
|
||||||
|
|
||||||
appsrc.set_caps(&info.to_caps().unwrap());
|
appsrc.set_caps(&info.to_caps().unwrap());
|
||||||
appsrc.set_property_format(gst::Format::Time);
|
appsrc.set_property_format(gst::Format::Time);
|
||||||
appsrc.set_max_bytes(1);
|
|
||||||
appsrc.set_property_block(true);
|
|
||||||
|
|
||||||
Ok((pipeline, appsrc))
|
// Our frame counter, that is stored in the mutable environment
|
||||||
}
|
// of the closure of the need-data callback
|
||||||
|
let mut i = 0;
|
||||||
|
appsrc.set_callbacks(
|
||||||
|
gst_app::AppSrcCallbacks::new()
|
||||||
|
.need_data(move |appsrc, _| {
|
||||||
|
if i == 100 {
|
||||||
|
let _ = appsrc.end_of_stream();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fn main_loop(pipeline: gst::Pipeline, appsrc: gst_app::AppSrc) -> Result<(), Error> {
|
|
||||||
thread::spawn(move || {
|
|
||||||
for i in 0..100 {
|
|
||||||
println!("Producing frame {}", i);
|
println!("Producing frame {}", i);
|
||||||
|
|
||||||
let r = if i % 2 == 0 { 0 } else { 255 };
|
let r = if i % 2 == 0 { 0 } else { 255 };
|
||||||
|
@ -90,14 +91,18 @@ fn main_loop(pipeline: gst::Pipeline, appsrc: gst_app::AppSrc) -> Result<(), Err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if appsrc.push_buffer(buffer) != gst::FlowReturn::Ok {
|
i += 1;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = appsrc.end_of_stream();
|
// appsrc already handles the error here
|
||||||
});
|
let _ = appsrc.push_buffer(buffer);
|
||||||
|
})
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(pipeline)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main_loop(pipeline: gst::Pipeline) -> Result<(), Error> {
|
||||||
pipeline.set_state(gst::State::Playing).into_result()?;
|
pipeline.set_state(gst::State::Playing).into_result()?;
|
||||||
|
|
||||||
let bus = pipeline
|
let bus = pipeline
|
||||||
|
@ -130,7 +135,7 @@ fn main_loop(pipeline: gst::Pipeline, appsrc: gst_app::AppSrc) -> Result<(), Err
|
||||||
}
|
}
|
||||||
|
|
||||||
fn example_main() {
|
fn example_main() {
|
||||||
match create_pipeline().and_then(|(pipeline, appsrc)| main_loop(pipeline, appsrc)) {
|
match create_pipeline().and_then(main_loop) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => eprintln!("Error! {}", e),
|
Err(e) => eprintln!("Error! {}", e),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue