6#define LOC QString("DetectLetterbox: ")
33 unsigned char *buf =
Frame->m_buffer;
39 const int height =
Frame->m_height;
46 const int fullLimit =
static_cast<int>((height * (1 - VideoAspect * 9 / 16) / 2) *
m_detectLetterboxLimit / 100);
47 const int halfLimit =
static_cast<int>((height * (1 - VideoAspect * 9 / 14) / 2) *
m_detectLetterboxLimit / 100);
50 const std::array<int,3> xPos {
Frame->m_width / 4,
Frame->m_width / 2,
Frame->m_width * 3 / 4} ;
57 std::array<int,3> topHit = { 0, 0, 0 };
58 std::array<int,3> bottomHit = { 0, 0, 0 };
60 switch (
Frame->m_type)
74 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"'%1' frame format detected")
80 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"'%1' frame format is not supported")
86 if (
Frame->m_frameNumber < 0)
88 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Strange frame number %1").arg(
Frame->m_frameNumber));
92 if (VideoAspect > 1.5F)
96 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"The source is already in widescreen (aspect: %1)")
97 .arg(
static_cast<double>(VideoAspect)));
106 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"The source is already in widescreen (aspect: %1)")
107 .arg(
static_cast<double>(VideoAspect)));
116 averageY += buf[offsets[0] + (5 * pitches[0]) + pos];
117 averageY += buf[offsets[0] + ((height - 6) * pitches[0]) + pos];
127 int leftshift = depth > 8 ? 1 : 0;
128 int rightshift = depth > 8 ? 0 : 1;
131 for (
int y = 5; y < height / 4; y++)
135 int Y = buf[offsets[0] + (y * pitches[0]) + (xPos[detectionLine] << leftshift)];
140 U = buf[offsets[1] + ((y>>1) * pitches[1]) + (xPos[detectionLine] >> rightshift)];
141 V = buf[offsets[2] + ((y>>1) * pitches[2]) + (xPos[detectionLine] >> rightshift)];
145 int offset = offsets[1] + ((y >> 1) * pitches[1]) + (xPos[detectionLine & ~0x1] << leftshift);
147 V = buf[offset + (1 << leftshift)];
150 if ((!topHit[detectionLine]) &&
152 U < 128 - 32 || U > 128 + 32 ||
153 V < 128 - 32 || V > 128 + 32 ))
155 topHit[detectionLine] = y;
162 Y = buf[offsets[0] + ((height-y-1) * pitches[0]) + (xPos[detectionLine] << leftshift)];
165 U = buf[offsets[1] + (((height-y-1) >> 1) * pitches[1]) + (xPos[detectionLine] >> rightshift)];
166 V = buf[offsets[2] + (((height-y-1) >> 1) * pitches[2]) + (xPos[detectionLine] >> rightshift)];
170 int offset = offsets[1] + (((height - y -1) >> 1) * pitches[1]) + (xPos[detectionLine & ~0x1] << leftshift);
172 V = buf[offset + (1 << leftshift)];
175 if ((!bottomHit[detectionLine]) &&
177 U < 128 - 32 || U > 128 + 32 ||
178 V < 128 - 32 || V > 128 + 32 ))
180 bottomHit[detectionLine] = y;
197 maxBottom = height / 4;
199 minBottom = height / 4;
212 if (minTop < halfLimit || minBottom < halfLimit)
214 if (minTop < fullLimit || minBottom < fullLimit)
231 if (maxTop < halfLimit || maxBottom < halfLimit)
236 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Non Letterbox detected on line: %1 (limit: %2)")
237 .arg(std::min(maxTop, maxBottom)).arg(halfLimit));
247 else if (horizontal && minTop > halfLimit && minBottom > halfLimit &&
248 maxTop < fullLimit && maxBottom < fullLimit)
253 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Narrow Letterbox detected on line: %1 (limit: %2) frame: %3")
271 else if (horizontal && minTop > fullLimit && minBottom > fullLimit)
277 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Detected Letterbox on line: %1 (limit: %2) frame: %3")
301 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Switched to '%1' on frame %2 (%3)")
309 else if (m_detectLetterboxSwitchFrame <= Frame->m_frameNumber)
311 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Not Switched to '%1' on frame %2 "
312 "(%3) Not enough consecutive detections (%4)")
static constexpr int8_t HORIZONTAL_THRESHOLD
static constexpr int8_t NUMBER_OF_DETECTION_LINES
static constexpr int8_t THRESHOLD
int m_detectLetterboxLimit
void SetDetectLetterbox(bool Detect, AdjustFillMode Mode)
long long m_firstFrameChecked
bool Detect(MythVideoFrame *Frame, float VideoAspect, AdjustFillMode &Current)
Detects if this frame is or is not letterboxed.
VideoFrameType m_frameType
long long m_detectLetterboxPossibleFullFrame
AdjustFillMode m_detectLetterboxDetectedMode
long long m_detectLetterboxPossibleHalfFrame
On which frame was the mode switch detected.
long long m_detectLetterboxSwitchFrame
Which mode was last detected.
AdjustFillMode m_detectLetterboxDefaultMode
bool GetDetectLetterbox() const
int m_detectLetterboxConsecutiveCounter
int GetNumSetting(const QString &key, int defaultval=0)
static QString FormatDescription(VideoFrameType Type)
static bool FormatIs420(VideoFrameType Type)
static int ColorDepth(int Format)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
std::array< int, 3 > FrameOffsets
std::array< int, 3 > FramePitches
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
@ kAdjustFill_AutoDetect_DefaultOff