videoplayer: allow custom scaling
authorKostya Shishkov <kostya.shiskov@gmail.com>
Mon, 2 Oct 2023 17:42:39 +0000 (19:42 +0200)
committerKostya Shishkov <kostya.shiskov@gmail.com>
Mon, 2 Oct 2023 17:42:39 +0000 (19:42 +0200)
videoplayer/src/main.rs

index e6952807130b28630fbb62d1ebf3217ce5ddc348..cd35eb5e8d2e6d8cb9aff0d314c2041e34abaf1e 100644 (file)
@@ -92,6 +92,41 @@ macro_rules! debug_log {
     ($log: expr; $blk: block) => {};
 }
 
+enum ScaleSize {
+    Auto,
+    Times(f32),
+    Fixed(usize, usize)
+}
+
+impl FromStr for ScaleSize {
+    type Err = ();
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        if matches!(s, "" | "auto") {
+            Ok(ScaleSize::Auto)
+        } else if s.ends_with('x') || s.ends_with('X') {
+            let factor = s[..s.len() - 1].parse::<f32>().map_err(|_| ())?;
+            if factor > 0.0 {
+                Ok(ScaleSize::Times(factor))
+            } else {
+                Err(())
+            }
+        } else if s.contains('x') | s.contains('X') {
+            let mut dims = if s.contains('x') { s.split('x') } else { s.split('X') };
+            let w = dims.next().unwrap();
+            let h = dims.next().unwrap();
+            let width  = w.parse::<usize>().map_err(|_| ())?;
+            let height = h.parse::<usize>().map_err(|_| ())?;
+            if width > 0 && height > 0 {
+                Ok(ScaleSize::Fixed(width, height))
+            } else {
+                Err(())
+            }
+        } else {
+            Err(())
+        }
+    }
+}
+
 pub enum PktSendEvent {
     Packet(NAPacket),
     GetFrames,
@@ -303,6 +338,7 @@ struct Player {
     has_audio:      bool,
     video_str:      u32,
     audio_str:      u32,
+    sc_size:        ScaleSize,
 
     vthreads:       usize,
     use_mt:         bool,
@@ -340,6 +376,7 @@ impl Player {
             has_audio:      false,
             video_str:      0,
             audio_str:      0,
+            sc_size:        ScaleSize::Auto,
 
             vthreads:       3,
             use_mt:         true,
@@ -707,10 +744,26 @@ impl Player {
             return window;
         }
 
-        while (width <= 384) && (height <= 288) {
-            width <<= 1;
-            height <<= 1;
-        }
+        match self.sc_size {
+            ScaleSize::Auto => {
+                while (width <= 384) && (height <= 288) {
+                    width <<= 1;
+                    height <<= 1;
+                }
+            },
+            ScaleSize::Times(factor) => {
+                let nw = ((width  as f32) * factor).ceil() as usize;
+                let nh = ((height as f32) * factor).ceil() as usize;
+                if nw > 0 && nh > 0 {
+                    width  = nw;
+                    height = nh;
+                }
+            },
+            ScaleSize::Fixed(w, h) => {
+                width  = w;
+                height = h;
+            },
+        };
 
         // prepare playback structure
         let mut new_vcontrol = VideoControl::new(video_dec, width, height, tb_num, tb_den);
@@ -927,6 +980,15 @@ fn main() {
                     }
                 }
             },
+            "-scale" => {
+                if let Some(arg) = aiter.next() {
+                    if let Ok(ssize) = arg.parse::<ScaleSize>() {
+                        player.sc_size = ssize;
+                    } else {
+                        println!("invalid scale size");
+                    }
+                }
+            },
             _ => {
                 window = player.play(window, arg, seek_time);
                 if player.end { break; }