replace vec.truncate(0) with vec.clear()
[nihav-player.git] / sndplay / src / main.rs
index 176a6d189d8e55b3821ca9c747aa17513ad4b81d..618c2271b14c9950d8d6429a93ce0d542baf0ec6 100644 (file)
@@ -2,7 +2,6 @@ extern crate libc;
 extern crate sdl2_sys;
 extern crate nihav_core;
 extern crate nihav_registry;
-extern crate nihav_allstuff;
 
 use std::fs::File;
 use std::io::prelude::*;
@@ -17,8 +16,8 @@ use nihav_core::codecs::*;
 use nihav_core::demuxers::*;
 use nihav_core::soundcvt::*;
 use nihav_registry::detect;
-use nihav_allstuff::*;
 
+mod allreg;
 mod command;
 use command::*;
 
@@ -86,6 +85,12 @@ impl AudioDevice {
     }
 }
 
+impl Drop for AudioDevice {
+    fn drop(&mut self) {
+        unsafe { sdl2_sys::SDL_CloseAudioDevice(self.device_id); }
+    }
+}
+
 struct Decoder<'a> {
     demuxer:    Demuxer<'a>,
     decoder:    Box<dyn NADecoder>,
@@ -102,7 +107,7 @@ struct Decoder<'a> {
 
 fn output_vol_i16(device: &AudioDevice, tmp: &mut Vec<i16>, src: &[i16], mute: bool, volume: u8) {
     if !mute {
-        tmp.truncate(0);
+        tmp.clear();
         tmp.reserve(src.len());
         let vol = i32::from(volume);
         for &sample in src.iter() {
@@ -110,7 +115,7 @@ fn output_vol_i16(device: &AudioDevice, tmp: &mut Vec<i16>, src: &[i16], mute: b
             tmp.push(nsamp.min(32767).max(-32768) as i16);
         }
     } else {
-        tmp.truncate(0);
+        tmp.clear();
         tmp.resize(src.len(), 0);
     }
     device.queue(&tmp);
@@ -118,7 +123,7 @@ fn output_vol_i16(device: &AudioDevice, tmp: &mut Vec<i16>, src: &[i16], mute: b
 
 fn output_vol_u8(device: &AudioDevice, tmp: &mut Vec<i16>, src: &[u8], mute: bool, volume: u8) {
     if !mute {
-        tmp.truncate(0);
+        tmp.clear();
         tmp.reserve(src.len());
         let vol = i32::from(volume);
         for sample in src.chunks_exact(2) {
@@ -127,7 +132,7 @@ fn output_vol_u8(device: &AudioDevice, tmp: &mut Vec<i16>, src: &[u8], mute: boo
             tmp.push(nsamp.min(32767).max(-32768) as i16);
         }
     } else {
-        tmp.truncate(0);
+        tmp.clear();
         tmp.resize(src.len() / 2, 0);
     }
     device.queue(&tmp);
@@ -142,6 +147,9 @@ impl<'a> Decoder<'a> {
                         match self.decoder.decode(&mut self.dsupp, &pkt) {
                             Ok(frm) => {
                                 let buf = frm.get_buffer();
+                                if let NABufferType::None = buf {
+                                    return false;
+                                }
                                 if let Some(pts) = frm.ts.get_pts() {
                                     self.samplepos = NATimeInfo::ts_to_time(pts, u64::from(self.arate), frm.ts.tb_num, frm.ts.tb_den);
                                 }
@@ -208,9 +216,9 @@ fn format_time(ms: u64) -> String {
 impl Player {
     fn new() -> Self {
         let mut dmx_reg = RegisteredDemuxers::new();
-        nihav_register_all_demuxers(&mut dmx_reg);
+        allreg::register_all_demuxers(&mut dmx_reg);
         let mut dec_reg = RegisteredDecoders::new();
-        nihav_register_all_decoders(&mut dec_reg);
+        allreg::register_all_decoders(&mut dec_reg);
 
         unsafe {
             if sdl2_sys::SDL_Init(sdl2_sys::SDL_INIT_AUDIO) != 0 {
@@ -228,7 +236,7 @@ impl Player {
             buf:    Vec::new(),
         }
     }
-    fn play_file(&mut self, name: &str, cmd_receiver: &mpsc::Receiver<Command>) {
+    fn play_file(&mut self, name: &str, cmd_receiver: &mpsc::Receiver<Command>, start_time: NATimePoint) {
         let ret = File::open(name);
         if ret.is_err() {
             println!("error opening {}", name);
@@ -303,7 +311,7 @@ impl Player {
         let ch    = ainfo.channels;
 
         println!("Playing {} [{}Hz {}ch]", name, arate, ch);
-        let ret = AudioDevice::open(arate, ch.max(2));
+        let ret = AudioDevice::open(arate, ch.min(2));
         if ret.is_none() {
             println!("cannot open output");
             return;
@@ -331,6 +339,10 @@ impl Player {
         let mut refill_limit = arate * u32::from(dspec.channels);
         let underfill_limit = (arate * u32::from(dspec.channels) / 4).max(block_limit);
 
+        if start_time != NATimePoint::None {
+            let _ret = decoder.demuxer.seek(start_time);
+        }
+
         let mut eof = decoder.refill(&device);
         while !eof && device.size() < refill_limit {
             eof = decoder.refill(&device);
@@ -523,11 +535,29 @@ fn main() {
         return;
     }
 
-    for arg in args[1..].iter() {
-        player.play_file(arg, &cmd_receiver);
-        if player.ended {
-            break;
-        }
+    let mut aiter = args[1..].iter();
+    let mut start_time = NATimePoint::None;
+    while let Some(arg) = aiter.next() {
+        match arg.as_str() {
+            "-start" => {
+                if let Some(arg) = aiter.next() {
+                    if let Ok(val) = arg.parse() {
+                        start_time = val;
+                    } else {
+                        println!("invalid time");
+                    }
+                } else {
+                    println!("argument is required");
+                }
+            },
+            _ => {
+                player.play_file(arg, &cmd_receiver, start_time);
+                if player.ended {
+                    break;
+                }
+                start_time = NATimePoint::None;
+            },
+        };
     }
     cmd_state.restore();