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