From d2c377d14b3a7e2e8462925c2fe9f9b45698a9f4 Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sun, 9 Jan 2022 16:28:14 +0100 Subject: [PATCH] Fix GStreamer cleanup on exit --- playback/src/audio_backend/gstreamer.rs | 43 +++++++++++++++++++------ playback/src/audio_backend/mod.rs | 2 ++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/playback/src/audio_backend/gstreamer.rs b/playback/src/audio_backend/gstreamer.rs index f96dc5dd..63aafbd0 100644 --- a/playback/src/audio_backend/gstreamer.rs +++ b/playback/src/audio_backend/gstreamer.rs @@ -1,17 +1,20 @@ -use super::{Open, Sink, SinkAsBytes, SinkResult}; -use crate::config::AudioFormat; -use crate::convert::Converter; -use crate::decoder::AudioPacket; -use crate::{NUM_CHANNELS, SAMPLE_RATE}; +use std::{ + ops::Drop, + sync::mpsc::{sync_channel, SyncSender}, + thread, +}; use gstreamer as gst; use gstreamer_app as gst_app; -use gst::prelude::*; +use gst::{prelude::*, State}; use zerocopy::AsBytes; -use std::sync::mpsc::{sync_channel, SyncSender}; -use std::thread; +use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult}; + +use crate::{ + config::AudioFormat, convert::Converter, decoder::AudioPacket, NUM_CHANNELS, SAMPLE_RATE, +}; #[allow(dead_code)] pub struct GstreamerSink { @@ -115,8 +118,8 @@ impl Open for GstreamerSink { }); pipeline - .set_state(gst::State::Playing) - .expect("unable to set the pipeline to the `Playing` state"); + .set_state(State::Ready) + .expect("unable to set the pipeline to the `Ready` state"); Self { tx, @@ -127,9 +130,29 @@ impl Open for GstreamerSink { } impl Sink for GstreamerSink { + fn start(&mut self) -> SinkResult<()> { + self.pipeline + .set_state(State::Playing) + .map_err(|e| SinkError::StateChange(e.to_string()))?; + Ok(()) + } + + fn stop(&mut self) -> SinkResult<()> { + self.pipeline + .set_state(State::Paused) + .map_err(|e| SinkError::StateChange(e.to_string()))?; + Ok(()) + } + sink_as_bytes!(); } +impl Drop for GstreamerSink { + fn drop(&mut self) { + let _ = self.pipeline.set_state(State::Null); + } +} + impl SinkAsBytes for GstreamerSink { fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> { // Copy expensively (in to_vec()) to avoid thread synchronization diff --git a/playback/src/audio_backend/mod.rs b/playback/src/audio_backend/mod.rs index 66f2ba29..959bf17d 100644 --- a/playback/src/audio_backend/mod.rs +++ b/playback/src/audio_backend/mod.rs @@ -13,6 +13,8 @@ pub enum SinkError { OnWrite(String), #[error("Audio Sink Error Invalid Parameters: {0}")] InvalidParams(String), + #[error("Audio Sink Error Changing State: {0}")] + StateChange(String), } pub type SinkResult = Result;