]> git.nihav.org Git - nihav-player.git/commitdiff
videoplayer: rework displaying stream info for a bit nicer look
authorKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 24 Jan 2026 17:15:02 +0000 (18:15 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 24 Jan 2026 17:15:02 +0000 (18:15 +0100)
videoplayer/src/main.rs

index f426450b50a9a001f5699047c2f50911fe9068ab..78462f87463f97102d7771cdf74f320ffaf19ef9 100644 (file)
@@ -170,6 +170,66 @@ fn format_time(ms: u64) -> String {
     }
 }
 
+fn gcd(mut a: u32, mut b: u32) -> u32 {
+    while a != b {
+        if a > b {
+            a -= b;
+        } else {
+            b -= a;
+        }
+    }
+    a
+}
+
+fn format_stream_info(num: usize, stream: &NAStream) -> String {
+    let mut ret = String::new();
+    let mtype = stream.get_media_type();
+    let info = stream.get_info();
+    ret += format!("stream {num} - {}@{} {} (", stream.get_media_type(), stream.get_id(), info.get_name()).as_str();
+    match info.get_properties() {
+        NACodecTypeInfo::Video(vinfo) => {
+            ret += format!("{}x{} ", vinfo.width, vinfo.height).as_str();
+        },
+        NACodecTypeInfo::Audio(ainfo) => {
+            ret += format!("{} Hz {} ch", ainfo.sample_rate, ainfo.channels).as_str();
+        },
+        NACodecTypeInfo::None => {},
+    }
+    if mtype != StreamType::Audio {
+        let (mut tb_num, mut tb_den) = stream.get_timebase();
+        if tb_num != 0 && tb_den != 0 {
+            let common = gcd(tb_num, tb_den);
+            tb_num /= common;
+            tb_den /= common;
+
+            if tb_num == 1 && tb_den > 200 {
+                ret += "VFR";
+            } else {
+                let inum = tb_den / tb_num;
+
+                if tb_num == 1 {
+                    ret += tb_den.to_string().as_str();
+                } else if (tb_den % tb_num) == 0 {
+                    ret += inum.to_string().as_str();
+                } else if tb_num < 100 {
+                    if inum > 0 {
+                        ret += inum.to_string().as_str();
+                    }
+                    ret += format!("{}/{tb_num}", tb_den % tb_num).as_str();
+                } else {
+                    ret += format!("~{inum}.{:02}", (tb_den % tb_num) * 100 / tb_num).as_str();
+                }
+                ret += " fps";
+            }
+        } else {
+            ret += format!(" timebase {tb_num}/{tb_den}").as_str();
+        }
+    }
+    ret += ")";
+
+    ret
+}
+
 const FRAME_QUEUE_LEN: usize = 25;
 const MAX_VOLUME: usize = 400;
 
@@ -735,10 +795,11 @@ impl Player {
             let info = s.get_info();
             let decfunc = dec_reg.find_decoder(info.get_name());
             let decfunc_mt = mtdec_reg.find_decoder(info.get_name());
+            let stream_info = format_stream_info(i, &s);
             if !self.quiet {
-                println!("stream {} - {} {}", i, s, info.get_name());
+                println!("{stream_info}");
             }
-            debug_log!(self; {format!(" stream {} - {} {}", i, s, info.get_name())});
+            debug_log!(self; {stream_info});
             let str_id = s.get_id();
             if info.is_video() {
                 if self.force_vstr.is_some() && self.force_vstr != Some(str_id) {