8#include "libavutil/frame.h"
31 unsigned int w,
unsigned int h,
32 unsigned int commdetectborder_in)
34 m_commDetector(commdetector),
35 m_commDetectBorder(commdetectborder_in),
36 m_commDetectLogoSecondsNeeded((int)(1.3 * m_commDetectLogoSamplesNeeded *
37 m_commDetectLogoSampleSpacing)),
40 m_logoMaxValues(new unsigned char[m_width * m_height]),
41 m_logoMinValues(new unsigned char[m_width * m_height]),
42 m_logoFrame(new unsigned char[m_width * m_height]),
43 m_logoMask(new unsigned char[m_width * m_height]),
44 m_logoCheckMask(new unsigned char[m_width * m_height])
84 LogoDetectorBase::deleteLater();
92 const std::array<const int,9> edgeDiffs {5, 7, 10, 15, 20, 30, 40, 50, 60 };
95 LOG(VB_COMMFLAG, LOG_INFO,
"Searching for Station Logo");
109 int minPixelsInMask =
112 for (
uint edgediff : edgeDiffs)
114 int pixelsInMask = 0;
116 LOG(VB_COMMFLAG, LOG_INFO,
117 QString(
"Trying with edgeDiff == %1, minPixelsInMask=%2")
118 .arg(edgediff).arg(minPixelsInMask));
127 while (loops < maxLoops && player->GetEof() ==
kEofStateNone)
131 if ((loops % 50) == 0)
142 std::this_thread::sleep_for(10ms);
146 seekFrame += seekIncrement;
152 LOG(VB_COMMFLAG, LOG_INFO,
"Analyzing edge data");
166 if (edgeCounts[pos].m_isEdge > (maxLoops * 0.66))
172 if (edgeCounts[pos].m_horiz > (maxLoops * 0.66))
175 if (edgeCounts[pos].m_vert > (maxLoops * 0.66))
178 if (edgeCounts[pos].m_ldiag > (maxLoops * 0.66))
180 if (edgeCounts[pos].m_rdiag > (maxLoops * 0.66))
196 for (
uint dy = y - 2; dy <= (y + 2); dy++ )
198 for (
uint dx = x - 2; dx <= (x + 2); dx++ )
211 LOG(VB_COMMFLAG, LOG_INFO,
212 QString(
"Testing Logo area: topleft (%1,%2), bottomright (%3,%4)")
218 (pixelsInMask > minPixelsInMask))
223 LOG(VB_COMMFLAG, LOG_INFO,
224 QString(
"Using Logo area: topleft (%1,%2), "
225 "bottomright (%3,%4), pixelsInMask (%5).")
232 LOG(VB_COMMFLAG, LOG_INFO,
233 QString(
"Rejecting Logo area: topleft (%1,%2), "
234 "bottomright (%3,%4), pixelsInMask (%5). "
235 "Not within specified limits.")
241 delete [] edgeCounts;
244 LOG(VB_COMMFLAG, LOG_NOTICE,
"No suitable logo area found.");
253 LOG(VB_COMMFLAG, LOG_INFO,
"SetLogoMaskArea()");
260 for (
unsigned int y = 0; y <
m_height; y++)
262 for (
unsigned int x = 0; x <
m_width; x++)
287 const unsigned char* framePtr)
289 std::string scrPixels {
" .oxX"};
294 std::cerr <<
"\nLogo Data ";
295 if (fromCurrentFrame)
296 std::cerr <<
"from current frame\n";
301 std::cerr << (x % 10);
306 QString
tmp = QString(
"%1: ").arg(y, 3);
307 QString ba =
tmp.toLatin1();
308 std::cerr << ba.constData();
311 if (fromCurrentFrame)
313 std::cerr << scrPixels[framePtr[(y *
m_width) + x] / 50];
320 case 2: std::cerr <<
" ";
322 case 1: std::cerr <<
"*";
324 case 3: std::cerr <<
".";
345 int testNotEdges = 0;
347 unsigned char* framePtr = frame->
m_buffer;
354 int pos1 = (y * bytesPerLine) + x;
355 int edgePos = (y *
m_width) + x;
356 int pos2 = ((y - radius) * bytesPerLine) + x;
357 int pos3 = ((y + radius) * bytesPerLine) + x;
359 int pixel = framePtr[pos1];
394 double goodEdgeRatio = (testEdges) ?
395 (
double)goodEdges / (double)testEdges : 0.0;
396 double badEdgeRatio = (testNotEdges) ?
397 (
double)badEdges / (double)testNotEdges : 0.0;
415 unsigned char *buf = frame->
m_buffer;
439 uchar
p = buf[(y * bytesPerLine) + x];
441 if (( abs(buf[(y * bytesPerLine) + (x - r)] -
p) >= edgeDiff) ||
442 ( abs(buf[(y * bytesPerLine) + (x + r)] -
p) >= edgeDiff))
447 if (( abs(buf[((y - r) * bytesPerLine) + x] -
p) >= edgeDiff) ||
448 ( abs(buf[((y + r) * bytesPerLine) + x] -
p) >= edgeDiff))
454 if (( abs(buf[((y - r) * bytesPerLine) + (x - r)] -
p) >= edgeDiff) ||
455 ( abs(buf[((y + r) * bytesPerLine) + (x + r)] -
p) >= edgeDiff))
461 if (( abs(buf[((y - r) * bytesPerLine) + (x + r)] -
p) >= edgeDiff) ||
462 ( abs(buf[((y + r) * bytesPerLine) + (x - r)] -
p) >= edgeDiff))
void logoDetectorBreathe()
double m_commDetectLogoGoodEdgeThreshold
QString m_commDetectLogoLocation
unsigned int m_commDetectBorder
bool searchForLogo(MythCommFlagPlayer *player) override
unsigned char * m_logoMinValues
int m_commDetectLogoSecondsNeeded
void DumpLogo(bool fromCurrentFrame, const unsigned char *framePtr)
void DetectEdges(MythVideoFrame *frame, EdgeMaskEntry *edges, int edgeDiff)
int m_commDetectLogoSamplesNeeded
bool doesThisFrameContainTheFoundLogo(MythVideoFrame *frame) override
bool pixelInsideLogo(unsigned int x, unsigned int y) override
int m_commDetectLogoSampleSpacing
unsigned char * m_logoCheckMask
unsigned char * m_logoMask
unsigned int getRequiredAvailableBufferForSearch() override
int m_commDetectLogoWidthRatio
unsigned char * m_logoMaxValues
unsigned char * m_logoFrame
virtual void deleteLater(void)
~ClassicLogoDetector() override
int m_commDetectLogoHeightRatio
int m_commDetectLogoMinPixels
ClassicLogoDetector(ClassicCommDetector *commDetector, unsigned int width, unsigned int height, unsigned int commdetectborder)
ClassicCommDetector * m_commDetector
unsigned int m_frameNumber
EdgeMaskEntry * m_edgeMask
double m_commDetectLogoBadEdgeThreshold
MythVideoFrame * GetRawVideoFrame(long long FrameNumber=-1)
Returns a specific frame from the video.
QString GetSetting(const QString &key, const QString &defaultval="")
int GetNumSetting(const QString &key, int defaultval=0)
float GetFrameRate(void) const
void DiscardVideoFrame(MythVideoFrame *buffer)
Places frame in the available frames queue.
static guint32 * pixel
--------------------------------------------------—**
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)