15 #include <QCoreApplication>
39 bool stopForBreath(
bool isrecording,
long long frameno)
41 return (isrecording && (frameno % 100) == 0) || (frameno % 500) == 0;
44 bool needToReportState(
bool showprogress,
bool isrecording,
long long frameno)
46 return ((showprogress || isrecording) && (frameno % 100) == 0) ||
50 void waitForBuffer(
const struct timeval *framestart,
int minlag,
int flaglag,
51 float fps,
bool fullspeed)
53 long usperframe = (long)(1000000.0 / fps);
54 struct timeval now, elapsed;
57 (
void)gettimeofday(&now, NULL);
58 timersub(&now, framestart, &elapsed);
61 sleepus = usperframe - elapsed.tv_sec * 1000000 - elapsed.tv_usec;
72 else if (flaglag < minlag)
75 sleepus = sleepus * 3 / 2;
86 FrameAnalyzerItem::iterator it = pass.begin();
87 while (it != pass.end())
90 (*it)->MythPlayerInited(player, nframes);
99 finishedAnalyzers.push_back(*it);
104 deadAnalyzers.push_back(*it);
109 LOG(VB_GENERAL, LOG_ERR,
110 QString(
"Unexpected return value from %1::MythPlayerInited: %2")
111 .arg((*it)->name()).arg(ares));
128 FrameAnalyzerItem::iterator it = pass.begin();
129 while (it != pass.end())
132 (*it)->analyzeFrame(frame, frameno, &nextFrame);
137 minNextFrame = std::min(minNextFrame, nextFrame);
142 finishedAnalyzers.push_back(*it);
149 LOG(VB_GENERAL, LOG_ERR,
150 QString(
"Unexpected return value from %1::analyzeFrame: %2")
151 .arg((*it)->name()).arg(ares));
154 deadAnalyzers.push_back(*it);
163 minNextFrame = frameno + 1;
170 FrameAnalyzerItem::iterator it = pass.begin();
171 for (; it != pass.end(); ++it)
172 (
void)(*it)->finished(nframes,
final);
179 FrameAnalyzerItem::const_iterator it = pass.begin();
180 for (; it != pass.end(); ++it)
181 (
void)(*it)->reportTime();
191 FrameAnalyzerItem::const_iterator it =
194 return it != pass.end();
199 namespace commDetector2 {
207 query.
prepare(
"SELECT basename"
209 " WHERE chanid = :CHANID"
210 " AND starttime = :STARTTIME"
213 query.
bindValue(
":STARTTIME", recstartts);
226 if (!pburl.startsWith(
"/"))
229 QString basename(query.
value(0).toString());
230 QString debugdir = pburl.section(
'/',0,-2) +
"/" + basename +
"-debug";
240 LOG(VB_COMMFLAG, LOG_INFO, QString(
"%1 using debug directory \"%2\"")
241 .arg(comment).arg(dirname));
245 if (qdir.mkdir(dirname))
247 LOG(VB_COMMFLAG, LOG_INFO,
248 QString(
"%1 created debug directory \"%1\"")
249 .arg(comment).arg(dirname));
253 LOG(VB_COMMFLAG, LOG_INFO, QString(
"%1 failed to create \"%2\": %3")
254 .arg(comment).arg(dirname).arg(strerror(
errno)));
264 ms = (
int)roundf(frameno / fps * 1000);
277 return ts.sprintf(
"%d:%02d:%02d", hh, mm, ss);
285 ms = (
int)roundf(frameno / fps * 1000);
293 return ts.sprintf(
"%d:%02d.%03d", mm, ss, ms);
299 return str.sprintf(
"%ld.%06ld", tv->tv_sec, tv->tv_usec);
304 using namespace commDetector2;
308 bool showProgress_in,
312 const QDateTime &startts_in,
313 const QDateTime &endts_in,
314 const QDateTime &recstartts_in,
315 const QDateTime &recendts_in,
318 showProgress(showProgress_in), fullSpeed(fullSpeed_in),
320 startts(startts_in), endts(endts_in),
321 recstartts(recstartts_in), recendts(recendts_in),
323 sendBreakMapUpdates(
false), breakMapUpdateRequested(
false),
324 finished(
false), currentFrameNumber(0),
325 logoFinder(NULL), logoMatcher(NULL),
326 blankFrameDetector(NULL), sceneChangeDetector(NULL),
349 if (!histogramAnalyzer)
375 if (!histogramAnalyzer)
405 if (!cannyEdgeDetector)
433 long long nframes,
unsigned int passno,
unsigned int npasses)
435 float fps = elapsedms ? (float)frameno * 1000 / elapsedms : 0;
436 int prevpercent = -1;
439 int percentage = passno == 0 ? 0 :
440 (passno - 1) * 100 / (npasses - 1) +
441 min((
long long)100, (frameno * 100 / nframes) / (npasses - 1));
448 tmp = QString(
"\r%1%/ %2fps").arg(percentage,3).arg(fps,6,
'f',2);
450 tmp = QString(
"\r%1/ %2fps").arg(frameno,6).arg(fps,6,
'f',2);
452 QByteArray tmp2 = tmp.toLocal8Bit();
453 cerr << tmp2.constData() <<
" \r";
459 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
460 "%1% Completed @ %2 fps.").arg(percentage).arg(fps));
464 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
465 "%1 Frames Completed @ %2 fps.").arg(frameno).arg(fps));
468 if (percentage % 10 == 0 && prevpercent != percentage)
470 prevpercent = percentage;
471 LOG(VB_GENERAL, LOG_INFO, QString(
"%1%% Completed @ %2 fps.")
472 .arg(percentage) .arg(fps));
478 int trow, tcol, twidth, theight;
533 LOG(VB_GENERAL, LOG_ERR,
534 "NVP: Unable to initialize video for FlagCommercials.");
541 totalFlagTime.start();
560 unsigned int passno = 0;
568 LOG(VB_COMMFLAG, LOG_INFO,
569 QString(
"CommDetector2::go pass %1 of %2 (%3 frames, %4 fps)")
570 .arg(passno + 1).arg(npasses)
574 if (!MythPlayerInited(
575 *
currentPass, finishedAnalyzers, deadAnalyzers, player, nframes))
581 long long nextFrame = -1;
584 QTime passTime, clock;
585 struct timeval getframetime;
590 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
591 "Performing Logo Identification"));
595 memset(&getframetime, 0,
sizeof(getframetime));
598 struct timeval start, end, elapsedtv;
600 (
void)gettimeofday(&start, NULL);
604 (
void)gettimeofday(&end, NULL);
605 timersub(&end, &start, &elapsedtv);
606 timeradd(&getframetime, &elapsedtv, &getframetime);
608 if (nextFrame != -1 && nextFrame == lastFrameNumber + 1 &&
615 LOG(VB_COMMFLAG, LOG_INFO,
616 QString(
"Jumped from frame %1 to frame %2")
641 nframes, passno, npasses);
644 nextFrame = processFrame(
649 (((nextFrame * 10) / nframes) !=
651 (nextFrame >= nframes))
654 int elapsed = clock.restart();
655 LOG(VB_COMMFLAG, LOG_INFO,
656 QString(
"processFrame %1 of %2 (%3%) - %4 fps")
667 waitForBuffer(&start, minlag,
684 frm_dir_map_t::const_iterator ii, jj;
685 ii = breakMap.begin();
686 jj = lastBreakMap.begin();
687 while (ii != breakMap.end() && jj != lastBreakMap.end())
689 if (ii.key() != jj.key())
696 bool same = ii == breakMap.end() && jj == lastBreakMap.end();
697 lastBreakMap = breakMap;
710 if (passno + 1 == npasses)
714 finishedAnalyzers.begin(),
715 finishedAnalyzers.end());
716 finishedAnalyzers.clear();
723 LOG(VB_COMMFLAG, LOG_INFO, QString(
"NVP Time: GetRawVideoFrame=%1s")
732 cerr <<
"\b\b\b\b\b\b \b\b\b\b\b\b";
734 cerr <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b "
735 "\b\b\b\b\b\b\b\b\b\b\b\b\b";
767 long long breakframes = 0;
768 for (FrameAnalyzer::FrameMap::Iterator bb =
breaks.begin();
772 long long segb = bb.key();
773 long long seglen = *bb;
774 long long sege = segb + seglen - 1;
781 breakframes += seglen;
787 for (frm_dir_map_t::const_iterator iimark = marks.begin();
788 iimark != marks.end();
791 long long markstart, markend;
794 markstart = iimark.key() + 1;
796 if (iimark == marks.end())
798 markend = iimark.key() + 1;
800 LOG(VB_COMMFLAG, LOG_INFO, QString(
"Break: frame %1-%2 (%3-%4, %5)")
801 .arg(markstart, 6).arg(markend, 6)
808 LOG(VB_COMMFLAG, LOG_INFO,
809 QString(
"Flagged %1 of %2 frames (%3 of %4), %5% commercials (%6)")
821 LOG(VB_COMMFLAG, LOG_INFO,
822 QString(
"CommDetector2::recordingFinished: %1 bytes")
823 .arg(totalFileSize));
830 LOG(VB_COMMFLAG, LOG_INFO,
"Ignoring request for commBreakMapUpdate; "
831 "still doing logo detection");
835 LOG(VB_COMMFLAG, LOG_INFO,
836 QString(
"commBreakMapUpdate requested at frame %1")
845 FrameAnalyzer::FrameMap::const_iterator it = frameMap.begin();
846 for (; it != frameMap.end(); ++it)
853 long long bb = it.key() + 1;
854 long long ee = (*it) ? (bb + *it) : 1;
855 QString
tmp = QString(
"%1: %2").arg(bb, 10).arg(ee - 1, 10);
857 out << qPrintable(tmp) <<
"\n";
878 out <<
"Logo Break Map" << endl;
880 out <<
"Blank Break Map" << endl;
882 out <<
"Blank Map" << endl;
884 out <<
"Scene Break Map" << endl;