diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 9439d39..3c95424 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -1372,7 +1372,12 @@ void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *enc,
             }
 
             if (FlagIsSet(kDecodeLowRes))
-                enc->lowres = 2; // 1 = 1/2 size, 2 = 1/4 size
+            {
+                if (enc->height > 720)
+                    enc->lowres = 2; // 2 = 1/4 size
+                else
+                    enc->lowres = 1; // 1 = 1/2 size
+            }
         }
         else if (CODEC_ID_H264 == codec->id)
         {
diff --git a/mythtv/programs/mythcommflag/ClassicCommDetector.cpp b/mythtv/programs/mythcommflag/ClassicCommDetector.cpp
index 800e83d..bb83323 100644
--- a/mythtv/programs/mythcommflag/ClassicCommDetector.cpp
+++ b/mythtv/programs/mythcommflag/ClassicCommDetector.cpp
@@ -134,12 +134,12 @@ ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in,
     width(0),                                  height(0),
     horizSpacing(0),                           vertSpacing(0),
     fpm(0.0),                                  blankFramesOnly(false),
-    blankFrameCount(0),                        currentAspect(0),
+    blankFrameCount(0),                        
+    currentAspect(0),                          colMax(NULL),
     totalMinBrightness(0),                     detectBlankFrames(false),
     detectSceneChanges(false),                 detectStationLogo(false),
     logoInfoAvailable(false),                  logoDetector(0),
-    framePtr(0),                               frameIsBlank(false),
-    sceneHasChanged(false),                    stationLogoPresent(false),
+    framePtr(0),                               sceneHasChanged(false),
     lastFrameWasBlank(false),                  lastFrameWasSceneChange(false),
     decoderFoundAspectChanges(false),          sceneChangeDetector(0),
     player(player_in),
@@ -152,7 +152,7 @@ ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in,
     preRoll(0),                                postRoll(0)
 {
     commDetectBorder =
-        gCoreContext->GetNumSetting("CommDetectBorder", 20);
+        gCoreContext->GetNumSetting("CommDetectBorder", 5);
     commDetectBlankFrameMaxDiff =
         gCoreContext->GetNumSetting("CommDetectBlankFrameMaxDiff", 25);
     commDetectDarkBrightness =
@@ -206,31 +206,8 @@ void ClassicCommDetector::Init()
             .arg(width).arg(height)
             .arg(player->GetFrameRate()).arg(commDetectMethod));
 
-    if ((width * height) > 1000000)
-    {
-        horizSpacing = 10;
-        vertSpacing = 10;
-    }
-    else if ((width * height) > 800000)
-    {
-        horizSpacing = 8;
-        vertSpacing = 8;
-    }
-    else if ((width * height) > 400000)
-    {
-        horizSpacing = 6;
-        vertSpacing = 6;
-    }
-    else if ((width * height) > 300000)
-    {
-        horizSpacing = 6;
-        vertSpacing = 4;
-    }
-    else
-    {
-        horizSpacing = 4;
-        vertSpacing = 4;
-    }
+    horizSpacing = 1;
+    vertSpacing = 1;
 
     LOG(VB_COMMFLAG, LOG_INFO,
         QString("Using Sample Spacing of %1 horizontal & %2 vertical pixels.")
@@ -245,13 +222,15 @@ void ClassicCommDetector::Init()
     decoderFoundAspectChanges = false;
 
     lastSentCommBreakMap.clear();
+    
+    colMax = new unsigned char[width];
 
     // Check if close to 4:3
     if (fabs(((width*1.0)/height) - 1.333333) < 0.1)
         currentAspect = COMM_ASPECT_NORMAL;
 
     sceneChangeDetector = new ClassicSceneChangeDetector(width, height,
-        commDetectBorder, horizSpacing, vertSpacing);
+        commDetectBorder, fps);
     connect(
          sceneChangeDetector,
          SIGNAL(haveNewInformation(unsigned int,bool,float)),
@@ -259,9 +238,6 @@ void ClassicCommDetector::Init()
          SLOT(sceneChangeDetectorHasNewInformation(unsigned int,bool,float))
     );
 
-    frameIsBlank = false;
-    stationLogoPresent = false;
-
     framePtr = NULL;
 
     logoInfoAvailable = false;
@@ -735,38 +711,13 @@ void ClassicCommDetector::SetVideoParams(float aspect)
 void ClassicCommDetector::ProcessFrame(VideoFrame *frame,
                                        long long frame_number)
 {
-    int max = 0;
-    int min = 255;
-    int avg = 0;
-    unsigned char pixel;
-    int blankPixelsChecked = 0;
-    long long totBrightness = 0;
-    unsigned char *rowMax = new unsigned char[height];
-    unsigned char *colMax = new unsigned char[width];
-    memset(rowMax, 0, sizeof(*rowMax)*height);
-    memset(colMax, 0, sizeof(*colMax)*width);
-    int topDarkRow = commDetectBorder;
-    int bottomDarkRow = height - commDetectBorder - 1;
-    int leftDarkCol = commDetectBorder;
-    int rightDarkCol = width - commDetectBorder - 1;
     FrameInfoEntry fInfo;
 
-    if (!frame || !(frame->buf) || frame_number == -1 ||
-        frame->codec != FMT_YV12)
+    if (!frame || !(frame->buf) || !width || !height ||
+        frame_number == -1 || frame->codec != FMT_YV12)
     {
         LOG(VB_COMMFLAG, LOG_ERR, "CommDetect: Invalid video frame or codec, "
                                   "unable to process frame.");
-        delete[] rowMax;
-        delete[] colMax;
-        return;
-    }
-
-    if (!width || !height)
-    {
-        LOG(VB_COMMFLAG, LOG_ERR, "CommDetect: Width or Height is 0, "
-                                  "unable to process frame.");
-        delete[] rowMax;
-        delete[] colMax;
         return;
     }
 
@@ -803,112 +754,76 @@ void ClassicCommDetector::ProcessFrame(VideoFrame *frame,
 
     frameInfo[curFrameNumber] = fInfo;
 
-    if (commDetectMethod & COMM_DETECT_BLANKS)
-        frameIsBlank = false;
-
     if (commDetectMethod & COMM_DETECT_SCENE)
     {
-        sceneChangeDetector->processFrame(framePtr);
+        sceneChangeDetector->processFrame(curFrameNumber, framePtr);
     }
-
-    stationLogoPresent = false;
-
-    for(int y = commDetectBorder; y < (height - commDetectBorder);
-            y += vertSpacing)
+    
+    if (commDetectMethod & COMM_DETECT_BLANKS)
     {
-        for(int x = commDetectBorder; x < (width - commDetectBorder);
-                x += horizSpacing)
+        unsigned char max = 0;
+        unsigned char min = 255;
+        unsigned char avg = 0;
+        long long brightnessSum = 0;
+        
+        memset(colMax, 0, sizeof(*colMax)*width);
+        
+        unsigned int topLight = height, bottomLight = 0;
+        for(unsigned int y = commDetectBorder; y < (height - commDetectBorder); ++y)
         {
-            pixel = framePtr[y * width + x];
-
-            if (commDetectMethod & COMM_DETECT_BLANKS)
+            for(unsigned int x = commDetectBorder; x < (width - commDetectBorder); x++)
             {
-                 bool checkPixel = false;
-                 if (!commDetectBlankCanHaveLogo)
-                     checkPixel = true;
-
-                 if (!logoInfoAvailable)
-                     checkPixel = true;
-                 else if (!logoDetector->pixelInsideLogo(x,y))
-                     checkPixel=true;
-
-                 if (checkPixel)
-                 {
-                     blankPixelsChecked++;
-                     totBrightness += pixel;
-
-                     if (pixel < min)
-                          min = pixel;
-
-                     if (pixel > max)
-                          max = pixel;
-
-                     if (pixel > rowMax[y])
-                         rowMax[y] = pixel;
-
-                     if (pixel > colMax[x])
-                         colMax[x] = pixel;
-                 }
+                unsigned char pixel = framePtr[y * width + x];
+                
+                brightnessSum += pixel;
+                if (max < pixel)
+                    max = pixel;
+                if (min > pixel)
+                    min = pixel;
+                
+                if (colMax[x] < pixel)
+                    colMax[x] = pixel;
+                
+                if (pixel > commDetectBoxBrightness && 
+                    (commDetectBlankCanHaveLogo || 
+                     !logoInfoAvailable ||
+                     !logoDetector->pixelInsideLogo(x,y)))
+                {
+                    if (topLight > y)
+                        topLight = y;
+                    bottomLight = y;
+                }
             }
         }
-    }
-
-    if (commDetectMethod & COMM_DETECT_BLANKS)
-    {
-        for(int y = commDetectBorder; y < (height - commDetectBorder);
-                y += vertSpacing)
-        {
-            if (rowMax[y] > commDetectBoxBrightness)
-                break;
-            else
-                topDarkRow = y;
-        }
-
-        for(int y = commDetectBorder; y < (height - commDetectBorder);
-                y += vertSpacing)
-            if (rowMax[y] >= commDetectBoxBrightness)
-                bottomDarkRow = y;
-
-        delete[] rowMax;
-        rowMax = 0;
-
-        for(int x = commDetectBorder; x < (width - commDetectBorder);
-                x += horizSpacing)
+        
+        unsigned int leftLight = width, rightLight = 0;
+        for(unsigned int x = commDetectBorder; x < (width - commDetectBorder); x ++)
         {
             if (colMax[x] > commDetectBoxBrightness)
-                break;
-            else
-                leftDarkCol = x;
+            {
+                if (leftLight > x)
+                    leftLight = x;
+                
+                rightLight = x;
+            }
         }
-
-        for(int x = commDetectBorder; x < (width - commDetectBorder);
-                x += horizSpacing)
-            if (colMax[x] >= commDetectBoxBrightness)
-                rightDarkCol = x;
-
-        delete[] colMax;
-        colMax = 0;
-
-        if ((topDarkRow > commDetectBorder) &&
-            (topDarkRow < (height * .20)) &&
-            (bottomDarkRow < (height - commDetectBorder)) &&
-            (bottomDarkRow > (height * .80)))
+        
+        if (abs(leftLight - (width - rightLight)) < 5 &&
+            leftLight <= width*0.2)
         {
             frameInfo[curFrameNumber].format = COMM_FORMAT_LETTERBOX;
         }
-        else if ((leftDarkCol > commDetectBorder) &&
-                 (leftDarkCol < (width * .20)) &&
-                 (rightDarkCol < (width - commDetectBorder)) &&
-                 (rightDarkCol > (width * .80)))
+        else if(abs(topLight - (height - bottomLight)) < 5 &&
+                topLight <= height*0.2)
         {
-            frameInfo[curFrameNumber].format = COMM_FORMAT_PILLARBOX;
+            frameInfo[curFrameNumber].format = COMM_FORMAT_LETTERBOX;
         }
         else
         {
             frameInfo[curFrameNumber].format = COMM_FORMAT_NORMAL;
         }
-
-        avg = totBrightness / blankPixelsChecked;
+        
+        avg = brightnessSum / (width * height);
 
         frameInfo[curFrameNumber].minBrightness = min;
         frameInfo[curFrameNumber].maxBrightness = max;
@@ -916,29 +831,34 @@ void ClassicCommDetector::ProcessFrame(VideoFrame *frame,
 
         totalMinBrightness += min;
         commDetectDimAverage = min + 10;
-
-        // Is the frame really dark
-        if (((max - min) <= commDetectBlankFrameMaxDiff) &&
-            (max < commDetectDimBrightness))
-            frameIsBlank = true;
-
-        // Are we non-strict and the frame is blank
-        if ((!aggressiveDetection) &&
-            ((max - min) <= commDetectBlankFrameMaxDiff))
-            frameIsBlank = true;
-
-        // Are we non-strict and the frame is dark
-        //                   OR the frame is dim and has a low avg brightness
-        if ((!aggressiveDetection) &&
-            ((max < commDetectDarkBrightness) ||
-             ((max < commDetectDimBrightness) && (avg < commDetectDimAverage))))
-            frameIsBlank = true;
+        
+        bool frameIsBlank;
+        if (aggressiveDetection)
+        {
+            // Is the frame uniform AND dark
+            frameIsBlank = (max - min) <= commDetectBlankFrameMaxDiff &&
+                            max < commDetectDimBrightness;
+        }
+        else
+        {
+            // Is the frame uniform OR very dark OR dark and low average brightness
+            frameIsBlank = (max - min) <= commDetectBlankFrameMaxDiff ||
+                           max < commDetectDarkBrightness ||
+                           (max < commDetectDimBrightness && avg < commDetectDimAverage);
+        }
+        
+        if (frameIsBlank)
+        {
+            blankFrameMap[curFrameNumber] = MARK_BLANK_FRAME;
+            flagMask |= COMM_FRAME_BLANK;
+            blankFrameCount++;
+        }
     }
 
-    if ((logoInfoAvailable) && (commDetectMethod & COMM_DETECT_LOGO))
+    if (logoInfoAvailable && (commDetectMethod & COMM_DETECT_LOGO))
     {
-        stationLogoPresent =
-            logoDetector->doesThisFrameContainTheFoundLogo(framePtr);
+        if (logoDetector->doesThisFrameContainTheFoundLogo(framePtr))
+            flagMask |= COMM_FRAME_LOGO_PRESENT;
     }
 
 #if 0
@@ -949,16 +869,6 @@ void ClassicCommDetector::ProcessFrame(VideoFrame *frame,
     }
 #endif
 
-    if (frameIsBlank)
-    {
-        blankFrameMap[curFrameNumber] = MARK_BLANK_FRAME;
-        flagMask |= COMM_FRAME_BLANK;
-        blankFrameCount++;
-    }
-
-    if (stationLogoPresent)
-        flagMask |= COMM_FRAME_LOGO_PRESENT;
-
     //TODO: move this debugging code out of the perframe loop, and do it after
     // we've processed all frames. this is because a scenechangedetector can
     // now use a few frames to determine whether the frame a few frames ago was
@@ -985,8 +895,6 @@ void ClassicCommDetector::ProcessFrame(VideoFrame *frame,
 #endif
 
     framesProcessed++;
-    delete[] rowMax;
-    delete[] colMax;
 }
 
 void ClassicCommDetector::ClearAllMaps(void)
@@ -1140,9 +1048,7 @@ void ClassicCommDetector::UpdateFrameBlock(FrameBlock *fbp,
                                            FrameInfoEntry finfo,
                                            int format, int aspect)
 {
-    int value = 0;
-
-    value = finfo.flagMask;
+    int value = finfo.flagMask;
 
     if (value & COMM_FRAME_LOGO_PRESENT)
         fbp->logoCount++;
@@ -1152,6 +1058,9 @@ void ClassicCommDetector::UpdateFrameBlock(FrameBlock *fbp,
 
     if (value & COMM_FRAME_SCENE_CHANGE)
         fbp->scCount++;
+    
+    if (value & COMM_FRAME_BLANK)
+        fbp->bfCount++;
 
     if (finfo.format == format)
         fbp->formatMatch++;
@@ -1165,21 +1074,16 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
 {
     LOG(VB_COMMFLAG, LOG_INFO, "CommDetect::BuildAllMethodsCommList()");
 
-    FrameBlock *fblock;
     FrameBlock *fbp;
-    int value = 0;
     int curBlock = 0;
     int maxBlock = 0;
     int lastScore = 0;
     int thisScore = 0;
-    int nextScore = 0;
     uint64_t curFrame = 0;
     int64_t  breakStart = 0;
     uint64_t lastStart = 0;
     uint64_t lastEnd = 0;
     int64_t firstLogoFrame = -1;
-    bool nextFrameIsBlank = false;
-    bool lastFrameWasBlank = false;
     uint64_t formatFrames = 0;
     int format = COMM_FORMAT_NORMAL;
     uint64_t aspectFrames = 0;
@@ -1191,12 +1095,14 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
 
     commBreakMap.clear();
 
-    fblock = new FrameBlock[blankFrameCount + 2];
+    QVector<FrameBlock> fblock;
+    fblock.reserve(blankFrameCount + 2);
 
     curBlock = 0;
     curFrame = 1;
 
-    fbp = &fblock[curBlock];
+    fblock.resize(1);
+    fbp = &fblock[0];
     fbp->start = 0;
     fbp->bfCount = 0;
     fbp->logoCount = 0;
@@ -1245,72 +1151,101 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
             }
         }
     }
-
+    
     while (curFrame <= framesProcessed)
     {
-        value = frameInfo[curFrame].flagMask;
-
-        if (((curFrame + 1) <= framesProcessed) &&
-            (frameInfo[curFrame + 1].flagMask & COMM_FRAME_BLANK))
-            nextFrameIsBlank = true;
-        else
-            nextFrameIsBlank = false;
-
-        if (value & COMM_FRAME_BLANK)
+        bool breakBlock = frameInfo[curFrame].flagMask & COMM_FRAME_BLANK;
+        /*if (!breakBlock &&
+            (frameInfo[curFrame].flagMask & COMM_FRAME_SCENE_CHANGE) &&
+            (frameInfo[curFrame].sceneChangePercent < 50))
         {
-            fbp->bfCount++;
-
-            if (!nextFrameIsBlank || !lastFrameWasBlank)
+            double length = (curFrame - fbp->start) / fps;
+            if (abs(length -  5) < 0.10 ||
+                abs(length - 10) < 0.25 ||
+                abs(length - 15) < 0.50 ||
+                abs(length - 20) < 0.50 ||
+                abs(length - 30) < 0.50 ||
+                abs(length - 40) < 0.50 ||
+                abs(length - 45) < 0.75 ||
+                abs(length - 60) < 0.75 ||
+                abs(length - 90) < 1.00 ||
+                abs(length -120) < 1.00)
             {
-                UpdateFrameBlock(fbp, frameInfo[curFrame], format, aspect);
-
-                fbp->end = curFrame;
-                fbp->frames = fbp->end - fbp->start + 1;
-                fbp->length = fbp->frames / fps;
-
-                if ((fbp->scCount) && (fbp->length > 1.05))
-                    fbp->scRate = fbp->scCount / fbp->length;
-
-                curBlock++;
-
-                fbp = &fblock[curBlock];
-                fbp->bfCount = 1;
-                fbp->logoCount = 0;
-                fbp->ratingCount = 0;
-                fbp->scCount = 0;
-                fbp->scRate = 0.0;
-                fbp->score = 0;
-                fbp->formatMatch = 0;
-                fbp->aspectMatch = 0;
-                fbp->start = curFrame;
+                breakBlock = true;
+                // Make sure we weren't going to break because of blanks soon anyways
+                for (unsigned int f = 1; f < fps*2 && curFrame + f < framesProcessed; ++f)
+                {
+                    if (frameInfo[curFrame+f].flagMask & COMM_FRAME_BLANK)
+                    {
+                        breakBlock = false;
+                        break;
+                    }
+                }
             }
-
-            lastFrameWasBlank = true;
+        }*/
+        
+        if (breakBlock)
+        {
+            unsigned int bfStart = curFrame, bfEnd = curFrame;
+            do
+            {
+                ++bfEnd;
+            }
+            while (bfEnd < framesProcessed && frameInfo[bfEnd].flagMask & COMM_FRAME_BLANK);
+            
+            unsigned int bfMiddle = curFrame + (bfEnd - bfStart)/2;
+            
+            do
+            {
+                UpdateFrameBlock(fbp, frameInfo[curFrame++], format, aspect);
+            }
+            while (curFrame < bfMiddle);
+            
+            fbp->end = curFrame;
+            fbp->frames = fbp->end - fbp->start + 1;
+            fbp->length = fbp->frames / fps;
+
+            if (fbp->length < 1.0)
+                fbp->scRate = fbp->scCount;
+            else
+                fbp->scRate = fbp->scCount / fbp->length; // changes per sec
+            
+            curBlock++;
+
+            fblock.resize(curBlock+1);
+            fbp = &fblock[curBlock];
+            fbp->bfCount = 0;
+            fbp->logoCount = 0;
+            fbp->ratingCount = 0;
+            fbp->scCount = 0;
+            fbp->scRate = 0.0;
+            fbp->score = 0;
+            fbp->formatMatch = 0;
+            fbp->aspectMatch = 0;
+            
+            fbp->start = curFrame;
+            for (; curFrame < bfEnd; ++curFrame)
+                UpdateFrameBlock(fbp, frameInfo[curFrame], format, aspect);
         }
         else
         {
-            lastFrameWasBlank = false;
+            UpdateFrameBlock(fbp, frameInfo[curFrame], format, aspect);
+            if ((frameInfo[curFrame].flagMask & COMM_FRAME_LOGO_PRESENT) && firstLogoFrame == -1)
+                firstLogoFrame = curFrame;
+            curFrame++;
         }
-
-        UpdateFrameBlock(fbp, frameInfo[curFrame], format, aspect);
-
-        if ((value & COMM_FRAME_LOGO_PRESENT) &&
-            (firstLogoFrame == -1))
-            firstLogoFrame = curFrame;
-
-        curFrame++;
     }
 
     fbp->end = curFrame;
     fbp->frames = fbp->end - fbp->start + 1;
     fbp->length = fbp->frames / fps;
 
-    if ((fbp->scCount) && (fbp->length > 1.05))
-        fbp->scRate = fbp->scCount / fbp->length;
-
+    if (fbp->length < 1.0)
+        fbp->scRate = fbp->scCount;
+    else
+        fbp->scRate = fbp->scCount / fbp->length; // changes per sec
+    
     maxBlock = curBlock;
-    curBlock = 0;
-    lastScore = 0;
 
     LOG(VB_COMMFLAG, LOG_INFO, "Initial Block pass");
     LOG(VB_COMMFLAG, LOG_DEBUG,
@@ -1319,7 +1254,7 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
     LOG(VB_COMMFLAG, LOG_INFO,
         "----- ------ ------ ------ ------ ------- "
         "--- ------ ------ ------ ----- ------ ------ -----");
-    while (curBlock <= maxBlock)
+    for (curBlock = 0; curBlock <= maxBlock; ++curBlock)
     {
         fbp = &fblock[curBlock];
 
@@ -1332,141 +1267,122 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
                     fbp->scCount, fbp->scRate, fbp->formatMatch,
                     fbp->aspectMatch, fbp->score);
         LOG(VB_COMMFLAG, LOG_DEBUG, msg);
-
-        if (fbp->frames > fps)
+        
+        if ((int)fbp->length > commDetectMaxCommLength)
         {
             if (verboseDebugging)
                 LOG(VB_COMMFLAG, LOG_DEBUG,
-                    QString("      FRAMES > %1").arg(fps));
-
-            if (fbp->length > commDetectMaxCommLength)
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      length > max comm length, +20");
-                fbp->score += 20;
-            }
+                    "      length > max comm length, +10");
+            fbp->score += 10;
+        }
 
-            if (fbp->length > commDetectMaxCommBreakLength)
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      length > max comm break length, +20");
-                fbp->score += 20;
-            }
+        if ((int)fbp->length > commDetectMaxCommBreakLength)
+        {
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG,
+                    "      length > max comm break length, +20");
+            fbp->score += 20;
+        }
 
-            if ((fbp->length > 4) &&
-                (fbp->logoCount > (fbp->frames * 0.60)) &&
-                (fbp->bfCount < (fbp->frames * 0.10)))
+        if ((fbp->logoCount > (fbp->frames * 0.20)) &&
+            (fbp->bfCount < (fbp->frames * 0.10)))
+        {
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG,
+                    "      logoCount > frames * 0.20 && "
+                    "bfCount < frames * .10, +10");
+            fbp->score += 10;
+            
+            if (fbp->logoCount > (fbp->frames * 0.50))
             {
                 if (verboseDebugging)
                     LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      length > 4 && logoCount > frames * 0.60 && "
-                        "bfCount < frames * .10");
-                if (fbp->length > commDetectMaxCommBreakLength)
-                {
-                    if (verboseDebugging)
-                        LOG(VB_COMMFLAG, LOG_DEBUG,
-                            "      length > max comm break length, +20");
-                    fbp->score += 20;
-                }
-                else
+                        "      logoCount > frames * 0.50, +10");
+                fbp->score += 10;
+                if (fbp->logoCount > (fbp->frames * 0.75))
                 {
                     if (verboseDebugging)
                         LOG(VB_COMMFLAG, LOG_DEBUG,
-                            "      length <= max comm break length, +10");
+                            "      logoCount > frames * 0.75, +10");
                     fbp->score += 10;
                 }
             }
+        }
+        else if ((logoInfoAvailable) &&
+                (fbp->logoCount < (fbp->frames * 0.10)))
+        {
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG,
+                    "      logoInfoAvailable && logoCount < frames * .10, "
+                    "-10");
+            fbp->score -= 10;
+        }
 
-            if ((logoInfoAvailable) &&
-                (fbp->logoCount < (fbp->frames * 0.50)))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      logoInfoAvailable && logoCount < frames * .50, "
-                        "-10");
-                fbp->score -= 10;
-            }
+        if (fbp->ratingCount > 5 * fps)
+        {
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG,
+                    "      rating present > 5 seconds, +20");
+            fbp->score += 20;
+        }
 
-            if (fbp->ratingCount > (fbp->frames * 0.05))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      rating symbol present > 5% of time, +20");
-                fbp->score += 20;
-            }
+        if ((fbp->scRate > 0.5) &&
+            (fbp->logoCount < (fbp->frames * .25)))
+        {
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG, "      scRate > 0.5, -10");
+            fbp->score -= 10;
 
-            if ((fbp->scRate > 1.0) &&
-                (fbp->logoCount < (fbp->frames * .90)))
+            if (fbp->scRate > 1.0)
             {
                 if (verboseDebugging)
                     LOG(VB_COMMFLAG, LOG_DEBUG, "      scRate > 1.0, -10");
                 fbp->score -= 10;
-
-                if (fbp->scRate > 2.0)
-                {
-                    if (verboseDebugging)
-                        LOG(VB_COMMFLAG, LOG_DEBUG, "      scRate > 2.0, -10");
-                    fbp->score -= 10;
-                }
             }
+        }
+        else if (fbp->scRate < 0.20)
+        {
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG, "      scRate < 0.20, +10");
+            fbp->score += 10;
+        }
 
-            if ((!decoderFoundAspectChanges) &&
-                (fbp->formatMatch < (fbp->frames * .10)))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      < 10% of frames match show letter/pillar-box "
-                        "format, -20");
-                fbp->score -= 20;
-            }
+        if ((!decoderFoundAspectChanges) &&
+            (fbp->formatMatch < (fbp->frames * .10)))
+        {
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG,
+                    "      < 10% of frames match show letter/pillar-box "
+                    "format, -20");
+            fbp->score -= 20;
+        }
 
-            if ((abs((int)(fbp->frames - (15 * fps))) < 5 ) ||
-                (abs((int)(fbp->frames - (30 * fps))) < 6 ) ||
-                (abs((int)(fbp->frames - (60 * fps))) < 8 ))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      block appears to be standard comm length, -10");
-                fbp->score -= 10;
-            }
+        if (abs(fbp->length -  5) < 0.10 ||
+            abs(fbp->length - 10) < 0.25 ||
+            abs(fbp->length - 15) < 0.50 ||
+            abs(fbp->length - 20) < 0.50 ||
+            abs(fbp->length - 30) < 0.50 ||
+            abs(fbp->length - 40) < 0.50 ||
+            abs(fbp->length - 45) < 0.75 ||
+            abs(fbp->length - 60) < 0.75 ||
+            abs(fbp->length - 90) < 1.00 ||
+            abs(fbp->length -120) < 1.00)
+        {
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG,
+                    "      block appears to be standard comm length, -10");
+            fbp->score -= 10;
         }
-        else
+        
+        if (fbp->length < 30 && fbp->bfCount > (fbp->frames * 0.90))
         {
             if (verboseDebugging)
                 LOG(VB_COMMFLAG, LOG_DEBUG,
-                    QString("      FRAMES <= %1").arg(fps));
-
-            if ((logoInfoAvailable) &&
-                (fbp->start >= firstLogoFrame) &&
-                (fbp->logoCount == 0))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      logoInfoAvailable && logoCount == 0, -10");
-                fbp->score -= 10;
-            }
-
-            if ((!decoderFoundAspectChanges) &&
-                (fbp->formatMatch < (fbp->frames * .10)))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      < 10% of frames match show letter/pillar-box "
-                        "format, -10");
-                fbp->score -= 10;
-            }
-
-            if (fbp->ratingCount > (fbp->frames * 0.25))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      rating symbol present > 25% of time, +10");
-                fbp->score += 10;
-            }
+                    "      blength < 30 && "
+                    "bfCount > frames * .9, -10");
+            fbp->score -= 10;
         }
-
+        
         if ((decoderFoundAspectChanges) &&
             (fbp->aspectMatch < (fbp->frames * .10)))
         {
@@ -1475,133 +1391,15 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
                     "      < 10% of frames match show aspect, -20");
             fbp->score -= 20;
         }
-
-        msg.sprintf("  NOW %3d:%02d %6ld %6ld %6ld %7.2f %3d %6d %6d %6d "
-                    "%5.2f %6d %6d %5d",
-                    (int)(fbp->start / fps) / 60,
-                    (int)((fbp->start / fps )) % 60,
-                    fbp->start, fbp->end, fbp->frames, fbp->length,
-                    fbp->bfCount, fbp->logoCount, fbp->ratingCount,
-                    fbp->scCount, fbp->scRate, fbp->formatMatch,
-                    fbp->aspectMatch, fbp->score);
-        LOG(VB_COMMFLAG, LOG_DEBUG, msg);
-
-        lastScore = fbp->score;
-        curBlock++;
-    }
-
-    curBlock = 0;
-    lastScore = 0;
-
-    LOG(VB_COMMFLAG, LOG_DEBUG, "============================================");
-    LOG(VB_COMMFLAG, LOG_INFO, "Second Block pass");
-    LOG(VB_COMMFLAG, LOG_DEBUG,
-        "Block StTime StFrm  EndFrm Frames Secs    "
-        "Bf  Lg Cnt RT Cnt SC Cnt SC Rt FmtMch AspMch Score");
-    LOG(VB_COMMFLAG, LOG_DEBUG,
-        "----- ------ ------ ------ ------ ------- "
-        "--- ------ ------ ------ ----- ------ ------ -----");
-    while (curBlock <= maxBlock)
-    {
-        fbp = &fblock[curBlock];
-
-        msg.sprintf("%5d %3d:%02d %6ld %6ld %6ld %7.2f %3d %6d %6d %6d "
-                    "%5.2f %6d %6d %5d",
-                    curBlock, (int)(fbp->start / fps) / 60,
-                    (int)((fbp->start / fps )) % 60,
-                    fbp->start, fbp->end, fbp->frames, fbp->length,
-                    fbp->bfCount, fbp->logoCount, fbp->ratingCount,
-                    fbp->scCount, fbp->scRate, fbp->formatMatch,
-                    fbp->aspectMatch, fbp->score);
-        LOG(VB_COMMFLAG, LOG_DEBUG, msg);
-
-        if ((curBlock > 0) && (curBlock < maxBlock))
-        {
-            nextScore = fblock[curBlock + 1].score;
-
-            if ((lastScore < 0) && (nextScore < 0) && (fbp->length < 35))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      lastScore < 0 && nextScore < 0 "
-                        "&& length < 35, setting -10");
-                fbp->score -= 10;
-            }
-
-            if ((fbp->bfCount > (fbp->frames * 0.95)) &&
-                (fbp->frames < (2*fps)) &&
-                (lastScore < 0 && nextScore < 0))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      blanks > frames * 0.95 && frames < 2*fps && "
-                        "lastScore < 0 && nextScore < 0, setting -10");
-                fbp->score -= 10;
-            }
-
-            if ((fbp->frames < (120*fps)) &&
-                (lastScore < 0) &&
-                (fbp->score > 0) &&
-                (fbp->score < 20) &&
-                (nextScore < 0))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      frames < 120 * fps && (-20 < lastScore < 0) && "
-                        "thisScore > 0 && nextScore < 0, setting score = -10");
-                fbp->score = -10;
-            }
-
-            if ((fbp->frames < (30*fps)) &&
-                (lastScore > 0) &&
-                (fbp->score < 0) &&
-                (fbp->score > -20) &&
-                (nextScore > 0))
-            {
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        "      frames < 30 * fps && (0 < lastScore < 20) && "
-                        "thisScore < 0 && nextScore > 0, setting score = 10");
-                fbp->score = 10;
-            }
-        }
-
-        if ((fbp->score == 0) && (lastScore > 30))
+        
+        if (fbp->score == 0 && fbp->length < 2)
         {
-            int offset = 1;
-            while(((curBlock + offset) <= maxBlock) &&
-                    (fblock[curBlock + offset].frames < (2 * fps)) &&
-                    (fblock[curBlock + offset].score == 0))
-                offset++;
-
-            if ((curBlock + offset) <= maxBlock)
-            {
-                offset--;
-                if (fblock[curBlock + offset + 1].score > 0)
-                {
-                    for (; offset >= 0; offset--)
-                    {
-                        fblock[curBlock + offset].score += 10;
-                        if (verboseDebugging)
-                            LOG(VB_COMMFLAG, LOG_DEBUG,
-                                QString("      Setting block %1 score +10")
-                                    .arg(curBlock+offset));
-                    }
-                }
-                else if (fblock[curBlock + offset + 1].score < 0)
-                {
-                    for (; offset >= 0; offset--)
-                    {
-                        fblock[curBlock + offset].score -= 10;
-                        if (verboseDebugging)
-                            LOG(VB_COMMFLAG, LOG_DEBUG,
-                                QString("      Setting block %1 score -10")
-                                    .arg(curBlock+offset));
-                    }
-                }
-            }
+            if (verboseDebugging)
+                LOG(VB_COMMFLAG, LOG_DEBUG,
+                    "      length < 2 && score == 0, -10");
+            fbp->score = -10;
         }
-
+        
         msg.sprintf("  NOW %3d:%02d %6ld %6ld %6ld %7.2f %3d %6d %6d %6d "
                     "%5.2f %6d %6d %5d",
                     (int)(fbp->start / fps) / 60,
@@ -1611,11 +1409,10 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
                     fbp->scCount, fbp->scRate, fbp->formatMatch,
                     fbp->aspectMatch, fbp->score);
         LOG(VB_COMMFLAG, LOG_DEBUG, msg);
-
+        
         lastScore = fbp->score;
-        curBlock++;
     }
-
+    
     LOG(VB_COMMFLAG, LOG_DEBUG, "============================================");
     LOG(VB_COMMFLAG, LOG_INFO, "FINAL Block stats");
     LOG(VB_COMMFLAG, LOG_DEBUG,
@@ -1624,162 +1421,112 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
     LOG(VB_COMMFLAG, LOG_DEBUG,
         "----- ------ ------ ------ ------ ------- "
         "--- ------ ------ ------ ----- ------ ------ -----");
-    curBlock = 0;
-    lastScore = 0;
+    lastScore = lastStart = lastEnd = 0;
     breakStart = -1;
-    while (curBlock <= maxBlock)
+    for (curBlock = 0; curBlock <= maxBlock; ++curBlock)
     {
         fbp = &fblock[curBlock];
         thisScore = fbp->score;
-
-        if ((breakStart >= 0) &&
-            ((fbp->end - breakStart) > (commDetectMaxCommBreakLength * fps)))
+        if (thisScore == 0)
+            thisScore = lastScore;
+        lastScore = thisScore;
+        
+        if (thisScore < 0 && breakStart == -1)
         {
-            if (((fbp->start - breakStart) >
-                (commDetectMinCommBreakLength * fps)) ||
-                (breakStart == 0))
+            if (curBlock > 0 &&
+               (fbp->start - lastEnd) < (commDetectMinShowLength * fps))
             {
+                commBreakMap.remove(lastStart);
+                commBreakMap.remove(lastEnd);
+                breakStart = lastStart;
+
                 if (verboseDebugging)
+                {
                     LOG(VB_COMMFLAG, LOG_DEBUG,
-                        QString("Closing commercial block at start of "
-                                "frame block %1 with length %2, frame "
-                                "block length of %3 frames would put comm "
-                                "block length over max of %4 seconds.")
-                            .arg(curBlock).arg(fbp->start - breakStart)
-                            .arg(fbp->frames)
-                            .arg(commDetectMaxCommBreakLength));
-
-                commBreakMap[breakStart] = MARK_COMM_START;
-                commBreakMap[fbp->start] = MARK_COMM_END;
-                lastStart = breakStart;
-                lastEnd = fbp->start;
-                breakStart = -1;
+                        QString("ReOpening commercial block at "
+                                "frame %1 because show less than "
+                                "%2 seconds")
+                            .arg(breakStart)
+                            .arg(commDetectMinShowLength));
+                }
             }
             else
             {
+                breakStart = fbp->start;
+
                 if (verboseDebugging)
                     LOG(VB_COMMFLAG, LOG_DEBUG,
-                        QString("Ignoring what appears to be commercial"
-                                " block at frame %1 with length %2, "
-                                "length of %3 frames would put comm "
-                                "block length under min of %4 seconds.")
-                            .arg(breakStart)
-                            .arg(fbp->start - breakStart)
-                            .arg(fbp->frames)
-                            .arg(commDetectMinCommBreakLength));
-                breakStart = -1;
+                        QString("Starting new commercial block at "
+                                "frame %1 from start of frame block %2")
+                            .arg(fbp->start).arg(curBlock));
             }
+            lastStart = breakStart;
         }
-        if (thisScore == 0)
+        
+        if(breakStart >= 0 && (
+            // Break should stop (by score)
+            thisScore >= 0 ||
+            // Break must stop at end of recording
+            curBlock == maxBlock ||
+            // Break will be too long
+            (fbp->end - breakStart) >= commDetectMaxCommBreakLength * fps
+          ))
         {
-            thisScore = lastScore;
-        }
-        else if (thisScore < 0)
-        {
-            if ((lastScore > 0) || (curBlock == 0))
+            unsigned int endOfBreak = fbp->start;
+            if (thisScore < 0 &&
+                curBlock == maxBlock && 
+                (fbp->end - breakStart) < commDetectMaxCommBreakLength * fps)
             {
-                if ((fbp->start - lastEnd) < (commDetectMinShowLength * fps))
-                {
-                    commBreakMap.remove(lastStart);
-                    commBreakMap.remove(lastEnd);
-                    breakStart = lastStart;
-
-                    if (verboseDebugging)
-                    {
-                        if (breakStart)
-                            LOG(VB_COMMFLAG, LOG_DEBUG,
-                                QString("ReOpening commercial block at "
-                                        "frame %1 because show less than "
-                                        "%2 seconds")
-                                    .arg(breakStart)
-                                    .arg(commDetectMinShowLength));
-                        else
-                            LOG(VB_COMMFLAG, LOG_DEBUG,
-                                "Opening initial commercial block "
-                                "at start of recording, block 0.");
-                    }
-                }
-                else
-                {
-                    breakStart = fbp->start;
-
-                    if (verboseDebugging)
-                        LOG(VB_COMMFLAG, LOG_DEBUG,
-                            QString("Starting new commercial block at "
-                                    "frame %1 from start of frame block %2")
-                                .arg(fbp->start).arg(curBlock));
-                }
+                // Create what is essentially an open-ended final skip region
+                // by setting the end point 10 seconds past the end of the
+                // recording.
+                endOfBreak = fbp->end + (10 * fps);
+                
+                if (verboseDebugging)
+                    LOG(VB_COMMFLAG, LOG_DEBUG,
+                        "    At end of recording.");
             }
-            else if (curBlock == maxBlock)
+            
+            if ((endOfBreak - breakStart) >= (commDetectMinCommBreakLength * fps))
             {
-                if ((fbp->end - breakStart) >
-                    (commDetectMinCommBreakLength * fps))
+                if (verboseDebugging)
                 {
-                    if (fbp->end <=
-                        ((int64_t)framesProcessed - (int64_t)(2 * fps) - 2))
+                    LOG(VB_COMMFLAG, LOG_DEBUG,
+                        QString("Closing commercial block at "
+                                "frame %1 from frame block %2, length %3")
+                            .arg(endOfBreak).arg(curBlock)
+                            .arg(endOfBreak - breakStart));
+                    
+                    if (thisScore < 0 &&
+                        (fbp->end - breakStart) >= commDetectMaxCommBreakLength * fps)
                     {
-                        if (verboseDebugging)
-                            LOG(VB_COMMFLAG, LOG_DEBUG,
-                                QString("Closing final commercial block at "
-                                        "frame %1").arg(fbp->end));
-
-                        commBreakMap[breakStart] = MARK_COMM_START;
-                        commBreakMap[fbp->end] = MARK_COMM_END;
-                        lastStart = breakStart;
-                        lastEnd = fbp->end;
-                        breakStart = -1;
-                    }
-                }
-                else
-                {
-                    if (verboseDebugging)
                         LOG(VB_COMMFLAG, LOG_DEBUG,
-                            QString("Ignoring what appears to be commercial"
-                                    " block at frame %1 with length %2, "
-                                    "length of %3 frames would put comm "
-                                    "block length under min of %4 seconds.")
-                                .arg(breakStart)
-                                .arg(fbp->start - breakStart)
+                            QString("    Frame block length of %1 frames would put comm "
+                                    "block length over max of %2 seconds.")
                                 .arg(fbp->frames)
-                                .arg(commDetectMinCommBreakLength));
-                    breakStart = -1;
+                                .arg(commDetectMaxCommBreakLength));
+                    }
                 }
-            }
-        }
-        else if ((thisScore > 0) &&
-                 (lastScore < 0) &&
-                 (breakStart != -1))
-        {
-            if (((fbp->start - breakStart) >
-                (commDetectMinCommBreakLength * fps)) ||
-                (breakStart == 0))
-            {
+
                 commBreakMap[breakStart] = MARK_COMM_START;
-                commBreakMap[fbp->start] = MARK_COMM_END;
+                commBreakMap[endOfBreak] = MARK_COMM_END;
                 lastStart = breakStart;
-                lastEnd = fbp->start;
-
-                if (verboseDebugging)
-                    LOG(VB_COMMFLAG, LOG_DEBUG,
-                        QString("Closing commercial block at frame %1")
-                            .arg(fbp->start));
+                lastEnd = endOfBreak;
             }
             else
             {
                 if (verboseDebugging)
                     LOG(VB_COMMFLAG, LOG_DEBUG,
-                        QString("Ignoring what appears to be commercial "
-                                "block at frame %1 with length %2, "
-                                "length of %3 frames would put comm block "
-                                "length under min of %4 seconds.")
+                        QString("Ignoring what appears to be commercial"
+                                " block at frame %1 with length %2, "
+                                "block length would be under min of %3 seconds.")
                             .arg(breakStart)
-                            .arg(fbp->start - breakStart)
-                            .arg(fbp->frames)
+                            .arg(endOfBreak - breakStart)
                             .arg(commDetectMinCommBreakLength));
             }
             breakStart = -1;
         }
-
+        
         msg.sprintf("%5d %3d:%02d %6ld %6ld %6ld %7.2f %3d %6d %6d %6d "
                     "%5.2f %6d %6d %5d",
                     curBlock, (int)(fbp->start / fps) / 60,
@@ -1789,27 +1536,6 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
                     fbp->scCount, fbp->scRate, fbp->formatMatch,
                     fbp->aspectMatch, thisScore);
         LOG(VB_COMMFLAG, LOG_DEBUG, msg);
-
-        lastScore = thisScore;
-        curBlock++;
-    }
-
-    if ((breakStart != -1) &&
-        (breakStart <= ((int64_t)framesProcessed - (int64_t)(2 * fps) - 2)))
-    {
-        if (verboseDebugging)
-            LOG(VB_COMMFLAG, LOG_DEBUG,
-                QString("Closing final commercial block started at "
-                        "block %1 and going to end of program. length "
-                        "is %2 frames")
-                    .arg(curBlock)
-                    .arg((framesProcessed - breakStart - 1)));
-
-        commBreakMap[breakStart] = MARK_COMM_START;
-        // Create what is essentially an open-ended final skip region
-        // by setting the end point 10 seconds past the end of the
-        // recording.
-        commBreakMap[framesProcessed + (10 * fps)] = MARK_COMM_END;
     }
 
     // include/exclude blanks from comm breaks
@@ -1821,51 +1547,22 @@ void ClassicCommDetector::BuildAllMethodsCommList(void)
             "Adjusting start/end marks according to blanks.");
     for (it = tmpCommMap.begin(); it != tmpCommMap.end(); ++it)
     {
-        if (*it == MARK_COMM_START)
-        {
-            uint64_t lastStartLower = it.key();
-            uint64_t lastStartUpper = it.key();
-            while ((lastStartLower > 0) &&
-                   (frameInfo[lastStartLower - 1].flagMask & COMM_FRAME_BLANK))
-                lastStartLower--;
-            while ((lastStartUpper < (framesProcessed - (2 * fps))) &&
-                   (frameInfo[lastStartUpper + 1].flagMask & COMM_FRAME_BLANK))
-                lastStartUpper++;
-            uint64_t adj = (lastStartUpper - lastStartLower) / 2;
-            if (adj > MAX_BLANK_FRAMES)
-                adj = MAX_BLANK_FRAMES;
-            lastStart = lastStartLower + adj;
-
-            if (verboseDebugging)
-                LOG(VB_COMMFLAG, LOG_DEBUG, QString("Start Mark: %1 -> %2")
-                        .arg(it.key()).arg(lastStart));
-
-            commBreakMap[lastStart] = MARK_COMM_START;
-        }
-        else
-        {
-            uint64_t lastEndLower = it.key();
-            uint64_t lastEndUpper = it.key();
-            while ((lastEndUpper < (framesProcessed - (2 * fps))) &&
-                   (frameInfo[lastEndUpper + 1].flagMask & COMM_FRAME_BLANK))
-                lastEndUpper++;
-            while ((lastEndLower > 0) &&
-                   (frameInfo[lastEndLower - 1].flagMask & COMM_FRAME_BLANK))
-                lastEndLower--;
-            uint64_t adj = (lastEndUpper - lastEndLower) / 2;
-            if (adj > MAX_BLANK_FRAMES)
-                adj = MAX_BLANK_FRAMES;
-            lastEnd = lastEndUpper - adj;
-
-            if (verboseDebugging)
-                LOG(VB_COMMFLAG, LOG_DEBUG, QString("End Mark  : %1 -> %2")
-                        .arg(it.key()).arg(lastEnd));
-
-            commBreakMap[lastEnd] = MARK_COMM_END;
-        }
+        uint64_t blankStart, blankEnd;
+        blankStart = blankEnd = it.key();
+        
+        while (blankStart > 0 && frameInfo[blankStart].flagMask & COMM_FRAME_BLANK)
+            --blankStart;
+        while (blankEnd < framesProcessed && frameInfo[blankEnd].flagMask & COMM_FRAME_BLANK)
+            ++blankEnd;
+        
+        uint64_t split = blankStart + (blankEnd - blankStart) / 2;
+        
+        commBreakMap[split] = *it;
+        
+        if (verboseDebugging)
+            LOG(VB_COMMFLAG, LOG_DEBUG, QString("Adjusted Mark %1: %2 -> %3")
+                    .arg(*it).arg(it.key()).arg(split));
     }
-
-    delete [] fblock;
 }
 
 
diff --git a/mythtv/programs/mythcommflag/ClassicCommDetector.h b/mythtv/programs/mythcommflag/ClassicCommDetector.h
index f9e5c4c..f397fec 100644
--- a/mythtv/programs/mythcommflag/ClassicCommDetector.h
+++ b/mythtv/programs/mythcommflag/ClassicCommDetector.h
@@ -142,7 +142,7 @@ class ClassicCommDetector : public CommDetectorBase
         bool blankFramesOnly;
         int blankFrameCount;
         int currentAspect;
-
+        unsigned char *colMax;
 
         int totalMinBrightness;
 
diff --git a/mythtv/programs/mythcommflag/ClassicLogoDetector.cpp b/mythtv/programs/mythcommflag/ClassicLogoDetector.cpp
index f961af0..6db9e12 100644
--- a/mythtv/programs/mythcommflag/ClassicLogoDetector.cpp
+++ b/mythtv/programs/mythcommflag/ClassicLogoDetector.cpp
@@ -6,22 +6,13 @@
 
 // MythTV headers
 #include "mythcorecontext.h"
-#include "mythplayer.h"
+#include "mythcommflagplayer.h"
 
 // Commercial Flagging headers
 #include "ClassicLogoDetector.h"
 #include "ClassicCommDetector.h"
-
-typedef struct edgemaskentry
-{
-    int isedge;
-    int horiz;
-    int vert;
-    int rdiag;
-    int ldiag;
-}
-EdgeMaskEntry;
-
+#include <ffmpeg-mmx.h>
+#include <lzoconf.h>
 
 ClassicLogoDetector::ClassicLogoDetector(ClassicCommDetector* commdetector,
                                          unsigned int w, unsigned int h,
@@ -29,17 +20,10 @@ ClassicLogoDetector::ClassicLogoDetector(ClassicCommDetector* commdetector,
                                          unsigned int xspacing_in,
                                          unsigned int yspacing_in)
     : LogoDetectorBase(w,h),
-      commDetector(commdetector),                       frameNumber(0),
-      previousFrameWasSceneChange(false),
-      xspacing(xspacing_in),                            yspacing(yspacing_in),
-      commDetectBorder(commdetectborder_in),            edgeMask(new EdgeMaskEntry[width * height]),
-      logoMaxValues(new unsigned char[width * height]), logoMinValues(new unsigned char[width * height]),
-      logoFrame(new unsigned char[width * height]),     logoMask(new unsigned char[width * height]),
-      logoCheckMask(new unsigned char[width * height]), tmpBuf(new unsigned char[width * height]),
-      logoEdgeDiff(0),                                  logoFrameCount(0),
-      logoMinX(0),                                      logoMaxX(0),
-      logoMinY(0),                                      logoMaxY(0),
-      logoInfoAvailable(false)
+      commDetector(commdetector), commDetectBorder(commdetectborder_in),
+      logoInfoAvailable(false),   logoEdgeDiff(0),
+      logoMinX(0),                logoWidth(0),
+      logoMinY(0),                logoHeight(0)
 {
     commDetectLogoSamplesNeeded =
         gCoreContext->GetNumSetting("CommDetectLogoSamplesNeeded", 240);
@@ -63,21 +47,7 @@ unsigned int ClassicLogoDetector::getRequiredAvailableBufferForSearch()
 void ClassicLogoDetector::deleteLater(void)
 {
     commDetector = 0;
-    if (edgeMask)
-        delete [] edgeMask;
-    if (logoFrame)
-        delete [] logoFrame;
-    if (logoMask)
-        delete [] logoMask;
-    if (logoCheckMask)
-        delete [] logoCheckMask;
-    if (logoMaxValues)
-        delete [] logoMaxValues;
-    if (logoMinValues)
-        delete [] logoMinValues;
-    if (tmpBuf)
-        delete [] tmpBuf;
-
+    
     LogoDetectorBase::deleteLater();
 }
 
@@ -88,26 +58,23 @@ bool ClassicLogoDetector::searchForLogo(MythPlayer* player)
     long long seekFrame;
     int loops;
     int maxLoops = commDetectLogoSamplesNeeded;
-    EdgeMaskEntry *edgeCounts;
-    unsigned int pos, i, x, y, dx, dy;
-    int edgeDiffs[] = {5, 7, 10, 15, 20, 30, 40, 50, 60, 0 };
-
-
+    const int edgeDiffs[] = {55, 25, 13, 6, 0};
+    
     LOG(VB_COMMFLAG, LOG_INFO, "Searching for Station Logo");
 
     logoInfoAvailable = false;
 
-    edgeCounts = new EdgeMaskEntry[width * height];
+    int *edgeCounts = new int[width * height];
 
-    for (i = 0; edgeDiffs[i] != 0 && !logoInfoAvailable; i++)
+    for (int i = 0; edgeDiffs[i] != 0 && !logoInfoAvailable; i++)
     {
         int pixelsInMask = 0;
 
         LOG(VB_COMMFLAG, LOG_INFO, QString("Trying with edgeDiff == %1")
                 .arg(edgeDiffs[i]));
 
-        memset(edgeCounts, 0, sizeof(EdgeMaskEntry) * width * height);
-        memset(edgeMask, 0, sizeof(EdgeMaskEntry) * width * height);
+        memset(edgeCounts, 0, sizeof(int) * width * height);
+        edgeMask.clear();
 
         player->DiscardVideoFrame(player->GetRawVideoFrame(0));
 
@@ -115,128 +82,37 @@ bool ClassicLogoDetector::searchForLogo(MythPlayer* player)
         seekFrame = commDetector->preRoll + seekIncrement;
         while(loops < maxLoops && !player->GetEof())
         {
-            VideoFrame* vf = player->GetRawVideoFrame(seekFrame);
-
             if ((loops % 50) == 0)
                 commDetector->logoDetectorBreathe();
 
+            if (!commDetector->fullSpeed)
+                usleep(10000);
+            
+            VideoFrame* vf = player->GetRawVideoFrame(seekFrame);
+            DetectEdges(vf, edgeCounts, edgeDiffs[i]);
+            player->DiscardVideoFrame(vf);
+            
             if (commDetector->m_bStop)
             {
-                player->DiscardVideoFrame(vf);
                 delete[] edgeCounts;
                 return false;
             }
-
-            if (!commDetector->fullSpeed)
-                usleep(10000);
-
-            DetectEdges(vf, edgeCounts, edgeDiffs[i]);
-
+            
             seekFrame += seekIncrement;
             loops++;
-
-            player->DiscardVideoFrame(vf);
-        }
-
-        LOG(VB_COMMFLAG, LOG_INFO, "Analyzing edge data");
-
-#ifdef SHOW_DEBUG_WIN
-        unsigned char *fakeFrame;
-        fakeFrame = new unsigned char[width * height * 3 / 2];
-        memset(fakeFrame, 0, width * height * 3 / 2);
-#endif
-
-        for (y = 0; y < height; y++)
-        {
-            if ((y > (height/4)) && (y < (height * 3 / 4)))
-                continue;
-
-            for (x = 0; x < width; x++)
-            {
-                if ((x > (width/4)) && (x < (width * 3 / 4)))
-                    continue;
-
-                pos = y * width + x;
-
-                if (edgeCounts[pos].isedge > (maxLoops * 0.66))
-                {
-                    edgeMask[pos].isedge = 1;
-                    pixelsInMask++;
-#ifdef SHOW_DEBUG_WIN
-                    fakeFrame[pos] = 0xff;
-#endif
-
-                }
-
-                if (edgeCounts[pos].horiz > (maxLoops * 0.66))
-                    edgeMask[pos].horiz = 1;
-
-                if (edgeCounts[pos].vert > (maxLoops * 0.66))
-                    edgeMask[pos].vert = 1;
-
-                if (edgeCounts[pos].ldiag > (maxLoops * 0.66))
-                    edgeMask[pos].ldiag = 1;
-                if (edgeCounts[pos].rdiag > (maxLoops * 0.66))
-                    edgeMask[pos].rdiag = 1;
-            }
-        }
-
-        SetLogoMaskArea();
-
-        for (y = logoMinY; y < logoMaxY; y++)
-        {
-            for (x = logoMinX; x < logoMaxX; x++)
-            {
-                int neighbors = 0;
-
-                if (!edgeMask[y * width + x].isedge)
-                    continue;
-
-                for (dy = y - 2; dy <= (y + 2); dy++ )
-                {
-                    for (dx = x - 2; dx <= (x + 2); dx++ )
-                    {
-                        if (edgeMask[dy * width + dx].isedge)
-                            neighbors++;
-                    }
-                }
-
-                if (neighbors < 5)
-                    edgeMask[y * width + x].isedge = 0;
-            }
         }
+        
+        player->DiscardVideoFrame(player->GetRawVideoFrame(0));
 
-        SetLogoMaskArea();
+        pixelsInMask = AnalyzeEdgeCounts(edgeCounts, maxLoops * 2 / 3);
+        
         LOG(VB_COMMFLAG, LOG_INFO,
-            QString("Testing Logo area: topleft (%1,%2), bottomright (%3,%4)")
+            QString("Testing Logo area: topleft (%1,%2), size (%3,%4)")
                 .arg(logoMinX).arg(logoMinY)
-                .arg(logoMaxX).arg(logoMaxY));
-
-#ifdef SHOW_DEBUG_WIN
-        for (x = logoMinX; x < logoMaxX; x++)
-        {
-            pos = logoMinY * width + x;
-            fakeFrame[pos] = 0x7f;
-            pos = logoMaxY * width + x;
-            fakeFrame[pos] = 0x7f;
-        }
-        for (y = logoMinY; y < logoMaxY; y++)
-        {
-            pos = y * width + logoMinX;
-            fakeFrame[pos] = 0x7f;
-            pos = y * width + logoMaxX;
-            fakeFrame[pos] = 0x7f;
-        }
-
-        comm_debug_show(fakeFrame);
-        delete [] fakeFrame;
+                .arg(logoWidth).arg(logoHeight));
 
-        cerr << "Hit ENTER to continue" << endl;
-        getchar();
-#endif
-        if (((logoMaxX - logoMinX) < (width / 4)) &&
-            ((logoMaxY - logoMinY) < (height / 4)) &&
-            (pixelsInMask > 50))
+        if (pixelsInMask > 100 && 
+            (logoWidth < (width / 6) || logoHeight < (height / 6)))
         {
             logoInfoAvailable = true;
             logoEdgeDiff = edgeDiffs[i];
@@ -245,7 +121,7 @@ bool ClassicLogoDetector::searchForLogo(MythPlayer* player)
                 QString("Using Logo area: topleft (%1,%2), "
                         "bottomright (%3,%4)")
                     .arg(logoMinX).arg(logoMinY)
-                    .arg(logoMaxX).arg(logoMaxY));
+                    .arg(logoWidth).arg(logoHeight));
         }
         else
         {
@@ -254,7 +130,7 @@ bool ClassicLogoDetector::searchForLogo(MythPlayer* player)
                         "bottomright (%3,%4), pixelsInMask (%5). "
                         "Not within specified limits.")
                     .arg(logoMinX).arg(logoMinY)
-                    .arg(logoMaxX).arg(logoMaxY)
+                    .arg(logoWidth).arg(logoHeight)
                     .arg(pixelsInMask));
         }
     }
@@ -263,27 +139,56 @@ bool ClassicLogoDetector::searchForLogo(MythPlayer* player)
 
     if (!logoInfoAvailable)
         LOG(VB_COMMFLAG, LOG_NOTICE, "No suitable logo area found.");
-
-    player->DiscardVideoFrame(player->GetRawVideoFrame(0));
+    else
+        DumpLogo();
+    
     return logoInfoAvailable;
 }
 
-
-void ClassicLogoDetector::SetLogoMaskArea()
+int ClassicLogoDetector::AnalyzeEdgeCounts(int *edgeCounts, int threshold)
 {
-    LOG(VB_COMMFLAG, LOG_INFO, "SetLogoMaskArea()");
-
+    const int minNeighbors = 2;
+    int pixelsInMask = 0;
+    unsigned int logoMaxX = 0, logoMaxY = 0;
+    
     logoMinX = width - 1;
-    logoMaxX = 0;
     logoMinY = height - 1;
-    logoMaxY = 0;
-
+    
+    LOG(VB_COMMFLAG, LOG_INFO, "Analyzing edge data");
+    
+    QBitArray tmpMask(width*height);
+    
     for (unsigned int y = 0; y < height; y++)
     {
         for (unsigned int x = 0; x < width; x++)
         {
-            if (edgeMask[y * width + x].isedge)
+            unsigned int pos = y * width + x;
+            if (edgeCounts[pos] < threshold)
+                continue;
+            
+            int neighbors = 0;
+            
+            // 3x3 block
+            for (int dy = y - 1; dy <= (y + 1); dy++)
+            {
+                for (int dx = x - 1; dx <= (x + 1); dx++)
+                {
+                    unsigned int dp = dy * width + dx;
+                    if (edgeCounts[dp] >= threshold)
+                    {
+                        neighbors++;
+                        if (neighbors > minNeighbors)
+                            break;
+                    }
+                }
+            }
+            
+            if (neighbors > minNeighbors)
             {
+                tmpMask[pos] = true;
+                
+                pixelsInMask++;
+                
                 if (x < logoMinX)
                     logoMinX = x;
                 if (y < logoMinY)
@@ -293,281 +198,159 @@ void ClassicLogoDetector::SetLogoMaskArea()
                 if (y > logoMaxY)
                     logoMaxY = y;
             }
-        }
-    }
-
-    logoMinX -= 5;
-    logoMaxX += 5;
-    logoMinY -= 5;
-    logoMaxY += 5;
-
-    if (logoMinX < 4)
-        logoMinX = 4;
-    if (logoMaxX > (width-5))
-        logoMaxX = (width-5);
-    if (logoMinY < 4)
-        logoMinY = 4;
-    if (logoMaxY > (height-5))
-        logoMaxY = (height-5);
-}
-
-void ClassicLogoDetector::SetLogoMask(unsigned char *mask)
-{
-    int pixels = 0;
-
-    memcpy(logoMask, mask, width * height);
-
-    SetLogoMaskArea();
-
-    for(unsigned int y = logoMinY; y <= logoMaxY; y++)
-        for(unsigned int x = logoMinX; x <= logoMaxX; x++)
-            if (!logoMask[y * width + x] == 1)
-                pixels++;
-
-    if (pixels < 30)
-        return;
-
-    // set the pixels around our logo
-    for(unsigned int y = (logoMinY - 1); y <= (logoMaxY + 1); y++)
-    {
-        for(unsigned int x = (logoMinX - 1); x <= (logoMaxX + 1); x++)
-        {
-            if (!logoMask[y * width + x])
+            else
             {
-                for (unsigned int y2 = y - 1; y2 <= (y + 1); y2++)
-                {
-                    for (unsigned int x2 = x - 1; x2 <= (x + 1); x2++)
-                    {
-                        if ((logoMask[y2 * width + x2] == 1) &&
-                            (!logoMask[y * width + x]))
-                        {
-                            logoMask[y * width + x] = 2;
-                            x2 = x + 2;
-                            y2 = y + 2;
-
-                            logoCheckMask[y2 * width + x2] = 1;
-                            logoCheckMask[y * width + x] = 1;
-                        }
-                    }
-                }
+                tmpMask[pos] = false;
             }
-        }
-    }
-
-    for(unsigned int y = (logoMinY - 2); y <= (logoMaxY + 2); y++)
+        } // end for x
+    } // end for y
+    
+    logoMinX -= 1;
+    logoMaxX += 1;
+    logoMinY -= 1;
+    logoMaxY += 1;
+
+    if (logoMinX < commDetectBorder)
+        logoMinX = commDetectBorder;
+    if (logoMaxX > (width-commDetectBorder))
+        logoMaxX = (width-commDetectBorder);
+    if (logoMinY < commDetectBorder)
+        logoMinY = commDetectBorder;
+    if (logoMaxY > (height-commDetectBorder))
+        logoMaxY = (height-commDetectBorder);
+    
+    if (pixelsInMask > 0 && logoMaxX > logoMinX && logoMaxY > logoMinY)
     {
-        for(unsigned int x = (logoMinX - 2); x <= (logoMaxX + 2); x++)
+        logoWidth = logoMaxX - logoMinX;
+        logoHeight = logoMaxY - logoMinY;
+        
+        edgeMask.resize(logoWidth * logoHeight);
+        for (unsigned int y = 0; y < logoHeight; ++y)
         {
-            if (!logoMask[y * width + x])
+            for (unsigned int x = 0; x < logoWidth; ++x)
             {
-                for (unsigned int y2 = y - 1; y2 <= (y + 1); y2++)
-                {
-                    for (unsigned int x2 = x - 1; x2 <= (x + 1); x2++)
-                    {
-                        if ((logoMask[y2 * width + x2] == 2) &&
-                            (!logoMask[y * width + x]))
-                        {
-                            logoMask[y * width + x] = 3;
-                            x2 = x + 2;
-                            y2 = y + 2;
-
-                            logoCheckMask[y * width + x] = 1;
-                        }
-                    }
-                }
+                edgeMask[y * logoWidth + x] = tmpMask[(y + logoMinY) * width + (x + logoMinX)];
             }
         }
     }
-
-#ifdef SHOW_DEBUG_WIN
-    DumpLogo(true,framePtr);
-#endif
-
-    logoFrameCount = 0;
-    logoInfoAvailable = true;
+    
+    return pixelsInMask;
 }
 
-
-void ClassicLogoDetector::DumpLogo(bool fromCurrentFrame,
-    unsigned char* framePtr)
+void ClassicLogoDetector::DumpLogo()
 {
-    char scrPixels[] = " .oxX";
-
-    if (!logoInfoAvailable)
-        return;
-
-    cerr << "\nLogo Data ";
-    if (fromCurrentFrame)
-        cerr << "from current frame\n";
-
-    cerr << "\n     ";
-
-    for(unsigned int x = logoMinX - 2; x <= (logoMaxX + 2); x++)
-        cerr << (x % 10);
-    cerr << "\n";
-
-    for(unsigned int y = logoMinY - 2; y <= (logoMaxY + 2); y++)
+    cerr << "Logo data (" << logoMinX << "," << logoMinY << ") x (" 
+                          << logoWidth << "," << logoHeight << ") @ "
+                          << logoEdgeDiff << ":\n";
+    
+    for (unsigned int y = 0; y < logoHeight; y++)
     {
-        QString tmp = QString("%1: ").arg(y, 3);
-        QString ba = tmp.toAscii();
-        cerr << ba.constData();
-        for(unsigned int x = logoMinX - 2; x <= (logoMaxX + 2); x++)
+        for (unsigned int x = 0; x < logoWidth; x++)
         {
-            if (fromCurrentFrame)
-            {
-                cerr << scrPixels[framePtr[y * width + x] / 50];
-            }
+            unsigned int pos = y * logoWidth + x;
+            if (edgeMask[pos])
+                cerr << "#";
             else
-            {
-                switch (logoMask[y * width + x])
-                {
-                        case 0:
-                        case 2: cerr << " ";
-                        break;
-                        case 1: cerr << "*";
-                        break;
-                        case 3: cerr << ".";
-                        break;
-                }
-            }
+                cerr << " ";
         }
         cerr << "\n";
     }
-    cerr.flush();
+    
+    cerr << "\n\n\n";
 }
 
+bool ClassicLogoDetector::pixelInsideLogo(unsigned int x, unsigned int y)
+{
+    if (!logoInfoAvailable)
+        return false;
+    
+    int xd = x - logoMinX;
+    int yd = y - logoMinY;
+    
+    return xd >= 0 && xd < (int)logoWidth &&
+           yd >= 0 && yd < (int)logoHeight;
+}
 
-/* ideas for this method ported back from comskip.c mods by Jere Jones
- * which are partially mods based on Myth's original commercial skip
- * code written by Chris Pinkham. */
-bool ClassicLogoDetector::doesThisFrameContainTheFoundLogo(
-    unsigned char* framePtr)
+bool ClassicLogoDetector::isSobelEdgeAt(unsigned char *buf,
+                                        unsigned int x,
+                                        unsigned int y,
+                                        unsigned int width,
+                                        unsigned char edgeDiff)
 {
-    int radius = 2;
-    unsigned int x, y;
-    int pos1, pos2, pos3;
-    int pixel;
-    int goodEdges = 0;
-    int badEdges = 0;
-    int testEdges = 0;
-    int testNotEdges = 0;
+    int center = y * width + x;
+    int above = center - width;
+    int below = center + width;
+    
+    int gx = 0;
+    gx -= buf[above - 1];
+    gx -= (buf[center - 1]*2);
+    gx -= buf[below - 1];
+    
+    gx += buf[above + 1];
+    gx += (buf[center + 1]*2);
+    gx += buf[below + 1];
+    
+    int gy = 0;
+    gy -= buf[above - 1];
+    gy -= (buf[above]*2);
+    gy -= buf[above + 1];
+    
+    gy += buf[below - 1];
+    gy += (buf[below]*2);
+    gy += buf[below + 1];
+    
+    return abs(gx) + abs(gy) > 3*edgeDiff;
+}
 
-    for (y = logoMinY; y <= logoMaxY; y++ )
+bool ClassicLogoDetector::doesThisFrameContainTheFoundLogo(unsigned char *framePtr)
+{
+    if (!logoInfoAvailable)
+        return false;
+    
+    unsigned int x, y;
+    unsigned int correct = 0, total = 0;
+    
+    for (y = 0; y < logoHeight; y++ )
     {
-        for (x = logoMinX; x <= logoMaxX; x++ )
+        for (x = 0; x < logoWidth; x++ )
         {
-            pos1 = y * width + x;
-            pos2 = (y - radius) * width + x;
-            pos3 = (y + radius) * width + x;
-
-            pixel = framePtr[pos1];
-
-            if (edgeMask[pos1].horiz)
-            {
-                if ((abs(framePtr[pos1 - radius] - pixel) >= logoEdgeDiff) ||
-                    (abs(framePtr[pos1 + radius] - pixel) >= logoEdgeDiff))
-                    goodEdges++;
-                testEdges++;
-            }
-            else
-            {
-                if ((abs(framePtr[pos1 - radius] - pixel) >= logoEdgeDiff) ||
-                    (abs(framePtr[pos1 + radius] - pixel) >= logoEdgeDiff))
-                    badEdges++;
-                testNotEdges++;
-            }
-
-            if (edgeMask[pos1].vert)
-            {
-                if ((abs(framePtr[pos2] - pixel) >= logoEdgeDiff) ||
-                    (abs(framePtr[pos3] - pixel) >= logoEdgeDiff))
-                    goodEdges++;
-                testEdges++;
-            }
-            else
+            if (edgeMask[y * logoWidth + x])
             {
-                if ((abs(framePtr[pos2] - pixel) >= logoEdgeDiff) ||
-                    (abs(framePtr[pos3] - pixel) >= logoEdgeDiff))
-                    badEdges++;
-                testNotEdges++;
+                if (isSobelEdgeAt(framePtr, x + logoMinX, y + logoMinY, width, logoEdgeDiff))
+                    correct++;
+                total ++;
             }
         }
     }
-
-    frameNumber++;
-    double goodEdgeRatio = (double)goodEdges / (double)testEdges;
-    double badEdgeRatio = (double)badEdges / (double)testNotEdges;
-    if ((goodEdgeRatio > commDetectLogoGoodEdgeThreshold) &&
-        (badEdgeRatio < commDetectLogoBadEdgeThreshold))
-        return true;
-    else
-        return false;
-}
-
-bool ClassicLogoDetector::pixelInsideLogo(unsigned int x, unsigned int y)
-{
-    if (!logoInfoAvailable)
-        return false;
-
-    return ((x > logoMinX) && (x < logoMaxX) &&
-            (y > logoMinY) && (y < logoMaxY));
+    
+    double d = (double)correct / (double)total;
+    return d >= commDetectLogoGoodEdgeThreshold;
 }
 
-void ClassicLogoDetector::DetectEdges(VideoFrame *frame, EdgeMaskEntry *edges,
-                                      int edgeDiff)
+void ClassicLogoDetector::DetectEdges(VideoFrame *frame, int *edgeCounts, int edgeDiff)
 {
-    int r = 2;
-    unsigned char *buf = frame->buf;
-    unsigned char p;
-    unsigned int pos, x, y;
-
-    for (y = commDetectBorder + r; y < (height - commDetectBorder - r); y++)
+    unsigned int x, y;
+    
+    unsigned int hOneThird = height / 3;
+    unsigned int hTwoThirds = hOneThird*2;
+    unsigned int wOneThird = width / 3;
+    unsigned int wTwoThirds = wOneThird*2;
+    
+    for (y = commDetectBorder; y < height - commDetectBorder; ++y)
     {
-        if ((y > (height/4)) && (y < (height * 3 / 4)))
-            continue;
-
-        for (x = commDetectBorder + r; x < (width - commDetectBorder - r); x++)
+        for (x = commDetectBorder; x < width - commDetectBorder; ++x)
         {
-            int edgeCount = 0;
-
-            if ((x > (width/4)) && (x < (width * 3 / 4)))
-                continue;
-
-            pos = y * width + x;
-            p = buf[pos];
-
-            if (( abs(buf[y * width + (x - r)] - p) >= edgeDiff) ||
-                ( abs(buf[y * width + (x + r)] - p) >= edgeDiff))
-            {
-                edges[pos].horiz++;
-                edgeCount++;
-            }
-            if (( abs(buf[(y - r) * width + x] - p) >= edgeDiff) ||
-                ( abs(buf[(y + r) * width + x] - p) >= edgeDiff))
-            {
-                edges[pos].vert++;
-                edgeCount++;
-            }
-
-            if (( abs(buf[(y - r) * width + (x - r)] - p) >= edgeDiff) ||
-                ( abs(buf[(y + r) * width + (x + r)] - p) >= edgeDiff))
+            if (y > hOneThird && y < hTwoThirds && 
+                x > wOneThird && x < wTwoThirds)
             {
-                edges[pos].ldiag++;
-                edgeCount++;
+                x = wTwoThirds - 1;
             }
-
-            if (( abs(buf[(y - r) * width + (x + r)] - p) >= edgeDiff) ||
-                ( abs(buf[(y + r) * width + (x - r)] - p) >= edgeDiff))
+            else if (isSobelEdgeAt(frame->buf, x, y, width, edgeDiff))
             {
-                edges[pos].rdiag++;
-                edgeCount++;
+                edgeCounts[y * width + x]++;
             }
-
-            if (edgeCount >= 3)
-                edges[pos].isedge++;
         }
     }
 }
 
 /* vim: set expandtab tabstop=4 shiftwidth=4: */
-
diff --git a/mythtv/programs/mythcommflag/ClassicLogoDetector.h b/mythtv/programs/mythcommflag/ClassicLogoDetector.h
index d589df5..a78ce4c 100644
--- a/mythtv/programs/mythcommflag/ClassicLogoDetector.h
+++ b/mythtv/programs/mythcommflag/ClassicLogoDetector.h
@@ -2,8 +2,8 @@
 #define _CLASSICLOGOGEDETECTOR_H_
 
 #include "LogoDetectorBase.h"
+#include <qbitarray.h>
 
-typedef struct edgemaskentry EdgeMaskEntry;
 typedef struct VideoFrame_ VideoFrame;
 class ClassicCommDetector;
 
@@ -16,49 +16,38 @@ class ClassicLogoDetector : public LogoDetectorBase
     virtual void deleteLater(void);
 
     bool searchForLogo(MythPlayer* player);
-    bool doesThisFrameContainTheFoundLogo(unsigned char* frame);
+    bool doesThisFrameContainTheFoundLogo(unsigned char *framePtr);
     bool pixelInsideLogo(unsigned int x, unsigned int y);
 
     unsigned int getRequiredAvailableBufferForSearch();
 
+    void DumpLogo();
+    static bool isSobelEdgeAt(unsigned char *buf, unsigned int x, unsigned int y, unsigned int width, unsigned char edgeDiff);
+    
   protected:
     virtual ~ClassicLogoDetector() {}
 
   private:
-    void SetLogoMaskArea();
-    void SetLogoMask(unsigned char *mask);
-    void DumpLogo(bool fromCurrentFrame,unsigned char* framePtr);
-    void DetectEdges(VideoFrame *frame, EdgeMaskEntry *edges, int edgeDiff);
-
+    int AnalyzeEdgeCounts(int *edgeCounts, int threshold);
+    void DetectEdges(VideoFrame *frame, int *edgeCounts, int edgeDiff);
+    
     ClassicCommDetector* commDetector;
-    unsigned int frameNumber;
-    bool previousFrameWasSceneChange;
-    unsigned int xspacing, yspacing;
     unsigned int commDetectBorder;
-
+    
     int commDetectLogoSamplesNeeded;
     int commDetectLogoSampleSpacing;
     int commDetectLogoSecondsNeeded;
     double commDetectLogoGoodEdgeThreshold;
     double commDetectLogoBadEdgeThreshold;
+    
+    QBitArray edgeMask;
 
-    EdgeMaskEntry *edgeMask;
-
-    unsigned char *logoMaxValues;
-    unsigned char *logoMinValues;
-    unsigned char *logoFrame;
-    unsigned char *logoMask;
-    unsigned char *logoCheckMask;
-    unsigned char *tmpBuf;
-
+    bool logoInfoAvailable;    
     int logoEdgeDiff;
-    unsigned int logoFrameCount;
     unsigned int logoMinX;
-    unsigned int logoMaxX;
+    unsigned int logoWidth;
     unsigned int logoMinY;
-    unsigned int logoMaxY;
-
-    bool logoInfoAvailable;
+    unsigned int logoHeight;
 };
 
 #endif
diff --git a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp
index c449353..ff096a5 100644
--- a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp
+++ b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp
@@ -6,40 +6,65 @@ using namespace std;
 
 ClassicSceneChangeDetector::ClassicSceneChangeDetector(unsigned int width,
         unsigned int height, unsigned int commdetectborder_in,
-        unsigned int xspacing_in, unsigned int yspacing_in):
+        unsigned int fps_in):
     SceneChangeDetectorBase(width,height),
-    frameNumber(0),
-    previousFrameWasSceneChange(false),
-    xspacing(xspacing_in),
-    yspacing(yspacing_in),
-    commdetectborder(commdetectborder_in)
+    commdetectborder(commdetectborder_in),
+    fps(fps_in),
+    prevSceneEnd(0),
+    thisSceneStart(0)
 {
     histogram = new Histogram;
     previousHistogram = new Histogram;
+    previousSceneHistogram = new Histogram;
 }
 
 void ClassicSceneChangeDetector::deleteLater(void)
 {
     delete histogram;
     delete previousHistogram;
+    delete previousSceneHistogram;
     SceneChangeDetectorBase::deleteLater();
 }
 
-void ClassicSceneChangeDetector::processFrame(unsigned char* frame)
+void ClassicSceneChangeDetector::processFrame(unsigned int frameNumber, unsigned char* frame)
 {
     histogram->generateFromImage(frame, width, height, commdetectborder,
                                  width-commdetectborder, commdetectborder,
-                                 height-commdetectborder, xspacing, yspacing);
+                                 height-commdetectborder, 1, 1);
     float similar = histogram->calculateSimilarityWith(*previousHistogram);
 
-    bool isSceneChange = (similar < .85 && !previousFrameWasSceneChange);
-
-    emit(haveNewInformation(frameNumber,isSceneChange,similar));
-    previousFrameWasSceneChange = isSceneChange;
-
-    std::swap(histogram,previousHistogram);
-    frameNumber++;
+    bool isSceneChange = similar < .85;
+    if (isSceneChange)
+    {
+        // If the last scene was recent we can consider it
+        if (frameNumber - prevSceneEnd <= fps * 30)
+        {
+            float prevSim = histogram->calculateSimilarityWith(*previousSceneHistogram);
+            if (prevSim >= 0.85)
+            {
+                // If this scene looks the same as the previous scene then there was no change
+                isSceneChange = false;
+                
+                // Undo what we previously said was a scene change
+                emit(haveNewInformation(prevSceneEnd, false, 1.25));
+            }
+        }
+        
+        if (frameNumber - thisSceneStart <= fps / 8)
+        {
+            // Supress change flags on rapidly changing scenery
+            isSceneChange = false;
+        }
+        else
+        {
+            std::swap(previousSceneHistogram, previousHistogram);
+            prevSceneEnd = thisSceneStart;
+            thisSceneStart = frameNumber;
+        }
+    }
+    std::swap(previousHistogram,histogram);
+    
+    emit(haveNewInformation(frameNumber, isSceneChange, similar));
 }
 
 /* vim: set expandtab tabstop=4 shiftwidth=4: */
-
diff --git a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h
index f4d2200..43a9687 100644
--- a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h
+++ b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h
@@ -9,11 +9,10 @@ class ClassicSceneChangeDetector : public SceneChangeDetectorBase
 {
   public:
     ClassicSceneChangeDetector(unsigned int width, unsigned int height,
-        unsigned int commdetectborder, unsigned int xspacing,
-        unsigned int yspacing);
+        unsigned int commdetectborder, unsigned int fps);
     virtual void deleteLater(void);
 
-    void processFrame(unsigned char* frame);
+    void processFrame(unsigned int frameNumber, unsigned char* frame);
 
   private:
     ~ClassicSceneChangeDetector() {}
@@ -21,10 +20,10 @@ class ClassicSceneChangeDetector : public SceneChangeDetectorBase
   private:
     Histogram* histogram;
     Histogram* previousHistogram;
-    unsigned int frameNumber;
-    bool previousFrameWasSceneChange;
-    unsigned int xspacing, yspacing;
+    Histogram* previousSceneHistogram;
     unsigned int commdetectborder;
+    unsigned int fps;
+    unsigned int prevSceneEnd, thisSceneStart;
 };
 
 #endif
diff --git a/mythtv/programs/mythcommflag/Histogram.cpp b/mythtv/programs/mythcommflag/Histogram.cpp
index 12d2a9a..849f23b 100644
--- a/mythtv/programs/mythcommflag/Histogram.cpp
+++ b/mythtv/programs/mythcommflag/Histogram.cpp
@@ -70,18 +70,35 @@ unsigned int Histogram::getThresholdForPercentageOfPixels(float percentage)
 
 float Histogram::calculateSimilarityWith(const Histogram& other) const
 {
-    long similar = 0;
-
-    for(unsigned int i = 0; i < 256; i++)
+    const int proximity = 5;
+    long similarity = 0;
+
+    similarity += std::min(data[0],
+                           other.data[0]);
+    similarity += std::min(data[0] + data[1],
+                           other.data[0] + other.data[1]);
+    similarity += std::min(data[0] + data[1] + data[2],
+                           other.data[0] + other.data[1] + other.data[2]);
+    
+    for(unsigned int i = 0; i <= 256 - proximity; i++)
     {
-        if (data[i] < other.data[i])
-            similar += data[i];
-        else
-            similar += other.data[i];
+        unsigned int mine = 0, others = 0;
+        for (int j = 0; j < proximity; ++j)
+        {
+            mine += data[i+j];
+            others += other.data[i+j];
+        }
+        similarity += std::min(mine, others);
     }
-
-    //Using c style cast for old gcc compatibility.
-    return static_cast<float>(similar) / static_cast<float>(numberOfSamples);
+    
+    similarity += std::min(data[253] + data[254] + data[255],
+                           other.data[253] + other.data[254] + other.data[255]);
+    similarity += std::min(data[254] + data[255],
+                           other.data[254] + other.data[255]);
+    similarity += std::min(data[255],
+                           other.data[255]);
+    
+    return similarity / static_cast<float>(numberOfSamples * proximity);
 }
 
 /* vim: set expandtab tabstop=4 shiftwidth=4: */
diff --git a/mythtv/programs/mythcommflag/SceneChangeDetectorBase.h b/mythtv/programs/mythcommflag/SceneChangeDetectorBase.h
index 67296d5..338c80a 100644
--- a/mythtv/programs/mythcommflag/SceneChangeDetectorBase.h
+++ b/mythtv/programs/mythcommflag/SceneChangeDetectorBase.h
@@ -11,7 +11,7 @@ class SceneChangeDetectorBase : public QObject
     SceneChangeDetectorBase(unsigned int w, unsigned int h) :
         width(w), height(h) {}
 
-    virtual void processFrame(unsigned char *frame) = 0;
+    virtual void processFrame(unsigned int frameNumber, unsigned char *frame) = 0;
 
   signals:
     void haveNewInformation(unsigned int framenum, bool scenechange,
diff --git a/mythtv/programs/mythcommflag/main.cpp b/mythtv/programs/mythcommflag/main.cpp
index 5c03c1d..0bc7e13 100644
--- a/mythtv/programs/mythcommflag/main.cpp
+++ b/mythtv/programs/mythcommflag/main.cpp
@@ -735,8 +735,7 @@ static int FlagCommercials(ProgramInfo *program_info, int jobid,
     int breaksFound = 0;
 
     // configure commercial detection method
-    SkipTypes commDetectMethod =
-            (enum SkipTypes)gCoreContext->GetNumSetting(
+    SkipTypes commDetectMethod = (SkipTypes)gCoreContext->GetNumSetting(
                                     "CommercialSkipMethod", COMM_DETECT_ALL);
 
     if (cmdline.toBool("commmethod"))
@@ -750,7 +749,7 @@ static int FlagCommercials(ProgramInfo *program_info, int jobid,
         if (!ok)
         {
             // not an integer, attempt comma separated list
-            commDetectMethod = COMM_DETECT_UNINIT;
+            commDetectMethod = COMM_DETECT_OFF;
             QMap<QString, SkipTypes>::const_iterator sit;
 
             QStringList list = commmethod.split(",", QString::SkipEmptyParts);
@@ -774,14 +773,13 @@ static int FlagCommercials(ProgramInfo *program_info, int jobid,
 
                 // append flag method to list
                 commDetectMethod = (SkipTypes) ((int)commDetectMethod
-                                             || (int)skipTypes->value(val));
+                                                | (int)skipTypes->value(val));
             }
-
         }
         if (commDetectMethod == COMM_DETECT_UNINIT)
             return GENERIC_EXIT_INVALID_CMDLINE;
     }
-    else if (!cmdline.toBool("skipdb"))
+    else if (useDB)
     {
         // if not manually specified, and we have a database to access
         // pull the commflag type from the channel
@@ -819,11 +817,7 @@ static int FlagCommercials(ProgramInfo *program_info, int jobid,
                 QString("Using method: %1 from channel %2")
                     .arg(commDetectMethod).arg(program_info->GetChanID()));
         }
-
     }
-    else if (cmdline.toBool("skipdb"))
-        // default to a cheaper method for debugging purposes
-        commDetectMethod = COMM_DETECT_BLANK;
 
     // if selection has failed, or intentionally disabled, drop out
     if (commDetectMethod == COMM_DETECT_UNINIT)
@@ -1143,7 +1137,14 @@ int main(int argc, char *argv[])
     cmdline.ApplySettingsOverride();
 
     MythTranslation::load("mythfrontend");
-
+    
+    if (cmdline.toBool("outputmethod"))
+    {
+	QString om = cmdline.toString("outputmethod");
+	if (outputTypes->contains(om))
+	    outputMethod = outputTypes->value(om);
+    }
+    
     if (cmdline.toBool("chanid") && cmdline.toBool("starttime"))
     {
         // operate on a recording in the database
