5 #define LOC QString("DetectLetterbox: ")
7 #define NUMBER_OF_DETECTION_LINES 3 // How many lines are we looking at
8 #define THRESHOLD 5 // Y component has to not vary more than this in the bars
9 #define HORIZONTAL_THRESHOLD 4 // How tolerant are we that the image has horizontal edges
32 unsigned char *buf =
Frame->m_buffer;
35 const int height =
Frame->m_height;
42 const int fullLimit =
static_cast<int>((height * (1 - VideoAspect * 9 / 16) / 2) *
m_detectLetterboxLimit / 100);
43 const int halfLimit =
static_cast<int>((height * (1 - VideoAspect * 9 / 14) / 2) *
m_detectLetterboxLimit / 100);
46 const std::array<int,3> xPos {
Frame->m_width / 4,
Frame->m_width / 2,
Frame->m_width * 3 / 4} ;
53 std::array<int,3> topHit = { 0, 0, 0 };
54 std::array<int,3> bottomHit = { 0, 0, 0 };
56 switch (
Frame->m_type)
70 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"'%1' frame format detected")
76 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"'%1' frame format is not supported")
82 if (
Frame->m_frameNumber < 0)
84 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Strange frame number %1").arg(
Frame->m_frameNumber));
88 if (VideoAspect > 1.5F)
92 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"The source is already in widescreen (aspect: %1)")
93 .arg(
static_cast<double>(VideoAspect)));
102 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"The source is already in widescreen (aspect: %1)")
103 .arg(
static_cast<double>(VideoAspect)));
112 averageY += buf[offsets[0] + 5 * pitches[0] + pos];
113 averageY += buf[offsets[0] + (height - 6) * pitches[0] + pos];
123 int leftshift = depth > 8 ? 1 : 0;
124 int rightshift = depth > 8 ? 0 : 1;
127 for (
int y = 5; y < height / 4; y++)
131 int Y = buf[offsets[0] + y * pitches[0] + (xPos[detectionLine] << leftshift)];
136 U = buf[offsets[1] + (y>>1) * pitches[1] + (xPos[detectionLine] >> rightshift)];
137 V = buf[offsets[2] + (y>>1) * pitches[2] + (xPos[detectionLine] >> rightshift)];
141 int offset = offsets[1] + ((y >> 1) * pitches[1]) + (xPos[detectionLine & ~0x1] << leftshift);
143 V = buf[offset + (1 << leftshift)];
146 if ((!topHit[detectionLine]) &&
148 U < 128 - 32 || U > 128 + 32 ||
149 V < 128 - 32 || V > 128 + 32 ))
151 topHit[detectionLine] = y;
158 Y = buf[offsets[0] + (height-y-1) * pitches[0] + (xPos[detectionLine] << leftshift)];
161 U = buf[offsets[1] + ((height-y-1) >> 1) * pitches[1] + (xPos[detectionLine] >> rightshift)];
162 V = buf[offsets[2] + ((height-y-1) >> 1) * pitches[2] + (xPos[detectionLine] >> rightshift)];
166 int offset = offsets[1] + (((height - y -1) >> 1) * pitches[1]) + (xPos[detectionLine & ~0
x1] << leftshift);
168 V = buf[offset + (1 << leftshift)];
171 if ((!bottomHit[detectionLine]) &&
173 U < 128 - 32 || U > 128 + 32 ||
174 V < 128 - 32 || V > 128 + 32 ))
176 bottomHit[detectionLine] = y;
193 maxBottom = height / 4;
195 minBottom = height / 4;
208 if (minTop < halfLimit || minBottom < halfLimit)
210 if (minTop < fullLimit || minBottom < fullLimit)
227 if (maxTop < halfLimit || maxBottom < halfLimit)
232 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Non Letterbox detected on line: %1 (limit: %2)")
233 .arg(std::min(maxTop, maxBottom)).arg(halfLimit));
243 else if (horizontal && minTop > halfLimit && minBottom > halfLimit &&
244 maxTop < fullLimit && maxBottom < fullLimit)
249 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Narrow Letterbox detected on line: %1 (limit: %2) frame: %3")
267 else if (horizontal && minTop > fullLimit && minBottom > fullLimit)
273 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Detected Letterbox on line: %1 (limit: %2) frame: %3")
297 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Switched to '%1' on frame %2 (%3)")
305 else if (m_detectLetterboxSwitchFrame <= Frame->m_frameNumber)
307 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Not Switched to '%1' on frame %2 "
308 "(%3) Not enough consecutive detections (%4)")