helens mcf fixes
From: Mark Spieth <mspieth@digivation.com.au>
---
.../programs/mythcommflag/ClassicCommDetector.cpp | 58 +++++++++++++-------
.../programs/mythcommflag/ClassicLogoDetector.cpp | 21 ++++++-
2 files changed, 54 insertions(+), 25 deletions(-)
diff --git a/mythtv/programs/mythcommflag/ClassicCommDetector.cpp b/mythtv/programs/mythcommflag/ClassicCommDetector.cpp
index 9d0d4d7..c545039 100644
|
a
|
b
|
typedef enum frameAspects {
|
| 31 | 31 | } FrameAspects; |
| 32 | 32 | |
| 33 | 33 | typedef enum frameFormats { |
| 34 | | COMM_FORMAT_NORMAL = 0, |
| 35 | | COMM_FORMAT_LETTERBOX, |
| 36 | | COMM_FORMAT_PILLARBOX, |
| 37 | | COMM_FORMAT_MAX |
| | 34 | COMM_FORMAT_NORMAL = 0, |
| | 35 | COMM_FORMAT_LETTERBOX = 1, |
| | 36 | COMM_FORMAT_PILLARBOX = 2, |
| | 37 | COMM_FORMAT_MAX = 4, |
| 38 | 38 | } FrameFormats; |
| 39 | 39 | |
| 40 | 40 | static QString toStringFrameMaskValues(int mask, bool verbose) |
| … |
… |
static QString toStringFrameFormats(int format, bool verbose)
|
| 87 | 87 | switch (format) |
| 88 | 88 | { |
| 89 | 89 | case COMM_FORMAT_NORMAL: |
| 90 | | return (verbose) ? "normal" : "N"; |
| | 90 | return (verbose) ? "normal" : " N "; |
| 91 | 91 | case COMM_FORMAT_LETTERBOX: |
| 92 | | return (verbose) ? "letter" : "L"; |
| | 92 | return (verbose) ? "letter" : " L "; |
| 93 | 93 | case COMM_FORMAT_PILLARBOX: |
| 94 | | return (verbose) ? "pillar" : "P"; |
| | 94 | return (verbose) ? "pillar" : " P "; |
| | 95 | case COMM_FORMAT_LETTERBOX | COMM_FORMAT_PILLARBOX: |
| | 96 | return (verbose) ? "letter,pillar" : "L,P"; |
| 95 | 97 | case COMM_FORMAT_MAX: |
| 96 | | return (verbose) ? " max " : "M"; |
| | 98 | return (verbose) ? " max " : " M "; |
| 97 | 99 | } |
| 98 | 100 | |
| 99 | | return (verbose) ? " null " : "n"; |
| | 101 | return (verbose) ? "unknown" : " U "; |
| 100 | 102 | } |
| 101 | 103 | |
| 102 | 104 | QString FrameInfoEntry::GetHeader(void) |
| … |
… |
ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in,
|
| 152 | 154 | fps(0.0), framesProcessed(0), |
| 153 | 155 | preRoll(0), postRoll(0) |
| 154 | 156 | { |
| 155 | | commDetectBorder = |
| 156 | | gCoreContext->GetNumSetting("CommDetectBorder", 20); |
| 157 | 157 | commDetectBlankFrameMaxDiff = |
| 158 | 158 | gCoreContext->GetNumSetting("CommDetectBlankFrameMaxDiff", 25); |
| 159 | 159 | commDetectDarkBrightness = |
| … |
… |
void ClassicCommDetector::Init()
|
| 189 | 189 | postRoll = (long long)( |
| 190 | 190 | max(int64_t(0), int64_t(stopsAt.secsTo(recordingStopsAt))) * fps); |
| 191 | 191 | |
| | 192 | // CommDetectBorder's default value of 20 predates the change to use |
| | 193 | // ffmpeg's lowres decoding capability by 5 years. |
| | 194 | // I believe it should be adjusted based on the height of the lowres video |
| | 195 | // CommDetectBorder * height / 720 seems to produce reasonable results. |
| | 196 | // source height = 480 gives border = 20 * 480 / 4 / 720 = 2 |
| | 197 | // source height = 720 gives border = 20 * 720 / 4 / 720 = 5 |
| | 198 | // source height = 1080 gives border = 20 * 1080 / 4 / 720 = 7 |
| | 199 | commDetectBorder = |
| | 200 | gCoreContext->GetNumSetting("CommDetectBorder", 20) * height / 720; |
| | 201 | |
| 192 | 202 | #ifdef SHOW_DEBUG_WIN |
| 193 | 203 | comm_debug_init(width, height); |
| 194 | 204 | #endif |
| … |
… |
bool ClassicCommDetector::go()
|
| 316 | 326 | |
| 317 | 327 | if (commDetectMethod & COMM_DETECT_LOGO) |
| 318 | 328 | { |
| | 329 | // Use a different border for logo detection. |
| | 330 | // If we try to detect logos in letterboxed areas, |
| | 331 | // chances are we won't detect the logo. |
| | 332 | // Generally speaking, SD video is likely to be letter boxed |
| | 333 | // and HD video is not likely to be letter boxed. |
| | 334 | // To detect logos, try to exclude letterboxed area from SD video |
| | 335 | // but exclude too much from HD video and you'll miss the logo. |
| | 336 | // Using the same border for both with no scaling seems to be |
| | 337 | // a good compromise. |
| | 338 | int logoDetectBorder = |
| | 339 | gCoreContext->GetNumSetting("CommDetectLogoBorder", 16); |
| 319 | 340 | logoDetector = new ClassicLogoDetector(this, width, height, |
| 320 | | commDetectBorder, horizSpacing, vertSpacing); |
| | 341 | logoDetectBorder, horizSpacing, vertSpacing); |
| 321 | 342 | |
| 322 | 343 | requiredHeadStart += max( |
| 323 | 344 | int64_t(0), int64_t(recordingStartedAt.secsTo(startedAt))); |
| … |
… |
void ClassicCommDetector::ProcessFrame(VideoFrame *frame,
|
| 897 | 918 | delete[] colMax; |
| 898 | 919 | colMax = 0; |
| 899 | 920 | |
| | 921 | frameInfo[curFrameNumber].format = COMM_FORMAT_NORMAL; |
| 900 | 922 | if ((topDarkRow > commDetectBorder) && |
| 901 | 923 | (topDarkRow < (height * .20)) && |
| 902 | 924 | (bottomDarkRow < (height - commDetectBorder)) && |
| 903 | 925 | (bottomDarkRow > (height * .80))) |
| 904 | 926 | { |
| 905 | | frameInfo[curFrameNumber].format = COMM_FORMAT_LETTERBOX; |
| | 927 | frameInfo[curFrameNumber].format |= COMM_FORMAT_LETTERBOX; |
| 906 | 928 | } |
| 907 | | else if ((leftDarkCol > commDetectBorder) && |
| | 929 | if ((leftDarkCol > commDetectBorder) && |
| 908 | 930 | (leftDarkCol < (width * .20)) && |
| 909 | 931 | (rightDarkCol < (width - commDetectBorder)) && |
| 910 | 932 | (rightDarkCol > (width * .80))) |
| 911 | 933 | { |
| 912 | | frameInfo[curFrameNumber].format = COMM_FORMAT_PILLARBOX; |
| 913 | | } |
| 914 | | else |
| 915 | | { |
| 916 | | frameInfo[curFrameNumber].format = COMM_FORMAT_NORMAL; |
| | 934 | frameInfo[curFrameNumber].format |= COMM_FORMAT_PILLARBOX; |
| 917 | 935 | } |
| 918 | 936 | |
| 919 | 937 | avg = totBrightness / blankPixelsChecked; |
| … |
… |
void ClassicCommDetector::BuildAllMethodsCommList(void)
|
| 1364 | 1382 | } |
| 1365 | 1383 | |
| 1366 | 1384 | if ((fbp->length > 4) && |
| 1367 | | (fbp->logoCount > (fbp->frames * 0.60)) && |
| | 1385 | (!logoInfoAvailable || fbp->logoCount > (fbp->frames * 0.60)) && |
| 1368 | 1386 | (fbp->bfCount < (fbp->frames * 0.10))) |
| 1369 | 1387 | { |
| 1370 | 1388 | if (verboseDebugging) |
diff --git a/mythtv/programs/mythcommflag/ClassicLogoDetector.cpp b/mythtv/programs/mythcommflag/ClassicLogoDetector.cpp
index 0cdc680..ccf1545 100644
|
a
|
b
|
bool ClassicLogoDetector::searchForLogo(MythPlayer* player)
|
| 100 | 100 | |
| 101 | 101 | edgeCounts = new EdgeMaskEntry[width * height]; |
| 102 | 102 | |
| | 103 | // Back in 2005, a threshold of 50 minimum pixelsInMask was established. |
| | 104 | // I don't know whether that was tested against SD or HD resolutions. |
| | 105 | // I do know that in 2010, mythcommflag was changed to use ffmpeg's |
| | 106 | // lowres support, effectively dividing the video area by 16. |
| | 107 | // But the 50 pixel minimum was not adjusted accordingly. |
| | 108 | // I believe the minimum threshold should vary with the video's area. |
| | 109 | // I am using 1280x720 (for 720p) video as the baseline. |
| | 110 | // This should improve logo detection for SD video. |
| | 111 | int minPixelsInMask = 50 * (width*height) / (1280*720 / 16); |
| | 112 | |
| 103 | 113 | for (i = 0; edgeDiffs[i] != 0 && !logoInfoAvailable; i++) |
| 104 | 114 | { |
| 105 | 115 | int pixelsInMask = 0; |
| 106 | 116 | |
| 107 | | LOG(VB_COMMFLAG, LOG_INFO, QString("Trying with edgeDiff == %1") |
| 108 | | .arg(edgeDiffs[i])); |
| | 117 | LOG(VB_COMMFLAG, LOG_INFO, QString("Trying with edgeDiff == %1, minPixelsInMask=%2") |
| | 118 | .arg(edgeDiffs[i]).arg(minPixelsInMask)); |
| 109 | 119 | |
| 110 | 120 | memset(edgeCounts, 0, sizeof(EdgeMaskEntry) * width * height); |
| 111 | 121 | memset(edgeMask, 0, sizeof(EdgeMaskEntry) * width * height); |
| … |
… |
bool ClassicLogoDetector::searchForLogo(MythPlayer* player)
|
| 237 | 247 | #endif |
| 238 | 248 | if (((logoMaxX - logoMinX) < (width / 4)) && |
| 239 | 249 | ((logoMaxY - logoMinY) < (height / 4)) && |
| 240 | | (pixelsInMask > 50)) |
| | 250 | (pixelsInMask > minPixelsInMask)) |
| 241 | 251 | { |
| 242 | 252 | logoInfoAvailable = true; |
| 243 | 253 | logoEdgeDiff = edgeDiffs[i]; |
| 244 | 254 | |
| 245 | 255 | LOG(VB_COMMFLAG, LOG_INFO, |
| 246 | 256 | QString("Using Logo area: topleft (%1,%2), " |
| 247 | | "bottomright (%3,%4)") |
| | 257 | "bottomright (%3,%4), pixelsInMask (%5).") |
| 248 | 258 | .arg(logoMinX).arg(logoMinY) |
| 249 | | .arg(logoMaxX).arg(logoMaxY)); |
| | 259 | .arg(logoMaxX).arg(logoMaxY) |
| | 260 | .arg(pixelsInMask)); |
| 250 | 261 | } |
| 251 | 262 | else |
| 252 | 263 | { |