53 const QString &destdir) :
57 m_showProgress(showProgress),
58 m_fileName(std::move(fileName))
64 if (destdir.isEmpty())
88 double duration = 1 / fps +
static_cast<double>(frame->
m_repeatPic) * 0.5 / fps;
100 MythTimer &flagTime, uint64_t m_myFramesPlayed, uint64_t totalFrames)
102 if (totalFrames == 0ULL)
104 return QString(
"%1 frames processed \r")
105 .arg(m_myFramesPlayed,7);
108 static const std::string kSpinChars { R
"(/-\|)" };
109 static uint s_spinCnt = 0;
111 double elapsed = flagTime.
elapsed() * 0.001;
112 double flagFPS = (elapsed > 0.0) ? (m_myFramesPlayed / elapsed) : 0;
114 double percentage = m_myFramesPlayed * 100.0 / totalFrames;
115 percentage = (percentage > 100.0 && percentage < 101.0) ?
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]);
139 LOG(VB_GENERAL, LOG_ERR,
"Unable to initialize video");
161 std::cout <<
"\r \r" << std::flush;
165 if (inuse_timer.
elapsed() > 2534)
179 std::cout << qPrintable(str) <<
'\r' << std::flush;
196 std::cout << qPrintable(str) << std::endl;
218 QList<OneSubtitle> &list,
const QStringList &
content)
const
222 (int64_t)
m_curTime == list.back().m_startTime &&
248 list.push_back(new_one);
265 content.m_startTime == list.back().m_startTime &&
270 list.back().m_img =
content.m_img;
290 list.push_back(new_one);
297 static constexpr std::array<int,7> kCcIndexTbl
314 bool changed =
false;
315 int streamRawIdx = -1;
316 CC608Buffer *textlist = (*it).m_reader->GetOutputText(
317 changed, streamRawIdx);
319 if (!changed || !textlist)
322 if (streamRawIdx < 0)
327 const int ccIdx = kCcIndexTbl[std::min(streamRawIdx,6)];
331 textlist->
m_lock.unlock();
338 textlist->
m_lock.unlock();
352 QString stream_id_str = (
m_cc608Info.size() <= 1) ?
353 QString(
"") : QString(
"%1.").arg(i,2,10,QChar(
'0'));
356 for (
auto it = subs.begin(); it != subs.end(); ++it)
365 if (!(*cc608it).m_srtWriters[idx])
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);
381 (*cc608it).m_srtWriters[idx] =
new SRTWriter(
385 if (!(*cc608it).m_srtWriters[idx]->IsOpen())
393 if ((*it).front().m_length <= 0)
396 (*cc608it).m_srtWriters[idx]->AddSubtitle(
397 (*it).front(), ++(*cc608it).m_subsNum[idx]);
401 (*cc608it).m_srtWriters[idx]->Flush();
413 CC708Service *service = (*it).m_reader->GetService(serviceIdx);
414 for (
uint windowIdx = 0; windowIdx < 8; ++windowIdx)
419 vector<CC708String*> strings;
428 service->
m_windows[windowIdx].ResetChanged();
439 const vector<CC708String*> &
content)
442 QStringList winContent = fsub.
ToSRT();
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;
449 QMap<uint, QStringList> orderedContent;
450 for (
const auto& ccIt : qAsConst(cc708win))
452 uint idx = ccIt.row * 1000 + ccIt.column;
453 for (
const auto& str : qAsConst(ccIt.text))
455 orderedContent[idx] += str;
459 QStringList screenContent;
460 for (
const auto & ordered : qAsConst(orderedContent))
461 screenContent += ordered;
472 QString stream_id_str = (
m_cc708Info.size() <= 1) ?
473 QString(
"") : QString(
"%1.").arg(i,2,10,QChar(
'0'));
476 for (
auto it = subs.begin(); it != subs.end(); ++it)
485 if (!(*cc708it).m_srtWriters[idx])
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);
500 (*cc708it).m_srtWriters[idx] =
new SRTWriter(
504 if (!(*cc708it).m_srtWriters[idx]->IsOpen())
512 if ((*it).front().m_length <= 0)
515 (*cc708it).m_srtWriters[idx]->AddSubtitle(
516 (*it).front(), ++(*cc708it).m_subsNum[idx]);
520 (*cc708it).m_srtWriters[idx]->Flush();
529 for (
size_t i = 1; i < subPage.
data.size(); ++i)
543 using qpii = QPair<int, int>;
544 QSet<qpii> updatedPages = (*ttxit).m_reader->GetUpdatedPages();
545 if (updatedPages.isEmpty())
548 for (
auto it = updatedPages.constBegin(); it != updatedPages.constEnd(); ++it)
550 (*ttxit).m_reader->SetPage((*it).first, (*it).second);
559 (*ttxit).m_reader->ClearUpdatedPages();
569 QString stream_id_str = (
m_cc608Info.size() <= 1) ?
570 QString(
"") : QString(
"%1.").arg(i,2,10,QChar(
'0'));
573 for (
auto it = subs.begin(); it != subs.end(); ++it)
580 uint page = it.key();
582 if (!(*ttxit).m_srtWriters[page])
592 QString
filename = QString(
"%1-%2.%3ttx-0x%4.srt")
596 .arg(page, 3, 16, QChar(
'0'));
598 (*ttxit).m_srtWriters[page] =
new SRTWriter(
602 if (!(*ttxit).m_srtWriters[page]->IsOpen())
610 if ((*it).front().m_length <= 0)
613 (*ttxit).m_srtWriters[page]->AddSubtitle(
614 (*it).front(), ++(*ttxit).m_subsNum[page]);
618 (*ttxit).m_srtWriters[page]->Flush();
629 if ((*subit).m_reader->HasTextSubtitles())
631 LOG(VB_VBI, LOG_DEBUG,
632 "There are unhandled text dvb subtitles");
635 uint64_t duration = 0;
636 const QStringList rawSubs =
637 (*subit).m_reader->GetRawTextSubtitles(duration);
638 if (!rawSubs.isEmpty())
640 LOG(VB_VBI, LOG_DEBUG,
641 QString(
"There are also %1 raw text subtitles with duration %2")
642 .
arg(rawSubs.size()).arg(duration));
646 AVSubtitles *avsubtitles = (*subit).m_reader->GetAVSubtitles();
648 QMutexLocker locker(&(avsubtitles->
m_lock));
652 AVSubtitle subtitle = avsubtitles->
m_buffers.front();
657 QImage sub_pict(v_size, QImage::Format_ARGB32);
660 int min_x = v_size.width();
661 int min_y = v_size.height();
665 QPainter painter(&sub_pict);
666 for (
int i = 0; i < (int) subtitle.num_rects; ++i)
668 AVSubtitleRect *rect = subtitle.rects[i];
670 if (subtitle.rects[i]->type == SUBTITLE_BITMAP)
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];
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]);
685 painter.drawImage(x, y, img);
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);
698 subtitle.end_display_time - subtitle.start_display_time;
702 if (min_x < max_x && min_y < max_y)
705 sub.
m_img = sub_pict.copy(
706 min_x, min_y, max_x - min_x, max_y - min_y);
718 (*subit).m_reader->ClearRawTextSubtitles();
725 int subtitleStreamCount = 0;
730 int idx = subit.key();
733 subtitleStreamCount++;
737 QString dir_name =
m_baseName + QString(
"-%1.dvb-%2").arg(lang).arg(subit.key());
740 LOG(VB_GENERAL, LOG_ERR, QString(
"Can't create directory '%1'")
742 (*subit).m_subs.clear();
755 if (subs.front().m_length <= 0)
760 const QString file_name =
762 QString(
"%1_%2-to-%3.png")
763 .
arg((*subit).m_subsNum)
770 filter << QString(
"*_%1*.png").arg(sub.
m_startTime);
771 QFileInfoList found = stream_dir.entryInfoList(filter);
775 if (!sub.
m_img.save(file_name))
777 LOG(VB_GENERAL, LOG_ERR,
778 QString(
"Can't write file '%1'")
781 (*subit).m_subsNum++;
796 LOG(VB_GENERAL, LOG_INFO,
"Created CC708Reader");
825 m_dvbsubInfo[id].m_reader->EnableRawTextSubtitles(
true);