MythTV  master
mythvideoscantracker.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "mythlogging.h"
3 #include "mythframe.h"
4 #include "mythavutil.h"
5 #include "mythplayerui.h"
6 #include "mythvideoout.h"
7 #include "mythvideoscantracker.h"
8 
9 #define LOC QString("ScanTracker: ")
10 
12  : m_parentPlayer(Parent)
13 {
14 }
15 
17 {
18  // Default to interlaced playback but set the tracker to progressive
19  // Enable autodetection of interlaced/progressive from video stream
20  // Previously we set to interlaced and the scan tracker to 2 but this
21  // mis-'detected' a number of streams as interlaced when they are progressive.
22  // This significantly reduces the number of errors and also ensures we do not
23  // needlessly setup deinterlacers - which may consume significant resources.
24  // We set to interlaced for those streams whose frame rate is initially detected
25  // as e.g. 59.9 when it is actually 29.97 interlaced.
27  m_scanLocked = false;
28  m_scanTracker = -2;
29  if (VideoOutput)
30  VideoOutput->SetDeinterlacing(true, m_parentPlayer->CanSupportDoubleRate());
31 }
32 
34 {
35  m_scanInitialized = false;
36  m_scanLocked = false;
37 }
38 
40 {
41  m_scanLocked = false;
42  m_scanTracker = (m_scan == kScan_Interlaced) ? 2 : 0;
43 }
44 
46 {
47  int next = m_scanOverride + 1;
48  if (next > kScan_Progressive)
49  next = kScan_Detect;
50  return static_cast<FrameScanType>(next);
51 }
52 
54 {
55  if (m_scanOverride == Scan)
56  return;
57 
58  m_scanOverride = Scan;
60  {
61  m_scanLocked = false;
62  m_scanInitialized = false;
63  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Reverting to auto detection of scan");
64  }
65 }
66 
68 {
69  if (!Frame)
70  return kScan_Progressive;
71 
72  // Update details for debug OSD
73  m_lastDeinterlacer = Frame->m_deinterlaceInuse;
74  m_lastDeinterlacer2x = Frame->m_deinterlaceInuse2x;
75  // We use the underlying pix_fmt as it retains the distinction between hardware
76  // and software frames for decode only decoders.
77  m_lastFrameCodec = MythAVUtil::PixelFormatToFrameType(static_cast<AVPixelFormat>(Frame->m_pixFmt));
78 
79  // Decide on type and rate
80  FrameScanType result = m_scan;
81  if ((kScan_Detect == m_scan) || (kScan_Ignore == m_scan) || Frame->m_alreadyDeinterlaced)
82  {
83  result = kScan_Progressive;
84  }
85  else if (is_interlaced(m_scan))
86  {
87  result = kScan_Interlaced;
88  Frame->m_interlacedReverse = (m_scan == kScan_Intr2ndField);
89  }
90 
91  // Only display the second field if needed.
92  // This is somewhat circular - we check for double rate support when enabling
93  // deinterlacing, request that in the video buffers and the differing implementations
94  // then set m_lastDeinterlacer2x when they are actually using double rate
95  SecondField = is_interlaced(result) && m_lastDeinterlacer2x;
96  return result;
97 }
98 
100 {
101  return m_scan;
102 }
103 
105 {
107  return m_scanOverride;
108  return m_scan;
109 }
110 
112 {
113  if (m_resetScan != kScan_Ignore)
114  SetScanType(m_resetScan, VideoOutput, FrameInterval);
115 }
116 
118 {
120 }
121 
123 {
125  {
126  m_resetScan = Scan;
127  return;
128  }
129 
130  if (!VideoOutput)
131  return;
132 
134 
135  if (m_scanInitialized && (m_scan == Scan) && (m_lastFrameInterval == FrameInterval))
136  return;
137 
138  m_scanLocked = (Scan != kScan_Detect);
139  m_scanInitialized = true;
140  m_lastFrameInterval = FrameInterval;
141 
142  if (is_interlaced(Scan))
143  {
144  float currentspeed = m_parentPlayer->GetPlaySpeed();
145  bool normal = (currentspeed > 0.99F) && (currentspeed < 1.01F) && m_parentPlayer->AtNormalSpeed();
146  VideoOutput->SetDeinterlacing(true, m_parentPlayer->CanSupportDoubleRate() && normal);
147  }
148  else if (kScan_Progressive == Scan)
149  {
150  VideoOutput->SetDeinterlacing(false, false);
151  }
152 
153  m_scan = Scan;
154 }
155 
177  int FrameInterval, bool AllowLock)
178 {
179  if (!Frame)
180  return;
181 
183  {
184  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Locking scan override to '%1'")
186  SetScanType(m_scanOverride, VideoOutput, FrameInterval);
187  }
188 
189  // This is currently only signalled for H264 content
190  if (Frame->m_newGOP)
191  {
193  ((Frame->m_interlaced && !is_interlaced(m_scan)) ||
194  (!Frame->m_interlaced && is_interlaced(m_scan))))
195  {
196  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Unlocking frame scan");
197  m_scanLocked = false;
198  }
199  }
200 
201  if (m_scanLocked)
202  return;
203 
204  if (Frame->m_interlaced)
205  {
206  if (m_scanTracker < 0)
207  {
208  LOG(VB_PLAYBACK, LOG_INFO, LOC +
209  QString("Interlaced frame seen after %1 progressive frames")
210  .arg(abs(m_scanTracker)));
211  m_scanTracker = 2;
212  if (AllowLock)
213  {
214  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Locking scan to Interlaced.");
215  SetScanType(kScan_Interlaced, VideoOutput, FrameInterval);
216  return;
217  }
218  }
219  m_scanTracker++;
220  }
221  else
222  {
223  if (m_scanTracker > 0)
224  {
225  LOG(VB_PLAYBACK, LOG_INFO, LOC +
226  QString("Progressive frame seen after %1 interlaced frames")
227  .arg(m_scanTracker));
228  m_scanTracker = 0;
229  }
230  m_scanTracker--;
231  }
232 
233  int min_count = !AllowLock ? 0 : 2;
234  if (abs(m_scanTracker) <= min_count)
235  return;
236 
238  VideoOutput, FrameInterval);
239  m_scanLocked = false;
240 }
241 
243 {
245  QString dbg = QString("DetectInterlace(") + ScanTypeToString(NewScan) +
246  QString(", ") + ScanTypeToString(scan) + QString(", ") +
247  QString("%1").arg(static_cast<double>(Rate)) + QString(", ") +
248  QString("%1").arg(VideoHeight) + QString(") ->");
249 
250  if (kScan_Ignore != NewScan || kScan_Detect == scan)
251  {
252  // The scanning mode should be decoded from the stream - otherwise guess
253  // default to interlaced
255  // 720P, outside interlaced frame rates or too large for interlaced
256  if ((720 == VideoHeight) || (Rate < 25) || (Rate > 30) || (VideoHeight > 1080))
258  if (kScan_Detect != NewScan)
259  scan = NewScan;
260  }
261 
262  LOG(VB_PLAYBACK, LOG_INFO, LOC + dbg + ScanTypeToString(scan));
263  return scan;
264 }
MythVideoScanTracker::m_scanInitialized
bool m_scanInitialized
Definition: mythvideoscantracker.h:43
MythVideoScanTracker::AutoDeint
virtual void AutoDeint(MythVideoFrame *Frame, MythVideoOutput *VideoOutput, int FrameInterval, bool AllowLock=true)
Check whether deinterlacing should be enabled.
Definition: mythvideoscantracker.cpp:176
MythPlayer::AtNormalSpeed
bool AtNormalSpeed(void) const
Definition: mythplayer.h:157
ScanTypeToUserString
QString ScanTypeToUserString(FrameScanType Scan, bool Forced=false)
Definition: videoouttypes.h:198
MythVideoOutput
Definition: mythvideoout.h:35
mythvideoout.h
kScan_Detect
@ kScan_Detect
Definition: videoouttypes.h:97
VideoOutput
This class serves as the base class for all video output methods.
mythplayerui.h
MythVideoScanTracker::m_scan
FrameScanType m_scan
Definition: mythvideoscantracker.h:40
MythVideoScanTracker::m_lastFrameInterval
int m_lastFrameInterval
Definition: mythvideoscantracker.h:44
Frame
Definition: zmdefines.h:93
MythVideoScanTracker::m_scanOverride
FrameScanType m_scanOverride
Definition: mythvideoscantracker.h:41
MythVideoScanTracker::NextScanOverride
FrameScanType NextScanOverride()
Definition: mythvideoscantracker.cpp:45
arg
arg(title).arg(filename).arg(doDelete))
FrameScanType
FrameScanType
Definition: videoouttypes.h:94
MythVideoScanTracker::m_lastFrameCodec
VideoFrameType m_lastFrameCodec
Definition: mythvideoscantracker.h:47
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
is_current_thread
bool is_current_thread(MThread *thread)
Use this to determine if you are in the named thread.
Definition: mthread.cpp:40
mythframe.h
MythVideoScanTracker::m_resetScan
FrameScanType m_resetScan
Definition: mythvideoscantracker.h:39
hardwareprofile.scan.scan
def scan(profile, smoonURL, gate)
Definition: scan.py:57
MythVideoScanTracker::m_lastDeinterlacer
MythDeintType m_lastDeinterlacer
Definition: mythvideoscantracker.h:46
MythPlayer::GetPlaySpeed
float GetPlaySpeed(void) const
Definition: mythplayer.h:138
MythVideoScanTracker::DetectInterlace
FrameScanType DetectInterlace(FrameScanType NewScan, float Rate, int VideoHeight)
Definition: mythvideoscantracker.cpp:242
MythPlayerUI
Definition: mythplayerui.h:10
kScan_Intr2ndField
@ kScan_Intr2ndField
Definition: videoouttypes.h:99
MythVideoScanTracker::m_parentPlayer
MythPlayerUI * m_parentPlayer
Definition: mythvideoscantracker.h:37
mythlogging.h
kScan_Progressive
@ kScan_Progressive
Definition: videoouttypes.h:100
MythVideoScanTracker::m_scanLocked
bool m_scanLocked
Definition: mythvideoscantracker.h:42
mythvideoscantracker.h
ScanTypeToString
QString ScanTypeToString(FrameScanType Scan)
Definition: videoouttypes.h:211
MythVideoScanTracker::m_lastDeinterlacer2x
bool m_lastDeinterlacer2x
Definition: mythvideoscantracker.h:45
MythVideoScanTracker::GetScanForDisplay
FrameScanType GetScanForDisplay(MythVideoFrame *Frame, bool &SecondField)
Definition: mythvideoscantracker.cpp:67
MythVideoScanTracker::SetScanType
void SetScanType(FrameScanType Scan, MythVideoOutput *VideoOutput, int FrameInterval)
Definition: mythvideoscantracker.cpp:122
LOC
#define LOC
Definition: mythvideoscantracker.cpp:9
MythAVUtil::PixelFormatToFrameType
static VideoFrameType PixelFormatToFrameType(AVPixelFormat Fmt)
Definition: mythavutil.cpp:70
MythVideoScanTracker::MythVideoScanTracker
MythVideoScanTracker(MythPlayerUI *Parent)
Definition: mythvideoscantracker.cpp:11
MythVideoScanTracker::InitialiseScan
void InitialiseScan(MythVideoOutput *VideoOutput)
Definition: mythvideoscantracker.cpp:16
MythVideoScanTracker::SetScanOverride
void SetScanOverride(FrameScanType Scan)
Definition: mythvideoscantracker.cpp:53
kScan_Interlaced
@ kScan_Interlaced
Definition: videoouttypes.h:98
MythVideoFrame::DeinterlacerName
static QString DeinterlacerName(MythDeintType Deint, bool DoubleRate, VideoFrameType Format=FMT_NONE)
Definition: mythframe.cpp:462
MythVideoScanTracker::CheckScanUpdate
void CheckScanUpdate(MythVideoOutput *VideoOutput, int FrameInterval)
Definition: mythvideoscantracker.cpp:111
mythavutil.h
MythVideoScanTracker::GetScanTypeWithOverride
FrameScanType GetScanTypeWithOverride() const
Definition: mythvideoscantracker.cpp:104
MythVideoScanTracker::GetDeinterlacerName
QString GetDeinterlacerName()
Definition: mythvideoscantracker.cpp:117
MythVideoFrame
Definition: mythframe.h:87
MythVideoScanTracker::ResetTracker
void ResetTracker()
Definition: mythvideoscantracker.cpp:39
MythVideoScanTracker::m_scanTracker
long long m_scanTracker
Definition: mythvideoscantracker.h:38
MythVideoScanTracker::GetScanType
FrameScanType GetScanType() const
Definition: mythvideoscantracker.cpp:99
MythVideoScanTracker::m_mainThread
QThread * m_mainThread
Definition: mythvideoscantracker.h:49
MythVideoScanTracker::UnlockScan
void UnlockScan()
Definition: mythvideoscantracker.cpp:33
MythPlayerUI::CanSupportDoubleRate
bool CanSupportDoubleRate()
Definition: mythplayerui.cpp:790
is_interlaced
bool is_interlaced(FrameScanType Scan)
Definition: videoouttypes.h:188
kScan_Ignore
@ kScan_Ignore
Definition: videoouttypes.h:96