3 #include "libmythbase/mythconfig.h"
6 #include "libavcodec/avcodec.h"
27 if (m_debugLevel >= 1)
28 LOG(VB_COMMFLAG, LOG_INFO,
29 QString(
"BorderDetector debugLevel %1").arg(m_debugLevel));
36 m_timeReported =
false;
37 memset(&m_analyzeTime, 0,
sizeof(m_analyzeTime));
44 if ((m_logoFinder = finder) && (m_logo = m_logoFinder->getTemplate(
45 &m_logoRow, &m_logoCol, &m_logoWidth, &m_logoHeight)))
47 LOG(VB_COMMFLAG, LOG_INFO,
48 QString(
"BorderDetector::setLogoState: %1x%2@(%3,%4)")
49 .arg(m_logoWidth).arg(m_logoHeight).arg(m_logoCol).arg(m_logoRow));
55 long long _frameno,
int *prow,
int *pcol,
int *pwidth,
int *pheight)
88 static constexpr
unsigned char kMaxRange = 32;
95 static constexpr
int kMaxLines = 2;
97 const int pgmwidth = pgm->linesize[0];
104 const int MAXOUTLIERS = pgmwidth * 12 / 1000;
110 const int VERTMARGIN = std::max(2, pgmheight * 1 / 60);
111 const int HORIZMARGIN = std::max(2, pgmwidth * 1 / 80);
118 const int VERTSLOP = std::max(kMaxLines, pgmheight * 1 / 120);
119 const int HORIZSLOP = std::max(kMaxLines, pgmwidth * 1 / 160);
121 int minrow = VERTMARGIN;
122 int mincol = HORIZMARGIN;
123 int maxrow1 = pgmheight - VERTMARGIN;
124 int maxcol1 = pgmwidth - HORIZMARGIN;
125 int newrow = minrow - 1;
126 int newcol = mincol - 1;
127 int newwidth = maxcol1 + 1 - mincol;
128 int newheight = maxrow1 + 1 - minrow;
132 auto start = nowAsDuration<std::chrono::microseconds>();
134 if (_frameno != kUncached && _frameno == m_frameNo)
141 uchar minval = UCHAR_MAX;
145 for (
int cc = mincol;
cc < maxcol1;
cc++)
149 for (
int rr = minrow; rr < maxrow1; rr++)
152 m_logoWidth, m_logoHeight))
155 uchar val = pgm->data[0][rr * pgmwidth +
cc];
156 int range = std::max(maxval, val) - std::min(minval, val) + 1;
157 if (range > kMaxRange)
159 if (outliers++ < MAXOUTLIERS)
162 if (lines++ < kMaxLines)
178 if (newcol != saved + 1 + HORIZSLOP)
180 newcol = std::min(maxcol1, saved + 1 + HORIZSLOP);
181 newwidth = std::max(0, maxcol1 - newcol);
186 goto monochromatic_frame;
197 for (
int cc = maxcol1 - 1;
cc >= mincol;
cc--)
201 for (
int rr = minrow; rr < maxrow1; rr++)
204 m_logoWidth, m_logoHeight))
207 uchar val = pgm->data[0][rr * pgmwidth +
cc];
208 int range = std::max(maxval, val) - std::min(minval, val) + 1;
209 if (range > kMaxRange)
211 if (outliers++ < MAXOUTLIERS)
214 if (lines++ < kMaxLines)
230 if (newwidth != saved - mincol - HORIZSLOP)
232 newwidth = std::max(0, saved - mincol - HORIZSLOP);
237 goto monochromatic_frame;
242 maxcol1 = mincol + newwidth;
250 for (
int rr = minrow; rr < maxrow1; rr++)
254 for (
int cc = mincol;
cc < maxcol1;
cc++)
257 m_logoWidth, m_logoHeight))
260 uchar val = pgm->data[0][rr * pgmwidth +
cc];
261 int range = std::max(maxval, val) - std::min(minval, val) + 1;
262 if (range > kMaxRange)
264 if (outliers++ < MAXOUTLIERS)
267 if (lines++ < kMaxLines)
283 if (newrow != saved + 1 + VERTSLOP)
285 newrow = std::min(maxrow1, saved + 1 + VERTSLOP);
286 newheight = std::max(0, maxrow1 - newrow);
291 goto monochromatic_frame;
299 for (
int rr = maxrow1 - 1; rr >= minrow; rr--)
303 for (
int cc = mincol;
cc < maxcol1;
cc++)
306 m_logoWidth, m_logoHeight))
309 uchar val = pgm->data[0][rr * pgmwidth +
cc];
310 int range = std::max(maxval, val) - std::min(minval, val) + 1;
311 if (range > kMaxRange)
313 if (outliers++ < MAXOUTLIERS)
316 if (lines++ < kMaxLines)
332 if (newheight != saved - minrow - VERTSLOP)
334 newheight = std::max(0, saved - minrow - VERTSLOP);
339 goto monochromatic_frame;
344 maxrow1 = minrow + newheight;
347 m_frameNo = _frameno;
351 m_height = newheight;
352 m_isMonochromatic =
false;
356 m_frameNo = _frameno;
360 m_height = newheight;
361 m_isMonochromatic =
true;
369 auto end = nowAsDuration<std::chrono::microseconds>();
370 m_analyzeTime += (end - start);
372 return m_isMonochromatic ? -1 : 0;
380 LOG(VB_COMMFLAG, LOG_INFO, QString(
"BD Time: analyze=%1s")
382 m_timeReported =
true;