Ticket #12308: mcf-combined.patch

File mcf-combined.patch, 26.9 KB (added by faginbagin <mythtv@…>, 5 years ago)
  • mythtv/programs/mythcommflag/ClassicCommDetector.cpp

    diff --git a/mythtv/programs/mythcommflag/ClassicCommDetector.cpp b/mythtv/programs/mythcommflag/ClassicCommDetector.cpp
    index 8db7f3d..4d9ff23 100644
    a b using namespace std; 
    2424#include "ClassicCommDetector.h"
    2525#include "ClassicLogoDetector.h"
    2626#include "ClassicSceneChangeDetector.h"
     27#include "commercial_debug.h"
    2728
    2829enum frameAspects {
    2930    COMM_ASPECT_NORMAL = 0,
    3031    COMM_ASPECT_WIDE
    3132} FrameAspects;
    3233
     34// letter-box and pillar-box are not mutually exclusive
     35// So 3 is a valid value = (COMM_FORMAT_LETTERBOX | COMM_FORMAT_PILLARBOX)
     36// And 4 = COMM_FORMAT_MAX is the number of valid values.
    3337enum frameFormats {
    34     COMM_FORMAT_NORMAL = 0,
    35     COMM_FORMAT_LETTERBOX,
    36     COMM_FORMAT_PILLARBOX,
    37     COMM_FORMAT_MAX
     38    COMM_FORMAT_NORMAL    = 0,
     39    COMM_FORMAT_LETTERBOX = 1,
     40    COMM_FORMAT_PILLARBOX = 2,
     41    COMM_FORMAT_MAX       = 4,
    3842} FrameFormats;
    3943
    4044static QString toStringFrameMaskValues(int mask, bool verbose)
    static QString toStringFrameFormats(int format, bool verbose) 
    8791    switch (format)
    8892    {
    8993        case COMM_FORMAT_NORMAL:
    90             return (verbose) ? "normal" : "N";
     94            return (verbose) ? "normal" : " N ";
    9195        case COMM_FORMAT_LETTERBOX:
    92             return (verbose) ? "letter" : "L";
     96            return (verbose) ? "letter" : " L ";
    9397        case COMM_FORMAT_PILLARBOX:
    94             return (verbose) ? "pillar" : "P";
     98            return (verbose) ? "pillar" : " P ";
     99        case COMM_FORMAT_LETTERBOX | COMM_FORMAT_PILLARBOX:
     100            return (verbose) ? "letter,pillar" : "L,P";
    95101        case COMM_FORMAT_MAX:
    96             return (verbose) ? " max  " : "M";
     102            return (verbose) ? " max  " : " M ";
    97103    }
    98104
    99     return (verbose) ? " null " : "n";
     105    return (verbose) ? "unknown" : " U ";
    100106}
    101107
    102108QString FrameInfoEntry::GetHeader(void)
    ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in, 
    139145    totalMinBrightness(0),                     detectBlankFrames(false),
    140146    detectSceneChanges(false),                 detectStationLogo(false),
    141147    logoInfoAvailable(false),                  logoDetector(0),
    142     framePtr(0),                               frameIsBlank(false),
     148    frameIsBlank(false),
    143149    sceneHasChanged(false),                    stationLogoPresent(false),
    144150    lastFrameWasBlank(false),                  lastFrameWasSceneChange(false),
    145151    decoderFoundAspectChanges(false),          sceneChangeDetector(0),
    ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in, 
    152158    fps(0.0),                                  framesProcessed(0),
    153159    preRoll(0),                                postRoll(0)
    154160{
    155     commDetectBorder =
    156         gCoreContext->GetNumSetting("CommDetectBorder", 20);
    157161    commDetectBlankFrameMaxDiff =
    158162        gCoreContext->GetNumSetting("CommDetectBlankFrameMaxDiff", 25);
    159163    commDetectDarkBrightness =
    void ClassicCommDetector::Init() 
    189193    postRoll = (long long)(
    190194        max(int64_t(0), int64_t(stopsAt.secsTo(recordingStopsAt))) * fps);
    191195
     196    // CommDetectBorder's default value of 20 predates the change to use
     197    // ffmpeg's lowres decoding capability by 5 years.
     198    // I believe it should be adjusted based on the height of the lowres video
     199    // CommDetectBorder * height / 720 seems to produce reasonable results.
     200    // source height =  480 gives border = 20 *  480 / 4 / 720 = 2
     201    // source height =  720 gives border = 20 *  720 / 4 / 720 = 5
     202    // source height = 1080 gives border = 20 * 1080 / 4 / 720 = 7
     203    commDetectBorder =
     204        gCoreContext->GetNumSetting("CommDetectBorder", 20) * height / 720;
     205
    192206#ifdef SHOW_DEBUG_WIN
    193207    comm_debug_init(width, height);
    194208#endif
    void ClassicCommDetector::Init() 
    265279    frameIsBlank = false;
    266280    stationLogoPresent = false;
    267281
    268     framePtr = NULL;
    269 
    270282    logoInfoAvailable = false;
    271283
    272284    ClearAllMaps();
    bool ClassicCommDetector::go() 
    318330
    319331    if (commDetectMethod & COMM_DETECT_LOGO)
    320332    {
     333        // Use a different border for logo detection.
     334        // If we try to detect logos in letterboxed areas,
     335        // chances are we won't detect the logo.
     336        // Generally speaking, SD video is likely to be letter boxed
     337        // and HD video is not likely to be letter boxed.
     338        // To detect logos, try to exclude letterboxed area from SD video
     339        // but exclude too much from HD video and you'll miss the logo.
     340        // Using the same border for both with no scaling seems to be
     341        // a good compromise.
     342        int logoDetectBorder =
     343            gCoreContext->GetNumSetting("CommDetectLogoBorder", 16);
    321344        logoDetector = new ClassicLogoDetector(this, width, height,
    322             commDetectBorder, horizSpacing, vertSpacing);
     345            logoDetectBorder, horizSpacing, vertSpacing);
    323346
    324347        requiredHeadStart += max(
    325348            int64_t(0), int64_t(recordingStartedAt.secsTo(startedAt)));
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    780803    }
    781804
    782805    curFrameNumber = frame_number;
    783     framePtr = frame->buf;
     806    unsigned char* framePtr = frame->buf;
     807    int bytesPerLine = frame->pitches[0];
    784808
    785809    fInfo.minBrightness = -1;
    786810    fInfo.maxBrightness = -1;
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    817841
    818842    if (commDetectMethod & COMM_DETECT_SCENE)
    819843    {
    820         sceneChangeDetector->processFrame(framePtr);
     844        sceneChangeDetector->processFrame(frame);
    821845    }
    822846
    823847    stationLogoPresent = false;
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    828852        for(int x = commDetectBorder; x < (width - commDetectBorder);
    829853                x += horizSpacing)
    830854        {
    831             pixel = framePtr[y * width + x];
     855            pixel = framePtr[y * bytesPerLine + x];
    832856
    833857            if (commDetectMethod & COMM_DETECT_BLANKS)
    834858            {
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    898922        delete[] colMax;
    899923        colMax = 0;
    900924
     925        frameInfo[curFrameNumber].format = COMM_FORMAT_NORMAL;
    901926        if ((topDarkRow > commDetectBorder) &&
    902927            (topDarkRow < (height * .20)) &&
    903928            (bottomDarkRow < (height - commDetectBorder)) &&
    904929            (bottomDarkRow > (height * .80)))
    905930        {
    906             frameInfo[curFrameNumber].format = COMM_FORMAT_LETTERBOX;
     931            frameInfo[curFrameNumber].format |= COMM_FORMAT_LETTERBOX;
    907932        }
    908         else if ((leftDarkCol > commDetectBorder) &&
     933        if ((leftDarkCol > commDetectBorder) &&
    909934                 (leftDarkCol < (width * .20)) &&
    910935                 (rightDarkCol < (width - commDetectBorder)) &&
    911936                 (rightDarkCol > (width * .80)))
    912937        {
    913             frameInfo[curFrameNumber].format = COMM_FORMAT_PILLARBOX;
    914         }
    915         else
    916         {
    917             frameInfo[curFrameNumber].format = COMM_FORMAT_NORMAL;
     938            frameInfo[curFrameNumber].format |= COMM_FORMAT_PILLARBOX;
    918939        }
    919940
    920941        avg = totBrightness / blankPixelsChecked;
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    947968    if ((logoInfoAvailable) && (commDetectMethod & COMM_DETECT_LOGO))
    948969    {
    949970        stationLogoPresent =
    950             logoDetector->doesThisFrameContainTheFoundLogo(framePtr);
     971            logoDetector->doesThisFrameContainTheFoundLogo(frame);
    951972    }
    952973
    953974#if 0
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    9891010                frameInfo[curFrameNumber].flagMask ));
    9901011
    9911012#ifdef SHOW_DEBUG_WIN
    992     comm_debug_show(frame->buf);
     1013    comm_debug_show(frame);
    9931014    getchar();
    9941015#endif
    9951016
    void ClassicCommDetector::BuildAllMethodsCommList(void) 
    13651386            }
    13661387
    13671388            if ((fbp->length > 4) &&
    1368                 (fbp->logoCount > (fbp->frames * 0.60)) &&
     1389                (!logoInfoAvailable || fbp->logoCount > (fbp->frames * 0.60)) &&
    13691390                (fbp->bfCount < (fbp->frames * 0.10)))
    13701391            {
    13711392                if (verboseDebugging)
  • mythtv/programs/mythcommflag/ClassicCommDetector.h

    diff --git a/mythtv/programs/mythcommflag/ClassicCommDetector.h b/mythtv/programs/mythcommflag/ClassicCommDetector.h
    index f9e5c4c..6c25f5d 100644
    a b class ClassicCommDetector : public CommDetectorBase 
    153153        bool logoInfoAvailable;
    154154        LogoDetectorBase* logoDetector;
    155155
    156         unsigned char *framePtr;
    157 
    158156        frm_dir_map_t blankFrameMap;
    159157        frm_dir_map_t blankCommMap;
    160158        frm_dir_map_t blankCommBreakMap;
  • mythtv/programs/mythcommflag/ClassicLogoDetector.cpp

    diff --git a/mythtv/programs/mythcommflag/ClassicLogoDetector.cpp b/mythtv/programs/mythcommflag/ClassicLogoDetector.cpp
    index 5a1b832..287f610 100644
    a b  
    77// MythTV headers
    88#include "mythcorecontext.h"
    99#include "mythplayer.h"
     10#include "frame.h"
    1011
    1112// Commercial Flagging headers
    1213#include "ClassicLogoDetector.h"
    1314#include "ClassicCommDetector.h"
     15#include "commercial_debug.h"
    1416
    1517typedef struct edgemaskentry
    1618{
    bool ClassicLogoDetector::searchForLogo(MythPlayer* player) 
    99101
    100102    edgeCounts = new EdgeMaskEntry[width * height];
    101103
     104    // Back in 2005, a threshold of 50 minimum pixelsInMask was established.
     105    // I don't know whether that was tested against SD or HD resolutions.
     106    // I do know that in 2010, mythcommflag was changed to use ffmpeg's
     107    // lowres support, effectively dividing the video area by 16.
     108    // But the 50 pixel minimum was not adjusted accordingly.
     109    // I believe the minimum threshold should vary with the video's area.
     110    // I am using 1280x720 (for 720p) video as the baseline.
     111    // This should improve logo detection for SD video.
     112    int minPixelsInMask = 50 * (width*height) / (1280*720 / 16);
     113
    102114    for (i = 0; edgeDiffs[i] != 0 && !logoInfoAvailable; i++)
    103115    {
    104116        int pixelsInMask = 0;
    105117
    106         LOG(VB_COMMFLAG, LOG_INFO, QString("Trying with edgeDiff == %1")
    107                 .arg(edgeDiffs[i]));
     118        LOG(VB_COMMFLAG, LOG_INFO, QString("Trying with edgeDiff == %1, minPixelsInMask=%2")
     119                .arg(edgeDiffs[i]).arg(minPixelsInMask));
    108120
    109121        memset(edgeCounts, 0, sizeof(EdgeMaskEntry) * width * height);
    110122        memset(edgeMask, 0, sizeof(EdgeMaskEntry) * width * height);
    bool ClassicLogoDetector::searchForLogo(MythPlayer* player) 
    236248#endif
    237249        if (((logoMaxX - logoMinX) < (width / 4)) &&
    238250            ((logoMaxY - logoMinY) < (height / 4)) &&
    239             (pixelsInMask > 50))
     251            (pixelsInMask > minPixelsInMask))
    240252        {
    241253            logoInfoAvailable = true;
    242254            logoEdgeDiff = edgeDiffs[i];
    243255
    244256            LOG(VB_COMMFLAG, LOG_INFO,
    245257                QString("Using Logo area: topleft (%1,%2), "
    246                         "bottomright (%3,%4)")
     258                        "bottomright (%3,%4), pixelsInMask (%5).")
    247259                    .arg(logoMinX).arg(logoMinY)
    248                     .arg(logoMaxX).arg(logoMaxY));
     260                    .arg(logoMaxX).arg(logoMaxY)
     261                    .arg(pixelsInMask));
    249262        }
    250263        else
    251264        {
    bool ClassicLogoDetector::searchForLogo(MythPlayer* player) 
    262275    delete [] edgeCounts;
    263276
    264277    if (!logoInfoAvailable)
    265         LOG(VB_COMMFLAG, LOG_NOTICE, "No suitable logo area found.");
     278        LOG(VB_GENERAL, LOG_NOTICE, "No suitable logo area found.");
    266279
    267280    player->DiscardVideoFrame(player->GetRawVideoFrame(0));
    268281    return logoInfoAvailable;
    void ClassicLogoDetector::SetLogoMask(unsigned char *mask) 
    380393    }
    381394
    382395#ifdef SHOW_DEBUG_WIN
    383     DumpLogo(true,framePtr);
     396    DumpLogo(false, NULL);
    384397#endif
    385398
    386399    logoFrameCount = 0;
    387400    logoInfoAvailable = true;
     401
    388402}
    389403
    390404
    void ClassicLogoDetector::DumpLogo(bool fromCurrentFrame, 
    441455 * which are partially mods based on Myth's original commercial skip
    442456 * code written by Chris Pinkham. */
    443457bool ClassicLogoDetector::doesThisFrameContainTheFoundLogo(
    444     unsigned char* framePtr)
     458    VideoFrame* frame)
    445459{
    446460    int radius = 2;
    447461    unsigned int x, y;
    448462    int pos1, pos2, pos3;
     463    int edgePos;
    449464    int pixel;
    450465    int goodEdges = 0;
    451466    int badEdges = 0;
    452467    int testEdges = 0;
    453468    int testNotEdges = 0;
    454469
     470    unsigned char* framePtr = frame->buf;
     471    int bytesPerLine = frame->pitches[0];
     472
    455473    for (y = logoMinY; y <= logoMaxY; y++ )
    456474    {
    457475        for (x = logoMinX; x <= logoMaxX; x++ )
    458476        {
    459             pos1 = y * width + x;
    460             pos2 = (y - radius) * width + x;
    461             pos3 = (y + radius) * width + x;
     477            pos1 = y * bytesPerLine + x;
     478            edgePos = y * width + x;
     479            pos2 = (y - radius) * bytesPerLine + x;
     480            pos3 = (y + radius) * bytesPerLine + x;
    462481
    463482            pixel = framePtr[pos1];
    464483
    465             if (edgeMask[pos1].horiz)
     484            if (edgeMask[edgePos].horiz)
    466485            {
    467486                if ((abs(framePtr[pos1 - radius] - pixel) >= logoEdgeDiff) ||
    468487                    (abs(framePtr[pos1 + radius] - pixel) >= logoEdgeDiff))
    bool ClassicLogoDetector::doesThisFrameContainTheFoundLogo( 
    477496                testNotEdges++;
    478497            }
    479498
    480             if (edgeMask[pos1].vert)
     499            if (edgeMask[edgePos].vert)
    481500            {
    482501                if ((abs(framePtr[pos2] - pixel) >= logoEdgeDiff) ||
    483502                    (abs(framePtr[pos3] - pixel) >= logoEdgeDiff))
    void ClassicLogoDetector::DetectEdges(VideoFrame *frame, EdgeMaskEntry *edges, 
    520539{
    521540    int r = 2;
    522541    unsigned char *buf = frame->buf;
     542    int bytesPerLine = frame->pitches[0];
    523543    unsigned char p;
    524544    unsigned int pos, x, y;
    525545
    void ClassicLogoDetector::DetectEdges(VideoFrame *frame, EdgeMaskEntry *edges, 
    536556                continue;
    537557
    538558            pos = y * width + x;
    539             p = buf[pos];
     559            p = buf[y * bytesPerLine + x];
    540560
    541             if (( abs(buf[y * width + (x - r)] - p) >= edgeDiff) ||
    542                 ( abs(buf[y * width + (x + r)] - p) >= edgeDiff))
     561            if (( abs(buf[y * bytesPerLine + (x - r)] - p) >= edgeDiff) ||
     562                ( abs(buf[y * bytesPerLine + (x + r)] - p) >= edgeDiff))
    543563            {
    544564                edges[pos].horiz++;
    545565                edgeCount++;
    546566            }
    547             if (( abs(buf[(y - r) * width + x] - p) >= edgeDiff) ||
    548                 ( abs(buf[(y + r) * width + x] - p) >= edgeDiff))
     567            if (( abs(buf[(y - r) * bytesPerLine + x] - p) >= edgeDiff) ||
     568                ( abs(buf[(y + r) * bytesPerLine + x] - p) >= edgeDiff))
    549569            {
    550570                edges[pos].vert++;
    551571                edgeCount++;
    552572            }
    553573
    554             if (( abs(buf[(y - r) * width + (x - r)] - p) >= edgeDiff) ||
    555                 ( abs(buf[(y + r) * width + (x + r)] - p) >= edgeDiff))
     574            if (( abs(buf[(y - r) * bytesPerLine + (x - r)] - p) >= edgeDiff) ||
     575                ( abs(buf[(y + r) * bytesPerLine + (x + r)] - p) >= edgeDiff))
    556576            {
    557577                edges[pos].ldiag++;
    558578                edgeCount++;
    559579            }
    560580
    561             if (( abs(buf[(y - r) * width + (x + r)] - p) >= edgeDiff) ||
    562                 ( abs(buf[(y + r) * width + (x - r)] - p) >= edgeDiff))
     581            if (( abs(buf[(y - r) * bytesPerLine + (x + r)] - p) >= edgeDiff) ||
     582                ( abs(buf[(y + r) * bytesPerLine + (x - r)] - p) >= edgeDiff))
    563583            {
    564584                edges[pos].rdiag++;
    565585                edgeCount++;
  • mythtv/programs/mythcommflag/ClassicLogoDetector.h

    diff --git a/mythtv/programs/mythcommflag/ClassicLogoDetector.h b/mythtv/programs/mythcommflag/ClassicLogoDetector.h
    index d589df5..b930c98 100644
    a b class ClassicLogoDetector : public LogoDetectorBase 
    1616    virtual void deleteLater(void);
    1717
    1818    bool searchForLogo(MythPlayer* player);
    19     bool doesThisFrameContainTheFoundLogo(unsigned char* frame);
     19    bool doesThisFrameContainTheFoundLogo(VideoFrame* frame);
    2020    bool pixelInsideLogo(unsigned int x, unsigned int y);
    2121
    2222    unsigned int getRequiredAvailableBufferForSearch();
  • mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp

    diff --git a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp
    index c449353..ca96f93 100644
    a b void ClassicSceneChangeDetector::deleteLater(void) 
    2525    SceneChangeDetectorBase::deleteLater();
    2626}
    2727
    28 void ClassicSceneChangeDetector::processFrame(unsigned char* frame)
     28void ClassicSceneChangeDetector::processFrame(VideoFrame* frame)
    2929{
    3030    histogram->generateFromImage(frame, width, height, commdetectborder,
    3131                                 width-commdetectborder, commdetectborder,
  • mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h

    diff --git a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h
    index f4d2200..a8fd53b 100644
    a b class ClassicSceneChangeDetector : public SceneChangeDetectorBase 
    1313        unsigned int yspacing);
    1414    virtual void deleteLater(void);
    1515
    16     void processFrame(unsigned char* frame);
     16    void processFrame(VideoFrame* frame);
    1717
    1818  private:
    1919    ~ClassicSceneChangeDetector() {}
  • mythtv/programs/mythcommflag/Histogram.cpp

    diff --git a/mythtv/programs/mythcommflag/Histogram.cpp b/mythtv/programs/mythcommflag/Histogram.cpp
    index 12d2a9a..90c040d 100644
    a b  
    33#include <cmath>
    44#include <cstring>
    55
     6#include "frame.h"
     7
    68Histogram::Histogram()
    79{
    810    memset(data,0,sizeof(data));
    Histogram::~Histogram() 
    1517{
    1618}
    1719
    18 void Histogram::generateFromImage(unsigned char* frame, unsigned int frameWidth,
     20void Histogram::generateFromImage(VideoFrame* frame, unsigned int frameWidth,
    1921         unsigned int frameHeight, unsigned int minScanX, unsigned int maxScanX,
    2022         unsigned int minScanY, unsigned int maxScanY, unsigned int XSpacing,
    2123         unsigned int YSpacing)
    void Histogram::generateFromImage(unsigned char* frame, unsigned int frameWidth, 
    2931    if (maxScanY > frameHeight-1)
    3032        maxScanY = frameHeight-1;
    3133
     34    unsigned char* framePtr = frame->buf;
     35    int bytesPerLine = frame->pitches[0];
    3236    for(unsigned int y = minScanY; y < maxScanY; y += YSpacing)
    3337        for(unsigned int x = minScanX; x < maxScanX; x += XSpacing)
    3438        {
    35             data[frame[y * frameWidth + x]]++;
     39            data[framePtr[y * bytesPerLine + x]]++;
    3640            numberOfSamples++;
    3741        }
    3842}
  • mythtv/programs/mythcommflag/Histogram.h

    diff --git a/mythtv/programs/mythcommflag/Histogram.h b/mythtv/programs/mythcommflag/Histogram.h
    index fbed991..06cd807 100644
    a b  
    11#ifndef _HISTOGRAM_H_
    22#define _HISTOGRAM_H_
    33
     4typedef struct VideoFrame_ VideoFrame;
     5
    46class Histogram
    57{
    68public:
    79    Histogram();
    810    ~Histogram();
    911
    10     void generateFromImage(unsigned char* frame, unsigned int frameWidth,
     12    void generateFromImage(VideoFrame* frame, unsigned int frameWidth,
    1113             unsigned int frameHeight, unsigned int minScanX,
    1214             unsigned int maxScanX, unsigned int minScanY,
    1315             unsigned int maxScanY, unsigned int XSpacing,
  • mythtv/programs/mythcommflag/LogoDetectorBase.h

    diff --git a/mythtv/programs/mythcommflag/LogoDetectorBase.h b/mythtv/programs/mythcommflag/LogoDetectorBase.h
    index ea3f62f..b28cbcc 100644
    a b  
    44#include <QObject>
    55
    66class MythPlayer;
     7typedef struct VideoFrame_ VideoFrame;
    78
    89class LogoDetectorBase : public QObject
    910{
    class LogoDetectorBase : public QObject 
    1415        foundLogo(false), width(w),height(h) {};
    1516
    1617    virtual bool searchForLogo(MythPlayer* player) = 0;
    17     virtual bool doesThisFrameContainTheFoundLogo(unsigned char* frame) = 0;
     18    virtual bool doesThisFrameContainTheFoundLogo(VideoFrame* frame) = 0;
    1819    virtual bool pixelInsideLogo(unsigned int x, unsigned int y) = 0;
    1920    virtual unsigned int getRequiredAvailableBufferForSearch() = 0;
    2021
  • mythtv/programs/mythcommflag/SceneChangeDetectorBase.h

    diff --git a/mythtv/programs/mythcommflag/SceneChangeDetectorBase.h b/mythtv/programs/mythcommflag/SceneChangeDetectorBase.h
    index 67296d5..9a1b311 100644
    a b  
    33
    44#include <QObject>
    55
     6typedef struct VideoFrame_ VideoFrame;
     7
    68class SceneChangeDetectorBase : public QObject
    79{
    810    Q_OBJECT
    class SceneChangeDetectorBase : public QObject 
    1113    SceneChangeDetectorBase(unsigned int w, unsigned int h) :
    1214        width(w), height(h) {}
    1315
    14     virtual void processFrame(unsigned char *frame) = 0;
     16    virtual void processFrame(VideoFrame* frame) = 0;
    1517
    1618  signals:
    1719    void haveNewInformation(unsigned int framenum, bool scenechange,
  • new file mythtv/programs/mythcommflag/commercial_debug.cpp

    diff --git a/mythtv/programs/mythcommflag/commercial_debug.cpp b/mythtv/programs/mythcommflag/commercial_debug.cpp
    new file mode 100644
    index 0000000..2021d5c
    - +  
     1//*****************************************************************************
     2// This code is meant for use in debugging the CommDetect class and shouldn't
     3// be used in normal compiled Myth versions.
     4
     5#include "commercial_debug.h"
     6
     7#ifdef SHOW_DEBUG_WIN
     8
     9#include <X11/Xlib.h>
     10//#include <X11/extensions/Xvlib.h>
     11
     12extern "C" {
     13#include "libavcodec/avcodec.h"
     14#include "libswscale/swscale.h"
     15}
     16
     17// INPUT_PIX_FMT is used when we convert an input YUV420 frame to a RGB ZPixmap
     18// Since the commercial detection algorithms only look at the Y luma channel,
     19// it can be useful to display only that channel.
     20// But there may be times when you want to see the color images.
     21// If you want to display color images, use AV_PIX_FMT_YUV420P
     22// If you want display grayscale images, use AV_PIX_FMT_GRAY8
     23// #define INPUT_PIX_FMT   AV_PIX_FMT_YUV420P
     24#define INPUT_PIX_FMT   AV_PIX_FMT_GRAY8
     25
     26Window comm_win;
     27GC comm_gc;
     28Display *comm_display;
     29int comm_width = 0;
     30int comm_width8 = 0;
     31int comm_height = 0;
     32int comm_depth = 24;
     33XImage *comm_image = NULL;
     34char *comm_buf = NULL;
     35struct SwsContext *scontext;
     36
     37void comm_debug_init( int width, int height )
     38{
     39    comm_display = XOpenDisplay(NULL);
     40
     41    Screen* comm_screen = DefaultScreenOfDisplay(comm_display);
     42    int comm_screen_num = DefaultScreen(comm_display);
     43
     44    comm_depth = DefaultDepthOfScreen(comm_screen);
     45
     46    comm_width = width;
     47    // FFmpeg likes linesizes that are multiples of 8.
     48    comm_width8 = (width + 7) & ~7;
     49    comm_height = height;
     50
     51    comm_win = XCreateSimpleWindow(comm_display,
     52                                   DefaultRootWindow(comm_display),
     53                                   100, 100, comm_width, comm_height, 0,
     54                                   XWhitePixel(comm_display, comm_screen_num),
     55                                   XBlackPixel(comm_display, comm_screen_num) );
     56
     57    XMapRaised(comm_display, comm_win);
     58
     59    XSync(comm_display, 0);
     60
     61    comm_gc = XCreateGC(comm_display, comm_win, 0, 0);
     62
     63    comm_buf = new char[4 * comm_width8 * comm_height];
     64    memset(comm_buf, 0, 4 * comm_width8 * comm_height);
     65
     66    comm_image = XCreateImage(comm_display, DefaultVisual(comm_display, 0),
     67                              comm_depth, ZPixmap, 0, comm_buf,
     68                              comm_width8, comm_height, 8, 0);
     69
     70    XSync(comm_display, 0);
     71
     72    printf( "Commercial Detection debug window created at %dx%dx%d\n",
     73        comm_width, comm_height, comm_depth );
     74}
     75
     76static void comm_debug_show( AVPicture* pic);
     77
     78void comm_debug_show( unsigned char *frame )
     79{
     80    AVPicture image_in;
     81
     82    avpicture_fill(&image_in, (uint8_t *)frame, AV_PIX_FMT_YUV420P,
     83                   comm_width, comm_height);
     84
     85    comm_debug_show(&image_in);
     86}
     87
     88void comm_debug_show( VideoFrame *frame )
     89{
     90    AVPicture image_in;
     91
     92    for (int i = 0; i < 3; i++)
     93    {
     94        image_in.data[i] = frame->buf + frame->offsets[i];
     95        image_in.linesize[i] = frame->pitches[i];
     96    }
     97
     98    comm_debug_show(&image_in);
     99}
     100
     101void comm_debug_show(AVPicture* pic)
     102{
     103    AVPicture image_out;
     104    AVPixelFormat av_format;
     105
     106    switch (comm_depth)
     107    {
     108        case 16: av_format = AV_PIX_FMT_RGB565; break;
     109        case 24: av_format = AV_PIX_FMT_RGB32;  break;
     110        case 32: av_format = AV_PIX_FMT_RGB32; break;
     111        default:
     112            printf("Unable to display debug video window in %d depth.\n",
     113                   comm_depth);
     114            exit(1);
     115    }
     116
     117    avpicture_fill(&image_out, (uint8_t *)comm_image->data, av_format,
     118                   comm_width8, comm_height);
     119
     120    scontext = sws_getCachedContext(scontext, comm_width, comm_height,
     121        INPUT_PIX_FMT, comm_width, comm_height, av_format,
     122        SWS_FAST_BILINEAR, NULL, NULL, NULL);
     123    if (!scontext)
     124    {
     125        printf("Cannot initialize the image conversion context");
     126        exit(1);
     127    }
     128
     129    sws_scale(scontext, pic->data, pic->linesize, 0, comm_height,
     130              image_out.data, image_out.linesize);
     131
     132    XPutImage(comm_display, comm_win, comm_gc, comm_image,
     133                0, 0, 0, 0, comm_width, comm_height );
     134
     135    XSync(comm_display, 0);
     136}
     137
     138void comm_debug_destroy()
     139{
     140    XFree(comm_image);
     141    delete comm_buf;
     142    XDestroyWindow(comm_display, comm_win);
     143    XCloseDisplay(comm_display);
     144}
     145
     146#endif
  • new file mythtv/programs/mythcommflag/commercial_debug.h

    diff --git a/mythtv/programs/mythcommflag/commercial_debug.h b/mythtv/programs/mythcommflag/commercial_debug.h
    new file mode 100644
    index 0000000..2c93dc0
    - +  
     1//*****************************************************************************
     2// This code is meant for use in debugging the CommDetect class and shouldn't
     3// be used in normal compiled Myth versions.
     4
     5// #define SHOW_DEBUG_WIN
     6
     7#ifdef SHOW_DEBUG_WIN
     8
     9#include "frame.h"
     10
     11extern void comm_debug_init( int width, int height );
     12extern void comm_debug_show( unsigned char *frame );
     13extern void comm_debug_show( VideoFrame *frame );
     14extern void comm_debug_destroy();
     15
     16#endif
     17
  • mythtv/programs/mythcommflag/mythcommflag.pro

    diff --git a/mythtv/programs/mythcommflag/mythcommflag.pro b/mythtv/programs/mythcommflag/mythcommflag.pro
    index 997966e..22f5bea 100644
    a b HEADERS += PrePostRollFlagger.h 
    3434HEADERS += LogoDetectorBase.h SceneChangeDetectorBase.h
    3535HEADERS += SlotRelayer.h CustomEventRelayer.h
    3636HEADERS += commandlineparser.h
     37HEADERS += commercial_debug.h
    3738
    3839SOURCES += CommDetectorFactory.cpp CommDetectorBase.cpp
    3940SOURCES += ClassicLogoDetector.cpp
    SOURCES += HistogramAnalyzer.cpp 
    5152SOURCES += BlankFrameDetector.cpp
    5253SOURCES += SceneChangeDetector.cpp
    5354SOURCES += PrePostRollFlagger.cpp
     55SOURCES += commercial_debug.cpp
    5456
    5557SOURCES += main.cpp commandlineparser.cpp
    5658