From 5531f3f4cbd659b754c0d03db8cba674aac4f498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Thu, 6 Dec 2018 16:19:37 -0500 Subject: [PATCH] Queue a/v data while player is setting up --- backends/gstreamer/src/player.rs | 36 ++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/backends/gstreamer/src/player.rs b/backends/gstreamer/src/player.rs index b7e52aac..3261fe58 100644 --- a/backends/gstreamer/src/player.rs +++ b/backends/gstreamer/src/player.rs @@ -90,6 +90,8 @@ struct PlayerInner { subscribers: Vec>, renderers: Vec>>, last_metadata: Option, + /// Data that was pushed to the player before we were ready. + queued_data: Vec, } impl PlayerInner { @@ -208,14 +210,31 @@ impl PlayerInner { } pub fn push_data(&mut self, data: Vec) -> Result<(), BackendError> { - if let Some(ref mut appsrc) = self.appsrc { - let buffer = - gst::Buffer::from_slice(data).ok_or_else(|| BackendError::PlayerPushDataFailed)?; - if appsrc.push_buffer(buffer) == gst::FlowReturn::Ok { - return Ok(()); + let buffer = + gst::Buffer::from_slice(data).ok_or_else(|| BackendError::PlayerPushDataFailed)?; + + match self.appsrc { + None => self.queued_data.push(buffer), + Some(ref mut appsrc) => { + if appsrc.push_buffer(buffer) != gst::FlowReturn::Ok { + return Err(BackendError::PlayerPushDataFailed); + } + } + }; + + Ok(()) + } + + pub fn flush_queued_data(&mut self) -> Result<(), BackendError> { + if self.appsrc.is_none() { + return Err(BackendError::PlayerPushDataFailed); + } + for buffer in self.queued_data.drain(..) { + if self.appsrc.as_ref().unwrap().push_buffer(buffer) != gst::FlowReturn::Ok { + return Err(BackendError::PlayerPushDataFailed); } } - Err(BackendError::PlayerPushDataFailed) + Ok(()) } pub fn set_app_src(&mut self, appsrc: gst_app::AppSrc) { @@ -293,6 +312,7 @@ impl GStreamerPlayer { subscribers: Vec::new(), renderers: Vec::new(), last_metadata: None, + queued_data: Vec::new(), }))); let inner = self.inner.borrow(); @@ -491,6 +511,10 @@ impl GStreamerPlayer { inner.set_app_src(appsrc); + if inner.flush_queued_data().is_err() { + eprintln!("Could not flush queued data"); + } + None });