try to improve state handling in decoding threads
[nihav-player.git] / videoplayer / src / audiodec.rs
index e9da970ad577d3a3c518c8f100134cff23286b2a..3ed639881d56c241f9fab18b6e3f2e36d81466e3 100644 (file)
@@ -12,11 +12,10 @@ use nihav_core::formats::*;
 use nihav_core::codecs::*;
 use nihav_core::soundcvt::*;
 
-use super::{DecoderStuff, DecoderType, PktSendEvent};
+use super::{DecoderStuff, DecoderType, DecoderState, DecodingState, PktSendEvent};
 
-static SKIP_ADECODING: AtomicBool = AtomicBool::new(false);
+static ADEC_STATE: DecoderState = DecoderState::new();
 static AUDIO_VOLUME: AtomicUsize = AtomicUsize::new(100);
-static AUDIO_END: AtomicBool = AtomicBool::new(false);
 static CUR_QUEUE_FILL: AtomicUsize = AtomicUsize::new(0);
 static SAMPLE_RATE: AtomicUsize = AtomicUsize::new(0);
 static CHANNELS: AtomicUsize = AtomicUsize::new(0);
@@ -188,18 +187,18 @@ fn start_audio_decoding(asystem: &AudioSubsystem, ainfo: NAAudioInfo, mut audio_
                 } else {
                     NAChannelMap::from_str("C").unwrap()
                 };
-            SKIP_ADECODING.store(false, Ordering::Relaxed);
+            ADEC_STATE.set_state(DecodingState::Normal);
             loop {
                 match aprecv.recv() {
                     Ok(PktSendEvent::Packet(pkt)) => {
                         loop {
                             if CUR_QUEUE_FILL.load(Ordering::Relaxed)
- < QUEUE_REFILL_LIMIT || SKIP_ADECODING.load(Ordering::Relaxed) {
+ < QUEUE_REFILL_LIMIT || ADEC_STATE.is_flushing() {
                                 break;
                             }
                             std::thread::sleep(Duration::from_millis(100));
                         }
-                        if !SKIP_ADECODING.load(Ordering::Relaxed) {
+                        if !ADEC_STATE.is_flushing() {
                             if let Ok(frm) = adec.decode(&mut audio_dec.dsupp, &pkt) {
                                 let buf = frm.get_buffer();
                                 if let Some(pts) = frm.get_pts() {
@@ -229,7 +228,7 @@ fn start_audio_decoding(asystem: &AudioSubsystem, ainfo: NAAudioInfo, mut audio_
                         adec.flush();
                         let mut qdata = queue.lock().unwrap();
                         qdata.flush();
-                        SKIP_ADECODING.store(false, Ordering::Relaxed);
+                        ADEC_STATE.set_state(DecodingState::Waiting);
                     },
                     Ok(PktSendEvent::End) => break,
                     Ok(PktSendEvent::ImmediateEnd) => {
@@ -245,11 +244,11 @@ fn start_audio_decoding(asystem: &AudioSubsystem, ainfo: NAAudioInfo, mut audio_
             }
             loop {
                 let qdata = queue.lock().unwrap();
-                if qdata.fill() == 0 || SKIP_ADECODING.load(Ordering::Relaxed) {
+                if qdata.fill() == 0 || ADEC_STATE.is_flushing() {
                     break;
                 }
             }
-            AUDIO_END.store(true, Ordering::Relaxed);
+            ADEC_STATE.set_state(DecodingState::End);
         }).unwrap())
 }
 
@@ -268,7 +267,7 @@ impl AudioControl {
             } else {
                 (None, dummy_audio_thread(aprecv))
             };
-        AUDIO_END.store(false, Ordering::Relaxed);
+        ADEC_STATE.set_state(DecodingState::Normal);
 
         Self {
             aqueue:     Vec::new(),
@@ -295,7 +294,7 @@ impl AudioControl {
         AUDIO_VOLUME.load(Ordering::Relaxed)
     }
     pub fn is_audio_end(&self) -> bool {
-        AUDIO_END.load(Ordering::Relaxed)
+        matches!(ADEC_STATE.get_state(), DecodingState::End | DecodingState::Error)
     }
     pub fn get_fill(&self) -> usize { CUR_QUEUE_FILL.load(Ordering::Relaxed) }
     pub fn get_time(&self) -> Option<u64> {
@@ -346,12 +345,12 @@ impl AudioControl {
     pub fn flush(&mut self) {
         self.pause();
         self.aqueue.clear();
-        SKIP_ADECODING.store(true, Ordering::Release);
+        ADEC_STATE.set_state(DecodingState::Flush);
         CURRENT_TIME_SET.store(false, Ordering::Release);
         let _ = self.apsend.send(PktSendEvent::Flush);
     }
     pub fn finish(self) {
-        SKIP_ADECODING.store(true, Ordering::Release);
+        ADEC_STATE.set_state(DecodingState::Flush);
         let _ = self.apsend.send(PktSendEvent::ImmediateEnd);
         self.athread.join().unwrap();
     }