MythTV  master
teletextreader.cpp
Go to the documentation of this file.
2 
3 #include <cstring>
4 
5 #include "captions/vbilut.h"
6 #include "tv.h"
7 #include "mythuiactions.h"
8 #include "tv_actions.h"
9 #include "mythlogging.h"
10 
11 #define MAGAZINE(page) ((page) / 256)
12 
14 {
15  m_bitswap.fill(0);
16  for (int i = 0; i < 256; i++)
17  {
18  for (int bit = 0; bit < 8; bit++)
19  if (i & (1 << bit))
20  m_bitswap[i] |= (1 << (7-bit));
21  }
22  Reset();
23 }
24 
25 bool TeletextReader::KeyPress(const QString &Key, bool& Exit)
26 {
27  int newPage = m_curpage;
28  int newSubPage = m_cursubpage;
29  bool numeric_input = false;
30 
31  if (Key == "MENU" || Key == ACTION_TOGGLETT || Key == "ESCAPE")
32  {
33  Exit = true;
34  return true;
35  }
36 
38  TeletextPage *page = nullptr;
39 
40  if (Key == ACTION_0 || Key == ACTION_1 || Key == ACTION_2 ||
41  Key == ACTION_3 || Key == ACTION_4 || Key == ACTION_5 ||
42  Key == ACTION_6 || Key == ACTION_7 || Key == ACTION_8 ||
43  Key == ACTION_9)
44  {
45  numeric_input = true;
46  m_curpageShowHeader = true;
47  if (m_pageinput[0] == ' ')
48  m_pageinput[0] = '0' + Key.toInt();
49  else if (m_pageinput[1] == ' ')
50  m_pageinput[1] = '0' + Key.toInt();
51  else if (m_pageinput[2] == ' ')
52  {
53  m_pageinput[2] = '0' + Key.toInt();
54  newPage = ((m_pageinput[0] - '0') * 256) +
55  ((m_pageinput[1] - '0') * 16) +
56  (m_pageinput[2] - '0');
57  newSubPage = -1;
58  }
59  else
60  {
61  m_pageinput[0] = '0' + Key.toInt();
62  m_pageinput[1] = ' ';
63  m_pageinput[2] = ' ';
64  }
65 
67  }
68  else if (Key == ACTION_NEXTPAGE)
69  {
70  TeletextPage *ttpage = FindPage(m_curpage, 1);
71  if (ttpage)
72  newPage = ttpage->pagenum;
73  newSubPage = -1;
74  m_curpageShowHeader = true;
75  }
76  else if (Key == ACTION_PREVPAGE)
77  {
78  TeletextPage *ttpage = FindPage(m_curpage, -1);
79  if (ttpage)
80  newPage = ttpage->pagenum;
81  newSubPage = -1;
82  m_curpageShowHeader = true;
83  }
84  else if (Key == ACTION_NEXTSUBPAGE)
85  {
87  if (ttpage)
88  newSubPage = ttpage->subpagenum;
89  m_curpageShowHeader = true;
90  }
91  else if (Key == ACTION_PREVSUBPAGE)
92  {
94  if (ttpage)
95  newSubPage = ttpage->subpagenum;
96  m_curpageShowHeader = true;
97  }
98  else if (Key == ACTION_TOGGLEBACKGROUND)
99  {
102  }
103  else if (Key == ACTION_REVEAL)
104  {
107  }
108  else if (Key == ACTION_MENURED)
109  {
110  if (!curpage)
111  return true;
112 
113  if ((page = FindPage(curpage->floflink[0])) != nullptr)
114  {
115  newPage = page->pagenum;
116  newSubPage = -1;
117  m_curpageShowHeader = true;
118  }
119  }
120  else if (Key == ACTION_MENUGREEN)
121  {
122  if (!curpage)
123  return true;
124 
125  if ((page = FindPage(curpage->floflink[1])) != nullptr)
126  {
127  newPage = page->pagenum;
128  newSubPage = -1;
129  m_curpageShowHeader = true;
130  }
131  }
132  else if (Key == ACTION_MENUYELLOW)
133  {
134  if (!curpage)
135  return true;
136 
137  if ((page = FindPage(curpage->floflink[2])) != nullptr)
138  {
139  newPage = page->pagenum;
140  newSubPage = -1;
141  m_curpageShowHeader = true;
142  }
143  }
144  else if (Key == ACTION_MENUBLUE)
145  {
146  if (!curpage)
147  return true;
148 
149  if ((page = FindPage(curpage->floflink[3])) != nullptr)
150  {
151  newPage = page->pagenum;
152  newSubPage = -1;
153  m_curpageShowHeader = true;
154  }
155  }
156  else if (Key == ACTION_MENUWHITE)
157  {
158  if (!curpage)
159  return true;
160 
161  if ((page = FindPage(curpage->floflink[4])) != nullptr)
162  {
163  newPage = page->pagenum;
164  newSubPage = -1;
165  m_curpageShowHeader = true;
166  }
167  }
168  else
169  return false;
170 
171  if (newPage < 0x100)
172  newPage = 0x100;
173  if (newPage > 0x899)
174  newPage = 0x899;
175 
176  if (!numeric_input)
177  {
178  m_pageinput[0] = (newPage / 256) + '0';
179  m_pageinput[1] = ((newPage % 256) / 16) + '0';
180  m_pageinput[2] = (newPage % 16) + '0';
181  }
182 
183  if (newPage != m_curpage || newSubPage != m_cursubpage)
184  {
185  m_curpage = newPage;
186  m_cursubpage = newSubPage;
187  m_revealHidden = false;
189  }
190 
191  return true;
192 }
193 
195 {
196  QString str = "";
197  int mag = MAGAZINE(m_curpage);
198  if (mag > 8 || mag < 1)
199  return str;
200 
201  int count = 1;
202  int selected = 0;
203  const TeletextPage *page = FindPage(m_curpage);
204  if (page)
205  {
206  m_magazines[mag - 1].lock->lock();
207  int_to_subpage_t::const_iterator subpageIter;
208  subpageIter = page->subpages.begin();
209  while (subpageIter != page->subpages.end())
210  {
211  const TeletextSubPage *subpage = &subpageIter->second;
212 
213  if (subpage->subpagenum == m_cursubpage)
214  {
215  selected = count;
216  str += "*";
217  }
218  else
219  str += " ";
220 
221  str += QString("%1").arg(subpage->subpagenum,2,16,QChar('0'));
222 
223  ++subpageIter;
224  ++count;
225  }
226  m_magazines[mag - 1].lock->unlock();
227  }
228 
229  if (str.isEmpty())
230  return str;
231 
232  // if there are less than 9 subpages fill the empty slots with spaces
233  if (count < 10)
234  {
235  QString spaces;
236  spaces.fill(' ', 27 - str.length());
237  str = " <" + str + spaces + " > ";
238  }
239  else
240  {
241  // try to centralize the selected sub page in the list
242  int startPos = selected - 5;
243  if (startPos < 0)
244  startPos = 0;
245  if (startPos + 9 >= count)
246  startPos = count - 10;
247 
248  str = " <" + str.mid(startPos * 3, 27) + " > ";
249  }
250  return str;
251 }
252 
253 void TeletextReader::SetPage(int page, int subpage)
254 {
255  if (page < 0x100 || page > 0x899)
256  return;
257 
258  m_pageinput[0] = (page / 256) + '0';
259  m_pageinput[1] = ((page % 256) / 16) + '0';
260  m_pageinput[2] = (page % 16) + '0';
261 
262  m_curpage = page;
263  m_cursubpage = subpage;
265 }
266 
268 {
269  for (auto & mag : m_magazines)
270  {
271  QMutexLocker lock(mag.lock);
272 
273  // clear all sub pages in page
274  int_to_page_t::iterator iter;
275  iter = mag.pages.begin();
276  while (iter != mag.pages.end())
277  {
278  TeletextPage *page = &iter->second;
279  page->subpages.clear();
280  ++iter;
281  }
282 
283  // clear pages
284  mag.pages.clear();
285  mag.current_page = 0;
286  mag.current_subpage = 0;
287  mag.loadingpage.active = false;
288  }
289  m_header.fill(' ');
290 
291  m_curpage = 0x100;
292  m_cursubpage = -1;
293  m_curpageShowHeader = true;
294 
295  m_pageinput[0] = '1';
296  m_pageinput[1] = '0';
297  m_pageinput[2] = '0';
298 }
299 
300 void TeletextReader::AddPageHeader(int page, int subpage, const uint8_t *buf,
301  int vbimode, int lang, int flags)
302 {
303  int magazine = MAGAZINE(page);
304  if (magazine < 1 || magazine > 8)
305  return;
306 
307  for(int m = 1; m <= 8; m++)
308  {
309  // ETS 300 706, chapter 7.2.1:
310  // The transmission of a given page begins with, and includes, its page
311  // header packet. It is terminated by and excludes the next page header
312  // packet having the same magazine address in parallel transmission
313  // mode, or any magazine address in serial transmission mode.
314  // ETS 300 706, chapter 9.3.1.3:
315  // When set to '1' the service is designated to be in Serial mode and
316  // the transmission of a page is terminated by the next page header with
317  // a different page number.
318  // When set to '0' the service is designated to be in Parallel mode and
319  // the transmission of a page is terminated by the next page header with
320  // a different page number but the same magazine number. The same
321  // setting shall be used for all page headers in the service.
322 
323  bool isMagazineSerialMode = (flags & TP_MAGAZINE_SERIAL) != 0;
324  if (!(isMagazineSerialMode) && m != magazine)
325  {
326  continue; // in parallel mode only process magazine
327  }
328 
329  int lastPage = m_magazines[m - 1].current_page;
330  int lastSubPage = m_magazines[m - 1].current_subpage;
331 
332  LOG(VB_VBI, LOG_DEBUG,
333  QString("AddPageHeader(p %1, sp %2, lang %3, mag %4, lp %5, lsp %6"
334  " sm %7)")
335  .arg(page).arg(subpage).arg(lang).arg(m).arg(lastPage)
336  .arg(lastSubPage).arg(isMagazineSerialMode));
337 
338  if ((page != lastPage || subpage != lastSubPage) &&
339  m_magazines[m - 1].loadingpage.active)
340  {
341  TeletextSubPage *ttpage = FindSubPage(lastPage, lastSubPage);
342  if (!ttpage)
343  {
344  ttpage = &(m_magazines[m - 1]
345  .pages[lastPage].subpages[lastSubPage]);
346  m_magazines[m - 1].pages[lastPage].pagenum = lastPage;
347  ttpage->subpagenum = lastSubPage;
348  }
349 
350  memcpy(ttpage, &m_magazines[m - 1].loadingpage,
351  sizeof(TeletextSubPage));
352 
353  m_magazines[m - 1].loadingpage.active = false;
354 
355  PageUpdated(lastPage, lastSubPage);
356  }
357  }
358 
359  m_fetchpage = page;
360  m_fetchsubpage = subpage;
361 
362  TeletextSubPage *ttpage = &m_magazines[magazine - 1].loadingpage;
363 
364  m_magazines[magazine - 1].current_page = page;
365  m_magazines[magazine - 1].current_subpage = subpage;
366 
367  for (auto & line : ttpage->data)
368  line.fill(' ');
369 
370  ttpage->active = true;
371  ttpage->subpagenum = subpage;
372  ttpage->floflink.fill(0);
373  ttpage->lang = lang;
374  ttpage->flags = flags;
375  ttpage->flof = 0;
376 
377  ttpage->subtitle = (vbimode == VBI_DVB_SUBTITLE);
378 
379  std::fill_n(ttpage->data[0].data(), 8, ' ');
380 
382  {
383  for (uint j = 8; j < 40; j++)
384  ttpage->data[0][j] = m_bitswap[buf[j]];
385  }
386  else
387  {
388  std::copy(buf, buf + 40, ttpage->data[0].data());
389  }
390 
391  if ( !(ttpage->flags & TP_INTERRUPTED_SEQ))
392  {
393  std::copy(ttpage->data[0].cbegin(), ttpage->data[0].cend(), m_header.data());
394  HeaderUpdated(page, subpage, ttpage->data[0],ttpage->lang);
395  }
396 }
397 
398 void TeletextReader::AddTeletextData(int magazine, int row,
399  const uint8_t* buf, int vbimode)
400 {
401  //LOG(VB_GENERAL, LOG_ERR, QString("AddTeletextData(%1, %2)")
402  // .arg(magazine).arg(row));
403 
404  int b1 = 0;
405  int b2 = 0;
406  int b3 = 0;
407  int err = 0;
408 
409  if (magazine < 1 || magazine > 8)
410  return;
411 
412  int currentpage = m_magazines[magazine - 1].current_page;
413  if (!currentpage)
414  return;
415 
416  TeletextSubPage *ttpage = &m_magazines[magazine - 1].loadingpage;
417 
418  switch (row)
419  {
420  case 26:
421  /* XXX TODO: Level 1.5, 2.5, 3.5
422  * Character location & override
423  * Level 2.5, 3.5
424  * Modifying display attributes
425  * All levels
426  * VCR Programming
427  * See 12.3
428  */
429  break;
430  case 27: // FLOF data (FastText)
431  switch (vbimode)
432  {
433  case VBI_IVTV:
434  b1 = hamm8(buf, &err);
435  b2 = hamm8(buf + 37, &err);
436  if (err & 0xF000)
437  return;
438  break;
439  case VBI_DVB:
440  case VBI_DVB_SUBTITLE:
441  b1 = hamm84(buf, &err);
442  b2 = hamm84(buf + 37, &err);
443  if (err == 1)
444  return;
445  break;
446  default:
447  return;
448  }
449  if (b1 != 0 || !(b2 & 8))
450  return;
451 
452  for (int i = 0; i < 6; ++i)
453  {
454  err = 0;
455  switch (vbimode)
456  {
457  case VBI_IVTV:
458  b1 = hamm16(buf+1+6*i, &err);
459  b2 = hamm16(buf+3+6*i, &err);
460  b3 = hamm16(buf+5+6*i, &err);
461  if (err & 0xF000)
462  return;
463  break;
464  case VBI_DVB:
465  case VBI_DVB_SUBTITLE:
466  b1 = hamm84(buf+2+6*i, &err) * 16 +
467  hamm84(buf+1+6*i, &err);
468  b2 = hamm84(buf+4+6*i, &err) * 16 +
469  hamm84(buf+3+6*i, &err);
470  b3 = hamm84(buf+6+6*i, &err) * 16 +
471  hamm84(buf+5+6*i, &err);
472  if (err == 1)
473  return;
474  break;
475  default:
476  return;
477  }
478 
479  int x = (b2 >> 7) | ((b3 >> 5) & 0x06);
480  int nTmp = (magazine ^ x);
481  ttpage->floflink[i] = ( nTmp ? nTmp : 8) * 256 + b1;
482  ttpage->flof = 1;
483  }
484  break;
485 
486  case 31: // private streams
487  break;
488 
489  default:
490 
491  if (( row >= 1 ) && ( row <= 24 )) // Page Data
492  {
494  {
495  for (uint j = 0; j < 40; j++)
496  ttpage->data[row][j] = m_bitswap[buf[j]];
497  }
498  else
499  {
500  std::copy(buf, buf + 40, ttpage->data[row].data());
501  }
502  }
503 
504  break;
505  }
506 }
507 
508 void TeletextReader::PageUpdated(int page, int subpage)
509 {
510  if (page != m_curpage)
511  return;
512  if (subpage != m_cursubpage && m_cursubpage != -1)
513  return;
514  m_pageChanged = true;
515 }
516 
518  int page, int subpage, tt_line_array& page_ptr, int lang)
519 {
520  (void)page;
521  (void)subpage;
522  (void)page_ptr;
523  (void)lang;
524 
525  if (!m_curpageShowHeader)
526  return;
527 
528  m_headerChanged = true;
529 }
530 
532  int page, int direction) const
533 {
534  int mag = MAGAZINE(page);
535 
536  if (mag > 8 || mag < 1)
537  return nullptr;
538 
539  QMutexLocker lock(m_magazines[mag - 1].lock);
540 
541  int_to_page_t::const_iterator pageIter;
542  pageIter = m_magazines[mag - 1].pages.find(page);
543  if (pageIter == m_magazines[mag - 1].pages.end())
544  return nullptr;
545 
546  const TeletextPage *res = &pageIter->second;
547  if (direction == -1)
548  {
549  --pageIter;
550  if (pageIter == m_magazines[mag - 1].pages.end())
551  {
552  int_to_page_t::const_reverse_iterator iter;
553  iter = m_magazines[mag - 1].pages.rbegin();
554  res = &iter->second;
555  }
556  else
557  res = &pageIter->second;
558  }
559 
560  if (direction == 1)
561  {
562  ++pageIter;
563  if (pageIter == m_magazines[mag - 1].pages.end())
564  {
565  pageIter = m_magazines[mag - 1].pages.begin();
566  res = &pageIter->second;
567  }
568  else
569  res = &pageIter->second;
570  }
571 
572  return res;
573 }
574 
576  int page, int subpage, int direction) const
577 {
578  int mag = MAGAZINE(page);
579 
580  if (mag > 8 || mag < 1)
581  return nullptr;
582 
583  QMutexLocker lock(m_magazines[mag - 1].lock);
584 
585  int_to_page_t::const_iterator pageIter;
586  pageIter = m_magazines[mag - 1].pages.find(page);
587  if (pageIter == m_magazines[mag - 1].pages.end())
588  return nullptr;
589 
590  const TeletextPage *ttpage = &(pageIter->second);
591  auto subpageIter = ttpage->subpages.cbegin();
592 
593  // try to find the subpage given, or first if subpage == -1
594  if (subpage != -1)
595  subpageIter = ttpage->subpages.find(subpage);
596 
597  if (subpageIter == ttpage->subpages.cend())
598  return nullptr;
599 
600  if (subpage == -1)
601  return &(subpageIter->second);
602 
603  const TeletextSubPage *res = &(subpageIter->second);
604  if (direction == -1)
605  {
606  --subpageIter;
607  if (subpageIter == ttpage->subpages.cend())
608  {
609  auto iter = ttpage->subpages.crbegin();
610  res = &(iter->second);
611  }
612  else
613  {
614  res = &(subpageIter->second);
615  }
616  }
617 
618  if (direction == 1)
619  {
620  ++subpageIter;
621  if (subpageIter == ttpage->subpages.cend())
622  subpageIter = ttpage->subpages.cbegin();
623 
624  res = &(subpageIter->second);
625  }
626 
627  return res;
628 }
TeletextSubPage::lang
int lang
language code
Definition: teletextreader.h:43
ACTION_TOGGLETT
#define ACTION_TOGGLETT
Definition: tv_actions.h:100
TeletextSubPage::flof
int flof
page has FastText links
Definition: teletextreader.h:46
VBI_IVTV
@ VBI_IVTV
Definition: vbilut.h:23
TeletextPage::subpages
int_to_subpage_t subpages
Definition: teletextreader.h:59
TeletextReader::GetPage
QString GetPage(void)
Definition: teletextreader.cpp:194
tv.h
ACTION_3
#define ACTION_3
Definition: mythuiactions.h:7
TeletextReader::m_curpage
int m_curpage
Definition: teletextreader.h:129
copy
long long copy(QFile &dst, QFile &src, uint block_size)
Copies src file to dst file.
Definition: mythmiscutil.cpp:309
TeletextSubPage::flags
int flags
misc flags
Definition: teletextreader.h:44
TeletextSubPage::floflink
std::array< int, 6 > floflink
FastText links (FLOF)
Definition: teletextreader.h:47
TeletextReader::m_bitswap
std::array< uint8_t, 256 > m_bitswap
Definition: teletextreader.h:140
ACTION_6
#define ACTION_6
Definition: mythuiactions.h:10
hamm84
int hamm84(const uint8_t *p, int *err)
Definition: vbilut.cpp:333
MAGAZINE
#define MAGAZINE(page)
Definition: teletextreader.cpp:11
ACTION_0
#define ACTION_0
Definition: mythuiactions.h:4
vbimode
vbimode
Definition: vbilut.h:21
TeletextPage::pagenum
int pagenum
Definition: teletextreader.h:57
TeletextReader::m_cursubpage
int m_cursubpage
Definition: teletextreader.h:130
TeletextSubPage::subtitle
bool subtitle
page is subtitle page
Definition: teletextreader.h:48
arg
arg(title).arg(filename).arg(doDelete))
ACTION_2
#define ACTION_2
Definition: mythuiactions.h:6
TeletextSubPage
Definition: teletextreader.h:38
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
ACTION_MENUYELLOW
#define ACTION_MENUYELLOW
Definition: tv_actions.h:79
teletextreader.h
TeletextReader::m_transparent
bool m_transparent
Definition: teletextreader.h:134
TeletextReader::PageUpdated
virtual void PageUpdated(int page, int subpage)
Definition: teletextreader.cpp:508
TeletextReader::FindPageInternal
const TeletextPage * FindPageInternal(int page, int direction) const
Definition: teletextreader.cpp:531
ACTION_NEXTPAGE
#define ACTION_NEXTPAGE
Definition: tv_actions.h:96
TeletextReader::m_headerChanged
bool m_headerChanged
Definition: teletextreader.h:137
TeletextReader::m_header
tt_line_array m_header
Definition: teletextreader.h:136
TeletextReader::m_magazines
std::array< TeletextMagazine, 8 > m_magazines
Definition: teletextreader.h:139
VBI_DVB_SUBTITLE
@ VBI_DVB_SUBTITLE
< DVB packet
Definition: vbilut.h:25
ACTION_8
#define ACTION_8
Definition: mythuiactions.h:12
TP_MAGAZINE_SERIAL
#define TP_MAGAZINE_SERIAL
Definition: teletextreader.h:31
mythlogging.h
ACTION_MENURED
#define ACTION_MENURED
Definition: tv_actions.h:77
vbilut.h
tv_actions.h
ACTION_PREVSUBPAGE
#define ACTION_PREVSUBPAGE
Definition: tv_actions.h:99
TeletextReader::m_fetchsubpage
int m_fetchsubpage
Definition: teletextreader.h:142
TeletextReader::m_pageChanged
bool m_pageChanged
Definition: teletextreader.h:138
TeletextReader::HeaderUpdated
virtual void HeaderUpdated(int page, int subpage, tt_line_array &page_ptr, int lang)
Definition: teletextreader.cpp:517
tt_line_array
std::array< uint8_t, 40 > tt_line_array
Definition: teletextreader.h:36
TeletextReader::SetPage
void SetPage(int page, int subpage)
Definition: teletextreader.cpp:253
uint
unsigned int uint
Definition: compat.h:141
ACTION_9
#define ACTION_9
Definition: mythuiactions.h:13
ACTION_4
#define ACTION_4
Definition: mythuiactions.h:8
hamm8
int hamm8(const uint8_t *p, int *err)
Definition: vbilut.cpp:326
ACTION_1
#define ACTION_1
Definition: mythuiactions.h:5
TeletextReader::m_fetchpage
int m_fetchpage
Definition: teletextreader.h:141
VBI_DVB
@ VBI_DVB
< IVTV packet
Definition: vbilut.h:24
ACTION_MENUBLUE
#define ACTION_MENUBLUE
Definition: tv_actions.h:80
ACTION_7
#define ACTION_7
Definition: mythuiactions.h:11
TeletextReader::AddTeletextData
void AddTeletextData(int magazine, int row, const uint8_t *buf, int vbimode)
Definition: teletextreader.cpp:398
TeletextReader::KeyPress
bool KeyPress(const QString &Key, bool &Exit)
Definition: teletextreader.cpp:25
TeletextReader::m_revealHidden
bool m_revealHidden
Definition: teletextreader.h:135
TeletextReader::m_curpageShowHeader
bool m_curpageShowHeader
Definition: teletextreader.h:131
ACTION_MENUGREEN
#define ACTION_MENUGREEN
Definition: tv_actions.h:78
ACTION_REVEAL
#define ACTION_REVEAL
Definition: tv_actions.h:103
TeletextReader::m_pageinput
std::array< int, 3 > m_pageinput
Definition: teletextreader.h:133
TeletextReader::FindSubPage
TeletextSubPage * FindSubPage(void)
Definition: teletextreader.h:96
TeletextReader::Reset
void Reset(void)
Definition: teletextreader.cpp:267
TeletextSubPage::active
bool active
data has arrived since page last cleared
Definition: teletextreader.h:49
ACTION_5
#define ACTION_5
Definition: mythuiactions.h:9
ACTION_PREVPAGE
#define ACTION_PREVPAGE
Definition: tv_actions.h:97
mythuiactions.h
TeletextSubPage::subpagenum
int subpagenum
the wanted subpage
Definition: teletextreader.h:42
ACTION_MENUWHITE
#define ACTION_MENUWHITE
Definition: tv_actions.h:101
TeletextReader::AddPageHeader
void AddPageHeader(int page, int subpage, const uint8_t *buf, int vbimode, int lang, int flags)
Definition: teletextreader.cpp:300
ACTION_NEXTSUBPAGE
#define ACTION_NEXTSUBPAGE
Definition: tv_actions.h:98
TP_INTERRUPTED_SEQ
#define TP_INTERRUPTED_SEQ
Definition: teletextreader.h:29
TeletextReader::FindSubPageInternal
const TeletextSubPage * FindSubPageInternal(int page, int subpage, int direction) const
Definition: teletextreader.cpp:575
TeletextReader::FindPage
const TeletextPage * FindPage(int page, int dir=0) const
Definition: teletextreader.h:120
ACTION_TOGGLEBACKGROUND
#define ACTION_TOGGLEBACKGROUND
Definition: tv_actions.h:102
TeletextReader::TeletextReader
TeletextReader()
Definition: teletextreader.cpp:13
hamm16
int hamm16(const uint8_t *p, int *err)
Definition: vbilut.cpp:343
TeletextPage
Definition: teletextreader.h:54
TeletextSubPage::data
std::array< tt_line_array, 25 > data
page data
Definition: teletextreader.h:45