MythTV  master
mythccextractorplayer.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 /*
4  * Class MythCCExtractorPlayer
5  *
6  * Copyright (C) Digital Nirvana, Inc. 2010
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <iostream>
24 #include <utility>
25 
26 #include <QFileInfo>
27 #include <QPainter>
28 
30 #include "avformatdecoder.h"
32 #include "captions/srtwriter.h"
33 #include "iso639.h"
34 #include "mythccextractorplayer.h"
35 
36 const int OneSubtitle::kDefaultLength = 750; /* ms */
37 
39 {
40  while (!m_srtWriters.empty())
41  {
42  delete *m_srtWriters.begin();
43  m_srtWriters.erase(m_srtWriters.begin());
44  }
45 }
50 
52  QString fileName,
53  const QString &destdir) :
54  MythPlayer(Context, flags),
55  m_curTime(0),
56  m_myFramesPlayed(0),
57  m_showProgress(showProgress),
58  m_fileName(std::move(fileName))
59 {
60  // Determine where we will put extracted info.
61  QStringList comps = QFileInfo(m_fileName).fileName().split(".");
62  if (!comps.empty())
63  comps.removeLast();
64  if (destdir.isEmpty())
65  m_workingDir = QDir(QFileInfo(m_fileName).path());
66  else
67  {
68  m_workingDir = QDir(destdir);
69  if (!m_workingDir.exists())
70  m_workingDir = QDir(QFileInfo(m_fileName).path());
71  }
72  m_baseName = comps.join(".");
73 }
74 
80 {
83  {
85  double fps = frame->m_frameRate;
86  if (fps <= 0)
87  fps = GetDecoder()->GetFPS();
88  double duration = 1 / fps + static_cast<double>(frame->m_repeatPic) * 0.5 / fps;
89  m_curTime += duration * 1000;
91  }
92 
97 }
98 
99 static QString progress_string(
100  MythTimer &flagTime, uint64_t m_myFramesPlayed, uint64_t totalFrames)
101 {
102  if (totalFrames == 0ULL)
103  {
104  return QString("%1 frames processed \r")
105  .arg(m_myFramesPlayed,7);
106  }
107 
108  static const std::string kSpinChars { R"(/-\|)" };
109  static uint s_spinCnt = 0;
110 
111  double elapsed = flagTime.elapsed() * 0.001;
112  double flagFPS = (elapsed > 0.0) ? (m_myFramesPlayed / elapsed) : 0;
113 
114  double percentage = m_myFramesPlayed * 100.0 / totalFrames;
115  percentage = (percentage > 100.0 && percentage < 101.0) ?
116  100.0 : percentage;
117 
118  if (m_myFramesPlayed < totalFrames)
119  return QString("%1 fps %2% \r")
120  .arg(flagFPS,4,'f', (flagFPS < 10.0 ? 1 : 0)).arg(percentage,4,'f',1);
121  return QString("%1 fps %2 \r")
122  .arg(flagFPS,4,'f', (flagFPS < 10.0 ? 1 : 0))
123  .arg(kSpinChars[++s_spinCnt % 4]);
124 }
125 
127 {
128  m_myFramesPlayed = 0;
129 
130  m_killDecoder = false;
131  m_framesPlayed = 0;
132 
134 
135  SetPlaying(true);
136 
137  if (!InitVideo())
138  {
139  LOG(VB_GENERAL, LOG_ERR, "Unable to initialize video");
140  SetPlaying(false);
141  return false;
142  }
143 
144  ClearAfterSeek();
145 
146  MythTimer flagTime;
147  MythTimer ui_timer;
148  MythTimer inuse_timer;
149  MythTimer save_timer;
150  flagTime.start();
151  ui_timer.start();
152  inuse_timer.start();
153  save_timer.start();
154 
155  m_curTime = 0;
156 
158  OnGotNewFrame();
159 
160  if (m_showProgress)
161  std::cout << "\r \r" << std::flush;
162 
163  while (!m_killDecoder && !IsErrored())
164  {
165  if (inuse_timer.elapsed() > 2534)
166  {
167  inuse_timer.restart();
168  m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
171  m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
172  }
173 
174  if (m_showProgress && (ui_timer.elapsed() > 98 * 4))
175  {
176  ui_timer.restart();
177  QString str = progress_string(
178  flagTime, m_myFramesPlayed, m_totalFrames);
179  std::cout << qPrintable(str) << '\r' << std::flush;
180  }
181 
183  break;
184 
185  OnGotNewFrame();
186  }
187 
188  if (m_showProgress)
189  {
191  ((m_myFramesPlayed + 30) > m_totalFrames))
192  {
194  }
195  QString str = progress_string(flagTime, m_myFramesPlayed, m_totalFrames);
196  std::cout << qPrintable(str) << std::endl;
197  }
198 
203 
204  SetPlaying(false);
205  m_killDecoder = true;
206 
207  return true;
208 }
209 
210 
218  QList<OneSubtitle> &list, const QStringList &content) const
219 {
220  bool update_last =
221  !list.isEmpty() &&
222  (int64_t)m_curTime == list.back().m_startTime &&
223  !content.isEmpty();
224 
225  if (update_last)
226  {
227  //update text only (need for cc608)
228  list.back().m_text = content;
229  return;
230  }
231 
232  OneSubtitle last_one = list.isEmpty() ? OneSubtitle() : list.back();
233  if (content != last_one.m_text || last_one.m_length >= 0)
234  {
235  // Finish previous subtitle.
236  if (!last_one.m_text.isEmpty() && last_one.m_length < 0)
237  {
238  list.back().m_length = (int64_t)m_curTime - last_one.m_startTime;
239  }
240 
241  // Put new one if it isn't empty.
242  if (!content.isEmpty())
243  {
244  OneSubtitle new_one;
245  new_one.m_startTime = (int64_t)m_curTime;
246  new_one.m_text = content;
247 
248  list.push_back(new_one);
249  }
250  }
251 }
252 
261  QList<OneSubtitle> &list, const OneSubtitle &content)
262 {
263  bool update_last =
264  !list.isEmpty() &&
265  content.m_startTime == list.back().m_startTime &&
266  !content.m_img.isNull();
267 
268  if (update_last)
269  {
270  list.back().m_img = content.m_img; // update image only
271  return;
272  }
273 
274  OneSubtitle last_one = list.isEmpty() ? OneSubtitle() : list.back();
275  if (content.m_img != last_one.m_img || last_one.m_length >= 0)
276  {
277  // Finish previous subtitle.
278  if (!last_one.m_img.isNull() && last_one.m_length < 0)
279  {
280  list.back().m_length = content.m_startTime - last_one.m_startTime;
281  }
282 
283  // Put new one if it isn't empty.
284  if (!content.m_img.isNull())
285  {
286  OneSubtitle new_one;
287  new_one.m_startTime = content.m_startTime;
288  new_one.m_img = content.m_img;
289 
290  list.push_back(new_one);
291  }
292  }
293 }
294 
296 {
297  static constexpr std::array<int,7> kCcIndexTbl
298  {
299  0, // CC_CC1
300  1, // CC_CC2
301  9, // sentinel
302  9, // sentinel
303  2, // CC_CC3
304  3, // CC_CC4
305  9, // sentinel
306  };
307 
308  // for each CC of each video...
309  // NOLINTNEXTLINE(modernize-loop-convert)
310  for (auto it = m_cc608Info.begin(); it != m_cc608Info.end(); ++it)
311  {
312  while (true)
313  {
314  bool changed = false;
315  int streamRawIdx = -1;
316  CC608Buffer *textlist = (*it).m_reader->GetOutputText(
317  changed, streamRawIdx);
318 
319  if (!changed || !textlist)
320  break;
321 
322  if (streamRawIdx < 0)
323  continue;
324 
325  textlist->m_lock.lock();
326 
327  const int ccIdx = kCcIndexTbl[std::min(streamRawIdx,6)];
328 
329  if (ccIdx >= 4)
330  {
331  textlist->m_lock.unlock();
332  continue;
333  }
334 
335  FormattedTextSubtitle608 fsub(textlist->m_buffers);
336  QStringList content = fsub.ToSRT();
337 
338  textlist->m_lock.unlock();
339 
340  IngestSubtitle((*it).m_subs[ccIdx], content);
341  }
342  }
343 }
344 
345 // Note: GetCaptionLanguage() will not return valid if there are multiple videos
347 {
348  int i = 0;
349  // NOLINTNEXTLINE(modernize-loop-convert)
350  for (auto cc608it = m_cc608Info.begin(); cc608it != m_cc608Info.end(); ++cc608it)
351  {
352  QString stream_id_str = (m_cc608Info.size() <= 1) ?
353  QString("") : QString("%1.").arg(i,2,10,QChar('0'));
354 
355  CC608StreamType &subs = (*cc608it).m_subs;
356  for (auto it = subs.begin(); it != subs.end(); ++it)
357  {
358  if ((*it).empty())
359  continue; // Skip empty subtitle streams.
360  if (((kProcessFinalize & flags) == 0) && ((*it).size() <= 1))
361  continue; // Leave one caption behind so it can be amended
362 
363  int idx = it.key();
364 
365  if (!(*cc608it).m_srtWriters[idx])
366  {
367  int langCode = 0;
368  auto *avd = dynamic_cast<AvFormatDecoder *>(m_decoder);
369  if (avd)
370  langCode = avd->GetCaptionLanguage(
371  kTrackTypeCC608, idx + 1);
372 
373  QString lang = iso639_key_to_str3(langCode);
374  lang = iso639_is_key_undefined(langCode) ? "und" : lang;
375 
376  QString service_key = QString("cc%1").arg(idx + 1);
377  QString filename = QString("%1.%2%3-%4.%5.srt")
378  .arg(m_baseName).arg(stream_id_str).arg("608")
379  .arg(service_key).arg(lang);
380 
381  (*cc608it).m_srtWriters[idx] = new SRTWriter(
382  m_workingDir.filePath(filename));
383  }
384 
385  if (!(*cc608it).m_srtWriters[idx]->IsOpen())
386  {
387  (*it).clear();
388  continue;
389  }
390 
391  while ((*it).size() > ((kProcessFinalize & flags) ? 0 : 1))
392  {
393  if ((*it).front().m_length <= 0)
394  (*it).front().m_length = OneSubtitle::kDefaultLength;
395 
396  (*cc608it).m_srtWriters[idx]->AddSubtitle(
397  (*it).front(), ++(*cc608it).m_subsNum[idx]);
398  (*it).pop_front();
399  }
400 
401  (*cc608it).m_srtWriters[idx]->Flush();
402  }
403  }
404 }
405 
407 {
408  // For each window of each service of each video...
409  for (auto it = m_cc708Info.cbegin(); it != m_cc708Info.cend(); ++it)
410  {
411  for (uint serviceIdx = 1; serviceIdx < k708MaxServices; ++serviceIdx)
412  {
413  CC708Service *service = (*it).m_reader->GetService(serviceIdx);
414  for (uint windowIdx = 0; windowIdx < 8; ++windowIdx)
415  {
416  CC708Window &win = service->m_windows[windowIdx];
417  if (win.GetChanged())
418  {
419  vector<CC708String*> strings;
420  if (win.GetVisible())
421  {
422  strings = win.GetStrings();
423  Ingest708Caption(it.key(), serviceIdx, windowIdx,
424  win.m_pen.m_row, win.m_pen.m_column,
425  win, strings);
427  }
428  service->m_windows[windowIdx].ResetChanged();
429  }
430  }
431  }
432  }
433 }
434 
436  uint streamId, uint serviceIdx,
437  uint windowIdx, uint start_row, uint start_column,
438  const CC708Window &win,
439  const vector<CC708String*> &content)
440 {
441  FormattedTextSubtitle708 fsub(win, windowIdx, content);
442  QStringList winContent = fsub.ToSRT();
443 
444  QMap<int, Window> &cc708win = m_cc708Windows[streamId][serviceIdx];
445  cc708win[windowIdx].row = start_row;
446  cc708win[windowIdx].column = start_column;
447  cc708win[windowIdx].text = winContent;
448 
449  QMap<uint, QStringList> orderedContent;
450  for (const auto& ccIt : qAsConst(cc708win))
451  {
452  uint idx = ccIt.row * 1000 + ccIt.column;
453  for (const auto& str : qAsConst(ccIt.text))
454  {
455  orderedContent[idx] += str;
456  }
457  }
458 
459  QStringList screenContent;
460  for (const auto & ordered : qAsConst(orderedContent))
461  screenContent += ordered;
462  IngestSubtitle(m_cc708Info[streamId].m_subs[serviceIdx], screenContent);
463 }
464 
465 // Note: GetCaptionLanguage() will not return valid if there are multiple videos
467 {
468  int i = 0;
469  // NOLINTNEXTLINE(modernize-loop-convert)
470  for (auto cc708it = m_cc708Info.begin(); cc708it != m_cc708Info.end(); ++cc708it)
471  {
472  QString stream_id_str = (m_cc708Info.size() <= 1) ?
473  QString("") : QString("%1.").arg(i,2,10,QChar('0'));
474 
475  CC708StreamType &subs = (*cc708it).m_subs;
476  for (auto it = subs.begin(); it != subs.end(); ++it)
477  {
478  if ((*it).empty())
479  continue; // Skip empty subtitle streams.
480  if (((kProcessFinalize & flags) == 0) && ((*it).size() <= 1))
481  continue; // Leave one caption behind so it can be amended
482 
483  int idx = it.key();
484 
485  if (!(*cc708it).m_srtWriters[idx])
486  {
487  int langCode = 0;
488  auto *avd = dynamic_cast<AvFormatDecoder*>(m_decoder);
489  if (avd)
490  langCode = avd->GetCaptionLanguage(kTrackTypeCC708, idx);
491 
492  QString lang = iso639_key_to_str3(langCode);
493 
494  QString service_key = QString("service-%1")
495  .arg(idx, 2, 10, QChar('0'));
496  QString filename = QString("%1.%2%3-%4.%5.srt")
497  .arg(m_baseName).arg(stream_id_str).arg("708")
498  .arg(service_key).arg(lang);
499 
500  (*cc708it).m_srtWriters[idx] = new SRTWriter(
501  m_workingDir.filePath(filename));
502  }
503 
504  if (!(*cc708it).m_srtWriters[idx]->IsOpen())
505  {
506  (*it).clear();
507  continue;
508  }
509 
510  while ((*it).size() > ((kProcessFinalize & flags) ? 0 : 1))
511  {
512  if ((*it).front().m_length <= 0)
513  (*it).front().m_length = OneSubtitle::kDefaultLength;
514 
515  (*cc708it).m_srtWriters[idx]->AddSubtitle(
516  (*it).front(), ++(*cc708it).m_subsNum[idx]);
517  (*it).pop_front();
518  }
519 
520  (*cc708it).m_srtWriters[idx]->Flush();
521  }
522  }
523 }
524 
525 static QStringList to_string_list(const TeletextSubPage &subPage)
526 {
527  QStringList content;
528  // Skip the page header (line 0)
529  for (size_t i = 1; i < subPage.data.size(); ++i)
530  {
531  QString str = decode_teletext(subPage.lang, subPage.data[i]).trimmed();
532  if (!str.isEmpty())
533  content += str;
534  }
535  return content;
536 }
537 
539 {
540  // NOLINTNEXTLINE(modernize-loop-convert)
541  for (auto ttxit = m_ttxInfo.begin(); ttxit != m_ttxInfo.end(); ++ttxit)
542  {
543  using qpii = QPair<int, int>;
544  QSet<qpii> updatedPages = (*ttxit).m_reader->GetUpdatedPages();
545  if (updatedPages.isEmpty())
546  continue;
547 
548  for (auto it = updatedPages.constBegin(); it != updatedPages.constEnd(); ++it)
549  {
550  (*ttxit).m_reader->SetPage((*it).first, (*it).second);
551  TeletextSubPage *subpage = (*ttxit).m_reader->FindSubPage();
552  if (subpage && subpage->subtitle)
553  {
554  IngestSubtitle((*ttxit).m_subs[(*it).first],
555  to_string_list(*subpage));
556  }
557  }
558 
559  (*ttxit).m_reader->ClearUpdatedPages();
560  }
561 }
562 
564 {
565  int i = 0;
566  // NOLINTNEXTLINE(modernize-loop-convert)
567  for (auto ttxit = m_ttxInfo.begin(); ttxit != m_ttxInfo.end(); ++ttxit)
568  {
569  QString stream_id_str = (m_cc608Info.size() <= 1) ?
570  QString("") : QString("%1.").arg(i,2,10,QChar('0'));
571 
572  TeletextStreamType &subs = (*ttxit).m_subs;
573  for (auto it = subs.begin(); it != subs.end(); ++it)
574  {
575  if ((*it).empty())
576  continue; // Skip empty subtitle streams.
577  if (((kProcessFinalize & flags) == 0) && ((*it).size() <= 1))
578  continue; // Leave one caption behind so it can be amended
579 
580  uint page = it.key();
581 
582  if (!(*ttxit).m_srtWriters[page])
583  {
584  int langCode = 0;
585  auto *avd = dynamic_cast<AvFormatDecoder *>(m_decoder);
586 
587  if (avd)
588  langCode = avd->GetTeletextLanguage(page);
589 
590  QString lang = iso639_key_to_str3(langCode);
591  lang = iso639_is_key_undefined(langCode) ? "und" : lang;
592  QString filename = QString("%1-%2.%3ttx-0x%4.srt")
593  .arg(m_baseName)
594  .arg(lang)
595  .arg(stream_id_str)
596  .arg(page, 3, 16, QChar('0'));
597 
598  (*ttxit).m_srtWriters[page] = new SRTWriter(
599  m_workingDir.filePath(filename));
600  }
601 
602  if (!(*ttxit).m_srtWriters[page]->IsOpen())
603  {
604  (*it).clear();
605  continue;
606  }
607 
608  while ((*it).size() > ((kProcessFinalize & flags) ? 0 : 1))
609  {
610  if ((*it).front().m_length <= 0)
611  (*it).front().m_length = OneSubtitle::kDefaultLength;
612 
613  (*ttxit).m_srtWriters[page]->AddSubtitle(
614  (*it).front(), ++(*ttxit).m_subsNum[page]);
615  (*it).pop_front();
616  }
617 
618  (*ttxit).m_srtWriters[page]->Flush();
619  }
620  }
621 }
622 
624 {
625  // NOLINTNEXTLINE(modernize-loop-convert)
626  for (auto subit = m_dvbsubInfo.begin(); subit != m_dvbsubInfo.end(); ++subit)
627  {
629  if ((*subit).m_reader->HasTextSubtitles())
630  {
631  LOG(VB_VBI, LOG_DEBUG,
632  "There are unhandled text dvb subtitles");
633  }
634 
635  uint64_t duration = 0;
636  const QStringList rawSubs =
637  (*subit).m_reader->GetRawTextSubtitles(duration);
638  if (!rawSubs.isEmpty())
639  {
640  LOG(VB_VBI, LOG_DEBUG,
641  QString("There are also %1 raw text subtitles with duration %2")
642  .arg(rawSubs.size()).arg(duration));
643  }
645 
646  AVSubtitles *avsubtitles = (*subit).m_reader->GetAVSubtitles();
647 
648  QMutexLocker locker(&(avsubtitles->m_lock));
649 
650  while (!avsubtitles->m_buffers.empty())
651  {
652  AVSubtitle subtitle = avsubtitles->m_buffers.front();
653  avsubtitles->m_buffers.pop_front();
654 
655  const QSize v_size =
656  QSize(GetVideoSize().width()*4, GetVideoSize().height()*4);
657  QImage sub_pict(v_size, QImage::Format_ARGB32);
658  sub_pict.fill(0);
659 
660  int min_x = v_size.width();
661  int min_y = v_size.height();
662  int max_x = 0;
663  int max_y = 0;
664 
665  QPainter painter(&sub_pict);
666  for (int i = 0; i < (int) subtitle.num_rects; ++i)
667  {
668  AVSubtitleRect *rect = subtitle.rects[i];
669 
670  if (subtitle.rects[i]->type == SUBTITLE_BITMAP)
671  {
672  const int x = rect->x;
673  const int y = rect->y;
674  const int w = rect->w;
675  const int h = rect->h;
676  const int cc = rect->nb_colors;
677  const uchar *data = rect->data[0];
678  const QRgb *palette = (QRgb *) rect->data[1];
679 
680  QImage img(data, w, h, QImage::Format_Indexed8);
681  img.setColorCount(cc);
682  for (int j = 0; j < cc; ++j)
683  img.setColor(j, palette[j]);
684 
685  painter.drawImage(x, y, img);
686 
687  min_x = std::min(min_x, x);
688  min_y = std::min(min_y, y);
689  max_x = std::max(max_x, x + w);
690  max_y = std::max(max_y, y + h);
691  }
692  }
693  painter.end();
694 
695  OneSubtitle sub;
696  sub.m_startTime = subtitle.start_display_time;
697  sub.m_length =
698  subtitle.end_display_time - subtitle.start_display_time;
699 
701 
702  if (min_x < max_x && min_y < max_y)
703  {
704  sub.m_imgShift = QPoint(min_x, min_y);
705  sub.m_img = sub_pict.copy(
706  min_x, min_y, max_x - min_x, max_y - min_y);
707  }
708  else
709  {
710  // Empty subtitle, do nothing.
711  }
712 
713  IngestSubtitle((*subit).m_subs, sub);
714  }
715 
716  locker.unlock();
717 
718  (*subit).m_reader->ClearRawTextSubtitles();
719  }
720 }
721 
723 {
724  // Process (DVB) subtitle streams.
725  int subtitleStreamCount = 0;
726  for (auto subit = m_dvbsubInfo.begin(); subit != m_dvbsubInfo.end(); ++subit)
727  {
728  int langCode = 0;
729  auto *avd = dynamic_cast<AvFormatDecoder *>(m_decoder);
730  int idx = subit.key();
731  if (avd)
732  langCode = avd->GetSubtitleLanguage(subtitleStreamCount, idx);
733  subtitleStreamCount++;
734 
735  QString lang = iso639_key_to_str3(langCode);
736  lang = iso639_is_key_undefined(langCode) ? "und" : lang;
737  QString dir_name = m_baseName + QString("-%1.dvb-%2").arg(lang).arg(subit.key());
738  if (!m_workingDir.exists(dir_name) && !m_workingDir.mkdir(dir_name))
739  {
740  LOG(VB_GENERAL, LOG_ERR, QString("Can't create directory '%1'")
741  .arg(dir_name));
742  (*subit).m_subs.clear();
743  continue;
744  }
745 
746  DVBStreamType &subs = (*subit).m_subs;
747  if (subs.empty())
748  continue; // Skip empty subtitle streams.
749  if (((kProcessFinalize & flags) == 0) && (subs.size() <= 1))
750  continue; // Leave one caption behind so it can be amended
751 
752  QDir stream_dir(m_workingDir.filePath(dir_name));
753  while (subs.size() > ((kProcessFinalize & flags) ? 0 : 1))
754  {
755  if (subs.front().m_length <= 0)
756  subs.front().m_length = OneSubtitle::kDefaultLength;
757 
758  const OneSubtitle &sub = subs.front();
759  int64_t end_time = sub.m_startTime + sub.m_length;
760  const QString file_name =
761  stream_dir.filePath(
762  QString("%1_%2-to-%3.png")
763  .arg((*subit).m_subsNum)
764  .arg(sub.m_startTime).arg(end_time));
765 
766  if (end_time > sub.m_startTime)
767  {
768  //check is there exist file with same m_startTime
769  QStringList filter;
770  filter << QString("*_%1*.png").arg(sub.m_startTime);
771  QFileInfoList found = stream_dir.entryInfoList(filter);
772  if (found.isEmpty())
773  {
774  //no same m_startTime founded
775  if (!sub.m_img.save(file_name))
776  {
777  LOG(VB_GENERAL, LOG_ERR,
778  QString("Can't write file '%1'")
779  .arg(file_name));
780  }
781  (*subit).m_subsNum++;
782  }
783  }
784  subs.pop_front();
785  }
786  }
787 }
788 
789 
791 {
792  if (!m_cc708Info[id].m_reader)
793  {
794  m_cc708Info[id].m_reader = new CC708Reader(this);
795  m_cc708Info[id].m_reader->SetEnabled(true);
796  LOG(VB_GENERAL, LOG_INFO, "Created CC708Reader");
797  }
798  return m_cc708Info[id].m_reader;
799 }
800 
802 {
803  if (!m_cc608Info[id].m_reader)
804  {
805  m_cc608Info[id].m_reader = new CC608Reader(this);
806  m_cc608Info[id].m_reader->SetEnabled(true);
807  }
808  return m_cc608Info[id].m_reader;
809 }
810 
812 {
813  if (!m_ttxInfo[id].m_reader)
814  m_ttxInfo[id].m_reader = new TeletextExtractorReader();
815  return m_ttxInfo[id].m_reader;
816 }
817 
819 {
820  if (!m_dvbsubInfo[id].m_reader)
821  {
822  m_dvbsubInfo[id].m_reader = new SubtitleReader();
823  m_dvbsubInfo[id].m_reader->EnableAVSubtitles(true);
824  m_dvbsubInfo[id].m_reader->EnableTextSubtitles(true);
825  m_dvbsubInfo[id].m_reader->EnableRawTextSubtitles(true);
826  }
827  return m_dvbsubInfo[id].m_reader;
828 }
TeletextSubPage::lang
int lang
language code
Definition: teletextreader.h:43
CC608Buffer::m_lock
QMutex m_lock
Definition: cc608reader.h:50
CC708Stuff::m_reader
CC708Reader * m_reader
Definition: mythccextractorplayer.h:83
comps
static const std::array< std::array< QString, 3 >, 95 > comps
Definition: mythvirtualkeyboard.cpp:25
TeletextStuff::m_reader
TeletextExtractorReader * m_reader
Definition: mythccextractorplayer.h:94
CC708Pen::m_column
uint m_column
Definition: cc708window.h:171
PlayerContext::UnlockPlayingInfo
void UnlockPlayingInfo(const char *file, int line) const
Definition: playercontext.cpp:299
MythCCExtractorPlayer::Process708Captions
void Process708Captions(uint flags)
Definition: mythccextractorplayer.cpp:466
CC708Service::m_windows
std::array< CC708Window, k708MaxWindows > m_windows
Definition: cc708window.h:319
MythTimer
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:14
MythCCExtractorPlayer::m_cc608Info
CC608Info m_cc608Info
Definition: mythccextractorplayer.h:151
k708MaxServices
const uint k708MaxServices
Definition: cc708reader.h:14
CC708Window
Definition: cc708window.h:194
build_compdb.content
content
Definition: build_compdb.py:38
cc
Definition: cc.h:10
CC608Buffer::m_buffers
std::vector< CC608Text * > m_buffers
Definition: cc608reader.h:51
TeletextSubPage::subtitle
bool subtitle
page is subtitle page
Definition: teletextreader.h:48
arg
arg(title).arg(filename).arg(doDelete))
MythCCExtractorPlayer::Process608Captions
void Process608Captions(uint flags)
Definition: mythccextractorplayer.cpp:346
Context
QHash< QString, Action * > Context
Definition: action.h:77
SubtitleReader
Definition: subtitlereader.h:33
TeletextSubPage
Definition: teletextreader.h:39
MythPlayer::IsErrored
bool IsErrored(void) const
Definition: mythplayer.cpp:3484
MythCCExtractorPlayer::IngestSubtitle
void IngestSubtitle(QList< OneSubtitle > &list, const QStringList &content) const
Adds new subtitle, finishes last if needed.
Definition: mythccextractorplayer.cpp:217
MythTimer::start
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
ProgramInfo::UpdateInUseMark
void UpdateInUseMark(bool force=false)
Definition: programinfo.cpp:4701
PlayerFlags
PlayerFlags
Definition: mythplayer.h:79
DVBSubStuff::~DVBSubStuff
~DVBSubStuff()
Definition: mythccextractorplayer.cpp:49
MythPlayer
Definition: mythplayer.h:100
TeletextStreamType
QHash< int, QList< OneSubtitle > > TeletextStreamType
Key is a page number, values are the subtitles in chrono order.
Definition: mythccextractorplayer.h:55
OneSubtitle
Represents one subtitle record.
Definition: mythccextractorplayer.h:30
MythCCExtractorPlayer::m_cc708Info
CC708Info m_cc708Info
Definition: mythccextractorplayer.h:152
MythPlayer::CC708Reader
friend class CC708Reader
Definition: mythplayer.h:105
SRTStuff::~SRTStuff
virtual ~SRTStuff()
Definition: mythccextractorplayer.cpp:38
FormattedTextSubtitle708
Definition: subtitlescreen.h:144
FormattedTextSubtitle608
Definition: subtitlescreen.h:128
teletextextractorreader.h
iso639_is_key_undefined
static bool iso639_is_key_undefined(int code)
Returns true if the key is 0, 0xFFFFFF, or 'und'.
Definition: iso639.h:55
MythCCExtractorPlayer::m_curTime
double m_curTime
Keeps track for decoding time to make timestamps for subtitles.
Definition: mythccextractorplayer.h:169
MythPlayer::CC608Reader
friend class CC608Reader
Definition: mythplayer.h:106
srtwriter.h
MythCCExtractorPlayer::ProcessDVBSubtitles
void ProcessDVBSubtitles(uint flags)
Definition: mythccextractorplayer.cpp:722
MythCCExtractorPlayer::GetSubReader
SubtitleReader * GetSubReader(uint id=0) override
Definition: mythccextractorplayer.cpp:818
MythCCExtractorPlayer::Ingest708Captions
void Ingest708Captions(void)
Definition: mythccextractorplayer.cpp:406
MythCCExtractorPlayer::IngestTeletext
void IngestTeletext(void)
Definition: mythccextractorplayer.cpp:538
CC708Window::GetVisible
bool GetVisible(void) const
Definition: cc708window.h:287
MythCCExtractorPlayer::MythCCExtractorPlayer
MythCCExtractorPlayer(PlayerContext *Context, PlayerFlags flags, bool showProgress, QString fileName, const QString &destdir)
Definition: mythccextractorplayer.cpp:51
TeletextReader
Definition: teletextreader.h:76
MythPlayer::m_decoder
DecoderBase * m_decoder
Definition: mythplayer.h:502
MythPlayer::m_framesPlayed
uint64_t m_framesPlayed
Definition: mythplayer.h:563
subtitlescreen.h
MythCCExtractorPlayer::m_baseName
QString m_baseName
Definition: mythccextractorplayer.h:174
decode_teletext
QString decode_teletext(int codePage, const tt_line_array &data)
Get decoded ttx as a string.
Definition: teletextextractorreader.cpp:132
PlayerContext::m_playingInfo
ProgramInfo * m_playingInfo
Currently playing info.
Definition: playercontext.h:124
DVBStreamType
QList< OneSubtitle > DVBStreamType
Subtitles in chrono order.
Definition: mythccextractorplayer.h:57
CC608Stuff::~CC608Stuff
~CC608Stuff() override
Definition: mythccextractorplayer.cpp:46
MythPlayer::DecoderGetFrame
bool DecoderGetFrame(DecodeType decodetype, bool unsafe=false)
Definition: mythplayer.cpp:2175
SRTWriter
Class to write SubRip files.
Definition: srtwriter.h:28
PlayerContext::LockPlayingInfo
void LockPlayingInfo(const char *file, int line) const
Definition: playercontext.cpp:287
OneSubtitle::m_length
int m_length
Time we have to show subtitle, msec.
Definition: mythccextractorplayer.h:35
CC708Service
Definition: cc708window.h:313
MythPlayer::m_videoOutput
MythVideoOutput * m_videoOutput
Definition: mythplayer.h:504
CC608Buffer
Definition: cc608reader.h:38
MythCCExtractorPlayer::run
bool run(void)
Definition: mythccextractorplayer.cpp:126
MythPlayer::InitVideo
virtual bool InitVideo(void)
Definition: mythplayer.cpp:314
CC708StreamType
QHash< int, QList< OneSubtitle > > CC708StreamType
Key is a CC service (1-63), values are the subtitles in chrono order.
Definition: mythccextractorplayer.h:53
MythCCExtractorPlayer::m_dvbsubInfo
DVBSubInfo m_dvbsubInfo
Definition: mythccextractorplayer.h:154
AVSubtitles
Definition: subtitlereader.h:14
to_string_list
static QStringList to_string_list(const TeletextSubPage &subPage)
Definition: mythccextractorplayer.cpp:525
MythPlayer::ClearAfterSeek
void ClearAfterSeek(bool clearvideobuffers=true)
This is to support seeking...
Definition: mythplayer.cpp:2743
MythCCExtractorPlayer::m_fileName
QString m_fileName
Definition: mythccextractorplayer.h:172
filename
QString filename
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:637
SubtitleReader::FreeAVSubtitle
static void FreeAVSubtitle(AVSubtitle &sub)
Definition: subtitlereader.cpp:82
MythPlayer::m_totalFrames
uint64_t m_totalFrames
Definition: mythplayer.h:564
MythCCExtractorPlayer::Ingest608Captions
void Ingest608Captions(void)
Definition: mythccextractorplayer.cpp:295
AvFormatDecoder::GetCaptionLanguage
virtual int GetCaptionLanguage(TrackType TrackType, int ServiceNum)
Return ATSC Closed Caption Language.
Definition: avformatdecoder.cpp:2579
MythPlayer::m_playerCtx
PlayerContext * m_playerCtx
Definition: mythplayer.h:505
CC608StreamType
QHash< int, QList< OneSubtitle > > CC608StreamType
Key is a CC number (1-4), values are the subtitles in chrono order.
Definition: mythccextractorplayer.h:51
OneSubtitle::m_text
QStringList m_text
Lines of text of subtitles.
Definition: mythccextractorplayer.h:39
DecoderBase::GetFPS
virtual double GetFPS(void) const
Definition: decoderbase.h:197
AvFormatDecoder
A decoder for media files.
Definition: avformatdecoder.h:87
kTrackTypeCC708
@ kTrackTypeCC708
Definition: decoderbase.h:33
iso639_key_to_str3
static QString iso639_key_to_str3(int code)
Definition: iso639.h:46
uint
unsigned int uint
Definition: compat.h:140
TeletextExtractorReader
Definition: teletextextractorreader.h:17
AvFormatDecoder::GetTeletextLanguage
virtual int GetTeletextLanguage(uint Index)
Returns TeleText language.
Definition: avformatdecoder.cpp:2562
mythccextractorplayer.h
MythPlayer::GetDecoder
DecoderBase * GetDecoder(void)
Returns the stream decoder currently in use.
Definition: mythplayer.h:216
MythCCExtractorPlayer::GetTeletextReader
TeletextReader * GetTeletextReader(uint id=0) override
Definition: mythccextractorplayer.cpp:811
OneSubtitle::m_img
QImage m_img
Image of subtitle.
Definition: mythccextractorplayer.h:41
MythCCExtractorPlayer::m_workingDir
QDir m_workingDir
Definition: mythccextractorplayer.h:173
MythVideoOutput::StartDisplayingFrame
virtual void StartDisplayingFrame()
Tell GetLastShownFrame() to return the next frame from the head of the queue of frames to display.
Definition: mythvideoout.cpp:504
MythCCExtractorPlayer::m_showProgress
bool m_showProgress
Definition: mythccextractorplayer.h:171
MythTimer::elapsed
int elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:90
MythCCExtractorPlayer::m_ttxInfo
TeletextInfo m_ttxInfo
Definition: mythccextractorplayer.h:153
MythCCExtractorPlayer::kProcessNormal
@ kProcessNormal
Definition: mythccextractorplayer.h:131
kDecodeVideo
@ kDecodeVideo
Definition: decoderbase.h:50
kTrackTypeCC608
@ kTrackTypeCC608
Definition: decoderbase.h:32
progress_string
static QString progress_string(MythTimer &flagTime, uint64_t m_myFramesPlayed, uint64_t totalFrames)
Definition: mythccextractorplayer.cpp:99
MythVideoFrame::m_repeatPic
bool m_repeatPic
used to unlock the scan type
Definition: mythframe.h:119
CC708Window::GetChanged
bool GetChanged(void) const
Definition: cc708window.h:288
DecoderBase::SetDecodeAllSubtitles
void SetDecodeAllSubtitles(bool DecodeAll)
Definition: decoderbase.cpp:909
CC608Stuff::m_reader
CC608Reader * m_reader
Definition: mythccextractorplayer.h:73
AVSubtitles::m_buffers
MythDeque< AVSubtitle > m_buffers
Definition: subtitlereader.h:17
MythCCExtractorPlayer::OnGotNewFrame
void OnGotNewFrame(void)
Call it when you got new video frame to process subtitles if any.
Definition: mythccextractorplayer.cpp:79
avformatdecoder.h
MythCCExtractorPlayer::kProcessFinalize
@ kProcessFinalize
Definition: mythccextractorplayer.h:131
TeletextStuff::~TeletextStuff
~TeletextStuff() override
Definition: mythccextractorplayer.cpp:48
DVBSubStuff::m_reader
SubtitleReader * m_reader
Definition: mythccextractorplayer.h:104
MythPlayer::GetVideoSize
QSize GetVideoSize(void) const
Definition: mythplayer.h:147
MythCCExtractorPlayer::GetCC608Reader
CC608Reader * GetCC608Reader(uint id=0) override
Definition: mythccextractorplayer.cpp:801
SRTStuff::m_srtWriters
QHash< int, SRTWriter * > m_srtWriters
Definition: mythccextractorplayer.h:64
MythPlayer::SetPlaying
void SetPlaying(bool is_playing)
Definition: mythplayer.cpp:286
AvFormatDecoder::GetSubtitleLanguage
virtual int GetSubtitleLanguage(uint, uint StreamIndex)
Returns DVD Subtitle language.
Definition: avformatdecoder.cpp:2572
CC708Window::GetStrings
std::vector< CC708String * > GetStrings(void) const
Definition: cc708window.cpp:284
CC708Window::DisposeStrings
static void DisposeStrings(std::vector< CC708String * > &strings)
Definition: cc708window.cpp:376
AVSubtitles::m_lock
QMutex m_lock
Definition: subtitlereader.h:18
MythCCExtractorPlayer::ProcessTeletext
void ProcessTeletext(uint flags)
Definition: mythccextractorplayer.cpp:563
OneSubtitle::kDefaultLength
static const int kDefaultLength
Definition: mythccextractorplayer.h:47
PlayerContext
Definition: playercontext.h:49
OneSubtitle::m_imgShift
QPoint m_imgShift
Shift of image on the screen.
Definition: mythccextractorplayer.h:43
FormattedTextSubtitle::ToSRT
QStringList ToSRT(void) const
Definition: subtitlescreen.cpp:926
iso639.h
ISO 639-1 and ISO 639-2 support functions.
CC708Pen::m_row
uint m_row
Definition: cc708window.h:170
MythCCExtractorPlayer::Ingest708Caption
void Ingest708Caption(uint streamId, uint serviceIdx, uint windowIdx, uint start_row, uint start_column, const CC708Window &win, const vector< CC708String * > &content)
Definition: mythccextractorplayer.cpp:435
MythCCExtractorPlayer::m_myFramesPlayed
uint64_t m_myFramesPlayed
Definition: mythccextractorplayer.h:170
MythVideoFrame
Definition: mythframe.h:83
MythCCExtractorPlayer::m_cc708Windows
QHash< uint, WindowsOnService > m_cc708Windows
Definition: mythccextractorplayer.h:166
CC708Reader
Definition: cc708reader.h:17
CC608Reader
Definition: cc608reader.h:78
MythVideoOutput::GetLastShownFrame
virtual MythVideoFrame * GetLastShownFrame()
Returns frame from the head of the ready to be displayed queue, if StartDisplayingFrame has been call...
Definition: mythvideoout.cpp:405
MythCCExtractorPlayer::GetCC708Reader
CC708Reader * GetCC708Reader(uint id=0) override
Definition: mythccextractorplayer.cpp:790
OneSubtitle::m_startTime
int64_t m_startTime
Time we have to start showing subtitle, msec.
Definition: mythccextractorplayer.h:33
CC708Stuff::~CC708Stuff
~CC708Stuff() override
Definition: mythccextractorplayer.cpp:47
MythVideoFrame::m_frameRate
double m_frameRate
Definition: mythframe.h:109
DecoderBase::GetFramesRead
long long GetFramesRead(void) const
Definition: decoderbase.h:202
MythTimer::restart
int restart(void)
Returns milliseconds elapsed since last start() or restart() and resets the count.
Definition: mythtimer.cpp:62
MythCCExtractorPlayer::IngestDVBSubtitles
void IngestDVBSubtitles(void)
Definition: mythccextractorplayer.cpp:623
MythPlayer::m_killDecoder
bool volatile m_killDecoder
Definition: mythplayer.h:527
MythVideoOutput::DoneDisplayingFrame
virtual void DoneDisplayingFrame(MythVideoFrame *Frame)
Releases frame returned from GetLastShownFrame() onto the queue of frames ready for decoding onto.
Definition: mythvideoout.cpp:511
CC708Window::m_pen
CC708Pen m_pen
Definition: cc708window.h:278
TeletextSubPage::data
std::array< tt_line_array, 25 > data
page data
Definition: teletextreader.h:45