8 #include <QCoreApplication>
58 msg = msg.left(msg.length() - 1);
87 return (
verbose) ?
"normal" :
" N ";
89 return (
verbose) ?
"letter" :
" L ";
91 return (
verbose) ?
"pillar" :
" P ";
93 return (
verbose) ?
"letter,pillar" :
"L,P";
95 return (
verbose) ?
" max " :
" M ";
98 return (
verbose) ?
"unknown" :
" U ";
103 return {
" frame min/max/avg scene aspect format flags"};
109 "%1: %2/%3/%4 %5% %6 %7 %8")
121 bool showProgress_in,
124 QDateTime startedAt_in,
125 QDateTime stopsAt_in,
126 QDateTime recordingStartedAt_in,
127 QDateTime recordingStopsAt_in) :
130 m_commDetectMethod(commDetectMethod_in),
132 m_startedAt(std::move(startedAt_in)),
133 m_stopsAt(std::move(stopsAt_in)),
134 m_recordingStartedAt(std::move(recordingStartedAt_in)),
135 m_recordingStopsAt(std::move(recordingStopsAt_in)),
137 m_fullSpeed(fullSpeed_in),
138 m_showProgress(showProgress_in)
166 m_width = video_disp_dim.width();
185 #ifdef SHOW_DEBUG_WIN
195 LOG(VB_COMMFLAG, LOG_INFO,
196 QString(
"Commercial Detection initialized: "
197 "width = %1, height = %2, fps = %3, method = %4")
227 LOG(VB_COMMFLAG, LOG_INFO,
228 QString(
"Using Sample Spacing of %1 horizontal & %2 vertical pixels.")
263 LOG(VB_COMMFLAG, LOG_DEBUG,
264 " Fr # Min Max Avg Scn F A Mask");
265 LOG(VB_COMMFLAG, LOG_DEBUG,
266 " ------ --- --- --- --- - - ----");
278 CommDetectorBase::deleteLater();
284 int requiredBuffer = 30;
285 int requiredHeadStart = requiredBuffer;
288 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
289 "Building Head Start Buffer"));
297 std::this_thread::sleep_for(2s);
317 int logoDetectBorder =
322 requiredHeadStart += std::max(
326 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
327 "Building Logo Detection Buffer"));
335 std::this_thread::sleep_for(2s);
341 if ((wereRecording) && (!
m_stillRecording) && (secsSince < requiredHeadStart))
349 LOG(VB_GENERAL, LOG_ERR,
350 "NVP: Unable to initialize video for FlagCommercials.");
356 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
357 "Searching for Logo"));
361 std::cerr <<
"Finding Logo";
364 LOG(VB_GENERAL, LOG_INFO,
"Finding Logo");
371 LOG(VB_COMMFLAG, LOG_WARNING,
"No logo found, abort flagging.");
378 std::cerr <<
"\b\b\b\b\b\b\b\b\b\b\b\b "
379 "\b\b\b\b\b\b\b\b\b\b\b\b";
388 QElapsedTimer flagTime;
391 long long myTotalFrames = 0;
401 std::cerr <<
"\r 0%/ \r" << std::flush;
403 std::cerr <<
"\r 0/ \r" << std::flush;
408 int prevpercent = -1;
418 std::chrono::microseconds startTime {0us};
420 startTime = nowAsDuration<std::chrono::microseconds>();
429 float newAspect = currentFrame->
m_aspect;
430 if (newAspect != aspect)
436 if (((currentFrameNumber % 500) == 0) ||
437 (((currentFrameNumber % 100) == 0) &&
450 ((currentFrameNumber % 500) == 0)))
453 frm_dir_map_t::iterator it;
454 frm_dir_map_t::iterator lastIt;
455 bool mapsAreIdentical =
false;
459 if ((commBreakMap.empty()) &&
462 mapsAreIdentical =
true;
467 mapsAreIdentical =
true;
468 for (it = commBreakMap.begin();
469 it != commBreakMap.end() && mapsAreIdentical; ++it)
474 mapsAreIdentical =
false;
491 std::this_thread::sleep_for(1s);
496 std::this_thread::sleep_for(10ms);
498 if (((currentFrameNumber % 500) == 0) ||
500 ((currentFrameNumber % 100) == 0)))
502 float flagFPS { 0.0 };
503 float elapsed = flagTime.elapsed() / 1000.0;
506 flagFPS = currentFrameNumber / elapsed;
512 percentage = currentFrameNumber * 100 / myTotalFrames;
514 percentage = std::min(percentage, 100);
520 QString
tmp = QString(
"\r%1%/%2fps \r")
521 .arg(percentage, 3).arg((
int)flagFPS, 4);
522 std::cerr << qPrintable(
tmp) << std::flush;
526 QString
tmp = QString(
"\r%1/%2fps \r")
527 .arg(currentFrameNumber, 6).arg((
int)flagFPS, 4);
528 std::cerr << qPrintable(
tmp) << std::flush;
534 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
535 "%1% Completed @ %2 fps.")
536 .arg(percentage).arg(flagFPS));
540 emit
statusUpdate(QCoreApplication::translate(
"(mythcommflag)",
541 "%1 Frames Completed @ %2 fps.")
542 .arg(currentFrameNumber).arg(flagFPS));
545 if (percentage % 10 == 0 && prevpercent != percentage)
547 prevpercent = percentage;
548 LOG(VB_GENERAL, LOG_INFO, QString(
"%1%% Completed @ %2 fps.")
549 .arg(percentage) .arg(flagFPS));
557 int secondsRecorded =
560 int secondsBehind = secondsRecorded - secondsFlagged;
563 auto endTime = nowAsDuration<std::chrono::microseconds>();
565 floatusecs usecSleep = usecPerFrame - (endTime - startTime);
567 if (secondsBehind > requiredBuffer)
572 usecSleep = usecSleep * 0.25;
574 else if (secondsBehind < requiredBuffer)
576 usecSleep = usecPerFrame * 1.5;
580 std::this_thread::sleep_for(usecSleep);
589 float elapsed = flagTime.elapsed() / 1000.0;
592 flagFPS = currentFrameNumber / elapsed;
598 std::cerr <<
"\b\b\b\b\b\b \b\b\b\b\b\b";
600 std::cerr <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b "
601 "\b\b\b\b\b\b\b\b\b\b\b\b\b";
609 unsigned int framenum,
bool isSceneChange,
float debugValue)
622 m_frameInfo[framenum].sceneChangePercent = (int) (debugValue*100);
628 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::GetCommBreakMap()");
641 if (!blank && !scene && !logo)
643 LOG(VB_COMMFLAG, LOG_ERR, QString(
"Unexpected commDetectMethod: 0x%1")
648 if (blank && scene && logo)
652 LOG(VB_COMMFLAG, LOG_INFO,
"Final Commercial Break Map");
674 int cnt = ((blank) ? 1 : 0) + ((scene) ? 1 : 0) + ((logo) ? 1 : 0);
682 else if (blank && logo)
687 else if (scene && logo)
694 LOG(VB_COMMFLAG, LOG_INFO,
"Final Commercial Break Map");
712 LOG(VB_COMMFLAG, LOG_INFO,
713 QString(
"CommDetect::SetVideoParams called with aspect = %1")
717 if (fabs(aspect - 1.333333F) < 0.1F)
722 LOG(VB_COMMFLAG, LOG_INFO,
723 QString(
"Aspect Ratio changed from %1 to %2 at frame %3")
737 LOG(VB_COMMFLAG, LOG_ERR,
738 QString(
"Unable to keep track of Aspect ratio change because "
739 "frameInfo for frame number %1 does not exist.")
747 long long frame_number)
751 int blankPixelsChecked = 0;
752 long long totBrightness = 0;
753 auto *rowMax =
new unsigned char[
m_height];
754 auto *colMax =
new unsigned char[
m_width];
755 memset(rowMax, 0,
sizeof(*rowMax)*
m_height);
756 memset(colMax, 0,
sizeof(*colMax)*
m_width);
763 if (!frame || !(frame->
m_buffer) || frame_number == -1 ||
766 LOG(VB_COMMFLAG, LOG_ERR,
"CommDetect: Invalid video frame or codec, "
767 "unable to process frame.");
775 LOG(VB_COMMFLAG, LOG_ERR,
"CommDetect: Width or Height is 0, "
776 "unable to process frame.");
783 unsigned char* framePtr = frame->
m_buffer;
786 fInfo.minBrightness = -1;
787 fInfo.maxBrightness = -1;
788 fInfo.avgBrightness = -1;
789 fInfo.sceneChangePercent = -1;
832 uchar
pixel = framePtr[(y * bytesPerLine) + x];
836 bool checkPixel =
false;
846 blankPixelsChecked++;
847 totBrightness +=
pixel;
849 min = std::min<int>(
pixel, min);
850 max = std::max<int>(
pixel, max);
851 rowMax[y] = std::max(
pixel, rowMax[y]);
852 colMax[x] = std::max(
pixel, colMax[x]);
901 (leftDarkCol < (
m_width * .20)) &&
903 (rightDarkCol > (
m_width * .80)))
908 int avg = totBrightness / blankPixelsChecked;
943 (CheckRatingSymbol()))
969 LOG(VB_COMMFLAG, LOG_DEBUG, QString(
"Frame: %1 -> %2 %3 %4 %5 %6 %7 %8")
980 #ifdef SHOW_DEBUG_WIN
981 comm_debug_show(frame->buf);
992 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::ClearAllMaps()");
1005 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::GetBlankCommMap()");
1015 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::GetBlankCommBreakMap()");
1024 int64_t start_frame)
1026 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::GetSceneChangeMap()");
1028 frm_dir_map_t::iterator it;
1030 if (start_frame == -1)
1034 if ((start_frame == -1) || ((int64_t)it.key() >= start_frame))
1035 scenes[it.key()] = *it;
1041 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::BuildMasterCommList()");
1047 frm_dir_map_t::const_iterator it = a.begin();
1048 for (; it != a.end(); ++it)
1049 newMap[it.key()] = *it;
1052 if ((a.size() > 1) &&
1056 frm_dir_map_t::const_iterator it_a;
1057 frm_dir_map_t::const_iterator it_b;
1062 if ((it_b.key() < 2) && (it_a.key() > 2))
1064 newMap.remove(it_a.key());
1070 frm_dir_map_t::const_iterator it;
1075 for (; it != a.end(); ++it)
1082 for (; it != b.end(); ++it)
1091 newMap.remove(max_a);
1096 if ((a.size() > 3) &&
1099 frm_dir_map_t::const_iterator it_a;
1100 frm_dir_map_t::const_iterator it_b;
1106 while (it_b != a.end())
1108 uint64_t fdiff = it_b.key() - it_a.key();
1109 bool allTrue =
false;
1111 if (fdiff < (62 *
m_fps))
1113 uint64_t f = it_a.key() + 1;
1123 newMap.remove(it_a.key());
1124 newMap.remove(it_b.key());
1129 if (it_b != a.end())
1139 int format,
int aspect)
1154 if (finfo.
format == format)
1157 if (finfo.
aspect == aspect)
1163 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::BuildAllMethodsCommList()");
1166 uint64_t lastStart = 0;
1167 uint64_t lastEnd = 0;
1168 int64_t firstLogoFrame = -1;
1172 std::array<uint64_t,COMM_FORMAT_MAX> formatCounts {};
1174 frm_dir_map_t::iterator it;
1181 uint64_t curFrame = 1;
1194 bool lastFrameWasBlank =
true;
1198 uint64_t aspectFrames = 0;
1215 formatCounts.fill(0);
1226 uint64_t formatFrames = 0;
1229 if (formatCounts[i] > formatFrames)
1232 formatFrames = formatCounts[i];
1248 if (!nextFrameIsBlank || !lastFrameWasBlank)
1252 fbp->
end = curFrame;
1261 fbp = &fblock[curBlock];
1270 fbp->
start = curFrame;
1273 lastFrameWasBlank =
true;
1277 lastFrameWasBlank =
false;
1283 (firstLogoFrame == -1))
1284 firstLogoFrame = curFrame;
1289 fbp->
end = curFrame;
1296 int maxBlock = curBlock;
1300 LOG(VB_COMMFLAG, LOG_INFO,
"Initial Block pass");
1301 LOG(VB_COMMFLAG, LOG_DEBUG,
1302 "Block StTime StFrm EndFrm Frames Secs "
1303 "Bf Lg Cnt RT Cnt SC Cnt SC Rt FmtMch AspMch Score");
1304 LOG(VB_COMMFLAG, LOG_INFO,
1305 "----- ------ ------ ------ ------ ------- "
1306 "--- ------ ------ ------ ----- ------ ------ -----");
1307 while (curBlock <= maxBlock)
1309 fbp = &fblock[curBlock];
1312 LOG(VB_COMMFLAG, LOG_DEBUG, msg);
1317 LOG(VB_COMMFLAG, LOG_DEBUG,
1318 QString(
" FRAMES > %1").arg(
m_fps));
1323 LOG(VB_COMMFLAG, LOG_DEBUG,
1324 " length > max comm length, +20");
1331 LOG(VB_COMMFLAG, LOG_DEBUG,
1332 " length > max comm break length, +20");
1342 LOG(VB_COMMFLAG, LOG_DEBUG,
1343 " length > 4 && logoCount > frames * 0.60 && "
1344 "bfCount < frames * .10");
1349 LOG(VB_COMMFLAG, LOG_DEBUG,
1350 " length > max comm break length, +20");
1356 LOG(VB_COMMFLAG, LOG_DEBUG,
1357 " length <= max comm break length, +10");
1367 LOG(VB_COMMFLAG, LOG_DEBUG,
1368 " logoInfoAvailable && logoCount < frames * .50, "
1377 LOG(VB_COMMFLAG, LOG_DEBUG,
1378 " rating symbol present > 5% of time, +20");
1382 if ((fbp->
scRate > 1.0) &&
1386 LOG(VB_COMMFLAG, LOG_DEBUG,
" scRate > 1.0, -10");
1392 LOG(VB_COMMFLAG, LOG_DEBUG,
" scRate > 2.0, -10");
1402 LOG(VB_COMMFLAG, LOG_DEBUG,
1403 " < 10% of frames match show letter/pillar-box "
1409 if ((abs((
int)(fbp->
frames - (15 *
m_fps))) < 5 ) ||
1414 LOG(VB_COMMFLAG, LOG_DEBUG,
1415 " block appears to be standard comm length, -10");
1422 LOG(VB_COMMFLAG, LOG_DEBUG,
1423 QString(
" FRAMES <= %1").arg(
m_fps));
1426 (fbp->
start >= firstLogoFrame) &&
1430 LOG(VB_COMMFLAG, LOG_DEBUG,
1431 " logoInfoAvailable && logoCount == 0, -10");
1440 LOG(VB_COMMFLAG, LOG_DEBUG,
1441 " < 10% of frames match show letter/pillar-box "
1450 LOG(VB_COMMFLAG, LOG_DEBUG,
1451 " rating symbol present > 25% of time, +10");
1460 LOG(VB_COMMFLAG, LOG_DEBUG,
1461 " < 10% of frames match show aspect, -20");
1466 LOG(VB_COMMFLAG, LOG_DEBUG, msg);
1475 LOG(VB_COMMFLAG, LOG_DEBUG,
"============================================");
1476 LOG(VB_COMMFLAG, LOG_INFO,
"Second Block pass");
1477 LOG(VB_COMMFLAG, LOG_DEBUG,
1478 "Block StTime StFrm EndFrm Frames Secs "
1479 "Bf Lg Cnt RT Cnt SC Cnt SC Rt FmtMch AspMch Score");
1480 LOG(VB_COMMFLAG, LOG_DEBUG,
1481 "----- ------ ------ ------ ------ ------- "
1482 "--- ------ ------ ------ ----- ------ ------ -----");
1483 while (curBlock <= maxBlock)
1485 fbp = &fblock[curBlock];
1488 LOG(VB_COMMFLAG, LOG_DEBUG, msg);
1490 if ((curBlock > 0) && (curBlock < maxBlock))
1492 int nextScore = fblock[curBlock + 1].score;
1494 if ((lastScore < 0) && (nextScore < 0) && (fbp->
length < 35))
1498 LOG(VB_COMMFLAG, LOG_DEBUG,
1499 " lastScore < 0 && nextScore < 0 "
1500 "&& length < 35, setting -10");
1507 (lastScore < 0 && nextScore < 0))
1511 LOG(VB_COMMFLAG, LOG_DEBUG,
1512 " blanks > frames * 0.95 && frames < 2*m_fps && "
1513 "lastScore < 0 && nextScore < 0, setting -10");
1521 (fbp->
score < 20) &&
1526 LOG(VB_COMMFLAG, LOG_DEBUG,
1527 " frames < 120 * m_fps && (-20 < lastScore < 0) && "
1528 "thisScore > 0 && nextScore < 0, setting score = -10");
1536 (fbp->
score > -20) &&
1541 LOG(VB_COMMFLAG, LOG_DEBUG,
1542 " frames < 30 * m_fps && (0 < lastScore < 20) && "
1543 "thisScore < 0 && nextScore > 0, setting score = 10");
1549 if ((fbp->
score == 0) && (lastScore > 30))
1552 while(((curBlock + offset) <= maxBlock) &&
1553 (fblock[curBlock + offset].frames < (2 *
m_fps)) &&
1554 (fblock[curBlock + offset].score == 0))
1557 if ((curBlock + offset) <= maxBlock)
1560 if (fblock[curBlock + offset + 1].score > 0)
1562 for (; offset >= 0; offset--)
1564 fblock[curBlock + offset].score += 10;
1567 LOG(VB_COMMFLAG, LOG_DEBUG,
1568 QString(
" Setting block %1 score +10")
1569 .arg(curBlock+offset));
1573 else if (fblock[curBlock + offset + 1].score < 0)
1575 for (; offset >= 0; offset--)
1577 fblock[curBlock + offset].score -= 10;
1580 LOG(VB_COMMFLAG, LOG_DEBUG,
1581 QString(
" Setting block %1 score -10")
1582 .arg(curBlock+offset));
1590 LOG(VB_COMMFLAG, LOG_DEBUG, msg);
1592 lastScore = fbp->
score;
1596 LOG(VB_COMMFLAG, LOG_DEBUG,
"============================================");
1597 LOG(VB_COMMFLAG, LOG_INFO,
"FINAL Block stats");
1598 LOG(VB_COMMFLAG, LOG_DEBUG,
1599 "Block StTime StFrm EndFrm Frames Secs "
1600 "Bf Lg Cnt RT Cnt SC Cnt SC Rt FmtMch AspMch Score");
1601 LOG(VB_COMMFLAG, LOG_DEBUG,
1602 "----- ------ ------ ------ ------ ------- "
1603 "--- ------ ------ ------ ----- ------ ------ -----");
1606 int64_t breakStart = -1;
1607 while (curBlock <= maxBlock)
1609 fbp = &fblock[curBlock];
1610 int thisScore = fbp->
score;
1612 if ((breakStart >= 0) &&
1615 if (((fbp->
start - breakStart) >
1621 LOG(VB_COMMFLAG, LOG_DEBUG,
1622 QString(
"Closing commercial block at start of "
1623 "frame block %1 with length %2, frame "
1624 "block length of %3 frames would put comm "
1625 "block length over max of %4 seconds.")
1626 .arg(curBlock).arg(fbp->
start - breakStart)
1633 lastStart = breakStart;
1634 lastEnd = fbp->
start;
1641 LOG(VB_COMMFLAG, LOG_DEBUG,
1642 QString(
"Ignoring what appears to be commercial"
1643 " block at frame %1 with length %2, "
1644 "length of %3 frames would put comm "
1645 "block length under min of %4 seconds.")
1647 .arg(fbp->
start - breakStart)
1656 thisScore = lastScore;
1658 else if (thisScore < 0)
1660 if ((lastScore > 0) || (curBlock == 0))
1666 breakStart = lastStart;
1672 LOG(VB_COMMFLAG, LOG_DEBUG,
1673 QString(
"ReOpening commercial block at "
1674 "frame %1 because show less than "
1681 LOG(VB_COMMFLAG, LOG_DEBUG,
1682 "Opening initial commercial block "
1683 "at start of recording, block 0.");
1689 breakStart = fbp->
start;
1693 LOG(VB_COMMFLAG, LOG_DEBUG,
1694 QString(
"Starting new commercial block at "
1695 "frame %1 from start of frame block %2")
1696 .arg(fbp->
start).arg(curBlock));
1700 else if (curBlock == maxBlock)
1702 if ((fbp->
end - breakStart) >
1710 LOG(VB_COMMFLAG, LOG_DEBUG,
1711 QString(
"Closing final commercial block at "
1712 "frame %1").arg(fbp->
end));
1717 lastStart = breakStart;
1726 LOG(VB_COMMFLAG, LOG_DEBUG,
1727 QString(
"Ignoring what appears to be commercial"
1728 " block at frame %1 with length %2, "
1729 "length of %3 frames would put comm "
1730 "block length under min of %4 seconds.")
1732 .arg(fbp->
start - breakStart)
1741 else if ((lastScore < 0) &&
1744 if (((fbp->
start - breakStart) >
1750 lastStart = breakStart;
1751 lastEnd = fbp->
start;
1755 LOG(VB_COMMFLAG, LOG_DEBUG,
1756 QString(
"Closing commercial block at frame %1")
1764 LOG(VB_COMMFLAG, LOG_DEBUG,
1765 QString(
"Ignoring what appears to be commercial "
1766 "block at frame %1 with length %2, "
1767 "length of %3 frames would put comm block "
1768 "length under min of %4 seconds.")
1770 .arg(fbp->
start - breakStart)
1779 LOG(VB_COMMFLAG, LOG_DEBUG, msg);
1781 lastScore = thisScore;
1785 if ((breakStart != -1) &&
1790 LOG(VB_COMMFLAG, LOG_DEBUG,
1791 QString(
"Closing final commercial block started at "
1792 "block %1 and going to end of program. length "
1810 LOG(VB_COMMFLAG, LOG_DEBUG,
1811 "Adjusting start/end marks according to blanks.");
1812 for (it = tmpCommMap.begin(); it != tmpCommMap.end(); ++it)
1816 uint64_t lastStartLower = it.key();
1817 uint64_t lastStartUpper = it.key();
1818 while ((lastStartLower > 0) &&
1824 uint64_t adj = (lastStartUpper - lastStartLower) / 2;
1826 lastStart = lastStartLower + adj;
1829 LOG(VB_COMMFLAG, LOG_DEBUG, QString(
"Start Mark: %1 -> %2")
1830 .arg(it.key()).arg(lastStart));
1836 uint64_t lastEndLower = it.key();
1837 uint64_t lastEndUpper = it.key();
1841 while ((lastEndLower > 0) &&
1844 uint64_t adj = (lastEndUpper - lastEndLower) / 2;
1846 lastEnd = lastEndUpper - adj;
1849 LOG(VB_COMMFLAG, LOG_DEBUG, QString(
"End Mark : %1 -> %2")
1850 .arg(it.key()).arg(lastEnd));
1862 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::BuildBlankFrameCommList()");
1871 int commercials = 0;
1876 bframes[frames++] = it.key();
1881 for(
int i = 0; i < frames; i++ )
1883 for(
int x=i+1; x < frames; x++ )
1888 int gap_length = bframes[x] - bframes[i];
1890 ((abs((
int)(gap_length - (5 *
m_fps))) < 5 ) ||
1891 (abs((
int)(gap_length - (10 *
m_fps))) < 7 ) ||
1892 (abs((
int)(gap_length - (15 *
m_fps))) < 10 ) ||
1893 (abs((
int)(gap_length - (20 *
m_fps))) < 11 ) ||
1894 (abs((
int)(gap_length - (30 *
m_fps))) < 12 ) ||
1895 (abs((
int)(gap_length - (40 *
m_fps))) < 1 ) ||
1896 (abs((
int)(gap_length - (45 *
m_fps))) < 1 ) ||
1897 (abs((
int)(gap_length - (60 *
m_fps))) < 15 ) ||
1898 (abs((
int)(gap_length - (90 *
m_fps))) < 10 ) ||
1899 (abs((
int)(gap_length - (120 *
m_fps))) < 10 ))) ||
1901 ((abs((
int)(gap_length - (5 *
m_fps))) < 11 ) ||
1902 (abs((
int)(gap_length - (10 *
m_fps))) < 13 ) ||
1903 (abs((
int)(gap_length - (15 *
m_fps))) < 16 ) ||
1904 (abs((
int)(gap_length - (20 *
m_fps))) < 17 ) ||
1905 (abs((
int)(gap_length - (30 *
m_fps))) < 18 ) ||
1906 (abs((
int)(gap_length - (40 *
m_fps))) < 3 ) ||
1907 (abs((
int)(gap_length - (45 *
m_fps))) < 3 ) ||
1908 (abs((
int)(gap_length - (60 *
m_fps))) < 20 ) ||
1909 (abs((
int)(gap_length - (90 *
m_fps))) < 20 ) ||
1910 (abs((
int)(gap_length - (120 *
m_fps))) < 20 ))))
1912 c_start[commercials] = bframes[i];
1913 c_end[commercials] = bframes[x] - 1;
1920 ((abs((
int)(gap_length - (30 *
m_fps))) < (
int)(
m_fps * 0.85)) ||
1921 (abs((
int)(gap_length - (60 *
m_fps))) < (
int)(
m_fps * 0.95)) ||
1922 (abs((
int)(gap_length - (90 *
m_fps))) < (
int)(
m_fps * 1.05)) ||
1923 (abs((
int)(gap_length - (120 *
m_fps))) < (
int)(
m_fps * 1.15))) &&
1924 ((x + 2) < frames) &&
1925 ((i + 2) < frames) &&
1926 ((bframes[i] + 1) == bframes[i+1]) &&
1927 ((bframes[x] + 1) == bframes[x+1]))
1929 c_start[commercials] = bframes[i];
1930 c_end[commercials] = bframes[x];
1942 if ((commercials > 1) &&
1943 (c_end[0] < (33 *
m_fps)) &&
1944 (c_start[1] > (c_end[0] + 40 *
m_fps)))
1948 bool first_comm =
true;
1949 for(; i < (commercials-1); i++)
1951 long long r = c_start[i];
1952 long long adjustment = 0;
1954 if ((r < (30 *
m_fps)) &&
1961 if ( i < (commercials-1))
1964 for(x = 0; x < (frames-1); x++)
1965 if (bframes[x] == r)
1967 while((x < (frames-1)) &&
1968 ((bframes[x] + 1 ) == bframes[x+1]) &&
1969 (bframes[x+1] < c_start[i+1]))
1976 (c_start[i+1] != (r+1)))
2005 LOG(VB_COMMFLAG, LOG_INFO,
"Blank-Frame Commercial Map" );
2007 LOG(VB_COMMFLAG, LOG_INFO, QString(
" %1:%2")
2008 .arg(it.key()).arg(*it));
2012 LOG(VB_COMMFLAG, LOG_INFO,
"Merged Blank-Frame Commercial Break Map" );
2014 LOG(VB_COMMFLAG, LOG_INFO, QString(
" %1:%2")
2015 .arg(it.key()).arg(*it));
2021 int section_start = -1;
2023 int *sc_histogram =
new int[seconds+1];
2027 memset(sc_histogram, 0, (seconds+1)*
sizeof(
int));
2031 sc_histogram[(uint64_t)(f /
m_fps)]++;
2034 for(
long long s = 0; s < (seconds + 1); s++)
2036 if (sc_histogram[s] > 2)
2038 if (section_start == -1)
2041 for(
int i = 0; i <
m_fps; i++, f++)
2046 i = (int)(
m_fps) + 1;
2054 if ((section_start >= 0) &&
2055 (s > (section_start + 32)))
2057 auto f = (
long long)(section_start *
m_fps);
2058 bool found_end =
false;
2060 for(
int i = 0; i <
m_fps; i++, f++)
2069 i = (int)(
m_fps) + 1;
2082 delete[] sc_histogram;
2084 if (section_start >= 0)
2089 frm_dir_map_t::iterator prev = it;
2096 (it.key() - prev.key()) < (30 *
m_fps))
2106 frm_dir_map_t::iterator dit;
2107 for (dit = deleteMap.begin(); dit != deleteMap.end(); ++dit)
2111 LOG(VB_COMMFLAG, LOG_INFO,
"Scene-Change Commercial Break Map" );
2114 LOG(VB_COMMFLAG, LOG_INFO, QString(
" %1:%2")
2115 .arg(it.key()).arg(*it));
2127 frm_dir_map_t::iterator it;
2128 LOG(VB_COMMFLAG, LOG_INFO,
"Logo Commercial Break Map" );
2130 LOG(VB_COMMFLAG, LOG_INFO, QString(
" %1:%2")
2131 .arg(it.key()).arg(*it));
2136 frm_dir_map_t::iterator it;
2137 frm_dir_map_t::iterator prev;
2138 QMap<long long, long long> tmpMap;
2139 QMap<long long, long long>::Iterator tmpMap_it;
2140 QMap<long long, long long>::Iterator tmpMap_prev;
2159 if ((((prev.key() + 1) == it.key()) ||
2160 ((prev.key() + (15 *
m_fps)) > it.key())) &&
2174 tmpMap[prev.key()] = it.key();
2179 tmpMap[prev.key()] = it.key();
2182 tmpMap_it = tmpMap.begin();
2183 tmpMap_prev = tmpMap_it;
2185 for(; tmpMap_it != tmpMap.end(); ++tmpMap_it, ++tmpMap_prev)
2189 if (((*tmpMap_prev + (35 *
m_fps)) > tmpMap_it.key()) &&
2190 ((*tmpMap_prev - tmpMap_prev.key()) > (35 *
m_fps)) &&
2191 ((*tmpMap_it - tmpMap_it.key()) > (35 *
m_fps)))
2204 if (breakMap.contains(i))
2206 int type = breakMap[i];
2216 for (uint64_t i = (f + 1); i-- > 0; )
2218 if (breakMap.contains(i))
2220 int type = breakMap[i];
2233 frm_dir_map_t::iterator it;
2236 LOG(VB_COMMFLAG, LOG_INFO,
2237 "---------------------------------------------------");
2238 for (it = map.begin(); it != map.end(); ++it)
2240 long long frame = it.key();
2242 int my_fps = (int)ceil(
m_fps);
2243 long long hour = (frame / my_fps) / 60 / 60;
2244 long long min = ((frame / my_fps) / 60) - (hour * 60);
2245 long long sec = (frame / my_fps) - (min * 60) - (hour * 60 * 60);
2246 long long frm = frame - ((sec * my_fps) + (min * 60 * my_fps) +
2247 (hour * 60 * 60 * my_fps));
2248 int my_sec = (int)(frame / my_fps);
2249 msg = QString(
"%1 : %2 (%3:%4:%5.%6) (%7)")
2250 .arg(frame, 7).arg(flag).arg(hour, 2, 10, QChar(
'0')).arg(min, 2, 10, QChar(
'0'))
2251 .arg(sec, 2, 10, QChar(
'0')).arg(frm, 2, 10, QChar(
'0')).arg(my_sec);
2252 LOG(VB_COMMFLAG, LOG_INFO, msg);
2254 LOG(VB_COMMFLAG, LOG_INFO,
2255 "---------------------------------------------------");
2261 show_map_t::iterator it;
2262 show_map_t::iterator prev;
2265 if (map.size() <= 2)
2269 LOG(VB_COMMFLAG, LOG_INFO,
"Commercial Map Before condense:" );
2270 for (it = map.begin(); it != map.end(); ++it)
2272 LOG(VB_COMMFLAG, LOG_INFO, QString(
" %1:%2")
2273 .arg(it.key()).arg(*it));
2274 tmpMap[it.key()] = *it;
2277 prev = tmpMap.begin();
2280 while (it != tmpMap.end())
2284 ((it.key() - prev.key()) < (uint64_t)spacing))
2286 map.remove(prev.key());
2287 map.remove(it.key());
2298 for (it = map.begin(); it != map.end(); ++it)
2299 tmpMap[it.key()] = *it;
2301 prev = tmpMap.begin();
2304 while (it != tmpMap.end())
2308 ((it.key() - prev.key()) < (uint64_t)length))
2310 map.remove(prev.key());
2311 map.remove(it.key());
2317 LOG(VB_COMMFLAG, LOG_INFO,
"Commercial Map After condense:" );
2318 for (it = map.begin(); it != map.end(); ++it)
2319 LOG(VB_COMMFLAG, LOG_INFO, QString(
" %1:%2")
2320 .arg(it.key()).arg(*it));
2330 show_map_t::const_iterator sit;
2331 for (sit = in.begin(); sit != in.end(); ++sit)
2339 frm_dir_map_t::iterator it = out.begin();
2340 if (it == out.end())
2343 switch (out[it.key()])
2366 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::CleanupFrameInfo()");
2372 std::array<int,256> avgHistogram {};
2374 int newThreshold = -1;
2376 LOG(VB_COMMFLAG, LOG_INFO,
2377 QString(
"ClassicCommDetect: Only found %1 blank frames but "
2378 "wanted at least %2, rechecking data using higher "
2385 avgHistogram.fill(0);
2390 for (
int i = 1; i <= 255 && minAvg == -1; i++)
2394 newThreshold = minAvg + 3;
2395 LOG(VB_COMMFLAG, LOG_INFO,
2396 QString(
"Minimum Average Brightness on a frame "
2397 "was %1, will use %2 as new threshold")
2398 .arg(minAvg).arg(newThreshold));
2414 LOG(VB_COMMFLAG, LOG_INFO,
2415 QString(
"Found %1 blank frames using new value")
2426 for (
int offset = 1; offset <= 10; offset++)
2431 for (
int offset = 1; offset <= 10; offset++)
2441 if ((before < 4) && (after < 4))
2446 if ((before > 6) && (after > 6))
2454 LOG(VB_COMMFLAG, LOG_INFO,
"CommDetect::GetLogoCommBreakMap()");
2458 bool PrevFrameLogo =
false;
2462 bool CurrentFrameLogo =
2465 if (!PrevFrameLogo && CurrentFrameLogo)
2467 else if (PrevFrameLogo && !CurrentFrameLogo)
2470 PrevFrameLogo = CurrentFrameLogo;
2485 out <<
tmp.constData() <<
" mark" << std::endl;
2490 QMap<long long, FrameInfoEntry>::const_iterator it =
m_frameInfo.find(i);
2494 QByteArray atmp = (*it).toString(i,
verbose).toLatin1();
2495 out << atmp.constData() <<
" ";
2498 frm_dir_map_t::const_iterator mit = comm_breaks->find(i);
2499 if (mit != comm_breaks->end())
2503 atmp =
tmp.toLatin1();
2505 out << atmp.constData();