MythTV  master
mythdisplaymode.cpp
Go to the documentation of this file.
1 // QT
2 #include <QStringList>
3 
4 // MythTV
5 #include "mythdisplaymode.h"
6 
7 // Std
8 #include <cmath>
9 
10 MythDisplayMode::MythDisplayMode(QSize Resolution, QSize PhysicalSize,
11  double AspectRatio, double RefreshRate)
12  : m_width(Resolution.width()),
13  m_height(Resolution.height()),
14  m_widthMM(PhysicalSize.width()),
15  m_heightMM(PhysicalSize.height())
16 {
18  if (RefreshRate > 0)
19  m_refreshRates.push_back(RefreshRate);
20 }
21 MythDisplayMode::MythDisplayMode(int Width, int Height, int MMWidth, int MMHeight,
22  double AspectRatio, double RefreshRate)
23  : m_width(Width),
24  m_height(Height),
25  m_widthMM(MMWidth),
26  m_heightMM(MMHeight)
27 {
29  if (RefreshRate > 0)
30  m_refreshRates.push_back(RefreshRate);
31 }
32 
34 {
35  if (m_width < Other.m_width)
36  return true;
37  if (m_height < Other.m_height)
38  return true;
39  return false;
40 }
41 
43 {
44  return m_width == Other.m_width && m_height == Other.m_height;
45 }
46 
48 {
50  m_aspect = -1.0;
51 }
52 
53 QSize MythDisplayMode::Resolution(void) const
54 {
55  return { m_width, m_height };
56 }
57 
58 int MythDisplayMode::Width(void) const
59 {
60  return m_width;
61 }
62 
63 int MythDisplayMode::Height(void) const
64 {
65  return m_height;
66 }
67 
68 int MythDisplayMode::WidthMM(void) const
69 {
70  return m_widthMM;
71 }
72 
74 {
75  return m_heightMM;
76 }
77 
78 const std::vector<double>& MythDisplayMode::RefreshRates(void) const
79 {
80  return m_refreshRates;
81 }
82 
84 {
85  if (m_aspect <= 0.0)
86  {
87  if (0 == m_heightMM)
88  return 1.0;
89  return static_cast<double>(m_widthMM) / m_heightMM;
90  }
91  return m_aspect;
92 }
93 
95 {
96  if (!m_refreshRates.empty())
97  return m_refreshRates[0];
98  return 0.0;
99 }
100 
101 void MythDisplayMode::SetAspectRatio(double AspectRatio)
102 {
103  if (AspectRatio > 0.0)
105  else if (HeightMM())
106  m_aspect = static_cast<double>(m_widthMM) / m_heightMM;
107 }
108 
110 {
111  m_refreshRates.push_back(Rate);
112  std::sort(m_refreshRates.begin(), m_refreshRates.end());
113 }
114 
116 {
117  m_refreshRates.clear();
118 }
119 
121 {
123  AddRefreshRate(Rate);
124 }
125 
126 uint64_t MythDisplayMode::CalcKey(QSize Size, double Rate)
127 {
128  return (static_cast<uint64_t>(Size.width()) << 34) |
129  (static_cast<uint64_t>(Size.height()) << 18) |
130  (static_cast<uint64_t>(Rate * 1000.0));
131 }
132 
134 bool MythDisplayMode::CompareRates(double First, double Second, double Precision)
135 {
136  return qAbs(First - Second) < Precision;
137 }
138 
139 int MythDisplayMode::FindBestMatch(const vector<MythDisplayMode>& Modes,
140  const MythDisplayMode& Mode, double &TargetRate)
141 {
142  double videorate = Mode.RefreshRate();
143  bool rate2x = false;
144  bool end = false;
145 
146  // We will give priority to refresh rates that are twice what is looked for
147  if ((videorate > 24.5) && (videorate < 30.5))
148  {
149  rate2x = true;
150  videorate *= 2.0;
151  }
152 
153  // Amend vector with custom list
154  for (size_t i = 0; i < Modes.size(); ++i)
155  {
156  if (Modes[i].Width() == Mode.Width() && Modes[i].Height() == Mode.Height())
157  {
158  auto rates = Modes[i].RefreshRates();
159  if (!rates.empty() && !qFuzzyCompare(videorate + 1.0, 1.0))
160  {
161  while (!end)
162  {
163  for (double precision : { 0.001, 0.01, 0.1 })
164  {
165  for (double rate : rates)
166  {
167  // Multiple of target_rate will do
168  if (CompareRates(videorate, rate, precision) ||
169  (qAbs(videorate - fmod(rate, videorate))
170  <= precision) ||
171  (fmod(rate,videorate) <= precision))
172  {
173  TargetRate = rate;
174  return static_cast<int>(i);
175  }
176  }
177  }
178  // Can't find exact frame rate, so try rounding to the
179  // nearest integer, so 23.97Hz will work with 24Hz etc
180  for (double precision : { 0.01, 0.1, 1.0 })
181  {
182  double rounded = round(videorate);
183  for (double rate : rates)
184  {
185  // Multiple of target_rate will do
186  if (CompareRates(rounded, rate, precision) ||
187  (qAbs(rounded - fmod(rate, rounded)) <= precision) ||
188  (fmod(rate,rounded) <= precision))
189  {
190  TargetRate = rate;
191  return static_cast<int>(i);
192  }
193  }
194  }
195  if (rate2x)
196  {
197  videorate /= 2.0;
198  rate2x = false;
199  }
200  else
201  {
202  end = true;
203  }
204  }
205  TargetRate = rates[rates.size() - 1];
206  }
207  else if (!rates.empty())
208  {
209  TargetRate = rates[rates.size() - 1];
210  }
211  return static_cast<int>(i);
212  }
213  }
214  return -1;
215 }
216 
217 #define extract_key(key) { \
218  rate = ((key) & ((1<<18) - 1)) / 1000.0; \
219  height = ((key) >> 18) & ((1<<16) - 1); \
220  width = ((key) >> 34) & ((1<<16) - 1); }
221 
223  int Width, int Height, double Rate)
224 {
225  int width = 0;
226  int height = 0;
227  double rate = 0.0;
228 
229  // 1. search for exact match (width, height, rate)
230  // 2. search for resolution, ignoring rate
231  // 3. search for matching height and rate (or any rate if rate = 0)
232  // 4. search for 2x rate
233  // 5. search for 1x rate
234 
235  for ( auto it = Map.cbegin(); it != Map.cend(); ++it)
236  {
237  extract_key(it->first);
238  if (width == Width && height == Height && CompareRates(Rate, rate, 0.01))
239  return it->first;
240  }
241  for (auto it = Map.cbegin(); it != Map.cend(); ++it)
242  {
243  extract_key(it->first);
244  if (width == Width && height == Height && qFuzzyCompare(rate + 1.0, 1.0))
245  return it->first;
246  }
247  for (auto it = Map.cbegin(); it != Map.cend(); ++it)
248  {
249  extract_key(it->first);
250  if ((width == 0 && height == Height &&
251  (CompareRates(Rate, rate, 0.01) || qFuzzyCompare(rate + 1.0, 1.0))) ||
252  (width == 0 && height == 0 && CompareRates(Rate, rate * 2.0, 0.01)) ||
253  (width == 0 && height == 0 && CompareRates(Rate, rate, 0.01)))
254  {
255  return it->first;
256  }
257  }
258 
259  return 0;
260 }
mythdisplaymode.h
MythDisplayMode::Init
void Init(void)
Definition: mythdisplaymode.cpp:47
MythDisplayMode::AddRefreshRate
void AddRefreshRate(double Rate)
Definition: mythdisplaymode.cpp:109
MythDisplayMode::FindBestScreen
static uint64_t FindBestScreen(const DisplayModeMap &Map, int Width, int Height, double Rate)
Definition: mythdisplaymode.cpp:222
MythDisplayMode::MythDisplayMode
MythDisplayMode()=default
MythDisplayMode::m_height
int m_height
Definition: mythdisplaymode.h:54
MythDisplayMode::CalcKey
static uint64_t CalcKey(QSize Size, double Rate)
Definition: mythdisplaymode.cpp:126
MythDisplayMode::m_width
int m_width
Definition: mythdisplaymode.h:53
MythDisplayMode::Width
int Width(void) const
Definition: mythdisplaymode.cpp:58
DisplayModeMap
map< uint64_t, MythDisplayMode > DisplayModeMap
Definition: mythdisplaymode.h:19
MythDisplayMode::Resolution
QSize Resolution(void) const
Definition: mythdisplaymode.cpp:53
MythDisplayMode::HeightMM
int HeightMM(void) const
Definition: mythdisplaymode.cpp:73
MythDisplayMode::m_aspect
double m_aspect
Definition: mythdisplaymode.h:57
MythDisplayMode::RefreshRates
const std::vector< double > & RefreshRates(void) const
Definition: mythdisplaymode.cpp:78
MythDisplayMode::operator==
bool operator==(const MythDisplayMode &Other) const
Definition: mythdisplaymode.cpp:42
MythDisplayMode::AspectRatio
double AspectRatio(void) const
Definition: mythdisplaymode.cpp:83
MythDisplayMode::ClearRefreshRates
void ClearRefreshRates(void)
Definition: mythdisplaymode.cpp:115
MythDisplayMode::SetAspectRatio
void SetAspectRatio(double AspectRatio)
Definition: mythdisplaymode.cpp:101
MythDisplayMode::m_heightMM
int m_heightMM
Definition: mythdisplaymode.h:56
MythDisplayMode::Height
int Height(void) const
Definition: mythdisplaymode.cpp:63
extract_key
#define extract_key(key)
Definition: mythdisplaymode.cpp:217
MythDisplayMode
Definition: mythdisplaymode.h:22
MythDisplayMode::m_widthMM
int m_widthMM
Definition: mythdisplaymode.h:55
MythDisplayMode::FindBestMatch
static int FindBestMatch(const vector< MythDisplayMode > &Modes, const MythDisplayMode &Mode, double &TargetRate)
Definition: mythdisplaymode.cpp:139
MythDisplayMode::WidthMM
int WidthMM(void) const
Definition: mythdisplaymode.cpp:68
MythDisplayMode::m_refreshRates
vector< double > m_refreshRates
Definition: mythdisplaymode.h:58
MythDisplayMode::SetRefreshRate
void SetRefreshRate(double Rate)
Definition: mythdisplaymode.cpp:120
MythDisplayMode::RefreshRate
double RefreshRate(void) const
Definition: mythdisplaymode.cpp:94
MythDisplayMode::CompareRates
static bool CompareRates(double First, double Second, double Precision=0.01)
Determine whether two rates are considered equal with the given precision.
Definition: mythdisplaymode.cpp:134
round
#define round(x)
Definition: mythplayer.cpp:64
MythDisplayMode::operator<
bool operator<(const MythDisplayMode &Other) const
Definition: mythdisplaymode.cpp:33