8 #include <QCoreApplication>
35 bool stopForBreath(
bool isrecording,
long long frameno)
37 return (isrecording && (frameno % 100) == 0) || (frameno % 500) == 0;
40 bool needToReportState(
bool showprogress,
bool isrecording,
long long frameno)
42 return ((showprogress || isrecording) && (frameno % 100) == 0) ||
46 void waitForBuffer(std::chrono::microseconds framestart,
int minlag,
int flaglag,
47 float fps,
bool fullspeed)
49 auto usperframe =
floatusecs(1000000.0F / fps);
51 auto now = nowAsDuration<std::chrono::microseconds>();
52 auto elapsed = (now - framestart);
55 auto sleepus = usperframe - duration_cast<floatusecs>(elapsed);
66 else if (flaglag < minlag)
69 sleepus = sleepus * 3 / 2;
71 std::this_thread::sleep_for(sleepus);
80 auto it = pass.begin();
81 while (it != pass.end())
84 (*it)->MythPlayerInited(player, nframes);
93 finishedAnalyzers.push_back(*it);
98 deadAnalyzers.push_back(*it);
103 LOG(VB_GENERAL, LOG_ERR,
104 QString(
"Unexpected return value from %1::MythPlayerInited: %2")
105 .arg((*it)->name()).arg(ares));
119 long long nextFrame = 0;
122 auto it = pass.begin();
123 while (it != pass.end())
126 (*it)->analyzeFrame(frame, frameno, &nextFrame);
131 minNextFrame = std::min(minNextFrame, nextFrame);
136 finishedAnalyzers.push_back(*it);
143 LOG(VB_GENERAL, LOG_ERR,
144 QString(
"Unexpected return value from %1::analyzeFrame: %2")
145 .arg((*it)->name()).arg(ares));
148 deadAnalyzers.push_back(*it);
157 minNextFrame = frameno + 1;
164 for (
auto & pas : pass)
165 (void)pas->finished(nframes,
final);
172 for (
auto *pas : pass)
173 (void)pas->reportTime();
183 auto it =
std::find(pass.cbegin(), pass.cend(), tf);
184 return it != pass.end();
197 query.
prepare(
"SELECT basename"
199 " WHERE chanid = :CHANID"
200 " AND starttime = :STARTTIME"
203 query.
bindValue(
":STARTTIME", recstartts);
216 if (!pburl.startsWith(
"/"))
219 QString basename(query.
value(0).toString());
220 QString m_debugdir = pburl.section(
'/',0,-2) +
"/" + basename +
"-debug";
230 LOG(VB_COMMFLAG, LOG_INFO, QString(
"%1 using debug directory \"%2\"")
231 .arg(comment, dirname));
235 if (qdir.mkdir(dirname))
237 LOG(VB_COMMFLAG, LOG_INFO,
238 QString(
"%1 created debug directory \"%1\"")
239 .arg(comment, dirname));
243 LOG(VB_COMMFLAG, LOG_INFO, QString(
"%1 failed to create \"%2\": %3")
244 .arg(comment, dirname, strerror(errno)));
252 auto secs = std::chrono::ceil<std::chrono::seconds>(ms);
265 auto msecs = duration_cast<std::chrono::milliseconds>(usecs);
275 bool showProgress_in,
279 QDateTime startts_in,
281 QDateTime recstartts_in,
282 QDateTime recendts_in,
285 m_showProgress(showProgress_in), m_fullSpeed(fullSpeed_in),
287 m_startts(
std::move(startts_in)), m_endts(
std::move(endts_in)),
288 m_recstartts(
std::move(recstartts_in)), m_recendts(
std::move(recendts_in)),
298 std::shared_ptr<PGMConverter> pgmConverter =
299 std::make_shared<PGMConverter>();
300 std::shared_ptr<BorderDetector> borderDetector =
301 std::make_shared<BorderDetector>();
302 std::shared_ptr<HistogramAnalyzer> histogramAnalyzer =
303 std::make_shared<HistogramAnalyzer>(pgmConverter, borderDetector,
342 std::shared_ptr<CannyEdgeDetector> cannyEdgeDetector =
343 std::make_shared<CannyEdgeDetector>();
370 long long nframes,
unsigned int passno,
unsigned int npasses)
372 float fps = elapsedms ? (float)frameno * 1000 / elapsedms : 0;
373 static int s_prevpercent = -1;
376 int percentage = (passno == 0 || npasses == 1 || nframes == 0) ? 0 :
377 (passno - 1) * 100 / (npasses - 1) +
378 std::min((
long long)100, (frameno * 100 / nframes) / (npasses - 1));
385 tmp = QString(
"\r%1%/ %2fps").arg(percentage,3).arg(fps,6,
'f',2);
387 tmp = QString(
"\r%1/ %2fps").arg(frameno,6).arg(fps,6,
'f',2);
389 QByteArray tmp2 =
tmp.toLocal8Bit();
390 std::cerr << tmp2.constData() <<
" \r";
396 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
397 "%1% Completed @ %2 fps.").arg(percentage).arg(fps));
401 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
402 "%1 Frames Completed @ %2 fps.").arg(frameno).arg(fps));
405 if (percentage % 10 == 0 && s_prevpercent != percentage)
407 s_prevpercent = percentage;
408 LOG(VB_GENERAL, LOG_INFO, QString(
"%1%% Completed @ %2 fps.")
409 .arg(percentage) .arg(fps));
472 LOG(VB_GENERAL, LOG_ERR,
473 "NVP: Unable to initialize video for FlagCommercials.");
477 QElapsedTimer totalFlagTime;
478 totalFlagTime.start();
490 std::cerr <<
" 0%/ ";
497 unsigned int passno = 0;
505 LOG(VB_COMMFLAG, LOG_INFO,
506 QString(
"CommDetector2::go pass %1 of %2 (%3 frames, %4 fps)")
507 .arg(passno + 1).arg(npasses)
511 if (!MythPlayerInited(
518 long long nextFrame = -1;
521 QElapsedTimer passTime;
523 std::chrono::microseconds getframetime {0us};
528 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
529 "Performing Logo Identification"));
535 auto start = nowAsDuration<std::chrono::microseconds>();
541 auto end = nowAsDuration<std::chrono::microseconds>();
542 getframetime += (end - start);
544 if (nextFrame != -1 && nextFrame == lastFrameNumber + 1 &&
551 LOG(VB_COMMFLAG, LOG_INFO,
552 QString(
"Jumped from frame %1 to frame %2")
569 std::this_thread::sleep_for(1s);
577 nframes, passno, npasses);
580 nextFrame = processFrame(
585 (((nextFrame * 10) / nframes) !=
587 (nextFrame >= nframes))
590 int elapsed = clock.restart();
591 LOG(VB_COMMFLAG, LOG_INFO,
592 QString(
"processFrame %1 of %2 (%3%) - %4 fps")
595 .arg((nframes == 0) ? 0 :
598 (elapsed ? elapsed : 1)));
604 waitForBuffer(start, minlag,
612 std::this_thread::sleep_for(10ms);
621 auto ii = breakMap.cbegin();
622 auto jj = lastBreakMap.cbegin();
623 while (ii != breakMap.cend() && jj != lastBreakMap.cend())
625 if (ii.key() != jj.key())
632 bool same = ii == breakMap.cend() && jj == lastBreakMap.cend();
633 lastBreakMap = breakMap;
646 if (passno + 1 == npasses)
659 LOG(VB_COMMFLAG, LOG_INFO, QString(
"NVP Time: GetRawVideoFrame=%1s")
668 std::cerr <<
"\b\b\b\b\b\b \b\b\b\b\b\b";
670 std::cerr <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b "
671 "\b\b\b\b\b\b\b\b\b\b\b\b\b";
702 long long breakframes = 0;
705 long long segb = bb.key();
706 long long seglen = *bb;
707 long long sege = segb + seglen - 1;
714 breakframes += seglen;
720 for (
auto iimark =
marks.cbegin(); iimark !=
marks.cend(); ++iimark)
723 long long markstart = iimark.key() + 1;
725 if (iimark ==
marks.cend())
727 long long markend = iimark.key() + 1;
729 LOG(VB_COMMFLAG, LOG_INFO, QString(
"Break: frame %1-%2 (%3-%4, %5)")
730 .arg(markstart, 6).arg(markend, 6)
737 LOG(VB_COMMFLAG, LOG_INFO,
738 QString(
"Flagged %1 of %2 frames (%3 of %4), %5% commercials (%6)")
750 LOG(VB_COMMFLAG, LOG_INFO,
751 QString(
"CommDetector2::recordingFinished: %1 bytes")
752 .arg(totalFileSize));
759 LOG(VB_COMMFLAG, LOG_INFO,
"Ignoring request for commBreakMapUpdate; "
760 "still doing logo detection");
764 LOG(VB_COMMFLAG, LOG_INFO,
765 QString(
"commBreakMapUpdate requested at frame %1")
774 FrameAnalyzer::FrameMap::const_iterator it = frameMap.begin();
775 for (; it != frameMap.end(); ++it)
782 long long bb = it.key() + 1;
783 long long ee = (*it) ? (bb + *it) : 1;
784 QString
tmp = QString(
"%1: %2").arg(bb, 10).arg(ee - 1, 10);
786 out << qPrintable(
tmp) <<
"\n";
810 out <<
"Logo Break Map" << std::endl;
812 out <<
"Blank Break Map" << std::endl;
814 out <<
"Blank Map" << std::endl;
816 out <<
"Scene Break Map" << std::endl;