11 #include <QCoreApplication>
38 bool stopForBreath(
bool isrecording,
long long frameno)
40 return (isrecording && (frameno % 100) == 0) || (frameno % 500) == 0;
43 bool needToReportState(
bool showprogress,
bool isrecording,
long long frameno)
45 return ((showprogress || isrecording) && (frameno % 100) == 0) ||
49 void waitForBuffer(
const struct timeval *framestart,
int minlag,
int flaglag,
50 float fps,
bool fullspeed)
52 long usperframe = (
long)(1000000.0F / fps);
53 struct timeval now {};
54 struct timeval elapsed {};
56 (void)gettimeofday(&now,
nullptr);
57 timersub(&now, framestart, &elapsed);
60 long sleepus = usperframe - elapsed.tv_sec * 1000000 - elapsed.tv_usec;
71 else if (flaglag < minlag)
74 sleepus = sleepus * 3 / 2;
76 std::this_thread::sleep_for(std::chrono::microseconds(sleepus));
85 auto it = pass.begin();
86 while (it != pass.end())
89 (*it)->MythPlayerInited(player, nframes);
98 finishedAnalyzers.push_back(*it);
103 deadAnalyzers.push_back(*it);
108 LOG(VB_GENERAL, LOG_ERR,
109 QString(
"Unexpected return value from %1::MythPlayerInited: %2")
110 .
arg((*it)->name()).arg(ares));
124 long long nextFrame = 0;
127 auto it = pass.begin();
128 while (it != pass.end())
131 (*it)->analyzeFrame(frame, frameno, &nextFrame);
136 minNextFrame = std::min(minNextFrame, nextFrame);
141 finishedAnalyzers.push_back(*it);
148 LOG(VB_GENERAL, LOG_ERR,
149 QString(
"Unexpected return value from %1::analyzeFrame: %2")
150 .
arg((*it)->name()).arg(ares));
153 deadAnalyzers.push_back(*it);
162 minNextFrame = frameno + 1;
169 for (
auto & pas : pass)
170 (void)pas->finished(nframes,
final);
177 for (
auto *pas : pass)
178 (void)pas->reportTime();
188 auto it =
std::find(pass.cbegin(), pass.cend(), tf);
189 return it != pass.end();
204 " WHERE chanid = :CHANID"
205 " AND starttime = :STARTTIME"
221 if (!pburl.startsWith(
"/"))
225 QString m_debugdir = pburl.section(
'/',0,-2) +
"/" + basename +
"-debug";
235 LOG(VB_COMMFLAG, LOG_INFO, QString(
"%1 using debug directory \"%2\"")
236 .
arg(comment).
arg(dirname));
240 if (qdir.mkdir(dirname))
242 LOG(VB_COMMFLAG, LOG_INFO,
243 QString(
"%1 created debug directory \"%1\"")
244 .
arg(comment).
arg(dirname));
248 LOG(VB_COMMFLAG, LOG_INFO, QString(
"%1 failed to create \"%2\": %3")
249 .
arg(comment).
arg(dirname).
arg(strerror(errno)));
256 int ms = (int)roundf(frameno / fps * 1000);
257 if (ms % 1000 >= 500)
264 int ms = (int)roundf(frameno / fps * 1000);
272 return QString(
"%1.%2")
273 .arg(tv->tv_sec).arg(tv->tv_usec, 6, 10, QChar(QChar(
'0')));
282 bool showProgress_in,
286 QDateTime startts_in,
288 QDateTime recstartts_in,
289 QDateTime recendts_in,
292 m_showProgress(showProgress_in), m_fullSpeed(fullSpeed_in),
294 m_startts(std::move(startts_in)), m_endts(std::move(endts_in)),
295 m_recstartts(std::move(recstartts_in)), m_recendts(std::move(recendts_in)),
305 std::shared_ptr<PGMConverter> pgmConverter =
306 std::make_shared<PGMConverter>();
307 std::shared_ptr<BorderDetector> borderDetector =
308 std::make_shared<BorderDetector>();
309 std::shared_ptr<HistogramAnalyzer> histogramAnalyzer =
310 std::make_shared<HistogramAnalyzer>(pgmConverter, borderDetector,
349 std::shared_ptr<CannyEdgeDetector> cannyEdgeDetector =
350 std::make_shared<CannyEdgeDetector>();
377 long long nframes,
unsigned int passno,
unsigned int npasses)
379 float fps = elapsedms ? (float)frameno * 1000 / elapsedms : 0;
380 static int s_prevpercent = -1;
383 int percentage = (passno == 0 || npasses == 1 || nframes == 0) ? 0 :
384 (passno - 1) * 100 / (npasses - 1) +
385 std::min((
long long)100, (frameno * 100 / nframes) / (npasses - 1));
392 tmp = QString(
"\r%1%/ %2fps").arg(percentage,3).arg(fps,6,
'f',2);
394 tmp = QString(
"\r%1/ %2fps").arg(frameno,6).arg(fps,6,
'f',2);
396 QByteArray tmp2 =
tmp.toLocal8Bit();
397 std::cerr << tmp2.constData() <<
" \r";
403 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
404 "%1% Completed @ %2 fps.").
arg(percentage).
arg(fps));
408 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
409 "%1 Frames Completed @ %2 fps.").
arg(frameno).
arg(fps));
412 if (percentage % 10 == 0 && s_prevpercent != percentage)
414 s_prevpercent = percentage;
415 LOG(VB_GENERAL, LOG_INFO, QString(
"%1%% Completed @ %2 fps.")
416 .
arg(percentage) .
arg(fps));
479 LOG(VB_GENERAL, LOG_ERR,
480 "NVP: Unable to initialize video for FlagCommercials.");
486 QElapsedTimer totalFlagTime;
487 totalFlagTime.start();
499 std::cerr <<
" 0%/ ";
506 unsigned int passno = 0;
514 LOG(VB_COMMFLAG, LOG_INFO,
515 QString(
"CommDetector2::go pass %1 of %2 (%3 frames, %4 fps)")
516 .
arg(passno + 1).
arg(npasses)
520 if (!MythPlayerInited(
527 long long nextFrame = -1;
530 QElapsedTimer passTime;
532 struct timeval getframetime {};
537 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
538 "Performing Logo Identification"));
542 memset(&getframetime, 0,
sizeof(getframetime));
545 struct timeval start {};
546 struct timeval end {};
547 struct timeval elapsedtv {};
549 (void)gettimeofday(&start,
nullptr);
555 (void)gettimeofday(&end,
nullptr);
557 timeradd(&getframetime, &elapsedtv, &getframetime);
559 if (nextFrame != -1 && nextFrame == lastFrameNumber + 1 &&
566 LOG(VB_COMMFLAG, LOG_INFO,
567 QString(
"Jumped from frame %1 to frame %2")
584 std::this_thread::sleep_for(std::chrono::seconds(1));
592 nframes, passno, npasses);
595 nextFrame = processFrame(
600 (((nextFrame * 10) / nframes) !=
602 (nextFrame >= nframes))
605 int elapsed = clock.restart();
606 LOG(VB_COMMFLAG, LOG_INFO,
607 QString(
"processFrame %1 of %2 (%3%) - %4 fps")
610 .
arg((nframes == 0) ? 0 :
613 (elapsed ? elapsed : 1)));
619 waitForBuffer(&start, minlag,
627 std::this_thread::sleep_for(std::chrono::milliseconds(10));
636 auto ii = breakMap.cbegin();
637 auto jj = lastBreakMap.cbegin();
638 while (ii != breakMap.cend() && jj != lastBreakMap.cend())
640 if (ii.key() != jj.key())
647 bool same = ii == breakMap.cend() && jj == lastBreakMap.cend();
648 lastBreakMap = breakMap;
661 if (passno + 1 == npasses)
674 LOG(VB_COMMFLAG, LOG_INFO, QString(
"NVP Time: GetRawVideoFrame=%1s")
683 std::cerr <<
"\b\b\b\b\b\b \b\b\b\b\b\b";
685 std::cerr <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b "
686 "\b\b\b\b\b\b\b\b\b\b\b\b\b";
717 long long breakframes = 0;
720 long long segb = bb.key();
721 long long seglen = *bb;
722 long long sege = segb + seglen - 1;
729 breakframes += seglen;
735 for (
auto iimark =
marks.cbegin(); iimark !=
marks.cend(); ++iimark)
738 long long markstart = iimark.key() + 1;
740 if (iimark ==
marks.cend())
742 long long markend = iimark.key() + 1;
744 LOG(VB_COMMFLAG, LOG_INFO, QString(
"Break: frame %1-%2 (%3-%4, %5)")
745 .
arg(markstart, 6).
arg(markend, 6)
752 LOG(VB_COMMFLAG, LOG_INFO,
753 QString(
"Flagged %1 of %2 frames (%3 of %4), %5% commercials (%6)")
765 LOG(VB_COMMFLAG, LOG_INFO,
766 QString(
"CommDetector2::recordingFinished: %1 bytes")
767 .
arg(totalFileSize));
774 LOG(VB_COMMFLAG, LOG_INFO,
"Ignoring request for commBreakMapUpdate; "
775 "still doing logo detection");
779 LOG(VB_COMMFLAG, LOG_INFO,
780 QString(
"commBreakMapUpdate requested at frame %1")
789 FrameAnalyzer::FrameMap::const_iterator it = frameMap.begin();
790 for (; it != frameMap.end(); ++it)
797 long long bb = it.key() + 1;
798 long long ee = (*it) ? (bb + *it) : 1;
799 QString
tmp = QString(
"%1: %2").arg(bb, 10).arg(ee - 1, 10);
801 out << qPrintable(
tmp) <<
"\n";
825 out <<
"Logo Break Map" << std::endl;
827 out <<
"Blank Break Map" << std::endl;
829 out <<
"Blank Map" << std::endl;
831 out <<
"Scene Break Map" << std::endl;