MythTV  master
ClassicLogoDetector.cpp
Go to the documentation of this file.
1 // C++ headers
2 #include <cstdlib>
3 #include <thread> // for sleep_for
4 
5 // FFmpeg headers
6 extern "C" {
7 #include "libavutil/frame.h"
8 }
9 
10 // MythTV headers
13 
14 // Commercial Flagging headers
15 #include "ClassicCommDetector.h"
16 #include "ClassicLogoDetector.h"
17 
19 {
20  int m_isEdge;
21  int m_horiz;
22  int m_vert;
23  int m_rdiag;
24  int m_ldiag;
25 };
26 
27 
29  unsigned int w, unsigned int h,
30  unsigned int commdetectborder_in)
31  : LogoDetectorBase(w,h),
32  m_commDetector(commdetector),
33  m_commDetectBorder(commdetectborder_in),
34  m_edgeMask(new EdgeMaskEntry[m_width * m_height]),
35  // cppcheck doesn't understand deleteLater
36  m_logoMaxValues(new unsigned char[m_width * m_height]),
37  m_logoMinValues(new unsigned char[m_width * m_height]),
38  m_logoFrame(new unsigned char[m_width * m_height]),
39  m_logoMask(new unsigned char[m_width * m_height]),
40  m_logoCheckMask(new unsigned char[m_width * m_height])
41 {
43  gCoreContext->GetNumSetting("CommDetectLogoSamplesNeeded", 240);
45  gCoreContext->GetNumSetting("CommDetectLogoSampleSpacing", 2);
49  gCoreContext->GetSetting("CommDetectLogoGoodEdgeThreshold", "0.75")
50  .toDouble();
52  gCoreContext->GetSetting("CommDetectLogoBadEdgeThreshold", "0.85")
53  .toDouble();
55  gCoreContext->GetSetting("CommDetectLogoLocation", "");
57  gCoreContext->GetNumSetting("CommDetectLogoWidthRatio", 4);
59  gCoreContext->GetNumSetting("CommDetectLogoHeightRatio", 4);
61  gCoreContext->GetNumSetting("CommDetectLogoMinPixels", 50);
62 }
63 
65 {
66  delete [] m_edgeMask;
67  delete [] m_logoFrame;
68  delete [] m_logoMask;
69  delete [] m_logoCheckMask;
70  delete [] m_logoMaxValues;
71  delete [] m_logoMinValues;
72 }
73 
75 {
77 }
78 
80 {
81  m_commDetector = nullptr;
82  LogoDetectorBase::deleteLater();
83 }
84 
86 {
87  int seekIncrement =
89  int maxLoops = m_commDetectLogoSamplesNeeded;
90  const std::array<const int,9> edgeDiffs {5, 7, 10, 15, 20, 30, 40, 50, 60 };
91 
92 
93  LOG(VB_COMMFLAG, LOG_INFO, "Searching for Station Logo");
94 
95  m_logoInfoAvailable = false;
96 
97  auto *edgeCounts = new EdgeMaskEntry[m_width * m_height];
98 
99  // Back in 2005, a threshold of 50 minimum pixelsInMask was established.
100  // I don't know whether that was tested against SD or HD resolutions.
101  // I do know that in 2010, mythcommflag was changed to use ffmpeg's
102  // lowres support, effectively dividing the video area by 16.
103  // But the 50 pixel minimum was not adjusted accordingly.
104  // I believe the minimum threshold should vary with the video's area.
105  // I am using 1280x720 (for 720p) video as the baseline.
106  // This should improve logo detection for SD video.
107  int minPixelsInMask =
108  m_commDetectLogoMinPixels * (m_width*m_height) / (1280*720 / 16);
109 
110  for (uint edgediff : edgeDiffs)
111  {
112  int pixelsInMask = 0;
113 
114  LOG(VB_COMMFLAG, LOG_INFO,
115  QString("Trying with edgeDiff == %1, minPixelsInMask=%2")
116  .arg(edgediff).arg(minPixelsInMask));
117 
118  memset(edgeCounts, 0, sizeof(EdgeMaskEntry) * m_width * m_height);
119  memset(m_edgeMask, 0, sizeof(EdgeMaskEntry) * m_width * m_height);
120 
121  player->DiscardVideoFrame(player->GetRawVideoFrame(0));
122 
123  int loops = 0;
124  long long seekFrame = m_commDetector->m_preRoll + seekIncrement;
125  while (loops < maxLoops && player->GetEof() == kEofStateNone)
126  {
127  MythVideoFrame* vf = player->GetRawVideoFrame(seekFrame);
128 
129  if ((loops % 50) == 0)
131 
132  if (m_commDetector->m_bStop)
133  {
134  player->DiscardVideoFrame(vf);
135  delete[] edgeCounts;
136  return false;
137  }
138 
140  std::this_thread::sleep_for(10ms);
141 
142  DetectEdges(vf, edgeCounts, edgediff);
143 
144  seekFrame += seekIncrement;
145  loops++;
146 
147  player->DiscardVideoFrame(vf);
148  }
149 
150  LOG(VB_COMMFLAG, LOG_INFO, "Analyzing edge data");
151 
152 #ifdef SHOW_DEBUG_WIN
153  unsigned char *fakeFrame;
154  fakeFrame = new unsigned char[m_width * m_height * 3 / 2];
155  memset(fakeFrame, 0, m_width * m_height * 3 / 2);
156 #endif
157 
158  for (uint y = 0; y < m_height; y++)
159  {
160  if ((y > (m_height/4)) && (y < (m_height * 3 / 4)))
161  continue;
162 
163  for (uint x = 0; x < m_width; x++)
164  {
165  if ((x > (m_width/4)) && (x < (m_width * 3 / 4)))
166  continue;
167 
168  uint pos = y * m_width + x;
169 
170  if (edgeCounts[pos].m_isEdge > (maxLoops * 0.66))
171  {
172  m_edgeMask[pos].m_isEdge = 1;
173  pixelsInMask++;
174 #ifdef SHOW_DEBUG_WIN
175  fakeFrame[pos] = 0xff;
176 #endif
177 
178  }
179 
180  if (edgeCounts[pos].m_horiz > (maxLoops * 0.66))
181  m_edgeMask[pos].m_horiz = 1;
182 
183  if (edgeCounts[pos].m_vert > (maxLoops * 0.66))
184  m_edgeMask[pos].m_vert = 1;
185 
186  if (edgeCounts[pos].m_ldiag > (maxLoops * 0.66))
187  m_edgeMask[pos].m_ldiag = 1;
188  if (edgeCounts[pos].m_rdiag > (maxLoops * 0.66))
189  m_edgeMask[pos].m_rdiag = 1;
190  }
191  }
192 
193  SetLogoMaskArea();
194 
195  for (uint y = m_logoMinY; y < m_logoMaxY; y++)
196  {
197  for (uint x = m_logoMinX; x < m_logoMaxX; x++)
198  {
199  int neighbors = 0;
200 
201  if (!m_edgeMask[y * m_width + x].m_isEdge)
202  continue;
203 
204  for (uint dy = y - 2; dy <= (y + 2); dy++ )
205  {
206  for (uint dx = x - 2; dx <= (x + 2); dx++ )
207  {
208  if (m_edgeMask[dy * m_width + dx].m_isEdge)
209  neighbors++;
210  }
211  }
212 
213  if (neighbors < 5)
214  m_edgeMask[y * m_width + x].m_isEdge = 0;
215  }
216  }
217 
218  SetLogoMaskArea();
219  LOG(VB_COMMFLAG, LOG_INFO,
220  QString("Testing Logo area: topleft (%1,%2), bottomright (%3,%4)")
221  .arg(m_logoMinX).arg(m_logoMinY)
222  .arg(m_logoMaxX).arg(m_logoMaxY));
223 
224 #ifdef SHOW_DEBUG_WIN
225  for (uint x = m_logoMinX; x < m_logoMaxX; x++)
226  {
227  uint pos = m_logoMinY * m_width + x;
228  fakeFrame[pos] = 0x7f;
229  pos = m_logoMaxY * m_width + x;
230  fakeFrame[pos] = 0x7f;
231  }
232  for (uint y = m_logoMinY; y < m_logoMaxY; y++)
233  {
234  uint pos = y * m_width + m_logoMinX;
235  fakeFrame[pos] = 0x7f;
236  pos = y * m_width + m_logoMaxX;
237  fakeFrame[pos] = 0x7f;
238  }
239 
240  comm_debug_show(fakeFrame);
241  delete [] fakeFrame;
242 
243  cerr << "Hit ENTER to continue" << endl;
244  getchar();
245 #endif
248  (pixelsInMask > minPixelsInMask))
249  {
250  m_logoInfoAvailable = true;
251  m_logoEdgeDiff = edgediff;
252 
253  LOG(VB_COMMFLAG, LOG_INFO,
254  QString("Using Logo area: topleft (%1,%2), "
255  "bottomright (%3,%4), pixelsInMask (%5).")
256  .arg(m_logoMinX).arg(m_logoMinY)
257  .arg(m_logoMaxX).arg(m_logoMaxY)
258  .arg(pixelsInMask));
259  break;
260  }
261 
262  LOG(VB_COMMFLAG, LOG_INFO,
263  QString("Rejecting Logo area: topleft (%1,%2), "
264  "bottomright (%3,%4), pixelsInMask (%5). "
265  "Not within specified limits.")
266  .arg(m_logoMinX).arg(m_logoMinY)
267  .arg(m_logoMaxX).arg(m_logoMaxY)
268  .arg(pixelsInMask));
269  }
270 
271  delete [] edgeCounts;
272 
273  if (!m_logoInfoAvailable)
274  LOG(VB_COMMFLAG, LOG_NOTICE, "No suitable logo area found.");
275 
276  player->DiscardVideoFrame(player->GetRawVideoFrame(0));
277  return m_logoInfoAvailable;
278 }
279 
280 
282 {
283  LOG(VB_COMMFLAG, LOG_INFO, "SetLogoMaskArea()");
284 
285  m_logoMinX = m_width - 1;
286  m_logoMaxX = 0;
287  m_logoMinY = m_height - 1;
288  m_logoMaxY = 0;
289 
290  for (unsigned int y = 0; y < m_height; y++)
291  {
292  for (unsigned int x = 0; x < m_width; x++)
293  {
294  if (m_edgeMask[y * m_width + x].m_isEdge)
295  {
296  if (x < m_logoMinX)
297  m_logoMinX = x;
298  if (y < m_logoMinY)
299  m_logoMinY = y;
300  if (x > m_logoMaxX)
301  m_logoMaxX = x;
302  if (y > m_logoMaxY)
303  m_logoMaxY = y;
304  }
305  }
306  }
307 
308  m_logoMinX -= 5;
309  m_logoMaxX += 5;
310  m_logoMinY -= 5;
311  m_logoMaxY += 5;
312 
313  if (m_logoMinX < 4)
314  m_logoMinX = 4;
315  if (m_logoMaxX > (m_width-5))
316  m_logoMaxX = (m_width-5);
317  if (m_logoMinY < 4)
318  m_logoMinY = 4;
319  if (m_logoMaxY > (m_height-5))
320  m_logoMaxY = (m_height-5);
321 }
322 
323 
324 void ClassicLogoDetector::DumpLogo(bool fromCurrentFrame,
325  const unsigned char* framePtr)
326 {
327  std::string scrPixels {" .oxX"};
328 
329  if (!m_logoInfoAvailable)
330  return;
331 
332  std::cerr << "\nLogo Data ";
333  if (fromCurrentFrame)
334  std::cerr << "from current frame\n";
335 
336  std::cerr << "\n ";
337 
338  for(unsigned int x = m_logoMinX - 2; x <= (m_logoMaxX + 2); x++)
339  std::cerr << (x % 10);
340  std::cerr << "\n";
341 
342  for(unsigned int y = m_logoMinY - 2; y <= (m_logoMaxY + 2); y++)
343  {
344  QString tmp = QString("%1: ").arg(y, 3);
345  QString ba = tmp.toLatin1();
346  std::cerr << ba.constData();
347  for(unsigned int x = m_logoMinX - 2; x <= (m_logoMaxX + 2); x++)
348  {
349  if (fromCurrentFrame)
350  {
351  std::cerr << scrPixels[framePtr[y * m_width + x] / 50];
352  }
353  else
354  {
355  switch (m_logoMask[y * m_width + x])
356  {
357  case 0:
358  case 2: std::cerr << " ";
359  break;
360  case 1: std::cerr << "*";
361  break;
362  case 3: std::cerr << ".";
363  break;
364  }
365  }
366  }
367  std::cerr << "\n";
368  }
369  std::cerr.flush();
370 }
371 
372 
373 /* ideas for this method ported back from comskip.c mods by Jere Jones
374  * which are partially mods based on Myth's original commercial skip
375  * code written by Chris Pinkham. */
377  MythVideoFrame* frame)
378 {
379  int radius = 2;
380  int goodEdges = 0;
381  int badEdges = 0;
382  int testEdges = 0;
383  int testNotEdges = 0;
384 
385  unsigned char* framePtr = frame->m_buffer;
386  int bytesPerLine = frame->m_pitches[0];
387 
388  for (uint y = m_logoMinY; y <= m_logoMaxY; y++ )
389  {
390  for (uint x = m_logoMinX; x <= m_logoMaxX; x++ )
391  {
392  int pos1 = y * bytesPerLine + x;
393  int edgePos = y * m_width + x;
394  int pos2 = (y - radius) * bytesPerLine + x;
395  int pos3 = (y + radius) * bytesPerLine + x;
396 
397  int pixel = framePtr[pos1];
398 
399  if (m_edgeMask[edgePos].m_horiz)
400  {
401  if ((abs(framePtr[pos1 - radius] - pixel) >= m_logoEdgeDiff) ||
402  (abs(framePtr[pos1 + radius] - pixel) >= m_logoEdgeDiff))
403  goodEdges++;
404  testEdges++;
405  }
406  else
407  {
408  if ((abs(framePtr[pos1 - radius] - pixel) >= m_logoEdgeDiff) ||
409  (abs(framePtr[pos1 + radius] - pixel) >= m_logoEdgeDiff))
410  badEdges++;
411  testNotEdges++;
412  }
413 
414  if (m_edgeMask[edgePos].m_vert)
415  {
416  if ((abs(framePtr[pos2] - pixel) >= m_logoEdgeDiff) ||
417  (abs(framePtr[pos3] - pixel) >= m_logoEdgeDiff))
418  goodEdges++;
419  testEdges++;
420  }
421  else
422  {
423  if ((abs(framePtr[pos2] - pixel) >= m_logoEdgeDiff) ||
424  (abs(framePtr[pos3] - pixel) >= m_logoEdgeDiff))
425  badEdges++;
426  testNotEdges++;
427  }
428  }
429  }
430 
431  m_frameNumber++;
432  double goodEdgeRatio = (testEdges) ?
433  (double)goodEdges / (double)testEdges : 0.0;
434  double badEdgeRatio = (testNotEdges) ?
435  (double)badEdges / (double)testNotEdges : 0.0;
436  return (goodEdgeRatio > m_commDetectLogoGoodEdgeThreshold) &&
437  (badEdgeRatio < m_commDetectLogoBadEdgeThreshold);
438 }
439 
440 bool ClassicLogoDetector::pixelInsideLogo(unsigned int x, unsigned int y)
441 {
442  if (!m_logoInfoAvailable)
443  return false;
444 
445  return ((x > m_logoMinX) && (x < m_logoMaxX) &&
446  (y > m_logoMinY) && (y < m_logoMaxY));
447 }
448 
450  int edgeDiff)
451 {
452  int r = 2;
453  unsigned char *buf = frame->m_buffer;
454  int bytesPerLine = frame->m_pitches[0];
455 
456  for (uint y = m_commDetectBorder + r; y < (m_height - m_commDetectBorder - r); y++)
457  {
458  if (
459  (m_commDetectLogoLocation.contains("N") && (y > (m_height/4))) ||
460  (m_commDetectLogoLocation.contains("S") && (y < (m_height * 3 / 4))) ||
461  ((y > (m_height/4)) && (y < (m_height * 3 / 4)))
462  )
463  continue;
464 
465  for (uint x = m_commDetectBorder + r; x < (m_width - m_commDetectBorder - r); x++)
466  {
467  int edgeCount = 0;
468 
469  if (
470  (m_commDetectLogoLocation.contains("W") && (x > (m_width/4))) ||
471  (m_commDetectLogoLocation.contains("E") && (x < (m_width * 3 / 4))) ||
472  ((x > (m_width/4)) && (x < (m_width * 3 / 4)))
473  )
474  continue;
475 
476  uint pos = y * m_width + x;
477  uchar p = buf[y * bytesPerLine + x];
478 
479  if (( abs(buf[y * bytesPerLine + (x - r)] - p) >= edgeDiff) ||
480  ( abs(buf[y * bytesPerLine + (x + r)] - p) >= edgeDiff))
481  {
482  edges[pos].m_horiz++;
483  edgeCount++;
484  }
485  if (( abs(buf[(y - r) * bytesPerLine + x] - p) >= edgeDiff) ||
486  ( abs(buf[(y + r) * bytesPerLine + x] - p) >= edgeDiff))
487  {
488  edges[pos].m_vert++;
489  edgeCount++;
490  }
491 
492  if (( abs(buf[(y - r) * bytesPerLine + (x - r)] - p) >= edgeDiff) ||
493  ( abs(buf[(y + r) * bytesPerLine + (x + r)] - p) >= edgeDiff))
494  {
495  edges[pos].m_ldiag++;
496  edgeCount++;
497  }
498 
499  if (( abs(buf[(y - r) * bytesPerLine + (x + r)] - p) >= edgeDiff) ||
500  ( abs(buf[(y + r) * bytesPerLine + (x - r)] - p) >= edgeDiff))
501  {
502  edges[pos].m_rdiag++;
503  edgeCount++;
504  }
505 
506  if (edgeCount >= 3)
507  edges[pos].m_isEdge++;
508  }
509  }
510 }
511 
512 /* vim: set expandtab tabstop=4 shiftwidth=4: */
EdgeMaskEntry
Definition: ClassicLogoDetector.cpp:18
ClassicLogoDetector::m_logoMaxY
unsigned int m_logoMaxY
Definition: ClassicLogoDetector.h:56
ClassicLogoDetector::m_commDetectLogoSecondsNeeded
int m_commDetectLogoSecondsNeeded
Definition: ClassicLogoDetector.h:36
ClassicCommDetector.h
ClassicLogoDetector::SetLogoMaskArea
void SetLogoMaskArea()
Definition: ClassicLogoDetector.cpp:281
ClassicLogoDetector.h
ClassicLogoDetector::pixelInsideLogo
bool pixelInsideLogo(unsigned int x, unsigned int y) override
Definition: ClassicLogoDetector.cpp:440
ClassicLogoDetector::m_logoMask
unsigned char * m_logoMask
Definition: ClassicLogoDetector.h:49
ClassicLogoDetector::m_commDetectLogoLocation
QString m_commDetectLogoLocation
Definition: ClassicLogoDetector.h:42
ClassicLogoDetector::m_logoMaxValues
unsigned char * m_logoMaxValues
Definition: ClassicLogoDetector.h:46
ClassicLogoDetector::m_commDetectLogoGoodEdgeThreshold
double m_commDetectLogoGoodEdgeThreshold
Definition: ClassicLogoDetector.h:40
kEofStateNone
@ kEofStateNone
Definition: decoderbase.h:69
ClassicLogoDetector::doesThisFrameContainTheFoundLogo
bool doesThisFrameContainTheFoundLogo(MythVideoFrame *frame) override
Definition: ClassicLogoDetector.cpp:376
ClassicLogoDetector::m_commDetector
ClassicCommDetector * m_commDetector
Definition: ClassicLogoDetector.h:30
ClassicLogoDetector::m_logoFrame
unsigned char * m_logoFrame
Definition: ClassicLogoDetector.h:48
mythcommflagplayer.h
EdgeMaskEntry::m_rdiag
int m_rdiag
Definition: ClassicLogoDetector.cpp:23
ClassicLogoDetector::m_edgeMask
EdgeMaskEntry * m_edgeMask
Definition: ClassicLogoDetector.h:44
ClassicCommDetector::logoDetectorBreathe
void logoDetectorBreathe()
Definition: ClassicCommDetector.cpp:2483
MythPlayer::GetFrameRate
float GetFrameRate(void) const
Definition: mythplayer.h:134
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
ClassicLogoDetector::m_commDetectLogoWidthRatio
int m_commDetectLogoWidthRatio
Definition: ClassicLogoDetector.h:37
pixel
static guint32 * pixel
--------------------------------------------------—**
Definition: goom_core.cpp:24
ClassicLogoDetector::searchForLogo
bool searchForLogo(MythCommFlagPlayer *player) override
Definition: ClassicLogoDetector.cpp:85
ClassicLogoDetector::m_logoMinX
unsigned int m_logoMinX
Definition: ClassicLogoDetector.h:53
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
ClassicLogoDetector::DetectEdges
void DetectEdges(MythVideoFrame *frame, EdgeMaskEntry *edges, int edgeDiff)
Definition: ClassicLogoDetector.cpp:449
ClassicLogoDetector::m_logoEdgeDiff
int m_logoEdgeDiff
Definition: ClassicLogoDetector.h:52
LogoDetectorBase::m_width
size_t m_width
Definition: LogoDetectorBase.h:31
ClassicLogoDetector::m_commDetectLogoBadEdgeThreshold
double m_commDetectLogoBadEdgeThreshold
Definition: ClassicLogoDetector.h:41
ClassicLogoDetector::m_commDetectLogoSampleSpacing
int m_commDetectLogoSampleSpacing
Definition: ClassicLogoDetector.h:35
hardwareprofile.config.p
p
Definition: config.py:33
ClassicLogoDetector::m_commDetectLogoMinPixels
int m_commDetectLogoMinPixels
Definition: ClassicLogoDetector.h:39
ClassicLogoDetector::deleteLater
virtual void deleteLater(void)
Definition: ClassicLogoDetector.cpp:79
ClassicCommDetector::m_preRoll
long long m_preRoll
Definition: ClassicCommDetector.h:199
MythCommFlagPlayer
Definition: mythcommflagplayer.h:25
EdgeMaskEntry::m_ldiag
int m_ldiag
Definition: ClassicLogoDetector.cpp:24
ClassicCommDetector::m_fullSpeed
bool m_fullSpeed
Definition: ClassicCommDetector.h:195
ClassicLogoDetector::getRequiredAvailableBufferForSearch
unsigned int getRequiredAvailableBufferForSearch() override
Definition: ClassicLogoDetector.cpp:74
ClassicCommDetector
Definition: ClassicCommDetector.h:47
ClassicLogoDetector::ClassicLogoDetector
ClassicLogoDetector(ClassicCommDetector *commDetector, unsigned int width, unsigned int height, unsigned int commdetectborder)
Definition: ClassicLogoDetector.cpp:28
LogoDetectorBase::m_height
size_t m_height
Definition: LogoDetectorBase.h:32
uint
unsigned int uint
Definition: compat.h:81
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
EdgeMaskEntry::m_isEdge
int m_isEdge
Definition: ClassicLogoDetector.cpp:20
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:912
LogoDetectorBase
Definition: LogoDetectorBase.h:9
MythVideoFrame::m_pitches
FramePitches m_pitches
Definition: mythframe.h:142
CommDetectorBase::m_bStop
bool m_bStop
Definition: CommDetectorBase.h:53
ClassicLogoDetector::m_logoCheckMask
unsigned char * m_logoCheckMask
Definition: ClassicLogoDetector.h:50
ClassicLogoDetector::~ClassicLogoDetector
~ClassicLogoDetector() override
Definition: ClassicLogoDetector.cpp:64
EdgeMaskEntry::m_vert
int m_vert
Definition: ClassicLogoDetector.cpp:22
ClassicLogoDetector::DumpLogo
void DumpLogo(bool fromCurrentFrame, const unsigned char *framePtr)
Definition: ClassicLogoDetector.cpp:324
EdgeMaskEntry::m_horiz
int m_horiz
Definition: ClassicLogoDetector.cpp:21
mythcorecontext.h
ClassicLogoDetector::m_logoMaxX
unsigned int m_logoMaxX
Definition: ClassicLogoDetector.h:54
ClassicLogoDetector::m_commDetectLogoHeightRatio
int m_commDetectLogoHeightRatio
Definition: ClassicLogoDetector.h:38
ClassicLogoDetector::m_logoMinY
unsigned int m_logoMinY
Definition: ClassicLogoDetector.h:55
ClassicLogoDetector::m_commDetectBorder
unsigned int m_commDetectBorder
Definition: ClassicLogoDetector.h:32
ClassicLogoDetector::m_frameNumber
unsigned int m_frameNumber
Definition: ClassicLogoDetector.h:31
ClassicLogoDetector::m_logoMinValues
unsigned char * m_logoMinValues
Definition: ClassicLogoDetector.h:47
MythVideoFrame
Definition: mythframe.h:88
ClassicLogoDetector::m_commDetectLogoSamplesNeeded
int m_commDetectLogoSamplesNeeded
Definition: ClassicLogoDetector.h:34
ClassicLogoDetector::m_logoInfoAvailable
bool m_logoInfoAvailable
Definition: ClassicLogoDetector.h:58
MythCommFlagPlayer::GetRawVideoFrame
MythVideoFrame * GetRawVideoFrame(long long FrameNumber=-1)
Returns a specific frame from the video.
Definition: mythcommflagplayer.cpp:226
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:898
MythVideoFrame::m_buffer
uint8_t * m_buffer
Definition: mythframe.h:120
MythPlayer::DiscardVideoFrame
void DiscardVideoFrame(MythVideoFrame *buffer)
Places frame in the available frames queue.
Definition: mythplayer.cpp:629