]>
Commit | Line | Data |
---|---|---|
8686f9f6 KS |
1 | use std::time::Instant; |
2 | ||
3 | #[derive(Default)] | |
4 | pub struct OSD { | |
5 | time: Option<Instant>, | |
6 | text: Vec<u8>, | |
7 | text_stride: usize, | |
8 | } | |
9 | ||
10 | impl OSD { | |
11 | pub fn new() -> Self { Self::default() } | |
12 | pub fn toggle(&mut self) { | |
13 | if self.time.is_none() { | |
14 | self.time = Some(Instant::now()); | |
15 | } else { | |
16 | self.time = None; | |
17 | } | |
18 | } | |
19 | pub fn update(&mut self) { | |
20 | if let Some(time) = self.time { | |
21 | if time.elapsed().as_millis() > 3000 { | |
22 | self.time = None; | |
23 | } | |
24 | } | |
25 | } | |
26 | pub fn is_active(&self) -> bool { self.time.is_some() } | |
27 | pub fn prepare(&mut self, ts: u64) { | |
28 | self.update(); | |
29 | if !self.is_active() { | |
30 | return; | |
31 | } | |
32 | let time_str = format_time(ts); | |
33 | let mut w = 0; | |
34 | let mut syms = Vec::with_capacity(time_str.len()); | |
35 | for chr in time_str.chars() { | |
36 | let sym_idx = OSD_GLYPHS.iter().position(|el| el.sym == chr).unwrap_or(0); | |
37 | w += OSD_GLYPHS[sym_idx].width; | |
38 | syms.push(sym_idx); | |
39 | } | |
40 | self.text_stride = w; | |
41 | if w > 0 { | |
42 | self.text.resize(self.text_stride * 16, 0); | |
43 | let mut pos = 0; | |
44 | for &sym_idx in syms.iter() { | |
45 | let glyph = &OSD_GLYPHS[sym_idx]; | |
46 | let mut mask = 1 << (glyph.width - 1); | |
47 | while mask > 0 { | |
48 | for (dline, (bits, mbits)) in self.text.chunks_exact_mut(w).zip(glyph.bits.iter().zip(glyph.mask.iter())) { | |
49 | let wval = (bits & mask) != 0; | |
50 | let bval = (mbits & mask) != 0; | |
51 | dline[pos] = if wval { 2 } else if bval { 1 } else { 0 }; | |
52 | } | |
53 | mask >>= 1; | |
54 | pos += 1; | |
55 | } | |
56 | } | |
57 | } else { | |
58 | self.text.clear(); | |
59 | } | |
60 | } | |
61 | pub fn draw_yuv(&self, buffer: &mut [u8], pitch: usize) { | |
62 | if !self.is_active() || self.text_stride == 0 { | |
63 | return; | |
64 | } | |
65 | for (dline, sline) in buffer.chunks_exact_mut(pitch).zip(self.text.chunks_exact(self.text_stride)) { | |
66 | for (dst, &src) in dline.iter_mut().zip(sline.iter()) { | |
67 | match src { | |
68 | 2 => *dst = 0xFF, | |
69 | 1 => *dst = 0x00, | |
70 | _ => {}, | |
71 | }; | |
72 | } | |
73 | } | |
74 | } | |
75 | pub fn draw_rgb(&self, buffer: &mut [u8], pitch: usize) { | |
76 | if !self.is_active() || self.text_stride == 0 { | |
77 | return; | |
78 | } | |
79 | for (dline, sline) in buffer.chunks_exact_mut(pitch).zip(self.text.chunks_exact(self.text_stride)) { | |
80 | for (dst, &src) in dline.chunks_exact_mut(3).zip(sline.iter()) { | |
81 | match src { | |
82 | 2 => dst.copy_from_slice(&[0xFF, 0xFF, 0xFF]), | |
83 | 1 => dst.copy_from_slice(&[0x00, 0x00, 0x00]), | |
84 | _ => {}, | |
85 | }; | |
86 | } | |
87 | } | |
88 | } | |
89 | } | |
90 | ||
91 | fn format_time(ms: u64) -> String { | |
92 | let s = ms / 1000; | |
93 | let (min, s) = (s / 60, s % 60); | |
94 | let (h, min) = (min / 60, min % 60); | |
95 | if h == 0 { | |
96 | if min == 0 { | |
97 | format!("{}", s) | |
98 | } else { | |
99 | format!("{}:{:02}", min, s) | |
100 | } | |
101 | } else { | |
102 | format!("{}:{:02}:{:02}", h, min, s) | |
103 | } | |
104 | } | |
105 | ||
106 | struct Glyph { | |
107 | width: usize, | |
108 | sym: char, | |
109 | bits: [u16; 16], | |
110 | mask: [u16; 16], | |
111 | } | |
112 | ||
113 | const OSD_GLYPHS: &[Glyph] = &[ | |
114 | Glyph { | |
115 | width: 16, | |
116 | sym: '?', | |
117 | bits: [ | |
118 | 0b_0000000000000000, | |
119 | 0b_0000111111100000, | |
120 | 0b_0001100001110000, | |
121 | 0b_0000000000110000, | |
122 | 0b_0000000000110000, | |
123 | 0b_0000000001100000, | |
124 | 0b_0000000011000000, | |
125 | 0b_0000000110000000, | |
126 | 0b_0000000110000000, | |
127 | 0b_0000000110000000, | |
128 | 0b_0000000000000000, | |
129 | 0b_0000000000000000, | |
130 | 0b_0000000000000000, | |
131 | 0b_0000001111000000, | |
132 | 0b_0000001111000000, | |
133 | 0b_0000000000000000 | |
134 | ], | |
135 | mask: [ | |
136 | 0b_0000111111100000, | |
137 | 0b_0001111111110000, | |
138 | 0b_0011111111111000, | |
139 | 0b_0001100001111000, | |
140 | 0b_0000000001111000, | |
141 | 0b_0000000011110000, | |
142 | 0b_0000000111100000, | |
143 | 0b_0000001111000000, | |
144 | 0b_0000001111000000, | |
145 | 0b_0000001111000000, | |
146 | 0b_0000000110000000, | |
147 | 0b_0000000000000000, | |
148 | 0b_0000001111000000, | |
149 | 0b_0000011111100000, | |
150 | 0b_0000011111100000, | |
151 | 0b_0000001111000000 | |
152 | ], | |
153 | }, | |
154 | Glyph { | |
155 | width: 14, | |
156 | sym: '0', | |
157 | bits: [ | |
158 | 0b_0000000000000000, | |
159 | 0b_0000000000000000, | |
160 | 0b_0000000000000000, | |
161 | 0b_0000000111100000, | |
162 | 0b_0000001000010000, | |
163 | 0b_0000010000011000, | |
164 | 0b_0000010000101000, | |
165 | 0b_0000010001001000, | |
166 | 0b_0000010010001000, | |
167 | 0b_0000010100001000, | |
168 | 0b_0000011000001000, | |
169 | 0b_0000001000010000, | |
170 | 0b_0000000111100000, | |
171 | 0b_0000000000000000, | |
172 | 0b_0000000000000000, | |
173 | 0b_0000000000000000 | |
174 | ], | |
175 | mask: [ | |
176 | 0b_0000000000000000, | |
177 | 0b_0000000000000000, | |
178 | 0b_0000001111110000, | |
179 | 0b_0000011000011000, | |
180 | 0b_0000110111101100, | |
181 | 0b_0000101000100100, | |
182 | 0b_0000101001010100, | |
183 | 0b_0000101010110100, | |
184 | 0b_0000101101010100, | |
185 | 0b_0000101010010100, | |
186 | 0b_0000100100110100, | |
187 | 0b_0000110111101100, | |
188 | 0b_0000011000011000, | |
189 | 0b_0000001111110000, | |
190 | 0b_0000000000000000, | |
191 | 0b_0000000000000000 | |
192 | ], | |
193 | }, | |
194 | Glyph { | |
195 | width: 12, | |
196 | sym: '1', | |
197 | bits: [ | |
198 | 0b_0000000000000000, | |
199 | 0b_0000000000000000, | |
200 | 0b_0000000000000000, | |
201 | 0b_0000000001100000, | |
202 | 0b_0000000011100000, | |
203 | 0b_0000000110100000, | |
204 | 0b_0000000000100000, | |
205 | 0b_0000000000100000, | |
206 | 0b_0000000000100000, | |
207 | 0b_0000000000100000, | |
208 | 0b_0000000000100000, | |
209 | 0b_0000000000100000, | |
210 | 0b_0000000011111000, | |
211 | 0b_0000000000000000, | |
212 | 0b_0000000000000000, | |
213 | 0b_0000000000000000 | |
214 | ], | |
215 | mask: [ | |
216 | 0b_0000000000000000, | |
217 | 0b_0000000000000000, | |
218 | 0b_0000000001110000, | |
219 | 0b_0000000010010000, | |
220 | 0b_0000000100010000, | |
221 | 0b_0000001001010000, | |
222 | 0b_0000001111010000, | |
223 | 0b_0000000001010000, | |
224 | 0b_0000000001010000, | |
225 | 0b_0000000001010000, | |
226 | 0b_0000000001010000, | |
227 | 0b_0000000111011100, | |
228 | 0b_0000000100000100, | |
229 | 0b_0000000111111100, | |
230 | 0b_0000000000000000, | |
231 | 0b_0000000000000000 | |
232 | ], | |
233 | }, | |
234 | Glyph { | |
235 | width: 12, | |
236 | sym: '2', | |
237 | bits: [ | |
238 | 0b_0000000000000000, | |
239 | 0b_0000000000000000, | |
240 | 0b_0000000011100000, | |
241 | 0b_0000000100010000, | |
242 | 0b_0000000000001000, | |
243 | 0b_0000000000001000, | |
244 | 0b_0000000000001000, | |
245 | 0b_0000000000010000, | |
246 | 0b_0000000000100000, | |
247 | 0b_0000000001000000, | |
248 | 0b_0000000010000000, | |
249 | 0b_0000000100000000, | |
250 | 0b_0000000111111000, | |
251 | 0b_0000000000000000, | |
252 | 0b_0000000000000000, | |
253 | 0b_0000000000000000 | |
254 | ], | |
255 | mask: [ | |
256 | 0b_0000000000000000, | |
257 | 0b_0000000011100000, | |
258 | 0b_0000000100010000, | |
259 | 0b_0000001011101000, | |
260 | 0b_0000001100010100, | |
261 | 0b_0000000000010100, | |
262 | 0b_0000000000010100, | |
263 | 0b_0000000000101000, | |
264 | 0b_0000000001010000, | |
265 | 0b_0000000010100000, | |
266 | 0b_0000000101000000, | |
267 | 0b_0000001011111100, | |
268 | 0b_0000001000000100, | |
269 | 0b_0000001111111100, | |
270 | 0b_0000000000000000, | |
271 | 0b_0000000000000000 | |
272 | ], | |
273 | }, | |
274 | Glyph { | |
275 | width: 12, | |
276 | sym: '3', | |
277 | bits: [ | |
278 | 0b_0000000000000000, | |
279 | 0b_0000000000000000, | |
280 | 0b_0000000000000000, | |
281 | 0b_0000000111111000, | |
282 | 0b_0000000100001000, | |
283 | 0b_0000000000010000, | |
284 | 0b_0000000000100000, | |
285 | 0b_0000000001000000, | |
286 | 0b_0000000000100000, | |
287 | 0b_0000000000010000, | |
288 | 0b_0000000000001000, | |
289 | 0b_0000000100001000, | |
290 | 0b_0000000011110000, | |
291 | 0b_0000000000000000, | |
292 | 0b_0000000000000000, | |
293 | 0b_0000000000000000 | |
294 | ], | |
295 | mask: [ | |
296 | 0b_0000000000000000, | |
297 | 0b_0000000000000000, | |
298 | 0b_0000001111111100, | |
299 | 0b_0000001000000100, | |
300 | 0b_0000001011110100, | |
301 | 0b_0000001110101000, | |
302 | 0b_0000000001010000, | |
303 | 0b_0000000010100000, | |
304 | 0b_0000000001010000, | |
305 | 0b_0000000000101000, | |
306 | 0b_0000001100010100, | |
307 | 0b_0000001011110100, | |
308 | 0b_0000000100001000, | |
309 | 0b_0000000011110000, | |
310 | 0b_0000000000000000, | |
311 | 0b_0000000000000000 | |
312 | ], | |
313 | }, | |
314 | Glyph { | |
315 | width: 12, | |
316 | sym: '4', | |
317 | bits: [ | |
318 | 0b_0000000000000000, | |
319 | 0b_0000000000000000, | |
320 | 0b_0000000000000000, | |
321 | 0b_0000000000011000, | |
322 | 0b_0000000000101000, | |
323 | 0b_0000000001001000, | |
324 | 0b_0000000010001000, | |
325 | 0b_0000000100001000, | |
326 | 0b_0000000111111000, | |
327 | 0b_0000000000001000, | |
328 | 0b_0000000000001000, | |
329 | 0b_0000000000001000, | |
330 | 0b_0000000000001000, | |
331 | 0b_0000000000000000, | |
332 | 0b_0000000000000000, | |
333 | 0b_0000000000000000 | |
334 | ], | |
335 | mask: [ | |
336 | 0b_0000000000000000, | |
337 | 0b_0000000000000000, | |
338 | 0b_0000000000011100, | |
339 | 0b_0000000000100100, | |
340 | 0b_0000000001010100, | |
341 | 0b_0000000010110100, | |
342 | 0b_0000000101010100, | |
343 | 0b_0000001011110100, | |
344 | 0b_0000001000000100, | |
345 | 0b_0000001111110100, | |
346 | 0b_0000000000010100, | |
347 | 0b_0000000000010100, | |
348 | 0b_0000000000010100, | |
349 | 0b_0000000000011100, | |
350 | 0b_0000000000000000, | |
351 | 0b_0000000000000000 | |
352 | ], | |
353 | }, | |
354 | Glyph { | |
355 | width: 12, | |
356 | sym: '5', | |
357 | bits: [ | |
358 | 0b_0000000000000000, | |
359 | 0b_0000000000000000, | |
360 | 0b_0000000000000000, | |
361 | 0b_0000000111111000, | |
362 | 0b_0000000100001000, | |
363 | 0b_0000000100000000, | |
364 | 0b_0000000010000000, | |
365 | 0b_0000000001000000, | |
366 | 0b_0000000000110000, | |
367 | 0b_0000000000001000, | |
368 | 0b_0000000000001000, | |
369 | 0b_0000000100001000, | |
370 | 0b_0000000011110000, | |
371 | 0b_0000000000000000, | |
372 | 0b_0000000000000000, | |
373 | 0b_0000000000000000 | |
374 | ], | |
375 | mask: [ | |
376 | 0b_0000000000000000, | |
377 | 0b_0000000000000000, | |
378 | 0b_0000001111111100, | |
379 | 0b_0000001000000100, | |
380 | 0b_0000001011110100, | |
381 | 0b_0000001010011100, | |
382 | 0b_0000000101000000, | |
383 | 0b_0000000010110000, | |
384 | 0b_0000000001001000, | |
385 | 0b_0000000000110100, | |
386 | 0b_0000001100010100, | |
387 | 0b_0000001011110100, | |
388 | 0b_0000000100001000, | |
389 | 0b_0000000011110000, | |
390 | 0b_0000000000000000, | |
391 | 0b_0000000000000000 | |
392 | ], | |
393 | }, | |
394 | Glyph { | |
395 | width: 12, | |
396 | sym: '6', | |
397 | bits: [ | |
398 | 0b_0000000000000000, | |
399 | 0b_0000000000000000, | |
400 | 0b_0000000000000000, | |
401 | 0b_0000000011110000, | |
402 | 0b_0000000100001000, | |
403 | 0b_0000000100000000, | |
404 | 0b_0000000100000000, | |
405 | 0b_0000000100000000, | |
406 | 0b_0000000111110000, | |
407 | 0b_0000000100001000, | |
408 | 0b_0000000100001000, | |
409 | 0b_0000000100001000, | |
410 | 0b_0000000011110000, | |
411 | 0b_0000000000000000, | |
412 | 0b_0000000000000000, | |
413 | 0b_0000000000000000 | |
414 | ], | |
415 | mask: [ | |
416 | 0b_0000000000000000, | |
417 | 0b_0000000000000000, | |
418 | 0b_0000000011110000, | |
419 | 0b_0000000100001000, | |
420 | 0b_0000001011110100, | |
421 | 0b_0000001010011100, | |
422 | 0b_0000001010000000, | |
423 | 0b_0000001011110000, | |
424 | 0b_0000001000001000, | |
425 | 0b_0000001011110100, | |
426 | 0b_0000001010010100, | |
427 | 0b_0000001011110100, | |
428 | 0b_0000000100001000, | |
429 | 0b_0000000011110000, | |
430 | 0b_0000000000000000, | |
431 | 0b_0000000000000000 | |
432 | ], | |
433 | }, | |
434 | Glyph { | |
435 | width: 12, | |
436 | sym: '7', | |
437 | bits: [ | |
438 | 0b_0000000000000000, | |
439 | 0b_0000000000000000, | |
440 | 0b_0000000000000000, | |
441 | 0b_0000001111111000, | |
442 | 0b_0000001000001000, | |
443 | 0b_0000000000001000, | |
444 | 0b_0000000000010000, | |
445 | 0b_0000000000010000, | |
446 | 0b_0000000000010000, | |
447 | 0b_0000000000100000, | |
448 | 0b_0000000000100000, | |
449 | 0b_0000000001100000, | |
450 | 0b_0000000001000000, | |
451 | 0b_0000000000000000, | |
452 | 0b_0000000000000000, | |
453 | 0b_0000000000000000 | |
454 | ], | |
455 | mask: [ | |
456 | 0b_0000000000000000, | |
457 | 0b_0000000000000000, | |
458 | 0b_0000011111111100, | |
459 | 0b_0000010000000100, | |
460 | 0b_0000010111110100, | |
461 | 0b_0000011100010100, | |
462 | 0b_0000000000101000, | |
463 | 0b_0000000000101000, | |
464 | 0b_0000000000101000, | |
465 | 0b_0000000001010000, | |
466 | 0b_0000000001010000, | |
467 | 0b_0000000010010000, | |
468 | 0b_0000000010100000, | |
469 | 0b_0000000011100000, | |
470 | 0b_0000000000000000, | |
471 | 0b_0000000000000000 | |
472 | ], | |
473 | }, | |
474 | Glyph { | |
475 | width: 12, | |
476 | sym: '8', | |
477 | bits: [ | |
478 | 0b_0000000000000000, | |
479 | 0b_0000000000000000, | |
480 | 0b_0000000000000000, | |
481 | 0b_0000000011110000, | |
482 | 0b_0000000100001000, | |
483 | 0b_0000000100001000, | |
484 | 0b_0000000100001000, | |
485 | 0b_0000000011110000, | |
486 | 0b_0000000010010000, | |
487 | 0b_0000000100001000, | |
488 | 0b_0000000100001000, | |
489 | 0b_0000000100001000, | |
490 | 0b_0000000011110000, | |
491 | 0b_0000000000000000, | |
492 | 0b_0000000000000000, | |
493 | 0b_0000000000000000 | |
494 | ], | |
495 | mask: [ | |
496 | 0b_0000000000000000, | |
497 | 0b_0000000000000000, | |
498 | 0b_0000000011110000, | |
499 | 0b_0000000100001000, | |
500 | 0b_0000001011110100, | |
501 | 0b_0000001010010100, | |
502 | 0b_0000001011110100, | |
503 | 0b_0000000100001000, | |
504 | 0b_0000000101101000, | |
505 | 0b_0000001010010100, | |
506 | 0b_0000001010010100, | |
507 | 0b_0000001011110100, | |
508 | 0b_0000000100001000, | |
509 | 0b_0000000011110000, | |
510 | 0b_0000000000000000, | |
511 | 0b_0000000000000000 | |
512 | ], | |
513 | }, | |
514 | Glyph { | |
515 | width: 12, | |
516 | sym: '9', | |
517 | bits: [ | |
518 | 0b_0000000000000000, | |
519 | 0b_0000000000000000, | |
520 | 0b_0000000000000000, | |
521 | 0b_0000000011110000, | |
522 | 0b_0000000100001000, | |
523 | 0b_0000000100001000, | |
524 | 0b_0000000100001000, | |
525 | 0b_0000000011111000, | |
526 | 0b_0000000000001000, | |
527 | 0b_0000000000001000, | |
528 | 0b_0000000000001000, | |
529 | 0b_0000000100001000, | |
530 | 0b_0000000011110000, | |
531 | 0b_0000000000000000, | |
532 | 0b_0000000000000000, | |
533 | 0b_0000000000000000 | |
534 | ], | |
535 | mask: [ | |
536 | 0b_0000000000000000, | |
537 | 0b_0000000000000000, | |
538 | 0b_0000000011110000, | |
539 | 0b_0000000100001000, | |
540 | 0b_0000001011110100, | |
541 | 0b_0000001010010100, | |
542 | 0b_0000001011110100, | |
543 | 0b_0000000100000100, | |
544 | 0b_0000000011110100, | |
545 | 0b_0000000000010100, | |
546 | 0b_0000001110010100, | |
547 | 0b_0000001011110100, | |
548 | 0b_0000000100001000, | |
549 | 0b_0000000011110000, | |
550 | 0b_0000000000000000, | |
551 | 0b_0000000000000000 | |
552 | ], | |
553 | }, | |
554 | Glyph { | |
555 | width: 9, | |
556 | sym: ':', | |
557 | bits: [ | |
558 | 0b_0000000000000000, | |
559 | 0b_0000000000000000, | |
560 | 0b_0000000000000000, | |
561 | 0b_0000000000000000, | |
562 | 0b_0000000000000000, | |
563 | 0b_0000000000111000, | |
564 | 0b_0000000000111000, | |
565 | 0b_0000000000000000, | |
566 | 0b_0000000000000000, | |
567 | 0b_0000000000000000, | |
568 | 0b_0000000000000000, | |
569 | 0b_0000000000111000, | |
570 | 0b_0000000000111000, | |
571 | 0b_0000000000000000, | |
572 | 0b_0000000000000000, | |
573 | 0b_0000000000000000 | |
574 | ], | |
575 | mask: [ | |
576 | 0b_0000000000000000, | |
577 | 0b_0000000000000000, | |
578 | 0b_0000000000000000, | |
579 | 0b_0000000000000000, | |
580 | 0b_0000000000111000, | |
581 | 0b_0000000001111100, | |
582 | 0b_0000000001111100, | |
583 | 0b_0000000000111000, | |
584 | 0b_0000000000000000, | |
585 | 0b_0000000000000000, | |
586 | 0b_0000000000111000, | |
587 | 0b_0000000001111100, | |
588 | 0b_0000000001111100, | |
589 | 0b_0000000000111000, | |
590 | 0b_0000000000000000, | |
591 | 0b_0000000000000000 | |
592 | ], | |
593 | }, | |
594 | Glyph { | |
595 | width: 12, | |
596 | sym: ' ', | |
597 | bits: [ | |
598 | 0b_0000000000000000, | |
599 | 0b_0000000000000000, | |
600 | 0b_0000000000000000, | |
601 | 0b_0000000000000000, | |
602 | 0b_0000000000000000, | |
603 | 0b_0000000000000000, | |
604 | 0b_0000000000000000, | |
605 | 0b_0000000000000000, | |
606 | 0b_0000000000000000, | |
607 | 0b_0000000000000000, | |
608 | 0b_0000000000000000, | |
609 | 0b_0000000000000000, | |
610 | 0b_0000000000000000, | |
611 | 0b_0000000000000000, | |
612 | 0b_0000000000000000, | |
613 | 0b_0000000000000000 | |
614 | ], | |
615 | mask: [ | |
616 | 0b_0000000000000000, | |
617 | 0b_0000000000000000, | |
618 | 0b_0000000000000000, | |
619 | 0b_0000000000000000, | |
620 | 0b_0000000000000000, | |
621 | 0b_0000000000000000, | |
622 | 0b_0000000000000000, | |
623 | 0b_0000000000000000, | |
624 | 0b_0000000000000000, | |
625 | 0b_0000000000000000, | |
626 | 0b_0000000000000000, | |
627 | 0b_0000000000000000, | |
628 | 0b_0000000000000000, | |
629 | 0b_0000000000000000, | |
630 | 0b_0000000000000000, | |
631 | 0b_0000000000000000 | |
632 | ], | |
633 | }, | |
634 | ]; |