74a8a95b3e3f356acdf10ea064c7d4e153feea20
[nihav-player.git] / videoplayer / src / osd.rs
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 ];