video: Add Future variant of convert_sample_async()

Requires to be spawned on the GLib main context futures executor as the
function itself requires a GLib main context to call the callback.
This commit is contained in:
Sebastian Dröge 2020-02-09 18:53:36 +02:00
parent c4e7ed513b
commit 80c93dfddb
3 changed files with 33 additions and 0 deletions

View file

@ -24,6 +24,8 @@ glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { path = "../gstreamer" }
gstreamer-base = { path = "../gstreamer-base" }
once_cell = "1.0"
futures-channel = "0.3"
futures-util = "0.3"
[build-dependencies]
rustdoc-stripper = { version = "0.1", optional = true }

View file

@ -107,6 +107,35 @@ unsafe fn convert_sample_async_unsafe<F>(
);
}
pub fn convert_sample_future(
sample: &gst::Sample,
caps: &gst::Caps,
timeout: gst::ClockTime,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<gst::Sample, glib::Error>> + 'static>>
{
use futures_channel::oneshot;
use futures_util::future::lazy;
use futures_util::future::FutureExt;
let (sender, receiver) = oneshot::channel();
let sample = sample.clone();
let caps = caps.clone();
let future = lazy(move |_| {
assert!(
glib::MainContext::ref_thread_default().is_owner(),
"Spawning futures only allowed if the thread is owning the MainContext"
);
convert_sample_async(&sample, &caps, timeout, move |res| {
let _ = sender.send(res);
});
})
.then(|_| receiver.map(|res| res.expect("Sender dropped before callback was called")));
Box::pin(future)
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -17,6 +17,8 @@ extern crate glib_sys;
extern crate gobject_sys;
#[macro_use]
extern crate gstreamer as gst;
extern crate futures_channel;
extern crate futures_util;
extern crate gstreamer_base as gst_base;
extern crate gstreamer_base_sys as gst_base_sys;
extern crate gstreamer_sys as gst_sys;