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