ts: use async fn in traits when possible

This is stable since Rust 1.75.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2278>
This commit is contained in:
François Laignel 2025-06-05 17:00:30 +02:00 committed by GStreamer Marge Bot
parent 9b677234dd
commit d0ae6b87b4
17 changed files with 1938 additions and 2306 deletions

View file

@ -6,9 +6,6 @@
//
// SPDX-License-Identifier: MPL-2.0
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
@ -96,29 +93,25 @@ struct AsyncPadSinkHandler(Arc<futures::lock::Mutex<PadSinkHandlerInner>>);
impl PadSinkHandler for AsyncPadSinkHandler {
type ElementImpl = AsyncMutexSink;
fn sink_chain(
async fn sink_chain(
self,
_pad: gst::Pad,
elem: super::AsyncMutexSink,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
if self.0.lock().await.handle_buffer(&elem, buffer).is_err() {
return Err(gst::FlowError::Flushing);
}
Ok(gst::FlowSuccess::Ok)
}
.boxed()
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
_pad: gst::Pad,
elem: super::AsyncMutexSink,
event: gst::Event,
) -> BoxFuture<'static, bool> {
async move {
) -> bool {
match event.view() {
EventView::Eos(_) => {
{
@ -131,8 +124,8 @@ impl PadSinkHandler for AsyncPadSinkHandler {
// it takes ages for the pipeline to process all of them.
// Let's just post an error message and let main shuts down
// after all streams have posted this message.
let _ = elem
.post_message(gst::message::Error::new(gst::LibraryError::Shutdown, "EOS"));
let _ =
elem.post_message(gst::message::Error::new(gst::LibraryError::Shutdown, "EOS"));
}
EventView::FlushStop(_) => {
self.0.lock().await.is_flushing = false;
@ -150,8 +143,6 @@ impl PadSinkHandler for AsyncPadSinkHandler {
true
}
.boxed()
}
fn sink_event(self, _pad: &gst::Pad, _imp: &AsyncMutexSink, event: gst::Event) -> bool {
if let EventView::FlushStart(..) = event.view() {

View file

@ -6,9 +6,6 @@
//
// SPDX-License-Identifier: MPL-2.0
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
@ -95,29 +92,25 @@ struct SyncPadSinkHandler(Arc<Mutex<PadSinkHandlerInner>>);
impl PadSinkHandler for SyncPadSinkHandler {
type ElementImpl = DirectSink;
fn sink_chain(
async fn sink_chain(
self,
_pad: gst::Pad,
elem: super::DirectSink,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
if self.0.lock().unwrap().handle_buffer(&elem, buffer).is_err() {
return Err(gst::FlowError::Flushing);
}
Ok(gst::FlowSuccess::Ok)
}
.boxed()
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
_pad: gst::Pad,
elem: super::DirectSink,
event: gst::Event,
) -> BoxFuture<'static, bool> {
async move {
) -> bool {
match event.view() {
EventView::Eos(_) => {
{
@ -130,8 +123,8 @@ impl PadSinkHandler for SyncPadSinkHandler {
// it takes ages for the pipeline to process all of them.
// Let's just post an error message and let main shuts down
// after all streams have posted this message.
let _ = elem
.post_message(gst::message::Error::new(gst::LibraryError::Shutdown, "EOS"));
let _ =
elem.post_message(gst::message::Error::new(gst::LibraryError::Shutdown, "EOS"));
}
EventView::FlushStop(_) => {
self.0.lock().unwrap().is_flushing = false;
@ -149,8 +142,6 @@ impl PadSinkHandler for SyncPadSinkHandler {
true
}
.boxed()
}
fn sink_event(self, _pad: &gst::Pad, _imp: &DirectSink, event: gst::Event) -> bool {
if let EventView::FlushStart(..) = event.view() {

View file

@ -6,9 +6,6 @@
//
// SPDX-License-Identifier: MPL-2.0
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::error_msg;
use gst::glib;
use gst::prelude::*;
@ -37,31 +34,27 @@ struct TaskPadSinkHandler;
impl PadSinkHandler for TaskPadSinkHandler {
type ElementImpl = TaskSink;
fn sink_chain(
async fn sink_chain(
self,
_pad: gst::Pad,
elem: super::TaskSink,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
) -> Result<gst::FlowSuccess, gst::FlowError> {
let sender = elem.imp().clone_item_sender();
async move {
if sender.send_async(StreamItem::Buffer(buffer)).await.is_err() {
return Err(gst::FlowError::Flushing);
}
Ok(gst::FlowSuccess::Ok)
}
.boxed()
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
_pad: gst::Pad,
elem: super::TaskSink,
event: gst::Event,
) -> BoxFuture<'static, bool> {
) -> bool {
let sender = elem.imp().clone_item_sender();
async move {
match event.view() {
EventView::Segment(_) => {
let _ = sender.send_async(StreamItem::Event(event)).await;
@ -74,8 +67,8 @@ impl PadSinkHandler for TaskPadSinkHandler {
// it takes ages for the pipeline to process all of them.
// Let's just post an error message and let main shuts down
// after all streams have posted this message.
let _ = elem
.post_message(gst::message::Error::new(gst::LibraryError::Shutdown, "EOS"));
let _ =
elem.post_message(gst::message::Error::new(gst::LibraryError::Shutdown, "EOS"));
}
EventView::FlushStop(_) => {
let imp = elem.imp();
@ -89,8 +82,6 @@ impl PadSinkHandler for TaskPadSinkHandler {
true
}
.boxed()
}
fn sink_event(self, _pad: &gst::Pad, imp: &TaskSink, event: gst::Event) -> bool {
if let EventView::FlushStart(..) = event.view() {
@ -136,13 +127,12 @@ impl TaskSinkTask {
impl TaskImpl for TaskSinkTask {
type Item = StreamItem;
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Preparing Task");
future::ok(()).boxed()
Ok(())
}
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Starting Task");
self.last_ts = None;
if let Some(stats) = self.stats.as_mut() {
@ -151,27 +141,18 @@ impl TaskImpl for TaskSinkTask {
Ok(())
}
.boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Stopping Task");
self.flush();
Ok(())
}
.boxed()
async fn try_next(&mut self) -> Result<StreamItem, gst::FlowError> {
Ok(self.item_receiver.recv_async().await.unwrap())
}
fn try_next(&mut self) -> BoxFuture<'_, Result<StreamItem, gst::FlowError>> {
self.item_receiver
.recv_async()
.map(|opt_item| Ok(opt_item.unwrap()))
.boxed()
}
fn handle_item(&mut self, item: StreamItem) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, item: StreamItem) -> Result<(), gst::FlowError> {
debug_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Received {item:?}");
match item {
@ -221,8 +202,6 @@ impl TaskImpl for TaskSinkTask {
Ok(())
}
.boxed()
}
}
#[derive(Debug)]

View file

@ -6,7 +6,6 @@
//
// SPDX-License-Identifier: MPL-2.0
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
@ -98,7 +97,7 @@ impl SrcTask {
impl TaskImpl for SrcTask {
type Item = ();
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
let imp = self.elem.imp();
let settings = imp.settings.lock().unwrap();
self.is_main_elem = settings.is_main_elem;
@ -108,11 +107,10 @@ impl TaskImpl for SrcTask {
self.push_period = settings.push_period;
self.num_buffers = settings.num_buffers;
future::ok(()).boxed()
Ok(())
}
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Starting Task");
if self.need_initial_events {
@ -125,8 +123,7 @@ impl TaskImpl for SrcTask {
"Pushing initial events"
);
let stream_id =
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
let stream_id = format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
let stream_start_evt = gst::event::StreamStart::builder(&stream_id)
.group_id(gst::GroupId::next())
.build();
@ -158,31 +155,25 @@ impl TaskImpl for SrcTask {
Ok(())
}
.boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Stopping Task");
self.buffer_pool.set_active(false).unwrap();
self.timer = None;
self.need_initial_events = true;
future::ok(()).boxed()
Ok(())
}
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Awaiting timer");
self.timer.as_mut().unwrap().next().await;
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Timer ticked");
Ok(())
}
.boxed()
}
fn handle_item(&mut self, _: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, _: ()) -> Result<(), gst::FlowError> {
let buffer = self
.buffer_pool
.acquire_buffer(None)
@ -215,11 +206,8 @@ impl TaskImpl for SrcTask {
Ok(())
}
.boxed()
}
fn handle_loop_error(&mut self, err: gst::FlowError) -> BoxFuture<'_, task::Trigger> {
async move {
async fn handle_loop_error(&mut self, err: gst::FlowError) -> task::Trigger {
match err {
gst::FlowError::Eos => {
debug_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Pushing EOS");
@ -249,8 +237,6 @@ impl TaskImpl for SrcTask {
}
}
}
.boxed()
}
}
#[derive(Debug)]

View file

@ -19,7 +19,6 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::channel::mpsc;
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
@ -226,18 +225,14 @@ impl AppSrcTask {
impl TaskImpl for AppSrcTask {
type Item = StreamItem;
fn try_next(&mut self) -> BoxFuture<'_, Result<StreamItem, gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<StreamItem, gst::FlowError> {
self.receiver
.next()
.await
.ok_or_else(|| panic!("Internal channel sender dropped while Task is Started"))
}
.boxed()
}
fn handle_item(&mut self, item: StreamItem) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, item: StreamItem) -> Result<(), gst::FlowError> {
let res = self.push_item(item).await;
match res {
Ok(_) => {
@ -264,11 +259,8 @@ impl TaskImpl for AppSrcTask {
res.map(drop)
}
.boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Stopping task");
self.flush();
@ -278,11 +270,8 @@ impl TaskImpl for AppSrcTask {
gst::log!(CAT, obj = self.element, "Task stopped");
Ok(())
}
.boxed()
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Starting task flush");
self.flush();
@ -291,8 +280,6 @@ impl TaskImpl for AppSrcTask {
gst::log!(CAT, obj = self.element, "Task flush started");
Ok(())
}
.boxed()
}
}
#[derive(Debug)]

View file

@ -6,9 +6,6 @@
//
// SPDX-License-Identifier: MPL-2.0
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
@ -240,7 +237,7 @@ impl AudioTestSrcTask {
impl TaskImpl for AudioTestSrcTask {
type Item = gst::Buffer;
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.elem, "Preparing Task");
let imp = self.elem.imp();
@ -255,18 +252,16 @@ impl TaskImpl for AudioTestSrcTask {
self.is_main_elem = settings.is_main_elem;
}
future::ok(()).boxed()
Ok(())
}
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.elem, "Starting Task");
if self.need_initial_events {
gst::debug!(CAT, obj = self.elem, "Pushing initial events");
let stream_id =
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
let stream_id = format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
let stream_start_evt = gst::event::StreamStart::builder(&stream_id)
.group_id(gst::GroupId::next())
.build();
@ -307,32 +302,30 @@ impl TaskImpl for AudioTestSrcTask {
Ok(())
}
.boxed()
}
fn pause(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async fn pause(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.elem, "Pausing Task");
self.buffer_pool.set_active(false).unwrap();
future::ok(()).boxed()
Ok(())
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.elem, "Stopping Task");
self.need_initial_events = true;
self.accumulator = 0.0;
self.last_buffer_end = None;
future::ok(()).boxed()
Ok(())
}
fn try_next(&mut self) -> BoxFuture<'_, Result<gst::Buffer, gst::FlowError>> {
async fn try_next(&mut self) -> Result<gst::Buffer, gst::FlowError> {
let mut buffer = match self.buffer_pool.acquire_buffer(None) {
Ok(buffer) => buffer,
Err(err) => {
gst::error!(CAT, obj = self.elem, "Failed to acquire buffer {}", err);
return future::err(err).boxed();
return Err(err);
}
};
@ -375,7 +368,6 @@ impl TaskImpl for AudioTestSrcTask {
self.last_buffer_end = start.opt_add(self.buffer_duration);
async move {
if self.is_live {
if let Some(delay) = self
.last_buffer_end
@ -392,11 +384,8 @@ impl TaskImpl for AudioTestSrcTask {
Ok(buffer)
}
.boxed()
}
fn handle_item(&mut self, buffer: gst::Buffer) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, buffer: gst::Buffer) -> Result<(), gst::FlowError> {
let imp = self.elem.imp();
gst::debug!(CAT, imp = imp, "Pushing {buffer:?}");
@ -409,8 +398,7 @@ impl TaskImpl for AudioTestSrcTask {
if self.is_main_elem {
if let Some(parked_duration_init) = self.parked_duration_init {
if self.buffer_count % LOG_BUFFER_INTERVAL == 0 {
let parked_duration =
runtime::Context::current().unwrap().parked_duration()
let parked_duration = runtime::Context::current().unwrap().parked_duration()
- parked_duration_init;
gst::info!(
@ -435,11 +423,8 @@ impl TaskImpl for AudioTestSrcTask {
Ok(())
}
.boxed()
}
fn handle_loop_error(&mut self, err: gst::FlowError) -> BoxFuture<'_, task::Trigger> {
async move {
async fn handle_loop_error(&mut self, err: gst::FlowError) -> task::Trigger {
match err {
gst::FlowError::Flushing => {
gst::debug!(CAT, obj = self.elem, "Flushing");
@ -469,8 +454,6 @@ impl TaskImpl for AudioTestSrcTask {
}
}
}
.boxed()
}
}
#[derive(Debug)]

View file

@ -17,7 +17,6 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::future::BoxFuture;
use futures::future::{abortable, AbortHandle};
use futures::prelude::*;
@ -156,22 +155,21 @@ impl InputSelectorPadSinkHandler {
impl PadSinkHandler for InputSelectorPadSinkHandler {
type ElementImpl = InputSelector;
fn sink_chain(
async fn sink_chain(
self,
pad: gst::Pad,
elem: super::InputSelector,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move { self.handle_item(&pad, &elem, buffer).await }.boxed()
) -> Result<gst::FlowSuccess, gst::FlowError> {
self.handle_item(&pad, &elem, buffer).await
}
fn sink_chain_list(
async fn sink_chain_list(
self,
pad: gst::Pad,
elem: super::InputSelector,
list: gst::BufferList,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
gst::log!(CAT, obj = pad, "Handling buffer list {:?}", list);
// TODO: Ideally we would keep the list intact and forward it in one go
for buffer in list.iter_owned() {
@ -180,16 +178,13 @@ impl PadSinkHandler for InputSelectorPadSinkHandler {
Ok(gst::FlowSuccess::Ok)
}
.boxed()
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
_pad: gst::Pad,
_elem: super::InputSelector,
event: gst::Event,
) -> BoxFuture<'static, bool> {
async move {
) -> bool {
let mut inner = self.0.lock().unwrap();
// Remember the segment for later use
@ -210,8 +205,6 @@ impl PadSinkHandler for InputSelectorPadSinkHandler {
true
}
}
.boxed()
}
fn sink_event(self, _pad: &gst::Pad, imp: &InputSelector, event: gst::Event) -> bool {
/* Drop all events for now */

View file

@ -17,7 +17,6 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::future::BoxFuture;
use futures::future::{abortable, AbortHandle, Aborted};
use futures::prelude::*;
@ -546,18 +545,15 @@ impl SinkHandler {
impl PadSinkHandler for SinkHandler {
type ElementImpl = JitterBuffer;
fn sink_chain(
async fn sink_chain(
self,
pad: gst::Pad,
elem: super::JitterBuffer,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
gst::debug!(CAT, obj = pad, "Handling {:?}", buffer);
self.enqueue_item(pad, elem.imp(), Some(buffer))
}
.boxed()
}
fn sink_event(self, pad: &gst::Pad, jb: &JitterBuffer, event: gst::Event) -> bool {
use gst::EventView;
@ -581,13 +577,12 @@ impl PadSinkHandler for SinkHandler {
jb.src_pad.gst_pad().push_event(event)
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
pad: gst::Pad,
elem: super::JitterBuffer,
event: gst::Event,
) -> BoxFuture<'static, bool> {
async move {
) -> bool {
gst::log!(CAT, obj = pad, "Handling {:?}", event);
let jb = elem.imp();
@ -630,8 +625,6 @@ impl PadSinkHandler for SinkHandler {
true
}
}
.boxed()
}
}
#[derive(Clone, Default)]
@ -1105,8 +1098,7 @@ impl JitterBufferTask {
impl TaskImpl for JitterBufferTask {
type Item = ();
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Starting task");
self.src_pad_handler.clear();
@ -1123,8 +1115,6 @@ impl TaskImpl for JitterBufferTask {
gst::log!(CAT, obj = self.element, "Task started");
Ok(())
}
.boxed()
}
// FIXME this function was migrated to the try_next / handle_item model
// but hasn't been touched as there are pending changes to jitterbuffer
@ -1136,8 +1126,7 @@ impl TaskImpl for JitterBufferTask {
// If latency can change during processing, a command based mechanism
// could be implemented. See the command implementation for ts-udpsink as
// an example.
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
let jb = self.element.imp();
let (latency, context_wait, do_lost, max_dropout_time) = {
let settings = jb.settings.lock().unwrap();
@ -1250,10 +1239,7 @@ impl TaskImpl for JitterBufferTask {
{
if let Some(earliest) = state.earliest_seqnum {
if next != earliest {
Some((
next,
last_popped_pts + state.packet_spacing,
))
Some((next, last_popped_pts + state.packet_spacing))
} else {
None
}
@ -1403,15 +1389,12 @@ impl TaskImpl for JitterBufferTask {
}
}
}
.boxed()
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
Ok(())
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::ok(()).boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Stopping task");
let jb = self.element.imp();
@ -1429,8 +1412,6 @@ impl TaskImpl for JitterBufferTask {
gst::log!(CAT, obj = self.element, "Task stopped");
Ok(())
}
.boxed()
}
}
pub struct JitterBuffer {

View file

@ -18,8 +18,6 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::channel::oneshot;
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
use gst::prelude::*;
@ -210,33 +208,27 @@ struct ProxySinkPadHandler;
impl PadSinkHandler for ProxySinkPadHandler {
type ElementImpl = ProxySink;
fn sink_chain(
async fn sink_chain(
self,
pad: gst::Pad,
elem: super::ProxySink,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
gst::log!(SINK_CAT, obj = pad, "Handling {:?}", buffer);
let imp = elem.imp();
imp.enqueue_item(DataQueueItem::Buffer(buffer)).await
}
.boxed()
}
fn sink_chain_list(
async fn sink_chain_list(
self,
pad: gst::Pad,
elem: super::ProxySink,
list: gst::BufferList,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
gst::log!(SINK_CAT, obj = pad, "Handling {:?}", list);
let imp = elem.imp();
imp.enqueue_item(DataQueueItem::BufferList(list)).await
}
.boxed()
}
fn sink_event(self, pad: &gst::Pad, imp: &ProxySink, event: gst::Event) -> bool {
gst::debug!(SINK_CAT, obj = pad, "Handling non-serialized {:?}", event);
@ -270,13 +262,12 @@ impl PadSinkHandler for ProxySinkPadHandler {
}
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
pad: gst::Pad,
elem: super::ProxySink,
event: gst::Event,
) -> BoxFuture<'static, bool> {
async move {
) -> bool {
gst::log!(SINK_CAT, obj = pad, "Handling serialized {:?}", event);
let imp = elem.imp();
@ -293,8 +284,6 @@ impl PadSinkHandler for ProxySinkPadHandler {
gst::log!(SINK_CAT, obj = pad, "Queuing serialized {:?}", event);
imp.enqueue_item(DataQueueItem::Event(event)).await.is_ok()
}
.boxed()
}
}
#[derive(Debug)]
@ -802,8 +791,7 @@ impl ProxySrcTask {
impl TaskImpl for ProxySrcTask {
type Item = DataQueueItem;
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(SRC_CAT, obj = self.element, "Starting task");
let proxysrc = self.element.imp();
@ -821,21 +809,15 @@ impl TaskImpl for ProxySrcTask {
gst::log!(SRC_CAT, obj = self.element, "Task started");
Ok(())
}
.boxed()
}
fn try_next(&mut self) -> BoxFuture<'_, Result<DataQueueItem, gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<DataQueueItem, gst::FlowError> {
self.dataqueue
.next()
.await
.ok_or_else(|| panic!("DataQueue stopped while Task is Started"))
}
.boxed()
}
fn handle_item(&mut self, item: DataQueueItem) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, item: DataQueueItem) -> Result<(), gst::FlowError> {
let res = self.push_item(item).await;
let proxysrc = self.element.imp();
match res {
@ -873,11 +855,8 @@ impl TaskImpl for ProxySrcTask {
res
}
.boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(SRC_CAT, obj = self.element, "Stopping task");
let proxysrc = self.element.imp();
@ -896,11 +875,8 @@ impl TaskImpl for ProxySrcTask {
gst::log!(SRC_CAT, obj = self.element, "Task stopped");
Ok(())
}
.boxed()
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(SRC_CAT, obj = self.element, "Starting task flush");
let proxysrc = self.element.imp();
@ -914,8 +890,6 @@ impl TaskImpl for ProxySrcTask {
gst::log!(SRC_CAT, obj = self.element, "Task flush started");
Ok(())
}
.boxed()
}
}
#[derive(Debug)]

View file

@ -18,8 +18,6 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::channel::oneshot;
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
use gst::prelude::*;
@ -82,33 +80,27 @@ struct QueuePadSinkHandler;
impl PadSinkHandler for QueuePadSinkHandler {
type ElementImpl = Queue;
fn sink_chain(
async fn sink_chain(
self,
pad: gst::Pad,
elem: super::Queue,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
gst::log!(CAT, obj = pad, "Handling {:?}", buffer);
let imp = elem.imp();
imp.enqueue_item(DataQueueItem::Buffer(buffer)).await
}
.boxed()
}
fn sink_chain_list(
async fn sink_chain_list(
self,
pad: gst::Pad,
elem: super::Queue,
list: gst::BufferList,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
gst::log!(CAT, obj = pad, "Handling {:?}", list);
let imp = elem.imp();
imp.enqueue_item(DataQueueItem::BufferList(list)).await
}
.boxed()
}
fn sink_event(self, pad: &gst::Pad, imp: &Queue, event: gst::Event) -> bool {
gst::debug!(CAT, obj = pad, "Handling non-serialized {:?}", event);
@ -130,13 +122,12 @@ impl PadSinkHandler for QueuePadSinkHandler {
imp.src_pad.gst_pad().push_event(event)
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
pad: gst::Pad,
elem: super::Queue,
event: gst::Event,
) -> BoxFuture<'static, bool> {
async move {
) -> bool {
gst::log!(CAT, obj = pad, "Handling serialized {:?}", event);
let imp = elem.imp();
@ -157,8 +148,6 @@ impl PadSinkHandler for QueuePadSinkHandler {
gst::log!(CAT, obj = pad, "Queuing serialized {:?}", event);
imp.enqueue_item(DataQueueItem::Event(event)).await.is_ok()
}
.boxed()
}
fn sink_query(self, pad: &gst::Pad, imp: &Queue, query: &mut gst::QueryRef) -> bool {
gst::log!(CAT, obj = pad, "Handling {:?}", query);
@ -276,8 +265,7 @@ impl QueueTask {
impl TaskImpl for QueueTask {
type Item = DataQueueItem;
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Starting task");
let queue = self.element.imp();
@ -290,21 +278,15 @@ impl TaskImpl for QueueTask {
gst::log!(CAT, obj = self.element, "Task started");
Ok(())
}
.boxed()
}
fn try_next(&mut self) -> BoxFuture<'_, Result<DataQueueItem, gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<DataQueueItem, gst::FlowError> {
self.dataqueue
.next()
.await
.ok_or_else(|| panic!("DataQueue stopped while Task is Started"))
}
.boxed()
}
fn handle_item(&mut self, item: DataQueueItem) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async {
async fn handle_item(&mut self, item: DataQueueItem) -> Result<(), gst::FlowError> {
let res = self.push_item(item).await;
let queue = self.element.imp();
match res {
@ -335,11 +317,8 @@ impl TaskImpl for QueueTask {
res
}
.boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Stopping task");
let queue = self.element.imp();
@ -357,11 +336,8 @@ impl TaskImpl for QueueTask {
gst::log!(CAT, obj = self.element, "Task stopped");
Ok(())
}
.boxed()
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Starting task flush");
let queue = self.element.imp();
@ -378,8 +354,6 @@ impl TaskImpl for QueueTask {
gst::log!(CAT, obj = self.element, "Task flush started");
Ok(())
}
.boxed()
}
}
#[derive(Debug)]

View file

@ -69,7 +69,6 @@
//! [`Context`]: ../executor/struct.Context.html
use futures::future;
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::prelude::*;
@ -104,11 +103,10 @@ fn event_to_event_full(ret: bool, event_type: gst::EventType) -> Result<FlowSucc
#[inline]
fn event_to_event_full_serialized(
ret: BoxFuture<'static, bool>,
ret: impl Future<Output = bool> + Send,
event_type: gst::EventType,
) -> BoxFuture<'static, Result<FlowSuccess, FlowError>> {
) -> impl Future<Output = Result<FlowSuccess, FlowError>> + Send {
ret.map(move |ret| event_ret_to_event_full_res(ret, event_type))
.boxed()
}
/// A trait to define `handler`s for [`PadSrc`] callbacks.
@ -538,8 +536,8 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
_pad: gst::Pad,
_elem: <Self::ElementImpl as ObjectSubclass>::Type,
_buffer: gst::Buffer,
) -> BoxFuture<'static, Result<FlowSuccess, FlowError>> {
future::err(FlowError::NotSupported).boxed()
) -> impl Future<Output = Result<FlowSuccess, FlowError>> + Send {
future::err(FlowError::NotSupported)
}
fn sink_chain_list(
@ -547,8 +545,8 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
_pad: gst::Pad,
_elem: <Self::ElementImpl as ObjectSubclass>::Type,
_buffer_list: gst::BufferList,
) -> BoxFuture<'static, Result<FlowSuccess, FlowError>> {
future::err(FlowError::NotSupported).boxed()
) -> impl Future<Output = Result<FlowSuccess, FlowError>> + Send {
future::err(FlowError::NotSupported)
}
fn sink_event(self, pad: &gst::Pad, imp: &Self::ElementImpl, event: gst::Event) -> bool {
@ -562,14 +560,13 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
pad: gst::Pad,
elem: <Self::ElementImpl as ObjectSubclass>::Type,
event: gst::Event,
) -> BoxFuture<'static, bool> {
) -> impl Future<Output = bool> + Send {
assert!(event.is_serialized());
async move {
gst::log!(RUNTIME_CAT, obj = pad, "Handling {:?}", event);
gst::Pad::event_default(&pad, Some(&elem), event)
}
.boxed()
}
fn sink_event_full(
@ -590,7 +587,7 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
pad: gst::Pad,
elem: <Self::ElementImpl as ObjectSubclass>::Type,
event: gst::Event,
) -> BoxFuture<'static, Result<FlowSuccess, FlowError>> {
) -> impl Future<Output = Result<FlowSuccess, FlowError>> + Send {
assert!(event.is_serialized());
// default is to dispatch to `sink_event`
// (as implemented in `gst_pad_send_event_unchecked`)

View file

@ -22,12 +22,11 @@
use futures::channel::mpsc as async_mpsc;
use futures::channel::oneshot;
use futures::future::{self, BoxFuture};
use futures::prelude::*;
use std::fmt;
use std::ops::Deref;
use std::pin::Pin;
use std::pin::{pin, Pin};
use std::sync::{Arc, Mutex, MutexGuard};
use std::task::Poll;
@ -319,16 +318,16 @@ impl fmt::Debug for TransitionStatus {
pub trait TaskImpl: Send + 'static {
type Item: Send + 'static;
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
future::ok(()).boxed()
fn prepare(&mut self) -> impl Future<Output = Result<(), gst::ErrorMessage>> + Send {
future::ok(())
}
fn unprepare(&mut self) -> BoxFuture<'_, ()> {
future::ready(()).boxed()
fn unprepare(&mut self) -> impl Future<Output = ()> + Send {
future::ready(())
}
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
future::ok(()).boxed()
fn start(&mut self) -> impl Future<Output = Result<(), gst::ErrorMessage>> + Send {
future::ok(())
}
/// Tries to retrieve the next item to process.
@ -343,7 +342,7 @@ pub trait TaskImpl: Send + 'static {
/// with said `Item`.
///
/// If `Err(..)` is returned, the iteration calls [`Self::handle_loop_error`].
fn try_next(&mut self) -> BoxFuture<'_, Result<Self::Item, gst::FlowError>>;
fn try_next(&mut self) -> impl Future<Output = Result<Self::Item, gst::FlowError>> + Send;
/// Does whatever needs to be done with the `item`.
///
@ -355,22 +354,25 @@ pub trait TaskImpl: Send + 'static {
/// to completion even if a state transition is requested.
///
/// If `Err(..)` is returned, the iteration calls [`Self::handle_loop_error`].
fn handle_item(&mut self, _item: Self::Item) -> BoxFuture<'_, Result<(), gst::FlowError>>;
fn handle_item(
&mut self,
_item: Self::Item,
) -> impl Future<Output = Result<(), gst::FlowError>> + Send;
fn pause(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
future::ok(()).boxed()
fn pause(&mut self) -> impl Future<Output = Result<(), gst::ErrorMessage>> + Send {
future::ok(())
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
future::ok(()).boxed()
fn flush_start(&mut self) -> impl Future<Output = Result<(), gst::ErrorMessage>> + Send {
future::ready(Ok(()))
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
future::ok(()).boxed()
fn flush_stop(&mut self) -> impl Future<Output = Result<(), gst::ErrorMessage>> + Send {
future::ready(Ok(()))
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
future::ok(()).boxed()
fn stop(&mut self) -> impl Future<Output = Result<(), gst::ErrorMessage>> + Send {
future::ready(Ok(()))
}
/// Handles an error occurring during the execution of the `Task` loop.
@ -387,7 +389,7 @@ pub trait TaskImpl: Send + 'static {
/// - `FlowError::Flushing` -> `Trigger::FlushStart`.
/// - `FlowError::Eos` -> `Trigger::Stop`.
/// - Other `FlowError` -> `Trigger::Error`.
fn handle_loop_error(&mut self, err: gst::FlowError) -> BoxFuture<'_, Trigger> {
fn handle_loop_error(&mut self, err: gst::FlowError) -> impl Future<Output = Trigger> + Send {
async move {
match err {
gst::FlowError::Flushing => {
@ -407,7 +409,6 @@ pub trait TaskImpl: Send + 'static {
}
}
}
.boxed()
}
/// Handles an error occurring during the execution of a transition action.
@ -425,7 +426,7 @@ pub trait TaskImpl: Send + 'static {
trigger: Trigger,
state: TaskState,
err: gst::ErrorMessage,
) -> BoxFuture<'_, Trigger> {
) -> impl Future<Output = Trigger> + Send {
async move {
gst::error!(
RUNTIME_CAT,
@ -437,7 +438,6 @@ pub trait TaskImpl: Send + 'static {
Trigger::Error
}
.boxed()
}
}
@ -663,11 +663,7 @@ impl Task {
inner.state = TaskState::Preparing;
gst::log!(RUNTIME_CAT, "Spawning task state machine");
inner.state_machine_handle = Some(StateMachine::spawn(
self.0.clone(),
Box::new(task_impl),
context,
));
inner.state_machine_handle = Some(StateMachine::spawn(self.0.clone(), task_impl, context));
let ack_rx = match inner.trigger(Trigger::Prepare) {
Ok(ack_rx) => ack_rx,
@ -809,8 +805,8 @@ impl Task {
}
}
struct StateMachine<Item: Send + 'static> {
task_impl: Box<dyn TaskImpl<Item = Item>>,
struct StateMachine<Task: TaskImpl> {
task_impl: Task,
triggering_evt_rx: async_mpsc::Receiver<TriggeringEvent>,
pending_triggering_evt: Option<TriggeringEvent>,
}
@ -845,12 +841,10 @@ macro_rules! exec_action {
}};
}
impl<Item: Send + 'static> StateMachine<Item> {
// Use dynamic dispatch for TaskImpl as it reduces memory usage compared to monomorphization
// without inducing any significant performance penalties.
impl<Task: TaskImpl> StateMachine<Task> {
fn spawn(
task_inner: Arc<Mutex<TaskInner>>,
task_impl: Box<dyn TaskImpl<Item = Item>>,
task_impl: Task,
context: Context,
) -> StateMachineHandle {
let (triggering_evt_tx, triggering_evt_rx) = async_mpsc::channel(4);
@ -1127,7 +1121,7 @@ impl<Item: Send + 'static> StateMachine<Item> {
// `try_next`. Since we need to get a new `BoxFuture` at
// each iteration, we can guarantee that the future is
// always valid for use in `select_biased`.
let mut try_next_fut = self.task_impl.try_next().fuse();
let mut try_next_fut = pin!(self.task_impl.try_next().fuse());
futures::select_biased! {
triggering_evt = self.triggering_evt_rx.next() => {
let triggering_evt = triggering_evt.expect("broken state machine channel");
@ -1156,8 +1150,8 @@ impl<Item: Send + 'static> StateMachine<Item> {
mod tests {
use futures::channel::{mpsc, oneshot};
use futures::executor::block_on;
use futures::future::BoxFuture;
use futures::prelude::*;
use std::future::pending;
use std::time::Duration;
use super::{
@ -1195,37 +1189,27 @@ mod tests {
impl TaskImpl for TaskTest {
type Item = ();
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "nominal: prepared");
self.prepared_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "nominal: started");
self.started_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
gst::debug!(RUNTIME_CAT, "nominal: entering try_next");
self.try_next_ready_sender.send(()).await.unwrap();
gst::debug!(RUNTIME_CAT, "nominal: awaiting try_next");
self.try_next_receiver.next().await.unwrap();
Ok(())
}
.boxed()
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
gst::debug!(RUNTIME_CAT, "nominal: entering handle_item");
self.handle_item_ready_sender.send(()).await.unwrap();
@ -1235,34 +1219,23 @@ mod tests {
Ok(())
}
.boxed()
}
fn pause(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn pause(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "nominal: paused");
self.paused_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "nominal: stopped");
self.stopped_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn unprepare(&mut self) -> BoxFuture<'_, ()> {
async move {
async fn unprepare(&mut self) {
gst::debug!(RUNTIME_CAT, "nominal: unprepared");
self.unprepared_sender.send(()).await.unwrap();
}
.boxed()
}
}
let context = Context::acquire("nominal", Duration::from_millis(2)).unwrap();
@ -1488,24 +1461,20 @@ mod tests {
impl TaskImpl for TaskPrepareTest {
type Item = ();
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "prepare_error: prepare returning an error");
Err(gst::error_msg!(
gst::ResourceError::Failed,
["prepare_error: intentional error"]
))
}
.boxed()
}
fn handle_action_error(
async fn handle_action_error(
&mut self,
trigger: Trigger,
state: TaskState,
err: gst::ErrorMessage,
) -> BoxFuture<'_, Trigger> {
async move {
) -> Trigger {
gst::debug!(
RUNTIME_CAT,
"prepare_error: handling prepare error {:?}",
@ -1519,14 +1488,12 @@ mod tests {
}
Trigger::Error
}
.boxed()
}
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
unreachable!("prepare_error: try_next");
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("prepare_error: handle_item");
}
}
@ -1590,8 +1557,7 @@ mod tests {
impl TaskImpl for TaskPrepareTest {
type Item = ();
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(
RUNTIME_CAT,
"prepare_start_ok: preparation awaiting trigger"
@ -1600,31 +1566,26 @@ mod tests {
gst::debug!(RUNTIME_CAT, "prepare_start_ok: preparation complete Ok");
Ok(())
}
.boxed()
}
fn handle_action_error(
async fn handle_action_error(
&mut self,
_trigger: Trigger,
_state: TaskState,
_err: gst::ErrorMessage,
) -> BoxFuture<'_, Trigger> {
) -> Trigger {
unreachable!("prepare_start_ok: handle_prepare_error");
}
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "prepare_start_ok: started");
Ok(())
}
.boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
pending().await
}
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::pending::<Result<(), gst::FlowError>>().boxed()
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("prepare_start_ok: handle_item");
}
}
@ -1721,8 +1682,7 @@ mod tests {
impl TaskImpl for TaskPrepareTest {
type Item = ();
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(
RUNTIME_CAT,
"prepare_start_error: preparation awaiting trigger"
@ -1735,16 +1695,13 @@ mod tests {
["prepare_start_error: intentional error"]
))
}
.boxed()
}
fn handle_action_error(
async fn handle_action_error(
&mut self,
trigger: Trigger,
state: TaskState,
err: gst::ErrorMessage,
) -> BoxFuture<'_, Trigger> {
async move {
) -> Trigger {
gst::debug!(
RUNTIME_CAT,
"prepare_start_error: handling prepare error {:?}",
@ -1758,18 +1715,16 @@ mod tests {
}
Trigger::Error
}
.boxed()
}
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
unreachable!("prepare_start_error: start");
}
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
unreachable!("prepare_start_error: try_next");
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("prepare_start_error: handle_item");
}
}
@ -1862,24 +1817,15 @@ mod tests {
impl TaskImpl for TaskTest {
type Item = gst::FlowError;
fn try_next(&mut self) -> BoxFuture<'_, Result<gst::FlowError, gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<gst::FlowError, gst::FlowError> {
gst::debug!(RUNTIME_CAT, "item_error: awaiting try_next");
Ok(self.try_next_receiver.next().await.unwrap())
}
.boxed()
}
fn handle_item(
&mut self,
item: gst::FlowError,
) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, item: gst::FlowError) -> Result<(), gst::FlowError> {
gst::debug!(RUNTIME_CAT, "item_error: handle_item received {:?}", item);
Err(item)
}
.boxed()
}
}
let context = Context::acquire("item_error", Duration::from_millis(2)).unwrap();
@ -1945,31 +1891,25 @@ mod tests {
impl TaskImpl for TaskFlushTest {
type Item = ();
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::pending::<Result<(), gst::FlowError>>().boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
pending().await
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("flush_regular_sync: handle_item");
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "flush_regular_sync: started flushing");
self.flush_start_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "flush_regular_sync: stopped flushing");
self.flush_stop_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context = Context::acquire("flush_regular_sync", Duration::from_millis(2)).unwrap();
@ -2032,16 +1972,15 @@ mod tests {
impl TaskImpl for TaskFlushTest {
type Item = ();
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::pending::<Result<(), gst::FlowError>>().boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
pending().await
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("flush_regular_different_context: handle_item");
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(
RUNTIME_CAT,
"flush_regular_different_context: started flushing"
@ -2049,11 +1988,8 @@ mod tests {
self.flush_start_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(
RUNTIME_CAT,
"flush_regular_different_context: stopped flushing"
@ -2061,8 +1997,6 @@ mod tests {
self.flush_stop_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context =
@ -2151,31 +2085,25 @@ mod tests {
impl TaskImpl for TaskFlushTest {
type Item = ();
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::pending::<Result<(), gst::FlowError>>().boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
pending().await
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("flush_regular_same_context: handle_item");
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "flush_regular_same_context: started flushing");
self.flush_start_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "flush_regular_same_context: stopped flushing");
self.flush_stop_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context =
@ -2255,12 +2183,11 @@ mod tests {
impl TaskImpl for TaskFlushTest {
type Item = ();
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::ok(()).boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
Ok(())
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
gst::debug!(RUNTIME_CAT, "flush_from_loop: flush_start from handle_item");
match self.task.flush_start() {
Pending {
@ -2272,17 +2199,12 @@ mod tests {
}
Ok(())
}
.boxed()
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "flush_from_loop: started flushing");
self.flush_start_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context = Context::acquire("flush_from_loop", Duration::from_millis(2)).unwrap();
@ -2332,12 +2254,11 @@ mod tests {
impl TaskImpl for TaskStartTest {
type Item = ();
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::ok(()).boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
Ok(())
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
gst::debug!(RUNTIME_CAT, "pause_from_loop: entering handle_item");
crate::runtime::timer::delay_for(Duration::from_millis(50)).await;
@ -2354,17 +2275,12 @@ mod tests {
Ok(())
}
.boxed()
}
fn pause(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn pause(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "pause_from_loop: entering pause action");
self.pause_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context = Context::acquire("pause_from_loop", Duration::from_millis(2)).unwrap();
@ -2403,16 +2319,15 @@ mod tests {
impl TaskImpl for TaskFlushTest {
type Item = ();
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::pending::<Result<(), gst::FlowError>>().boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
pending().await
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("trigger_from_action: handle_item");
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(
RUNTIME_CAT,
"trigger_from_action: flush_start triggering flush_stop"
@ -2428,17 +2343,12 @@ mod tests {
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "trigger_from_action: stopped flushing");
self.flush_stop_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context = Context::acquire("trigger_from_action", Duration::from_millis(2)).unwrap();
@ -2481,40 +2391,31 @@ mod tests {
impl TaskImpl for TaskFlushTest {
type Item = ();
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "pause_flush_start: started");
self.started_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
pending().await
}
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::pending::<Result<(), gst::FlowError>>().boxed()
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("pause_flush_start: handle_item");
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "pause_flush_start: started flushing");
self.flush_start_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "pause_flush_start: stopped flushing");
self.flush_stop_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context = Context::acquire("pause_flush_start", Duration::from_millis(2)).unwrap();
@ -2597,40 +2498,31 @@ mod tests {
impl TaskImpl for TaskFlushTest {
type Item = ();
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "pause_flushing_start: started");
self.started_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
pending().await
}
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::pending::<Result<(), gst::FlowError>>().boxed()
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("pause_flushing_start: handle_item");
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "pause_flushing_start: started flushing");
self.flush_start_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "pause_flushing_start: stopped flushing");
self.flush_stop_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context = Context::acquire("pause_flushing_start", Duration::from_millis(2)).unwrap();
@ -2703,31 +2595,25 @@ mod tests {
impl TaskImpl for TaskStartTest {
type Item = ();
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
future::pending::<Result<(), gst::FlowError>>().boxed()
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
pending().await
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
unreachable!("flush_concurrent_start: handle_item");
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "flush_concurrent_start: started flushing");
self.flush_start_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::debug!(RUNTIME_CAT, "flush_concurrent_start: stopped flushing");
self.flush_stop_sender.send(()).await.unwrap();
Ok(())
}
.boxed()
}
}
let context = Context::acquire("flush_concurrent_start", Duration::from_millis(2)).unwrap();
@ -2826,26 +2712,19 @@ mod tests {
impl TaskImpl for TaskTimerTest {
type Item = ();
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
self.timer = Some(crate::runtime::timer::delay_for(Duration::from_millis(50)));
gst::debug!(RUNTIME_CAT, "start_timer: started");
Ok(())
}
.boxed()
}
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<(), gst::FlowError> {
gst::debug!(RUNTIME_CAT, "start_timer: awaiting timer");
self.timer.take().unwrap().await;
Ok(())
}
.boxed()
}
fn handle_item(&mut self, _item: ()) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, _item: ()) -> Result<(), gst::FlowError> {
gst::debug!(RUNTIME_CAT, "start_timer: timer elapsed");
if let Some(timer_elapsed_sender) = self.timer_elapsed_sender.take() {
timer_elapsed_sender.send(()).unwrap();
@ -2853,8 +2732,6 @@ mod tests {
Err(gst::FlowError::Eos)
}
.boxed()
}
}
let context = Context::acquire("start_timer", Duration::from_millis(2)).unwrap();

View file

@ -18,8 +18,6 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::future::BoxFuture;
use gst::glib;
use gst::prelude::*;
@ -27,6 +25,7 @@ use std::sync::LazyLock;
use std::error;
use std::fmt;
use std::future::Future;
use std::io;
use std::net::UdpSocket;
@ -52,7 +51,7 @@ pub trait SocketRead: Send + Unpin {
fn read<'buf>(
&'buf mut self,
buffer: &'buf mut [u8],
) -> BoxFuture<'buf, io::Result<(usize, Option<std::net::SocketAddr>)>>;
) -> impl Future<Output = io::Result<(usize, Option<std::net::SocketAddr>)>> + Send;
}
pub struct Socket<T: SocketRead> {

View file

@ -18,7 +18,6 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
@ -87,11 +86,11 @@ impl TcpClientReader {
impl SocketRead for TcpClientReader {
const DO_TIMESTAMP: bool = false;
fn read<'buf>(
async fn read<'buf>(
&'buf mut self,
buffer: &'buf mut [u8],
) -> BoxFuture<'buf, io::Result<(usize, Option<std::net::SocketAddr>)>> {
async move { self.0.read(buffer).await.map(|read_size| (read_size, None)) }.boxed()
) -> io::Result<(usize, Option<std::net::SocketAddr>)> {
Ok((self.0.read(buffer).await?, None))
}
}
@ -270,8 +269,7 @@ impl TcpClientSrcTask {
impl TaskImpl for TcpClientSrcTask {
type Item = gst::Buffer;
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(
CAT,
obj = self.element,
@ -305,16 +303,13 @@ impl TaskImpl for TcpClientSrcTask {
gst::log!(CAT, obj = self.element, "Task prepared");
Ok(())
}
.boxed()
}
fn handle_action_error(
async fn handle_action_error(
&mut self,
trigger: task::Trigger,
state: TaskState,
err: gst::ErrorMessage,
) -> BoxFuture<'_, task::Trigger> {
async move {
) -> task::Trigger {
match trigger {
task::Trigger::Prepare => {
gst::error!(CAT, "Task preparation failed: {:?}", err);
@ -325,11 +320,8 @@ impl TaskImpl for TcpClientSrcTask {
other => unreachable!("Action error for {:?} in state {:?}", other, state),
}
}
.boxed()
}
fn try_next(&mut self) -> BoxFuture<'_, Result<gst::Buffer, gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<gst::Buffer, gst::FlowError> {
let event_fut = self.event_receiver.next().fuse();
let socket_fut = self.socket.as_mut().unwrap().try_next().fuse();
@ -383,35 +375,27 @@ impl TaskImpl for TcpClientSrcTask {
},
}
}
.boxed()
async fn handle_item(&mut self, buffer: gst::Buffer) -> Result<(), gst::FlowError> {
let _ = self.push_buffer(buffer).await?;
Ok(())
}
fn handle_item(&mut self, buffer: gst::Buffer) -> BoxFuture<'_, Result<(), gst::FlowError>> {
self.push_buffer(buffer).map_ok(drop).boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Stopping task");
self.need_initial_events = true;
gst::log!(CAT, obj = self.element, "Task stopped");
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Stopping task flush");
self.need_initial_events = true;
gst::log!(CAT, obj = self.element, "Task flush stopped");
Ok(())
}
.boxed()
}
fn handle_loop_error(&mut self, err: gst::FlowError) -> BoxFuture<'_, task::Trigger> {
async move {
async fn handle_loop_error(&mut self, err: gst::FlowError) -> task::Trigger {
match err {
gst::FlowError::Flushing => {
gst::debug!(CAT, obj = self.element, "Flushing");
@ -441,8 +425,6 @@ impl TaskImpl for TcpClientSrcTask {
}
}
}
.boxed()
}
}
pub struct TcpClientSrc {

View file

@ -17,9 +17,6 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
use gst::prelude::*;
use gst::subclass::prelude::*;
@ -350,22 +347,21 @@ impl UdpSinkPadHandler {
impl PadSinkHandler for UdpSinkPadHandler {
type ElementImpl = UdpSink;
fn sink_chain(
async fn sink_chain(
self,
_pad: gst::Pad,
elem: super::UdpSink,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move { self.0.lock().await.handle_buffer(&elem, buffer).await }.boxed()
) -> Result<gst::FlowSuccess, gst::FlowError> {
self.0.lock().await.handle_buffer(&elem, buffer).await
}
fn sink_chain_list(
async fn sink_chain_list(
self,
_pad: gst::Pad,
elem: super::UdpSink,
list: gst::BufferList,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
let mut inner = self.0.lock().await;
for buffer in list.iter_owned() {
inner.handle_buffer(&elem, buffer).await?;
@ -373,16 +369,13 @@ impl PadSinkHandler for UdpSinkPadHandler {
Ok(gst::FlowSuccess::Ok)
}
.boxed()
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
_pad: gst::Pad,
elem: super::UdpSink,
event: gst::Event,
) -> BoxFuture<'static, bool> {
async move {
) -> bool {
gst::debug!(CAT, obj = elem, "Handling {event:?}");
match event.view() {
@ -403,8 +396,6 @@ impl PadSinkHandler for UdpSinkPadHandler {
true
}
.boxed()
}
fn sink_event(self, _pad: &gst::Pad, imp: &UdpSink, event: gst::Event) -> bool {
gst::debug!(CAT, imp = imp, "Handling {event:?}");

View file

@ -17,7 +17,6 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
@ -112,17 +111,12 @@ impl UdpReader {
impl SocketRead for UdpReader {
const DO_TIMESTAMP: bool = true;
fn read<'buf>(
async fn read<'buf>(
&'buf mut self,
buffer: &'buf mut [u8],
) -> BoxFuture<'buf, io::Result<(usize, Option<std::net::SocketAddr>)>> {
async move {
self.0
.recv_from(buffer)
.await
.map(|(read_size, saddr)| (read_size, Some(saddr)))
}
.boxed()
) -> io::Result<(usize, Option<std::net::SocketAddr>)> {
let (read_size, saddr) = self.0.recv_from(buffer).await?;
Ok((read_size, Some(saddr)))
}
}
@ -224,8 +218,7 @@ impl UdpSrcTask {
impl TaskImpl for UdpSrcTask {
type Item = gst::Buffer;
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn prepare(&mut self) -> Result<(), gst::ErrorMessage> {
let udpsrc = self.element.imp();
let mut settings = udpsrc.settings.lock().unwrap();
@ -459,13 +452,14 @@ impl TaskImpl for UdpSrcTask {
gst::debug!(CAT, "interface {} joining the multicast", iface.name);
// use the custom written API to be able to pass the interface index
// for all types of target OS
net::imp::join_multicast_v4(socket.as_ref(), &addr, iface)
.map_err(|err| {
net::imp::join_multicast_v4(socket.as_ref(), &addr, iface).map_err(
|err| {
gst::error_msg!(
gst::ResourceError::OpenRead,
["Failed to join multicast group: {}", err]
)
})?;
},
)?;
}
socket
@ -566,11 +560,8 @@ impl TaskImpl for UdpSrcTask {
Ok(())
}
.boxed()
}
fn unprepare(&mut self) -> BoxFuture<'_, ()> {
async move {
async fn unprepare(&mut self) {
gst::debug!(CAT, obj = self.element, "Unpreparing Task");
let udpsrc = self.element.imp();
if let Some(reader) = &self.socket {
@ -589,8 +580,7 @@ impl TaskImpl for UdpSrcTask {
}
gst::debug!(CAT, "interface {} leaving the multicast", iface.name);
net::imp::leave_multicast_v4(socket.as_ref(), &addr, iface)
.unwrap();
net::imp::leave_multicast_v4(socket.as_ref(), &addr, iface).unwrap();
}
}
IpAddr::V6(addr) => {
@ -617,11 +607,8 @@ impl TaskImpl for UdpSrcTask {
udpsrc.settings.lock().unwrap().used_socket = None;
self.element.notify("used-socket");
}
.boxed()
}
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Starting task");
self.socket
.as_mut()
@ -630,11 +617,8 @@ impl TaskImpl for UdpSrcTask {
gst::log!(CAT, obj = self.element, "Task started");
Ok(())
}
.boxed()
}
fn try_next(&mut self) -> BoxFuture<'_, Result<gst::Buffer, gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<gst::Buffer, gst::FlowError> {
let event_fut = self.event_receiver.next().fuse();
let socket_fut = self.socket.as_mut().unwrap().try_next().fuse();
@ -699,19 +683,15 @@ impl TaskImpl for UdpSrcTask {
},
}
}
.boxed()
}
fn handle_item(&mut self, buffer: gst::Buffer) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async {
async fn handle_item(&mut self, buffer: gst::Buffer) -> Result<(), gst::FlowError> {
gst::log!(CAT, obj = self.element, "Handling {:?}", buffer);
let udpsrc = self.element.imp();
if self.need_initial_events {
gst::debug!(CAT, obj = self.element, "Pushing initial events");
let stream_id =
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
let stream_id = format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
let stream_start_evt = gst::event::StreamStart::builder(&stream_id)
.group_id(gst::GroupId::next())
.build();
@ -758,32 +738,23 @@ impl TaskImpl for UdpSrcTask {
res
}
.boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Stopping task");
self.need_initial_events = true;
self.need_segment = true;
gst::log!(CAT, obj = self.element, "Task stopped");
Ok(())
}
.boxed()
}
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(CAT, obj = self.element, "Stopping task flush");
self.need_segment = true;
gst::log!(CAT, obj = self.element, "Stopped task flush");
Ok(())
}
.boxed()
}
fn handle_loop_error(&mut self, err: gst::FlowError) -> BoxFuture<'_, task::Trigger> {
async move {
async fn handle_loop_error(&mut self, err: gst::FlowError) -> task::Trigger {
match err {
gst::FlowError::Flushing => {
gst::debug!(CAT, obj = self.element, "Flushing");
@ -813,8 +784,6 @@ impl TaskImpl for UdpSrcTask {
}
}
}
.boxed()
}
}
pub struct UdpSrc {

View file

@ -20,7 +20,6 @@
#![allow(clippy::non_send_fields_in_send_ty, unused_doc_comments)]
use futures::channel::mpsc;
use futures::future::BoxFuture;
use futures::prelude::*;
use gst::glib;
@ -145,18 +144,14 @@ mod imp_src {
impl TaskImpl for ElementSrcTestTask {
type Item = Item;
fn try_next(&mut self) -> BoxFuture<'_, Result<Item, gst::FlowError>> {
async move {
async fn try_next(&mut self) -> Result<Item, gst::FlowError> {
self.receiver.next().await.ok_or_else(|| {
gst::log!(SRC_CAT, obj = self.element, "SrcPad channel aborted");
gst::FlowError::Eos
})
}
.boxed()
}
fn handle_item(&mut self, item: Item) -> BoxFuture<'_, Result<(), gst::FlowError>> {
async move {
async fn handle_item(&mut self, item: Item) -> Result<(), gst::FlowError> {
let res = self.push_item(item).await.map(drop);
match res {
Ok(_) => gst::log!(SRC_CAT, obj = self.element, "Successfully pushed item"),
@ -168,28 +163,20 @@ mod imp_src {
res
}
.boxed()
}
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn stop(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(SRC_CAT, obj = self.element, "Stopping task");
self.flush();
gst::log!(SRC_CAT, obj = self.element, "Task stopped");
Ok(())
}
.boxed()
}
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
async move {
async fn flush_start(&mut self) -> Result<(), gst::ErrorMessage> {
gst::log!(SRC_CAT, obj = self.element, "Starting task flush");
self.flush();
gst::log!(SRC_CAT, obj = self.element, "Task flush started");
Ok(())
}
.boxed()
}
}
#[derive(Debug)]
@ -438,31 +425,25 @@ mod imp_sink {
impl PadSinkHandler for PadSinkTestHandler {
type ElementImpl = ElementSinkTest;
fn sink_chain(
async fn sink_chain(
self,
_pad: gst::Pad,
elem: super::ElementSinkTest,
buffer: gst::Buffer,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
let imp = elem.imp();
imp.forward_item(Item::Buffer(buffer)).await
}
.boxed()
}
fn sink_chain_list(
async fn sink_chain_list(
self,
_pad: gst::Pad,
elem: super::ElementSinkTest,
list: gst::BufferList,
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
async move {
) -> Result<gst::FlowSuccess, gst::FlowError> {
let imp = elem.imp();
imp.forward_item(Item::BufferList(list)).await
}
.boxed()
}
fn sink_event(self, pad: &gst::Pad, imp: &ElementSinkTest, event: gst::Event) -> bool {
gst::debug!(SINK_CAT, obj = pad, "Handling non-serialized {:?}", event);
@ -476,13 +457,12 @@ mod imp_sink {
}
}
fn sink_event_serialized(
async fn sink_event_serialized(
self,
pad: gst::Pad,
elem: super::ElementSinkTest,
event: gst::Event,
) -> BoxFuture<'static, bool> {
async move {
) -> bool {
gst::log!(SINK_CAT, obj = pad, "Handling serialized {:?}", event);
let imp = elem.imp();
@ -492,8 +472,6 @@ mod imp_sink {
imp.forward_item(Item::Event(event)).await.is_ok()
}
.boxed()
}
}
#[derive(Debug)]