4 #include "libmythbase/mythconfig.h"
7 #include "libavcodec/avcodec.h"
29 if (m_debugLevel >= 1)
30 LOG(VB_COMMFLAG, LOG_INFO,
31 QString(
"BorderDetector debugLevel %1").arg(m_debugLevel));
37 m_timeReported =
false;
38 memset(&m_analyzeTime, 0,
sizeof(m_analyzeTime));
45 m_logoFinder = finder;
46 if (m_logoFinder ==
nullptr)
48 m_logo = m_logoFinder->
getTemplate(&m_logoRow, &m_logoCol,
49 &m_logoWidth, &m_logoHeight);
50 if (m_logo ==
nullptr)
52 LOG(VB_COMMFLAG, LOG_INFO,
53 QString(
"BorderDetector::setLogoState: %1x%2@(%3,%4)")
54 .arg(m_logoWidth).arg(m_logoHeight).arg(m_logoCol).arg(m_logoRow));
59 long long _frameno,
int *prow,
int *pcol,
int *pwidth,
int *pheight)
92 static constexpr
unsigned char kMaxRange = 32;
99 static constexpr
int kMaxLines = 2;
101 const int pgmwidth = pgm->linesize[0];
108 const int MAXOUTLIERS = pgmwidth * 12 / 1000;
114 const int VERTMARGIN = std::max(2, pgmheight * 1 / 60);
115 const int HORIZMARGIN = std::max(2, pgmwidth * 1 / 80);
122 const int VERTSLOP = std::max(kMaxLines, pgmheight * 1 / 120);
123 const int HORIZSLOP = std::max(kMaxLines, pgmwidth * 1 / 160);
125 int minrow = VERTMARGIN;
126 int mincol = HORIZMARGIN;
127 int maxrow1 = pgmheight - VERTMARGIN;
128 int maxcol1 = pgmwidth - HORIZMARGIN;
129 int newrow = minrow - 1;
130 int newcol = mincol - 1;
131 int newwidth = maxcol1 + 1 - mincol;
132 int newheight = maxrow1 + 1 - minrow;
136 auto start = nowAsDuration<std::chrono::microseconds>();
138 if (_frameno != kUncached && _frameno == m_frameNo)
145 uchar minval = UCHAR_MAX;
149 for (
int cc = mincol; cc < maxcol1; cc++)
153 for (
int rr = minrow; rr < maxrow1; rr++)
155 if (m_logo &&
rrccinrect(rr, cc, m_logoRow, m_logoCol,
156 m_logoWidth, m_logoHeight))
159 uchar val = pgm->data[0][(rr * pgmwidth) + cc];
160 int range = std::max(maxval, val) - std::min(minval, val) + 1;
161 if (range > kMaxRange)
163 if (outliers++ < MAXOUTLIERS)
166 if (lines++ < kMaxLines)
170 minval = std::min(val, minval);
171 maxval = std::max(val, maxval);
180 if (newcol != saved + 1 + HORIZSLOP)
182 newcol = std::min(maxcol1, saved + 1 + HORIZSLOP);
183 newwidth = std::max(0, maxcol1 - newcol);
188 goto monochromatic_frame;
199 for (
int cc = maxcol1 - 1; cc >= mincol; cc--)
203 for (
int rr = minrow; rr < maxrow1; rr++)
205 if (m_logo &&
rrccinrect(rr, cc, m_logoRow, m_logoCol,
206 m_logoWidth, m_logoHeight))
209 uchar val = pgm->data[0][(rr * pgmwidth) + cc];
210 int range = std::max(maxval, val) - std::min(minval, val) + 1;
211 if (range > kMaxRange)
213 if (outliers++ < MAXOUTLIERS)
216 if (lines++ < kMaxLines)
220 minval = std::min(val, minval);
221 maxval = std::max(val, maxval);
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++)
256 if (m_logo &&
rrccinrect(rr, cc, m_logoRow, m_logoCol,
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)
271 minval = std::min(val, minval);
272 maxval = std::max(val, maxval);
281 if (newrow != saved + 1 + VERTSLOP)
283 newrow = std::min(maxrow1, saved + 1 + VERTSLOP);
284 newheight = std::max(0, maxrow1 - newrow);
289 goto monochromatic_frame;
297 for (
int rr = maxrow1 - 1; rr >= minrow; rr--)
301 for (
int cc = mincol; cc < maxcol1; cc++)
303 if (m_logo &&
rrccinrect(rr, cc, m_logoRow, m_logoCol,
304 m_logoWidth, m_logoHeight))
307 uchar val = pgm->data[0][(rr * pgmwidth) + cc];
308 int range = std::max(maxval, val) - std::min(minval, val) + 1;
309 if (range > kMaxRange)
311 if (outliers++ < MAXOUTLIERS)
314 if (lines++ < kMaxLines)
318 minval = std::min(val, minval);
319 maxval = std::max(val, maxval);
328 if (newheight != saved - minrow - VERTSLOP)
330 newheight = std::max(0, saved - minrow - VERTSLOP);
335 goto monochromatic_frame;
340 maxrow1 = minrow + newheight;
343 m_frameNo = _frameno;
347 m_height = newheight;
348 m_isMonochromatic =
false;
352 m_frameNo = _frameno;
356 m_height = newheight;
357 m_isMonochromatic =
true;
365 auto end = nowAsDuration<std::chrono::microseconds>();
366 m_analyzeTime += (end - start);
368 return m_isMonochromatic ? -1 : 0;
376 LOG(VB_COMMFLAG, LOG_INFO, QString(
"BD Time: analyze=%1s")
378 m_timeReported =
true;