MythTV  master
vbi.cpp
Go to the documentation of this file.
1 // POSIX headers
2 #include <unistd.h>
3 #include <fcntl.h>
4 
5 #include <sys/ioctl.h>
6 
7 // ANSI C++ headers
8 #include <cmath>
9 #include <cstdarg>
10 #include <cstddef>
11 #include <cstdio>
12 #include <cstdlib>
13 #include <cstring>
14 
15 #ifdef USING_V4L2
16 #include <linux/videodev2.h>
17 #endif // USING_V4L2
18 
19 // vbitext headers
20 #include "captions/vbilut.h"
21 #include "vbi.h"
22 #include "vt.h"
23 
24 #define FAC (1<<16) // factor for fix-point arithmetic
25 
26 static unsigned char *rawbuf = nullptr;// one common buffer for raw vbi data.
27 #ifdef USING_V4L2
28 static int rawbuf_size; // its current size
29 #endif // USING_V4L2
30 
31 /***** bttv api *****/
32 #define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int)
33 
34 
35 static void
36 error(const char *str, ...)
37 {
38  va_list ap;
39 
40  va_start(ap, str);
41  vfprintf(stderr, str, ap);
42  fprintf(stderr, "\n");
43  va_end(ap);
44 }
45 
46 
47 static int
48 chk_parity(uint8_t *p, int n)
49 {
50  int err = 0;
51 
52  for (err = 0; n--; p++)
53  {
54  if (hamm24par[0][*p] & 32)
55  *p &= 0x7f;
56  else
57  *p = BAD_CHAR, err++;
58  }
59  return err;
60 }
61 
62 static void
64 {
65  int i = 0;
66 
67  // discard all in progress pages
68  for (i = 0; i < 8; ++i)
69  vbi->rpage[i].page->flags &= ~PG_ACTIVE;
70 }
71 
72 
73 // send an event to all clients
74 
75 static void
76 vbi_send(struct vbi *vbi, int type, int i1, int i2, int i3, void *p1)
77 {
78  struct vt_event ev {};
79  struct vbi_client *cl = nullptr;
80  struct vbi_client *cln = nullptr;
81 
82  ev.resource = vbi;
83  ev.type = type;
84  ev.i1 = i1;
85  ev.i2 = i2;
86  ev.i3 = i3;
87  ev.p1 = p1;
88 
89  for (cl = static_cast<vbi_client *>((void*)vbi->clients[0].first);
90  (cln = static_cast<vbi_client *>((void*)cl->node->next)) != nullptr;
91  cl = cln)
92  cl->handler(cl->data, &ev);
93 }
94 
95 static void
96 vbi_send_page(struct vbi *vbi, struct raw_page *rvtp, int page)
97 {
98  if (rvtp->page->flags & PG_ACTIVE)
99  {
100  if (rvtp->page->pgno % 256 != page)
101  {
102  struct vt_page *cvtp = nullptr;
103  rvtp->page->flags &= ~PG_ACTIVE;
104  do_enhancements(rvtp->enh, rvtp->page);
105 // if (vbi->cache)
106 // cvtp = vbi->cache->op->put(vbi->cache, rvtp->page);
107  vbi_send(vbi, EV_PAGE, 0, 0, 0, cvtp ?: rvtp->page);
108  }
109  }
110 }
111 
112 // fine tune pll
113 // this routines tries to adjust the sampling point of the decoder.
114 // it collects parity and hamming errors and moves the sampling point
115 // a 10th of a bitlength left or right.
116 
117 static constexpr int8_t PLL_SAMPLES { 4 }; // number of err vals to collect
118 static constexpr int8_t PLL_ERROR { 4 }; // if this err val is crossed, readjust
119 //static constexpr int8_t PLL_ADJUST { 4 }; // max/min adjust (10th of bitlength)
120 
121 static void
122 pll_add(struct vbi *vbi, int n, int err)
123 {
124  if (vbi->pll_fixed)
125  return;
126 
127  if (err > PLL_ERROR*2/3) // limit burst errors
128  err = PLL_ERROR*2/3;
129 
130  vbi->pll_err += err;
131  vbi->pll_cnt += n;
132  if (vbi->pll_cnt < PLL_SAMPLES)
133  return;
134 
135  if (vbi->pll_err > PLL_ERROR)
136  {
137  if (vbi->pll_err > vbi->pll_lerr)
138  vbi->pll_dir = -vbi->pll_dir;
139  vbi->pll_lerr = vbi->pll_err;
140 
141  vbi->pll_adj += vbi->pll_dir;
142  if (vbi->pll_adj < -PLL_ADJUST || vbi->pll_adj > PLL_ADJUST)
143  {
144  vbi->pll_adj = 0;
145  vbi->pll_dir = -1;
146  vbi->pll_lerr = 0;
147  }
148 
149 #ifdef DEBUG
150  printf("pll_adj = %2d\n", vbi->pll_adj);
151 #endif
152  }
153  vbi->pll_cnt = 0;
154  vbi->pll_err = 0;
155 }
156 
157 void
158 vbi_pll_reset(struct vbi *vbi, int fine_tune)
159 {
160  vbi->pll_fixed = static_cast<int>(fine_tune >= -PLL_ADJUST && fine_tune <= PLL_ADJUST);
161 
162  vbi->pll_err = 0;
163  vbi->pll_lerr = 0;
164  vbi->pll_cnt = 0;
165  vbi->pll_dir = -1;
166  vbi->pll_adj = 0;
167  if (vbi->pll_fixed)
168  vbi->pll_adj = fine_tune;
169 #ifdef DEBUG
170  if (vbi->pll_fixed)
171  printf("pll_reset (fixed@%d)\n", vbi->pll_adj);
172  else
173  printf("pll_reset (auto)\n");
174 #endif
175 }
176 
177 // process one videotext packet
178 
179 static int
180 vt_line(struct vbi *vbi, unsigned char *p)
181 {
182  struct vt_page *cvtp = nullptr;
183  struct raw_page *rvtp = nullptr;
184  int err = 0;
185 
186  int hdr = hamm16(p, &err);
187  if (err & 0xf000)
188  return -4;
189 
190  int mag = hdr & 7;
191  int mag8 = mag?: 8;
192  int pkt = (hdr >> 3) & 0x1f;
193  p += 2;
194 
195  rvtp = vbi->rpage + mag;
196  cvtp = rvtp->page;
197 
198  switch (pkt)
199  {
200  case 0:
201  {
202  int b1 = hamm16(p, &err); // page number
203  int b2 = hamm16(p+2, &err); // subpage number + flags
204  int b3 = hamm16(p+4, &err); // subpage number + flags
205  int b4 = hamm16(p+6, &err); // language code + more flags
206 
207  if (vbi->ppage->page->flags & PG_MAGSERIAL)
208  vbi_send_page(vbi, vbi->ppage, b1);
209  vbi_send_page(vbi, rvtp, b1);
210 
211  if (err & 0xf000)
212  return 4;
213 
214  cvtp->errors = (err >> 8) + chk_parity(p + 8, 32);;
215  cvtp->pgno = mag8 * 256 + b1;
216  cvtp->subno = (b2 + b3 * 256) & 0x3f7f;
217  cvtp->lang = "\0\4\2\6\1\5\3\7"[b4 >> 5] + (isLatin1 ? 0 : 8);
218  cvtp->flags = b4 & 0x1f;
219  cvtp->flags |= b3 & 0xc0;
220  cvtp->flags |= (b2 & 0x80) >> 2;
221  cvtp->lines = 1;
222  cvtp->flof = 0;
223  vbi->ppage = rvtp;
224 
225  pll_add(vbi, 1, cvtp->errors);
226 
227  conv2latin(p + 8, 32, cvtp->lang);
228  vbi_send(vbi, EV_HEADER, cvtp->pgno, cvtp->subno, cvtp->flags, p);
229 
230  if (b1 == 0xff)
231  return 0;
232 
233  cvtp->flags |= PG_ACTIVE;
234  init_enhance(rvtp->enh);
235  memcpy(cvtp->data[0]+0, p, 40);
236  memset(cvtp->data[0]+40, ' ', sizeof(cvtp->data)-40);
237  return 0;
238  }
239 
240  case 1 ... 24:
241  {
242  pll_add(vbi, 1, err = chk_parity(p, 40));
243 
244  if (~cvtp->flags & PG_ACTIVE)
245  return 0;
246 
247  cvtp->errors += err;
248  cvtp->lines |= 1 << pkt;
249  conv2latin(p, 40, cvtp->lang);
250  memcpy(cvtp->data[pkt], p, 40);
251  return 0;
252  }
253  case 26:
254  {
255  if (~cvtp->flags & PG_ACTIVE)
256  return 0;
257 
258  int d = hamm8(p, &err);
259  if (err & 0xf000)
260  return 4;
261 
262  std::array<unsigned int,13> t {};
263  for (ptrdiff_t i = 0; i < 13; ++i)
264  t[i] = hamm24(p + 1 + 3*i, &err);
265  if (err & 0xf000)
266  return 4;
267 
268  //printf("enhance on %x/%x\n", cvtp->pgno, cvtp->subno);
269  add_enhance(rvtp->enh, d, t);
270  return 0;
271  }
272  case 27:
273  {
274  // FLOF data (FastText)
275  if (~cvtp->flags & PG_ACTIVE)
276  return 0; // -1 flushes all pages. we may never resync again :(
277 
278  int b1 = hamm8(p, &err);
279  int b2 = hamm8(p + 37, &err);
280  if (err & 0xf000)
281  return 4;
282  if (b1 != 0 || !(b2 & 8))
283  return 0;
284 
285  for (ptrdiff_t i = 0; i < 6; ++i)
286  {
287  err = 0;
288  b1 = hamm16(p+1+6*i, &err);
289  b2 = hamm16(p+3+6*i, &err);
290  int b3 = hamm16(p+5+6*i, &err);
291  if (err & 0xf000)
292  return 1;
293  int x = (b2 >> 7) | ((b3 >> 5) & 0x06);
294  cvtp->link[i].pgno = ((mag ^ x) ?: 8) * 256 + b1;
295  cvtp->link[i].subno = (b2 + b3 * 256) & 0x3f7f;
296  }
297  cvtp->flof = 1;
298  return 0;
299  }
300  case 30:
301  {
302  if (mag8 != 8)
303  return 0;
304 
305  p[0] = hamm8(p, &err); // designation code
306  p[1] = hamm16(p+1, &err); // initial page
307  p[3] = hamm16(p+3, &err); // initial subpage + mag
308  p[5] = hamm16(p+5, &err); // initial subpage + mag
309  if (err & 0xf000)
310  return 4;
311 
312  err += chk_parity(p+20, 20);
313  conv2latin(p+20, 20, 0);
314 
315  vbi_send(vbi, EV_XPACKET, mag8, pkt, err, p);
316  return 0;
317  }
318  default:
319  // unused at the moment...
320  //vbi_send(vbi, EV_XPACKET, mag8, pkt, err, p);
321  return 0;
322  }
323  return 0;
324 }
325 
326 
327 
328 // process one raw vbi line
329 
330 static int
331 vbi_line(struct vbi *vbi, const unsigned char *p)
332 {
333  std::array<unsigned char,43> data {};
334  std::array<int,2566> dt {};
335  std::array<int,6> hi {};
336  std::array<int,6> lo {};
337  int i = 0;
338  int n = 0;
339  int bpb = vbi->bpb;
340 
341  /* remove DC. edge-detector */
342  for (i = vbi->soc; i < vbi->eoc; ++i)
343  dt[i] = p[i+bpb/FAC] - p[i]; // amplifies the edges best.
344 
345  /* set barrier */
346  for (i = vbi->eoc; i < vbi->eoc+16; i += 2)
347  dt[i] = 100, dt[i+1] = -100;
348 
349  /* find 6 rising and falling edges */
350  for (i = vbi->soc, n = 0; n < 6; ++n)
351  {
352  while (dt[i] < 32)
353  i++;
354  hi[n] = i;
355  while (dt[i] > -32)
356  i++;
357  lo[n] = i;
358  }
359  if (i >= vbi->eoc)
360  return -1; // not enough periods found
361 
362  i = hi[5] - hi[1]; // length of 4 periods (8 bits)
363  if (i < vbi->bp8bl || i > vbi->bp8bh)
364  return -1; // bad frequency
365 
366  /* AGC and sync-reference */
367  unsigned char min = 255;
368  unsigned char max = 0;
369  int sync = 0;
370  for (i = hi[4]; i < hi[5]; ++i)
371  if (p[i] > max)
372  max = p[i], sync = i;
373  for (i = lo[4]; i < lo[5]; ++i)
374  if (p[i] < min)
375  min = p[i];
376  int thr = (min + max) / 2;
377 
378  p += sync;
379 
380  /* search start-byte 11100100 */
381  for (i = 4*bpb + vbi->pll_adj*bpb/10; i < 16*bpb; i += bpb)
382  {
383  if (p[i/FAC] > thr && p[(i+bpb)/FAC] > thr) // two ones is enough...
384  {
385  /* got it... */
386  data.fill(0);
387 
388  for (n = 0; n < 43*8; ++n, i += bpb)
389  if (p[i/FAC] > thr)
390  data[n/8] |= 1 << (n%8);
391 
392  if (data[0] != 0x27) // really 11100100? (rev order!)
393  return -1;
394 
395  if ((i = vt_line(vbi, data.data()+1)))
396  {
397  if (i < 0)
398  pll_add(vbi, 2, -i);
399  else
400  pll_add(vbi, 1, i);
401  }
402  return 0;
403  }
404  }
405  return -1;
406 }
407 
408 
409 
410 // called when new vbi data is waiting
411 
412 void
413 vbi_handler(struct vbi *vbi, [[maybe_unused]] int fd)
414 {
415  int n = 0;
416  unsigned int seq = 0;
417 
418  n = read(vbi->fd, rawbuf, vbi->bufsize);
419 
420  if (dl_empty(vbi->clients))
421  return;
422 
423  if (n != vbi->bufsize)
424  return;
425 
426  seq = *(unsigned int *)&rawbuf[n - 4];
427  if (vbi->seq+1 != seq)
428  {
429  out_of_sync(vbi);
430  if (seq < 3 && vbi->seq >= 3)
431  vbi_reset(vbi);
432  }
433  vbi->seq = seq;
434 
435  if (seq > 1) // the first may contain data from prev channel
436  {
437 #if 1
438  for (int i = 0; i+vbi->bpl <= n; i += vbi->bpl)
439  vbi_line(vbi, rawbuf + i);
440 #else
441  /* work-around for old saa7134 driver versions (prior 0.2.6) */
442  for (int i = 16 * vbi->bpl; i + vbi->bpl <= n; i += vbi->bpl)
443  vbi_line(vbi, rawbuf + i);
444 
445  for (int i = 0; i + vbi->bpl <= 16 * vbi->bpl; i += vbi->bpl)
446  vbi_line(vbi, rawbuf + i);
447 #endif
448  }
449 }
450 
451 
452 
453 int
454 vbi_add_handler(struct vbi *vbi, vbic_handler handler, void *data)
455 {
456  struct vbi_client *cl = nullptr;
457 
458  if (!(cl = new struct vbi_client))
459  return -1;
460  cl->handler = handler;
461  cl->data = data;
462  // cl is not leaking, the first struct element has the same address
463  // as the struct
465  return 0; // cppcheck-suppress memleak
466 }
467 
468 
469 
470 void
472 {
473  struct vbi_client *cl = nullptr;
474 
475  for (cl = static_cast<vbi_client*>((void*)vbi->clients->first);
476  cl->node->next != nullptr;
477  cl = static_cast<vbi_client*>((void*)cl->node->next))
478  {
479  if (cl->handler == handler && cl->data == data)
480  {
481  dl_remove(cl->node);
482  delete cl;
483  break;
484  }
485  }
486 }
487 
488 #ifdef USING_V4L2
489 static int
490 set_decode_parms(struct vbi *vbi, struct v4l2_vbi_format *p)
491 {
492  if (p->sample_format != V4L2_PIX_FMT_GREY)
493  {
494  fprintf(stderr, "got pix fmt %x\n", p->sample_format);
495  error("v4l2: unsupported vbi data format");
496  return -1;
497  }
498 
499  // some constants from the standard:
500  // horizontal frequency fh = 15625Hz
501  // teletext bitrate ft = 444*fh = 6937500Hz
502  // teletext identification sequence 10101010 10101010 11100100
503  // 13th bit of seq rel to falling hsync 12us -1us +0.4us
504  // I search for the clock run-in (10101010 10101010) from 12us-1us-12.5/ft
505  // (earliest first bit) to 12us+0.4us+3.5/ft (latest last bit)
506  // earlist first bit tf = 12us-1us-12.5/ft = 9.2us
507  // latest last bit tl = 12us+0.4us+3.5/ft = 12.9us
508  // total number of used bits n = (2+1+2+40)*8 = 360
509 
510  int bpl = p->samples_per_line; // bytes per line
511  double fs = p->sampling_rate; // sampling rate
512  double bpb = fs/6937500.0; // bytes per bit
513  int soc = (int)(9.2e-6*fs) - (int)p->offset; // start of clock run-in
514  int eoc = (int)(12.9e-6*fs) - (int)p->offset; // end of clock run-in
515  if (soc < 0)
516  soc = 0;
517  if (eoc > bpl - (int)(43*8*bpb))
518  eoc = bpl - (int)(43*8*bpb);
519  if (eoc - soc < (int)(16*bpb))
520  {
521  // line too short or offset too large or wrong sample_rate
522  error("v4l2: broken vbi format specification");
523  return -1;
524  }
525  if (eoc > 240)
526  {
527  // the vbi_line routine can hold max 240 values in its work buffer
528  error("v4l2: unable to handle these sampling parameters");
529  return -1;
530  }
531 
532  vbi->bpb = lround(bpb * FAC);
533  vbi->soc = soc;
534  vbi->eoc = eoc;
535  vbi->bp8bl = 0.97 * 8*bpb; // -3% tolerance
536  vbi->bp8bh = 1.03 * 8*bpb; // +3% tolerance
537 
538  vbi->bpl = bpl;
539  vbi->bufsize = bpl * (p->count[0] + p->count[1]);
540 
541  return 0;
542 }
543 #endif // USING_V4L2
544 
545 static int
546 setup_dev([[maybe_unused]] struct vbi *vbi)
547 {
548 #ifdef USING_V4L2
549  struct v4l2_format v4l2_format {};
550  struct v4l2_vbi_format *vbifmt = &v4l2_format.fmt.vbi;
551 
552  memset(&v4l2_format, 0, sizeof(v4l2_format));
553  v4l2_format.type = V4L2_BUF_TYPE_VBI_CAPTURE;
554  if (ioctl(vbi->fd, VIDIOC_G_FMT, &v4l2_format) == -1)
555  {
556  error("Video 4 Linux version 1 support is not enabled.");
557  return -1;
558  }
559 
560  if (set_decode_parms(vbi, vbifmt) == -1)
561  return -1;
562 
563  if (vbi->bpl < 1 || vbi->bufsize < vbi->bpl || vbi->bufsize % vbi->bpl != 0)
564  {
565  error("strange size of vbi buffer (%d/%d)", vbi->bufsize, vbi->bpl);
566  return -1;
567  }
568 
569  // grow buffer if necessary
570  if (rawbuf_size < vbi->bufsize)
571  {
572  delete [] rawbuf;
574  if (!(rawbuf = new u_char[rawbuf_size]))
575  {
576  error("unable to allocate in setup_dev()\n");
577  }
578  }
579 
580  return 0;
581 #else
582  return -1;
583 #endif // USING_V4L2
584 }
585 
586 
587 
588 struct vbi *
589 vbi_open(const char *vbi_dev_name,
590  [[maybe_unused]] struct cache *ca,
591  int fine_tune,
592  int big_buf)
593 {
594  static int s_inited = 0;
595  struct vbi *vbi = nullptr;
596 
597  if (! s_inited)
598  lang_init();
599  s_inited = 1;
600 
601  vbi = new struct vbi;
602  if (vbi == nullptr)
603  {
604  error("out of memory");
605  goto fail1;
606  }
607 
608  if ((vbi->fd = open(vbi_dev_name, O_RDONLY)) == -1)
609  {
610  error("cannot open vbi device");
611  goto fail2;
612  }
613 
614  if (big_buf != -1)
615  error("-oldbttv/-newbttv is obsolete. option ignored.");
616 
617  if (setup_dev(vbi) == -1)
618  goto fail3;
619 
620 // vbi->cache = ca;
621 
622  dl_init(vbi->clients);
623  vbi->seq = 0;
624  out_of_sync(vbi);
625  vbi->ppage = vbi->rpage;
626 
627  vbi_pll_reset(vbi, fine_tune);
628 // ECA removed fdset_add_fd(fds, vbi->fd, vbi_handler, vbi);
629  return vbi;
630 
631 fail3:
632  close(vbi->fd);
633 fail2:
634  delete vbi;
635 fail1:
636  return nullptr;
637 }
638 
639 
640 
641 void
642 vbi_close(struct vbi *vbi)
643 {
644 // fdset_del_fd(fds, vbi->fd);
645 // if (vbi->cache)
646 // vbi->cache->op->close(vbi->cache);
647  close(vbi->fd);
648  delete vbi;
649 }
650 
651 
652 struct vt_page *
653 vbi_query_page([[maybe_unused]] struct vbi *vbi,
654  [[maybe_unused]] int pgno,
655  [[maybe_unused]] int subno)
656 {
657 #ifdef IMPLEMENTED
658  struct vt_page *vtp = 0;
659 
660  if (vbi->cache)
661  vtp = vbi->cache->op->get(vbi->cache, pgno, subno);
662  if (vtp == 0)
663  {
664  // EV_PAGE will come later...
665  return 0;
666  }
667 
668  vbi_send(vbi, EV_PAGE, 1, 0, 0, vtp);
669  return vtp;
670 #else
671  return nullptr;
672 #endif
673 }
674 
675 void
676 vbi_reset(struct vbi *vbi)
677 {
678 // if (vbi->cache)
679 // vbi->cache->op->reset(vbi->cache);
680  vbi_send(vbi, EV_RESET, 0, 0, 0, nullptr);
681 }
682 
hamm24par
const std::array< const std::array< const uint8_t, 256 >, 3 > hamm24par
This table generates the parity checks for hamm24/18 decoding.
Definition: vbilut.cpp:213
vt_event::i2
int i2
Definition: vt.h:12
vbi.h
vt.h
error
static void error(const char *str,...)
Definition: vbi.cpp:36
vbi_send
static void vbi_send(struct vbi *vbi, int type, int i1, int i2, int i3, void *p1)
Definition: vbi.cpp:76
vbi
Definition: vbi.h:17
vbi::pll_err
int pll_err
Definition: vbi.h:34
vbi::clients
struct dl_head clients[1]
Definition: vbi.h:21
vt_page::flags
int flags
Definition: vt.h:40
discid.disc.read
def read(device=None, features=[])
Definition: disc.py:35
vt_page::link
struct vt_page::@69 link[6]
isLatin1
int isLatin1
Definition: lang.cpp:7
vbi_line
static int vbi_line(struct vbi *vbi, const unsigned char *p)
Definition: vbi.cpp:331
vt_page::subno
int subno
Definition: vt.h:38
vt_event::i1
int i1
Definition: vt.h:12
dl_head::first
struct dl_node * first
Definition: dllist.h:16
vbi::pll_dir
int pll_dir
Definition: vbi.h:32
vbi::pll_adj
int pll_adj
Definition: vbi.h:31
vt_page
Definition: vt.h:36
vt_line
static int vt_line(struct vbi *vbi, unsigned char *p)
Definition: vbi.cpp:180
BAD_CHAR
#define BAD_CHAR
Definition: vt.h:6
vbi_close
void vbi_close(struct vbi *vbi)
Definition: vbi.cpp:642
vt_event::i3
int i3
Definition: vt.h:12
vbi::ppage
struct raw_page * ppage
Definition: vbi.h:28
close
#define close
Definition: compat.h:43
EV_XPACKET
#define EV_XPACKET
Definition: vt.h:22
PLL_ERROR
static constexpr int8_t PLL_ERROR
Definition: vbi.cpp:118
raw_page::enh
struct enhance enh[1]
Definition: vbi.h:14
vbi_pll_reset
void vbi_pll_reset(struct vbi *vbi, int fine_tune)
Definition: vbi.cpp:158
rawbuf_size
static int rawbuf_size
Definition: vbi.cpp:28
vbi::bpb
int bpb
Definition: vbi.h:36
do_enhancements
void do_enhancements(struct enhance *eh, struct vt_page *vtp)
Definition: lang.cpp:147
PLL_SAMPLES
static constexpr int8_t PLL_SAMPLES
Definition: vbi.cpp:117
vt_page::errors
int errors
Definition: vt.h:41
dl_remove
static struct dl_node * dl_remove(struct dl_node *n)
Definition: dllist.h:31
vbi_client::data
void * data
Definition: vbi.h:47
vbilut.h
vbi_query_page
struct vt_page * vbi_query_page([[maybe_unused]] struct vbi *vbi, [[maybe_unused]] int pgno, [[maybe_unused]] int subno)
Definition: vbi.cpp:653
out_of_sync
static void out_of_sync(struct vbi *vbi)
Definition: vbi.cpp:63
vbi::bpl
int bpl
Definition: vbi.h:24
dl_node::next
struct dl_node * next
Definition: dllist.h:10
hardwareprofile.config.p
p
Definition: config.py:33
hardwareprofile.i18n.t
t
Definition: i18n.py:36
conv2latin
void conv2latin(unsigned char *p, int n, int lang)
Definition: lang.cpp:107
vbi_open
struct vbi * vbi_open(const char *vbi_dev_name, [[maybe_unused]] struct cache *ca, int fine_tune, int big_buf)
Definition: vbi.cpp:589
vt_page::flof
int flof
Definition: vt.h:44
vbi_send_page
static void vbi_send_page(struct vbi *vbi, struct raw_page *rvtp, int page)
Definition: vbi.cpp:96
chk_parity
static int chk_parity(uint8_t *p, int n)
Definition: vbi.cpp:48
vt_event::type
int type
Definition: vt.h:10
vbi::eoc
int eoc
Definition: vbi.h:38
PLL_ADJUST
static constexpr int8_t PLL_ADJUST
Definition: vbi.h:9
init_enhance
void init_enhance(struct enhance *eh)
Definition: lang.cpp:128
vbi::bp8bh
int bp8bh
Definition: vbi.h:37
vbi::bufsize
int bufsize
Definition: vbi.h:23
lang_init
void lang_init(void)
Definition: lang.cpp:96
rawbuf
static unsigned char * rawbuf
Definition: vbi.cpp:26
vbi_add_handler
int vbi_add_handler(struct vbi *vbi, vbic_handler handler, void *data)
Definition: vbi.cpp:454
p1
static guint32 * p1
Definition: goom_core.cpp:26
vbi::pll_fixed
int pll_fixed
Definition: vbi.h:30
hamm8
int hamm8(const uint8_t *p, int *err)
Definition: vbilut.cpp:326
vbi_reset
void vbi_reset(struct vbi *vbi)
Definition: vbi.cpp:676
vbi::pll_cnt
int pll_cnt
Definition: vbi.h:33
vbi::seq
unsigned int seq
Definition: vbi.h:25
EV_HEADER
#define EV_HEADER
Definition: vt.h:21
dl_insert_last
#define dl_insert_last(h, n)
Definition: dllist.h:52
setup_dev
static int setup_dev([[maybe_unused]] struct vbi *vbi)
Definition: vbi.cpp:546
vt_page::lines
unsigned int lines
Definition: vt.h:42
pll_add
static void pll_add(struct vbi *vbi, int n, int err)
Definition: vbi.cpp:122
bbciplayer.stderr
stderr
Definition: bbciplayer.py:199
set_decode_parms
static int set_decode_parms(struct vbi *vbi, struct v4l2_vbi_format *p)
Definition: vbi.cpp:490
vbi::rpage
struct raw_page rpage[8]
Definition: vbi.h:27
vt_event::resource
void * resource
Definition: vt.h:11
PG_MAGSERIAL
#define PG_MAGSERIAL
Definition: vt.h:55
EV_PAGE
#define EV_PAGE
Definition: vt.h:20
vbi_handler
void vbi_handler(struct vbi *vbi, [[maybe_unused]] int fd)
Definition: vbi.cpp:413
vbi::pll_lerr
int pll_lerr
Definition: vbi.h:34
PG_ACTIVE
#define PG_ACTIVE
Definition: vt.h:60
vbi_client::handler
vbic_handler handler
Definition: vbi.h:46
dl_init
static struct dl_head * dl_init(struct dl_head *h)
Definition: dllist.h:22
raw_page
Definition: vbi.h:11
vbi::cache
struct cache * cache
Definition: vbi.h:20
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
vbi_client::node
struct dl_node node[1]
Definition: vbi.h:45
vbi::soc
int soc
Definition: vbi.h:38
vbi_client
Definition: vbi.h:43
vbi_del_handler
void vbi_del_handler(struct vbi *vbi, vbic_handler handler, void *data)
Definition: vbi.cpp:471
FAC
#define FAC
Definition: vbi.cpp:24
vt_event
Definition: vt.h:8
vt_page::data
unsigned char data[VT_HEIGHT][VT_WIDTH]
Definition: vt.h:43
vbi::fd
int fd
Definition: vbi.h:19
vt_event::p1
void * p1
Definition: vt.h:13
add_enhance
void add_enhance(struct enhance *eh, int dcode, std::array< unsigned int, 13 > &data)
Definition: lang.cpp:134
EV_RESET
#define EV_RESET
Definition: vt.h:23
vt_page::pgno
int pgno
Definition: vt.h:38
vbi::bp8bl
int bp8bl
Definition: vbi.h:37
vbic_handler
void(*)(void *data, struct vt_event *ev) vbic_handler
Definition: vbi.h:41
vt_page::lang
int lang
Definition: vt.h:39
hamm16
int hamm16(const uint8_t *p, int *err)
Definition: vbilut.cpp:343
raw_page::page
struct vt_page page[1]
Definition: vbi.h:13
hamm24
int hamm24(const uint8_t *p, int *err)
Definition: vbilut.cpp:352
dl_empty
#define dl_empty(h)
Definition: dllist.h:48