Ticket #10793: 20141111-30-helen-mcf.patch

File 20141111-30-helen-mcf.patch, 7.9 KB (added by Mark Spieth, 9 years ago)
  • mythtv/programs/mythcommflag/ClassicCommDetector.cpp

    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 { 
    3131} FrameAspects;
    3232
    3333typedef 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,
    3838} FrameFormats;
    3939
    4040static QString toStringFrameMaskValues(int mask, bool verbose)
    static QString toStringFrameFormats(int format, bool verbose) 
    8787    switch (format)
    8888    {
    8989        case COMM_FORMAT_NORMAL:
    90             return (verbose) ? "normal" : "N";
     90            return (verbose) ? "normal" : " N ";
    9191        case COMM_FORMAT_LETTERBOX:
    92             return (verbose) ? "letter" : "L";
     92            return (verbose) ? "letter" : " L ";
    9393        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";
    9597        case COMM_FORMAT_MAX:
    96             return (verbose) ? " max  " : "M";
     98            return (verbose) ? " max  " : " M ";
    9799    }
    98100
    99     return (verbose) ? " null " : "n";
     101    return (verbose) ? "unknown" : " U ";
    100102}
    101103
    102104QString FrameInfoEntry::GetHeader(void)
    ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in, 
    152154    fps(0.0),                                  framesProcessed(0),
    153155    preRoll(0),                                postRoll(0)
    154156{
    155     commDetectBorder =
    156         gCoreContext->GetNumSetting("CommDetectBorder", 20);
    157157    commDetectBlankFrameMaxDiff =
    158158        gCoreContext->GetNumSetting("CommDetectBlankFrameMaxDiff", 25);
    159159    commDetectDarkBrightness =
    void ClassicCommDetector::Init() 
    189189    postRoll = (long long)(
    190190        max(int64_t(0), int64_t(stopsAt.secsTo(recordingStopsAt))) * fps);
    191191
     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
    192202#ifdef SHOW_DEBUG_WIN
    193203    comm_debug_init(width, height);
    194204#endif
    bool ClassicCommDetector::go() 
    316326
    317327    if (commDetectMethod & COMM_DETECT_LOGO)
    318328    {
     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);
    319340        logoDetector = new ClassicLogoDetector(this, width, height,
    320             commDetectBorder, horizSpacing, vertSpacing);
     341            logoDetectBorder, horizSpacing, vertSpacing);
    321342
    322343        requiredHeadStart += max(
    323344            int64_t(0), int64_t(recordingStartedAt.secsTo(startedAt)));
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    897918        delete[] colMax;
    898919        colMax = 0;
    899920
     921        frameInfo[curFrameNumber].format = COMM_FORMAT_NORMAL;
    900922        if ((topDarkRow > commDetectBorder) &&
    901923            (topDarkRow < (height * .20)) &&
    902924            (bottomDarkRow < (height - commDetectBorder)) &&
    903925            (bottomDarkRow > (height * .80)))
    904926        {
    905             frameInfo[curFrameNumber].format = COMM_FORMAT_LETTERBOX;
     927            frameInfo[curFrameNumber].format |= COMM_FORMAT_LETTERBOX;
    906928        }
    907         else if ((leftDarkCol > commDetectBorder) &&
     929        if ((leftDarkCol > commDetectBorder) &&
    908930                 (leftDarkCol < (width * .20)) &&
    909931                 (rightDarkCol < (width - commDetectBorder)) &&
    910932                 (rightDarkCol > (width * .80)))
    911933        {
    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;
    917935        }
    918936
    919937        avg = totBrightness / blankPixelsChecked;
    void ClassicCommDetector::BuildAllMethodsCommList(void) 
    13641382            }
    13651383
    13661384            if ((fbp->length > 4) &&
    1367                 (fbp->logoCount > (fbp->frames * 0.60)) &&
     1385                (!logoInfoAvailable || fbp->logoCount > (fbp->frames * 0.60)) &&
    13681386                (fbp->bfCount < (fbp->frames * 0.10)))
    13691387            {
    13701388                if (verboseDebugging)
  • mythtv/programs/mythcommflag/ClassicLogoDetector.cpp

    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) 
    100100
    101101    edgeCounts = new EdgeMaskEntry[width * height];
    102102
     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
    103113    for (i = 0; edgeDiffs[i] != 0 && !logoInfoAvailable; i++)
    104114    {
    105115        int pixelsInMask = 0;
    106116
    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));
    109119
    110120        memset(edgeCounts, 0, sizeof(EdgeMaskEntry) * width * height);
    111121        memset(edgeMask, 0, sizeof(EdgeMaskEntry) * width * height);
    bool ClassicLogoDetector::searchForLogo(MythPlayer* player) 
    237247#endif
    238248        if (((logoMaxX - logoMinX) < (width / 4)) &&
    239249            ((logoMaxY - logoMinY) < (height / 4)) &&
    240             (pixelsInMask > 50))
     250            (pixelsInMask > minPixelsInMask))
    241251        {
    242252            logoInfoAvailable = true;
    243253            logoEdgeDiff = edgeDiffs[i];
    244254
    245255            LOG(VB_COMMFLAG, LOG_INFO,
    246256                QString("Using Logo area: topleft (%1,%2), "
    247                         "bottomright (%3,%4)")
     257                        "bottomright (%3,%4), pixelsInMask (%5).")
    248258                    .arg(logoMinX).arg(logoMinY)
    249                     .arg(logoMaxX).arg(logoMaxY));
     259                    .arg(logoMaxX).arg(logoMaxY)
     260                    .arg(pixelsInMask));
    250261        }
    251262        else
    252263        {