MythTV  0.26-pre
FrameAnalyzer.cpp
Go to the documentation of this file.
00001 #include "mythlogging.h"
00002 #include "CommDetector2.h"
00003 #include "FrameAnalyzer.h"
00004 
00005 using namespace commDetector2;
00006 
00007 namespace frameAnalyzer {
00008 
00009 bool
00010 rrccinrect(int rr, int cc, int rrow, int rcol, int rwidth, int rheight)
00011 {
00012     return rr >= rrow && cc >= rcol &&
00013         rr < rrow + rheight && cc < rcol + rwidth;
00014 }
00015 
00016 void
00017 frameAnalyzerReportMap(const FrameAnalyzer::FrameMap *frameMap, float fps,
00018         const char *comment)
00019 {
00020     for (FrameAnalyzer::FrameMap::const_iterator ii = frameMap->begin();
00021             ii != frameMap->end();
00022             ++ii)
00023     {
00024         long long   bb, ee, len;
00025 
00026         /*
00027          * QMap'd as 0-based index, but display as 1-based index to match "Edit
00028          * Recording" OSD.
00029          */
00030         bb = ii.key() + 1;
00031         if (*ii)
00032         {
00033             ee = bb + *ii;
00034             len = ee - bb;
00035 
00036             LOG(VB_COMMFLAG, LOG_INFO, QString("%1: %2-%3 (%4-%5, %6)")
00037                     .arg(comment)
00038                     .arg(bb, 6).arg(ee - 1, 6)
00039                     .arg(frameToTimestamp(bb, fps))
00040                     .arg(frameToTimestamp(ee - 1, fps))
00041                     .arg(frameToTimestamp(len, fps)));
00042         }
00043         else
00044         {
00045             LOG(VB_COMMFLAG, LOG_INFO, QString("%1: %2 (%3)")
00046                     .arg(comment)
00047                     .arg(bb, 6)
00048                     .arg(frameToTimestamp(bb, fps)));
00049         }
00050     }
00051 }
00052 
00053 void
00054 frameAnalyzerReportMapms(const FrameAnalyzer::FrameMap *frameMap, float fps,
00055         const char *comment)
00056 {
00057     for (FrameAnalyzer::FrameMap::const_iterator ii = frameMap->begin();
00058             ii != frameMap->end();
00059             ++ii)
00060     {
00061         long long   bb, ee, len;
00062 
00063         /*
00064          * QMap'd as 0-based index, but display as 1-based index to match "Edit
00065          * Recording" OSD.
00066          */
00067         bb = ii.key() + 1;
00068         if (*ii)
00069         {
00070             ee = bb + *ii;
00071             len = ee - bb;
00072 
00073             LOG(VB_COMMFLAG, LOG_INFO, QString("%1: %2-%3 (%4-%5, %6)")
00074                     .arg(comment)
00075                     .arg(bb, 6).arg(ee - 1, 6)
00076                     .arg(frameToTimestamp(bb, fps))
00077                     .arg(frameToTimestamp(ee - 1, fps))
00078                     .arg(frameToTimestampms(len, fps)));
00079         }
00080         else
00081         {
00082             LOG(VB_COMMFLAG, LOG_INFO, QString("%1: %2 (%3)")
00083                     .arg(comment)
00084                     .arg(bb, 6)
00085                     .arg(frameToTimestamp(bb, fps)));
00086         }
00087     }
00088 }
00089 
00090 long long
00091 frameAnalyzerMapSum(const FrameAnalyzer::FrameMap *frameMap)
00092 {
00093     long long sum = 0;
00094     for (FrameAnalyzer::FrameMap::const_iterator ii = frameMap->begin();
00095             ii != frameMap->end();
00096             ++ii)
00097         sum += *ii;
00098     return sum;
00099 }
00100 
00101 bool
00102 removeShortBreaks(FrameAnalyzer::FrameMap *breakMap, float fps, int minbreaklen,
00103     bool verbose)
00104 {
00105     /*
00106      * Remove any breaks that are less than "minbreaklen" units long.
00107      *
00108      * Return whether or not any breaks were actually removed.
00109      */
00110     FrameAnalyzer::FrameMap::Iterator   bb;
00111     bool                                removed;
00112 
00113     removed = false;
00114 
00115     /* Don't remove the initial commercial break, no matter how short. */
00116     bb = breakMap->begin();
00117     if (bb != breakMap->end() && bb.key() == 0)
00118         ++bb;
00119     while (bb != breakMap->end())
00120     {
00121         if (*bb >= minbreaklen)
00122         {
00123             ++bb;
00124             continue;
00125         }
00126 
00127         /* Don't remove the final commercial break, no matter how short. */
00128         FrameAnalyzer::FrameMap::Iterator bb1 = bb;
00129         ++bb;
00130         if (bb == breakMap->end())
00131             continue;
00132 
00133         if (verbose)
00134         {
00135             long long start = bb1.key();
00136             long long end = start + *bb1 - 1;
00137             LOG(VB_COMMFLAG, LOG_INFO, QString("Removing break %1-%2 (%3-%4)")
00138                 .arg(frameToTimestamp(start, fps))
00139                 .arg(frameToTimestamp(end, fps))
00140                 .arg(start + 1).arg(end + 1));
00141         }
00142         breakMap->erase(bb1);
00143         removed = true;
00144     }
00145 
00146     return removed;
00147 }
00148 
00149 bool
00150 removeShortSegments(FrameAnalyzer::FrameMap *breakMap, long long nframes,
00151     float fps, int minseglen, bool verbose)
00152 {
00153     /*
00154      * Remove any segments that are less than "minseglen" units long.
00155      *
00156      * Return whether or not any segments were actually removed.
00157      */
00158     FrameAnalyzer::FrameMap::Iterator   bb, bbnext;
00159     bool                                removed;
00160 
00161     removed = false;
00162 
00163 
00164     for (bb = breakMap->begin(); bb != breakMap->end(); bb = bbnext)
00165     {
00166         /* Never remove initial segment (beginning at frame 0). */
00167         if (bb == breakMap->begin() && bb != breakMap->end() &&
00168                 bb.key() != 0 && bb.key() < minseglen)
00169             ++bb;
00170 
00171         bbnext = bb;
00172         ++bbnext;
00173         long long brkb = bb.key();
00174         long long segb = brkb + *bb;
00175         long long sege = bbnext == breakMap->end() ? nframes : bbnext.key();
00176         long long seglen = sege - segb;
00177         if (seglen >= minseglen)
00178             continue;
00179 
00180         /* Merge break with next break. */
00181         if (bbnext == breakMap->end())
00182         {
00183             if (segb != nframes)
00184             {
00185                 /* Extend break "bb" to end of recording. */
00186                 if (verbose)
00187                 {
00188                     long long old1 = brkb;
00189                     long long old2 = segb - 1;
00190                     long long new1 = brkb;
00191                     long long new2 = nframes - 1;
00192                     LOG(VB_COMMFLAG, LOG_INFO,
00193                         QString("Removing segment %1-%2 (%3-%4)")
00194                         .arg(frameToTimestamp(segb + 1, fps))
00195                         .arg(frameToTimestamp(sege + 1, fps))
00196                         .arg(segb + 1).arg(sege + 1));
00197                     LOG(VB_COMMFLAG, LOG_INFO,
00198                         QString("Replacing break %1-%2 (%3-%4)"
00199                         " with %5-%6 (%7-%8, EOF)")
00200                         .arg(frameToTimestamp(old1 + 1, fps))
00201                         .arg(frameToTimestamp(old2 + 1, fps))
00202                         .arg(old1 + 1).arg(old2 + 1)
00203                         .arg(frameToTimestamp(new1 + 1, fps))
00204                         .arg(frameToTimestamp(new2 + 1, fps))
00205                         .arg(new1 + 1).arg(new2 + 1));
00206                 }
00207                 breakMap->remove(brkb);
00208                 breakMap->insert(brkb, nframes - brkb);
00209                 removed = true;
00210             }
00211         }
00212         else
00213         {
00214             /* Extend break "bb" to cover "bbnext"; delete "bbnext". */
00215             if (verbose)
00216             {
00217                 long long old1 = brkb;
00218                 long long old2 = segb - 1;
00219                 long long new1 = brkb;
00220                 long long new2 = bbnext.key() + *bbnext - 1;
00221                 LOG(VB_COMMFLAG, LOG_INFO,
00222                     QString("Removing segment %1-%2 (%3-%4)")
00223                     .arg(frameToTimestamp(segb + 1, fps))
00224                     .arg(frameToTimestamp(sege + 1, fps))
00225                     .arg(segb + 1).arg(sege + 1));
00226                 LOG(VB_COMMFLAG, LOG_INFO,
00227                     QString("Replacing break %1-%2 (%3-%4)"
00228                             " with %5-%6 (%7-%8)")
00229                     .arg(frameToTimestamp(old1 + 1, fps))
00230                     .arg(frameToTimestamp(old2 + 1, fps))
00231                     .arg(old1 + 1).arg(old2 + 1)
00232                     .arg(frameToTimestamp(new1 + 1, fps))
00233                     .arg(frameToTimestamp(new2 + 1, fps))
00234                     .arg(new1 + 1).arg(new2 + 1));
00235             }
00236             breakMap->remove(brkb);
00237             breakMap->insert(brkb, bbnext.key() + *bbnext - brkb);
00238 
00239             bb = bbnext;
00240             ++bbnext;
00241             if (verbose)
00242             {
00243                 long long start = bb.key();
00244                 long long end = start + *bb - 1;
00245                 LOG(VB_COMMFLAG, LOG_INFO,
00246                     QString("Removing break %1-%2 (%3-%4)")
00247                     .arg(frameToTimestamp(start + 1, fps))
00248                     .arg(frameToTimestamp(end + 1, fps))
00249                     .arg(start + 1).arg(end + 1));
00250             }
00251             breakMap->erase(bb);
00252 
00253             removed = true;
00254         }
00255     }
00256 
00257     return removed;
00258 }
00259 
00260 FrameAnalyzer::FrameMap::const_iterator
00261 frameMapSearchForwards(const FrameAnalyzer::FrameMap *frameMap, long long mark,
00262     long long markend)
00263 {
00264     /*
00265      * Search forwards to find the earliest block "block" such that
00266      *
00267      *          mark <= blockbegin < markend
00268      *
00269      * Return frameMap->constEnd() if there is no such block.
00270      */
00271     FrameAnalyzer::FrameMap::const_iterator block = frameMap->constBegin();
00272 
00273     for (; block != frameMap->constEnd(); ++block)
00274     {
00275         const long long bb = block.key();
00276         const long long ee = bb + *block;
00277         if (mark < ee)
00278         {
00279             if (mark <= bb && bb < markend)
00280                 return block;
00281             break;
00282         }
00283     }
00284     return frameMap->constEnd();
00285 }
00286 
00287 FrameAnalyzer::FrameMap::const_iterator
00288 frameMapSearchBackwards(const FrameAnalyzer::FrameMap *frameMap,
00289     long long markbegin, long long mark)
00290 {
00291     /*
00292      * Search backards to find the latest block "block" such that
00293      *
00294      *          markbegin < blockend <= mark
00295      *
00296      * Return frameMap->constEnd() if there is no such block.
00297      */
00298     FrameAnalyzer::FrameMap::const_iterator block = frameMap->constEnd();
00299     for (--block; block != frameMap->constBegin(); --block)
00300     {
00301         const long long bb = block.key();
00302         const long long ee = bb + *block;
00303         if (bb < mark)
00304         {
00305             if (markbegin < ee && ee <= mark)
00306                 return block;
00307             break;
00308         }
00309     }
00310     return frameMap->constEnd();
00311 }
00312 
00313 };  /* namespace */
00314 
00315 /* vim: set expandtab tabstop=4 shiftwidth=4: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends