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