52 const QString &destdir) :
54 m_showProgress(showProgress),
55 m_fileName(
std::move(fileName))
61 if (destdir.isEmpty())
85 double duration = 1 / fps +
static_cast<double>(frame->
m_repeatPic) * 0.5 / fps;
97 MythTimer &flagTime, uint64_t m_myFramesPlayed, uint64_t totalFrames)
99 if (totalFrames == 0ULL)
101 return QString(
"%1 frames processed \r")
102 .arg(m_myFramesPlayed,7);
105 static const std::string kSpinChars { R
"(/-\|)" };
106 static uint s_spinCnt = 0;
108 double elapsed = flagTime.
elapsed().count() * 0.001;
109 double flagFPS = (elapsed > 0.0) ? (m_myFramesPlayed / elapsed) : 0;
111 double percentage = m_myFramesPlayed * 100.0 / totalFrames;
112 percentage = (percentage > 100.0 && percentage < 101.0) ?
115 if (m_myFramesPlayed < totalFrames)
116 return QString(
"%1 fps %2% \r")
117 .arg(flagFPS,4,
'f', (flagFPS < 10.0 ? 1 : 0)).arg(percentage,4,
'f',1);
118 return QString(
"%1 fps %2 \r")
119 .arg(flagFPS,4,
'f', (flagFPS < 10.0 ? 1 : 0))
120 .arg(kSpinChars[++s_spinCnt % 4]);
136 LOG(VB_GENERAL, LOG_ERR,
"Unable to initialize video");
158 std::cout <<
"\r \r" << std::flush;
162 if (inuse_timer.
elapsed() > 2534ms)
176 std::cout << qPrintable(str) <<
'\r' << std::flush;
193 std::cout << qPrintable(str) << std::endl;
215 QList<OneSubtitle> &list,
const QStringList &
content)
const
245 list.push_back(new_one);
262 content.m_startTime == list.back().m_startTime &&
267 list.back().m_img =
content.m_img;
287 list.push_back(new_one);
294 static constexpr std::array<int,7> kCcIndexTbl
311 bool changed =
false;
312 int streamRawIdx = -1;
313 CC608Buffer *textlist = (*it).m_reader->GetOutputText(
314 changed, streamRawIdx);
316 if (!changed || !textlist)
319 if (streamRawIdx < 0)
324 const int ccIdx = kCcIndexTbl[std::min(streamRawIdx,6)];
328 textlist->
m_lock.unlock();
335 textlist->
m_lock.unlock();
349 QString stream_id_str = (
m_cc608Info.size() <= 1) ?
350 QString(
"") : QString(
"%1.").arg(i,2,10,QChar(
'0'));
353 for (
auto it = subs.begin(); it != subs.end(); ++it)
362 if (!(*cc608it).m_srtWriters[idx])
373 QString service_key = QString(
"cc%1").arg(idx + 1);
374 QString
filename = QString(
"%1.%2%3-%4.%5.srt")
378 (*cc608it).m_srtWriters[idx] =
new SRTWriter(
382 if (!(*cc608it).m_srtWriters[idx]->IsOpen())
390 if ((*it).front().m_length <= 0ms)
393 (*cc608it).m_srtWriters[idx]->AddSubtitle(
394 (*it).front(), ++(*cc608it).m_subsNum[idx]);
398 (*cc608it).m_srtWriters[idx]->Flush();
410 CC708Service *service = (*it).m_reader->GetService(serviceIdx);
411 for (
uint windowIdx = 0; windowIdx < 8; ++windowIdx)
416 std::vector<CC708String*> strings;
425 service->
m_windows[windowIdx].ResetChanged();
436 const std::vector<CC708String*> &
content)
439 QStringList winContent = fsub.
ToSRT();
441 QMap<int, Window> &cc708win =
m_cc708Windows[streamId][serviceIdx];
442 cc708win[windowIdx].row = start_row;
443 cc708win[windowIdx].column = start_column;
444 cc708win[windowIdx].text = winContent;
446 QMap<uint, QStringList> orderedContent;
447 for (
const auto& ccIt : qAsConst(cc708win))
449 uint idx = ccIt.row * 1000 + ccIt.column;
450 for (
const auto& str : qAsConst(ccIt.text))
452 orderedContent[idx] += str;
456 QStringList screenContent;
457 for (
const auto & ordered : qAsConst(orderedContent))
458 screenContent += ordered;
469 QString stream_id_str = (
m_cc708Info.size() <= 1) ?
470 QString(
"") : QString(
"%1.").arg(i,2,10,QChar(
'0'));
473 for (
auto it = subs.begin(); it != subs.end(); ++it)
482 if (!(*cc708it).m_srtWriters[idx])
491 QString service_key = QString(
"service-%1")
492 .arg(idx, 2, 10, QChar(
'0'));
493 QString
filename = QString(
"%1.%2%3-%4.%5.srt")
497 (*cc708it).m_srtWriters[idx] =
new SRTWriter(
501 if (!(*cc708it).m_srtWriters[idx]->IsOpen())
509 if ((*it).front().m_length <= 0ms)
512 (*cc708it).m_srtWriters[idx]->AddSubtitle(
513 (*it).front(), ++(*cc708it).m_subsNum[idx]);
517 (*cc708it).m_srtWriters[idx]->Flush();
526 for (
size_t i = 1; i < subPage.
data.size(); ++i)
540 using qpii = QPair<int, int>;
541 QSet<qpii> updatedPages = (*ttxit).m_reader->GetUpdatedPages();
542 if (updatedPages.isEmpty())
545 for (
auto it = updatedPages.constBegin(); it != updatedPages.constEnd(); ++it)
547 (*ttxit).m_reader->SetPage((*it).first, (*it).second);
556 (*ttxit).m_reader->ClearUpdatedPages();
566 QString stream_id_str = (
m_cc608Info.size() <= 1) ?
567 QString(
"") : QString(
"%1.").arg(i,2,10,QChar(
'0'));
570 for (
auto it = subs.begin(); it != subs.end(); ++it)
577 uint page = it.key();
579 if (!(*ttxit).m_srtWriters[page])
589 QString
filename = QString(
"%1-%2.%3ttx-0x%4.srt")
591 .arg(page, 3, 16, QChar(
'0'));
593 (*ttxit).m_srtWriters[page] =
new SRTWriter(
597 if (!(*ttxit).m_srtWriters[page]->IsOpen())
605 if ((*it).front().m_length <= 0ms)
608 (*ttxit).m_srtWriters[page]->AddSubtitle(
609 (*it).front(), ++(*ttxit).m_subsNum[page]);
613 (*ttxit).m_srtWriters[page]->Flush();
624 if ((*subit).m_reader->HasTextSubtitles())
626 LOG(VB_VBI, LOG_DEBUG,
627 "There are unhandled text dvb subtitles");
630 std::chrono::milliseconds duration = 0ms;
631 const QStringList rawSubs =
632 (*subit).m_reader->GetRawTextSubtitles(duration);
633 if (!rawSubs.isEmpty())
635 LOG(VB_VBI, LOG_DEBUG,
636 QString(
"There are also %1 raw text subtitles with duration %2")
637 .arg(rawSubs.size()).arg(duration.count()));
641 AVSubtitles *avsubtitles = (*subit).m_reader->GetAVSubtitles();
643 QMutexLocker locker(&(avsubtitles->
m_lock));
647 AVSubtitle subtitle = avsubtitles->
m_buffers.front();
652 QImage sub_pict(v_size, QImage::Format_ARGB32);
655 int min_x = v_size.width();
656 int min_y = v_size.height();
660 QPainter painter(&sub_pict);
661 for (
int i = 0; i < (int) subtitle.num_rects; ++i)
663 AVSubtitleRect *rect = subtitle.rects[i];
665 if (subtitle.rects[i]->type == SUBTITLE_BITMAP)
667 const int x = rect->x;
668 const int y = rect->y;
669 const int w = rect->w;
670 const int h = rect->h;
671 const int cc = rect->nb_colors;
672 const uchar *data = rect->data[0];
673 const QRgb *palette = (QRgb *) rect->data[1];
675 QImage img(data, w, h, QImage::Format_Indexed8);
676 img.setColorCount(
cc);
677 for (
int j = 0; j <
cc; ++j)
678 img.setColor(j, palette[j]);
680 painter.drawImage(x, y, img);
682 min_x = std::min(min_x, x);
683 min_y = std::min(min_y, y);
684 max_x = std::max(max_x, x + w);
685 max_y = std::max(max_y, y + h);
692 std::chrono::milliseconds(subtitle.start_display_time);
694 std::chrono::milliseconds(subtitle.end_display_time -
695 subtitle.start_display_time);
699 if (min_x < max_x && min_y < max_y)
702 sub.
m_img = sub_pict.copy(
703 min_x, min_y, max_x - min_x, max_y - min_y);
715 (*subit).m_reader->ClearRawTextSubtitles();
722 int subtitleStreamCount = 0;
727 int idx = subit.key();
730 subtitleStreamCount++;
734 QString dir_name =
m_baseName + QString(
"-%1.dvb-%2").arg(lang).arg(subit.key());
737 LOG(VB_GENERAL, LOG_ERR, QString(
"Can't create directory '%1'")
739 (*subit).m_subs.clear();
752 if (subs.front().m_length <= 0ms)
757 const QString file_name =
759 QString(
"%1_%2-to-%3.png")
760 .arg((*subit).m_subsNum)
761 .arg(sub.
m_startTime.count()).arg(end_time.count()));
767 filter << QString(
"*_%1*.png").arg(sub.
m_startTime.count());
768 QFileInfoList found = stream_dir.entryInfoList(filter);
772 if (!sub.
m_img.save(file_name))
774 LOG(VB_GENERAL, LOG_ERR,
775 QString(
"Can't write file '%1'")
778 (*subit).m_subsNum++;
793 LOG(VB_GENERAL, LOG_INFO,
"Created CC708Reader");
822 m_dvbsubInfo[id].m_reader->EnableRawTextSubtitles(
true);