Ticket #12308: mcf-combined.patch
File mcf-combined.patch, 26.9 KB (added by , 9 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; 24 24 #include "ClassicCommDetector.h" 25 25 #include "ClassicLogoDetector.h" 26 26 #include "ClassicSceneChangeDetector.h" 27 #include "commercial_debug.h" 27 28 28 29 enum frameAspects { 29 30 COMM_ASPECT_NORMAL = 0, 30 31 COMM_ASPECT_WIDE 31 32 } FrameAspects; 32 33 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. 33 37 enum 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, 38 42 } FrameFormats; 39 43 40 44 static QString toStringFrameMaskValues(int mask, bool verbose) … … static QString toStringFrameFormats(int format, bool verbose) 87 91 switch (format) 88 92 { 89 93 case COMM_FORMAT_NORMAL: 90 return (verbose) ? "normal" : " N";94 return (verbose) ? "normal" : " N "; 91 95 case COMM_FORMAT_LETTERBOX: 92 return (verbose) ? "letter" : " L";96 return (verbose) ? "letter" : " L "; 93 97 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"; 95 101 case COMM_FORMAT_MAX: 96 return (verbose) ? " max " : " M";102 return (verbose) ? " max " : " M "; 97 103 } 98 104 99 return (verbose) ? " null " : "n";105 return (verbose) ? "unknown" : " U "; 100 106 } 101 107 102 108 QString FrameInfoEntry::GetHeader(void) … … ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in, 139 145 totalMinBrightness(0), detectBlankFrames(false), 140 146 detectSceneChanges(false), detectStationLogo(false), 141 147 logoInfoAvailable(false), logoDetector(0), 142 frame Ptr(0), frameIsBlank(false),148 frameIsBlank(false), 143 149 sceneHasChanged(false), stationLogoPresent(false), 144 150 lastFrameWasBlank(false), lastFrameWasSceneChange(false), 145 151 decoderFoundAspectChanges(false), sceneChangeDetector(0), … … ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in, 152 158 fps(0.0), framesProcessed(0), 153 159 preRoll(0), postRoll(0) 154 160 { 155 commDetectBorder =156 gCoreContext->GetNumSetting("CommDetectBorder", 20);157 161 commDetectBlankFrameMaxDiff = 158 162 gCoreContext->GetNumSetting("CommDetectBlankFrameMaxDiff", 25); 159 163 commDetectDarkBrightness = … … void ClassicCommDetector::Init() 189 193 postRoll = (long long)( 190 194 max(int64_t(0), int64_t(stopsAt.secsTo(recordingStopsAt))) * fps); 191 195 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 192 206 #ifdef SHOW_DEBUG_WIN 193 207 comm_debug_init(width, height); 194 208 #endif … … void ClassicCommDetector::Init() 265 279 frameIsBlank = false; 266 280 stationLogoPresent = false; 267 281 268 framePtr = NULL;269 270 282 logoInfoAvailable = false; 271 283 272 284 ClearAllMaps(); … … bool ClassicCommDetector::go() 318 330 319 331 if (commDetectMethod & COMM_DETECT_LOGO) 320 332 { 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); 321 344 logoDetector = new ClassicLogoDetector(this, width, height, 322 commDetectBorder, horizSpacing, vertSpacing);345 logoDetectBorder, horizSpacing, vertSpacing); 323 346 324 347 requiredHeadStart += max( 325 348 int64_t(0), int64_t(recordingStartedAt.secsTo(startedAt))); … … void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 780 803 } 781 804 782 805 curFrameNumber = frame_number; 783 framePtr = frame->buf; 806 unsigned char* framePtr = frame->buf; 807 int bytesPerLine = frame->pitches[0]; 784 808 785 809 fInfo.minBrightness = -1; 786 810 fInfo.maxBrightness = -1; … … void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 817 841 818 842 if (commDetectMethod & COMM_DETECT_SCENE) 819 843 { 820 sceneChangeDetector->processFrame(frame Ptr);844 sceneChangeDetector->processFrame(frame); 821 845 } 822 846 823 847 stationLogoPresent = false; … … void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 828 852 for(int x = commDetectBorder; x < (width - commDetectBorder); 829 853 x += horizSpacing) 830 854 { 831 pixel = framePtr[y * width+ x];855 pixel = framePtr[y * bytesPerLine + x]; 832 856 833 857 if (commDetectMethod & COMM_DETECT_BLANKS) 834 858 { … … void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 898 922 delete[] colMax; 899 923 colMax = 0; 900 924 925 frameInfo[curFrameNumber].format = COMM_FORMAT_NORMAL; 901 926 if ((topDarkRow > commDetectBorder) && 902 927 (topDarkRow < (height * .20)) && 903 928 (bottomDarkRow < (height - commDetectBorder)) && 904 929 (bottomDarkRow > (height * .80))) 905 930 { 906 frameInfo[curFrameNumber].format = COMM_FORMAT_LETTERBOX;931 frameInfo[curFrameNumber].format |= COMM_FORMAT_LETTERBOX; 907 932 } 908 elseif ((leftDarkCol > commDetectBorder) &&933 if ((leftDarkCol > commDetectBorder) && 909 934 (leftDarkCol < (width * .20)) && 910 935 (rightDarkCol < (width - commDetectBorder)) && 911 936 (rightDarkCol > (width * .80))) 912 937 { 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; 918 939 } 919 940 920 941 avg = totBrightness / blankPixelsChecked; … … void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 947 968 if ((logoInfoAvailable) && (commDetectMethod & COMM_DETECT_LOGO)) 948 969 { 949 970 stationLogoPresent = 950 logoDetector->doesThisFrameContainTheFoundLogo(frame Ptr);971 logoDetector->doesThisFrameContainTheFoundLogo(frame); 951 972 } 952 973 953 974 #if 0 … … void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 989 1010 frameInfo[curFrameNumber].flagMask )); 990 1011 991 1012 #ifdef SHOW_DEBUG_WIN 992 comm_debug_show(frame ->buf);1013 comm_debug_show(frame); 993 1014 getchar(); 994 1015 #endif 995 1016 … … void ClassicCommDetector::BuildAllMethodsCommList(void) 1365 1386 } 1366 1387 1367 1388 if ((fbp->length > 4) && 1368 ( fbp->logoCount > (fbp->frames * 0.60)) &&1389 (!logoInfoAvailable || fbp->logoCount > (fbp->frames * 0.60)) && 1369 1390 (fbp->bfCount < (fbp->frames * 0.10))) 1370 1391 { 1371 1392 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 153 153 bool logoInfoAvailable; 154 154 LogoDetectorBase* logoDetector; 155 155 156 unsigned char *framePtr;157 158 156 frm_dir_map_t blankFrameMap; 159 157 frm_dir_map_t blankCommMap; 160 158 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 7 7 // MythTV headers 8 8 #include "mythcorecontext.h" 9 9 #include "mythplayer.h" 10 #include "frame.h" 10 11 11 12 // Commercial Flagging headers 12 13 #include "ClassicLogoDetector.h" 13 14 #include "ClassicCommDetector.h" 15 #include "commercial_debug.h" 14 16 15 17 typedef struct edgemaskentry 16 18 { … … bool ClassicLogoDetector::searchForLogo(MythPlayer* player) 99 101 100 102 edgeCounts = new EdgeMaskEntry[width * height]; 101 103 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 102 114 for (i = 0; edgeDiffs[i] != 0 && !logoInfoAvailable; i++) 103 115 { 104 116 int pixelsInMask = 0; 105 117 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)); 108 120 109 121 memset(edgeCounts, 0, sizeof(EdgeMaskEntry) * width * height); 110 122 memset(edgeMask, 0, sizeof(EdgeMaskEntry) * width * height); … … bool ClassicLogoDetector::searchForLogo(MythPlayer* player) 236 248 #endif 237 249 if (((logoMaxX - logoMinX) < (width / 4)) && 238 250 ((logoMaxY - logoMinY) < (height / 4)) && 239 (pixelsInMask > 50))251 (pixelsInMask > minPixelsInMask)) 240 252 { 241 253 logoInfoAvailable = true; 242 254 logoEdgeDiff = edgeDiffs[i]; 243 255 244 256 LOG(VB_COMMFLAG, LOG_INFO, 245 257 QString("Using Logo area: topleft (%1,%2), " 246 "bottomright (%3,%4) ")258 "bottomright (%3,%4), pixelsInMask (%5).") 247 259 .arg(logoMinX).arg(logoMinY) 248 .arg(logoMaxX).arg(logoMaxY)); 260 .arg(logoMaxX).arg(logoMaxY) 261 .arg(pixelsInMask)); 249 262 } 250 263 else 251 264 { … … bool ClassicLogoDetector::searchForLogo(MythPlayer* player) 262 275 delete [] edgeCounts; 263 276 264 277 if (!logoInfoAvailable) 265 LOG(VB_ COMMFLAG, LOG_NOTICE, "No suitable logo area found.");278 LOG(VB_GENERAL, LOG_NOTICE, "No suitable logo area found."); 266 279 267 280 player->DiscardVideoFrame(player->GetRawVideoFrame(0)); 268 281 return logoInfoAvailable; … … void ClassicLogoDetector::SetLogoMask(unsigned char *mask) 380 393 } 381 394 382 395 #ifdef SHOW_DEBUG_WIN 383 DumpLogo( true,framePtr);396 DumpLogo(false, NULL); 384 397 #endif 385 398 386 399 logoFrameCount = 0; 387 400 logoInfoAvailable = true; 401 388 402 } 389 403 390 404 … … void ClassicLogoDetector::DumpLogo(bool fromCurrentFrame, 441 455 * which are partially mods based on Myth's original commercial skip 442 456 * code written by Chris Pinkham. */ 443 457 bool ClassicLogoDetector::doesThisFrameContainTheFoundLogo( 444 unsigned char* framePtr)458 VideoFrame* frame) 445 459 { 446 460 int radius = 2; 447 461 unsigned int x, y; 448 462 int pos1, pos2, pos3; 463 int edgePos; 449 464 int pixel; 450 465 int goodEdges = 0; 451 466 int badEdges = 0; 452 467 int testEdges = 0; 453 468 int testNotEdges = 0; 454 469 470 unsigned char* framePtr = frame->buf; 471 int bytesPerLine = frame->pitches[0]; 472 455 473 for (y = logoMinY; y <= logoMaxY; y++ ) 456 474 { 457 475 for (x = logoMinX; x <= logoMaxX; x++ ) 458 476 { 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; 462 481 463 482 pixel = framePtr[pos1]; 464 483 465 if (edgeMask[ pos1].horiz)484 if (edgeMask[edgePos].horiz) 466 485 { 467 486 if ((abs(framePtr[pos1 - radius] - pixel) >= logoEdgeDiff) || 468 487 (abs(framePtr[pos1 + radius] - pixel) >= logoEdgeDiff)) … … bool ClassicLogoDetector::doesThisFrameContainTheFoundLogo( 477 496 testNotEdges++; 478 497 } 479 498 480 if (edgeMask[ pos1].vert)499 if (edgeMask[edgePos].vert) 481 500 { 482 501 if ((abs(framePtr[pos2] - pixel) >= logoEdgeDiff) || 483 502 (abs(framePtr[pos3] - pixel) >= logoEdgeDiff)) … … void ClassicLogoDetector::DetectEdges(VideoFrame *frame, EdgeMaskEntry *edges, 520 539 { 521 540 int r = 2; 522 541 unsigned char *buf = frame->buf; 542 int bytesPerLine = frame->pitches[0]; 523 543 unsigned char p; 524 544 unsigned int pos, x, y; 525 545 … … void ClassicLogoDetector::DetectEdges(VideoFrame *frame, EdgeMaskEntry *edges, 536 556 continue; 537 557 538 558 pos = y * width + x; 539 p = buf[ pos];559 p = buf[y * bytesPerLine + x]; 540 560 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)) 543 563 { 544 564 edges[pos].horiz++; 545 565 edgeCount++; 546 566 } 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)) 549 569 { 550 570 edges[pos].vert++; 551 571 edgeCount++; 552 572 } 553 573 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)) 556 576 { 557 577 edges[pos].ldiag++; 558 578 edgeCount++; 559 579 } 560 580 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)) 563 583 { 564 584 edges[pos].rdiag++; 565 585 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 16 16 virtual void deleteLater(void); 17 17 18 18 bool searchForLogo(MythPlayer* player); 19 bool doesThisFrameContainTheFoundLogo( unsigned char* frame);19 bool doesThisFrameContainTheFoundLogo(VideoFrame* frame); 20 20 bool pixelInsideLogo(unsigned int x, unsigned int y); 21 21 22 22 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) 25 25 SceneChangeDetectorBase::deleteLater(); 26 26 } 27 27 28 void ClassicSceneChangeDetector::processFrame( unsigned char* frame)28 void ClassicSceneChangeDetector::processFrame(VideoFrame* frame) 29 29 { 30 30 histogram->generateFromImage(frame, width, height, commdetectborder, 31 31 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 13 13 unsigned int yspacing); 14 14 virtual void deleteLater(void); 15 15 16 void processFrame( unsigned char* frame);16 void processFrame(VideoFrame* frame); 17 17 18 18 private: 19 19 ~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 3 3 #include <cmath> 4 4 #include <cstring> 5 5 6 #include "frame.h" 7 6 8 Histogram::Histogram() 7 9 { 8 10 memset(data,0,sizeof(data)); … … Histogram::~Histogram() 15 17 { 16 18 } 17 19 18 void Histogram::generateFromImage( unsigned char* frame, unsigned int frameWidth,20 void Histogram::generateFromImage(VideoFrame* frame, unsigned int frameWidth, 19 21 unsigned int frameHeight, unsigned int minScanX, unsigned int maxScanX, 20 22 unsigned int minScanY, unsigned int maxScanY, unsigned int XSpacing, 21 23 unsigned int YSpacing) … … void Histogram::generateFromImage(unsigned char* frame, unsigned int frameWidth, 29 31 if (maxScanY > frameHeight-1) 30 32 maxScanY = frameHeight-1; 31 33 34 unsigned char* framePtr = frame->buf; 35 int bytesPerLine = frame->pitches[0]; 32 36 for(unsigned int y = minScanY; y < maxScanY; y += YSpacing) 33 37 for(unsigned int x = minScanX; x < maxScanX; x += XSpacing) 34 38 { 35 data[frame [y * frameWidth+ x]]++;39 data[framePtr[y * bytesPerLine + x]]++; 36 40 numberOfSamples++; 37 41 } 38 42 } -
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 1 1 #ifndef _HISTOGRAM_H_ 2 2 #define _HISTOGRAM_H_ 3 3 4 typedef struct VideoFrame_ VideoFrame; 5 4 6 class Histogram 5 7 { 6 8 public: 7 9 Histogram(); 8 10 ~Histogram(); 9 11 10 void generateFromImage( unsigned char* frame, unsigned int frameWidth,12 void generateFromImage(VideoFrame* frame, unsigned int frameWidth, 11 13 unsigned int frameHeight, unsigned int minScanX, 12 14 unsigned int maxScanX, unsigned int minScanY, 13 15 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 4 4 #include <QObject> 5 5 6 6 class MythPlayer; 7 typedef struct VideoFrame_ VideoFrame; 7 8 8 9 class LogoDetectorBase : public QObject 9 10 { … … class LogoDetectorBase : public QObject 14 15 foundLogo(false), width(w),height(h) {}; 15 16 16 17 virtual bool searchForLogo(MythPlayer* player) = 0; 17 virtual bool doesThisFrameContainTheFoundLogo( unsigned char* frame) = 0;18 virtual bool doesThisFrameContainTheFoundLogo(VideoFrame* frame) = 0; 18 19 virtual bool pixelInsideLogo(unsigned int x, unsigned int y) = 0; 19 20 virtual unsigned int getRequiredAvailableBufferForSearch() = 0; 20 21 -
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 3 3 4 4 #include <QObject> 5 5 6 typedef struct VideoFrame_ VideoFrame; 7 6 8 class SceneChangeDetectorBase : public QObject 7 9 { 8 10 Q_OBJECT … … class SceneChangeDetectorBase : public QObject 11 13 SceneChangeDetectorBase(unsigned int w, unsigned int h) : 12 14 width(w), height(h) {} 13 15 14 virtual void processFrame( unsigned char *frame) = 0;16 virtual void processFrame(VideoFrame* frame) = 0; 15 17 16 18 signals: 17 19 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 12 extern "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 26 Window comm_win; 27 GC comm_gc; 28 Display *comm_display; 29 int comm_width = 0; 30 int comm_width8 = 0; 31 int comm_height = 0; 32 int comm_depth = 24; 33 XImage *comm_image = NULL; 34 char *comm_buf = NULL; 35 struct SwsContext *scontext; 36 37 void 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 76 static void comm_debug_show( AVPicture* pic); 77 78 void 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 88 void 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 101 void 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 138 void 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 11 extern void comm_debug_init( int width, int height ); 12 extern void comm_debug_show( unsigned char *frame ); 13 extern void comm_debug_show( VideoFrame *frame ); 14 extern 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 34 34 HEADERS += LogoDetectorBase.h SceneChangeDetectorBase.h 35 35 HEADERS += SlotRelayer.h CustomEventRelayer.h 36 36 HEADERS += commandlineparser.h 37 HEADERS += commercial_debug.h 37 38 38 39 SOURCES += CommDetectorFactory.cpp CommDetectorBase.cpp 39 40 SOURCES += ClassicLogoDetector.cpp … … SOURCES += HistogramAnalyzer.cpp 51 52 SOURCES += BlankFrameDetector.cpp 52 53 SOURCES += SceneChangeDetector.cpp 53 54 SOURCES += PrePostRollFlagger.cpp 55 SOURCES += commercial_debug.cpp 54 56 55 57 SOURCES += main.cpp commandlineparser.cpp 56 58