1 use std::time::Instant;
3 const XOFF: usize = 10;
15 pub fn new() -> Self { Self::default() }
16 pub fn reset(&mut self) {
21 pub fn set_duration(&mut self, duration: u64) { self.duration = duration; }
22 pub fn toggle(&mut self) {
23 if self.time.is_none() {
24 self.time = Some(Instant::now());
29 pub fn update(&mut self) {
30 if let Some(time) = self.time {
31 if time.elapsed().as_millis() > 3000 {
36 pub fn is_active(&self) -> bool { self.time.is_some() }
37 pub fn prepare(&mut self, ts: u64) {
39 if !self.is_active() {
42 let mut time_str = format_time(ts);
43 if self.duration != 0 {
45 time_str += format_time(self.duration).as_str();
48 let mut syms = Vec::with_capacity(time_str.len());
49 for chr in time_str.chars() {
50 let sym_idx = OSD_GLYPHS.iter().position(|el| el.sym == chr).unwrap_or(0);
51 w += OSD_GLYPHS[sym_idx].width;
56 self.text.resize(self.text_stride * 16, 0);
58 for &sym_idx in syms.iter() {
59 let glyph = &OSD_GLYPHS[sym_idx];
60 let mut mask = 1 << (glyph.width - 1);
62 for (dline, (bits, mbits)) in self.text.chunks_exact_mut(w).zip(glyph.bits.iter().zip(glyph.mask.iter())) {
63 let wval = (bits & mask) != 0;
64 let bval = (mbits & mask) != 0;
65 dline[pos] = if wval { 2 } else if bval { 1 } else { 0 };
75 pub fn draw_yuv(&self, buffer: &mut [u8], pitch: usize) {
76 if !self.is_active() || self.text_stride == 0 {
79 for (dline, sline) in buffer.chunks_exact_mut(pitch).skip(YOFF).zip(self.text.chunks_exact(self.text_stride)) {
80 for (dst, &src) in dline.iter_mut().skip(XOFF).zip(sline.iter()) {
89 pub fn draw_rgb(&self, buffer: &mut [u8], pitch: usize) {
90 if !self.is_active() || self.text_stride == 0 {
93 for (dline, sline) in buffer.chunks_exact_mut(pitch).skip(YOFF).zip(self.text.chunks_exact(self.text_stride)) {
94 for (dst, &src) in dline.chunks_exact_mut(3).skip(XOFF).zip(sline.iter()) {
96 2 => dst.copy_from_slice(&[0xFF, 0xFF, 0xFF]),
97 1 => dst.copy_from_slice(&[0x00, 0x00, 0x00]),
105 fn format_time(ms: u64) -> String {
107 let (min, s) = (s / 60, s % 60);
108 let (h, min) = (min / 60, min % 60);
111 format!("0:{:02}", s)
113 format!("{}:{:02}", min, s)
116 format!("{}:{:02}:{:02}", h, min, s)
127 const OSD_GLYPHS: &[Glyph] = &[