MythTV  master
mythedid.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "mythlogging.h"
3 #include "mythedid.h"
4 
5 // Qt
6 #include <QObject>
7 
8 // Std
9 #include <cmath>
10 
11 #define DESCRIPTOR_ALPHANUMERIC_STRING 0xFE
12 #define DESCRIPTOR_PRODUCT_NAME 0xFC
13 #define DESCRIPTOR_RANGE_LIMITS 0xFD
14 #define DESCRIPTOR_SERIAL_NUMBER 0xFF
15 #define DATA_BLOCK_OFFSET 0x36
16 #define SERIAL_OFFSET 0x0C
17 #define VERSION_OFFSET 0x12
18 #define DISPLAY_OFFSET 0x14
19 #define WIDTH_OFFSET 0x15
20 #define HEIGHT_OFFSET 0x16
21 #define GAMMA_OFFSET 0x17
22 #define FEATURES_OFFSET 0x18
23 #define EXTENSIONS_OFFSET 0x7E
24 
25 #define LOC QString("EDID: ")
26 
27 MythEDID::MythEDID(QByteArray Data)
28  : m_data(std::move(Data))
29 {
30  Parse();
31 }
32 
33 MythEDID::MythEDID(const char* Data, int Length)
34  : m_data(Data, Length)
35 {
36  Parse();
37 }
38 
39 bool MythEDID::Valid() const
40 {
41  return m_valid;
42 }
43 
44 QStringList MythEDID::SerialNumbers() const
45 {
46  return m_serialNumbers;
47 }
48 
49 QSize MythEDID::DisplaySize() const
50 {
51  return m_displaySize;
52 }
53 
55 {
56  return m_displayAspect;
57 }
58 
60 {
61  return m_physicalAddress;
62 }
63 
64 float MythEDID::Gamma() const
65 {
66  return m_gamma;
67 }
68 
69 bool MythEDID::IsHDMI() const
70 {
71  return m_isHDMI;
72 }
73 
74 bool MythEDID::IsSRGB() const
75 {
76  return m_sRGB;
77 }
78 
80 {
81  return m_likeSRGB;
82 }
83 
85 {
86  return m_primaries;
87 }
88 
89 int MythEDID::AudioLatency(bool Interlaced) const
90 {
91  return m_audioLatency[Interlaced ? 1 : 0];
92 }
93 
94 int MythEDID::VideoLatency(bool Interlaced) const
95 {
96  return m_videoLatency[Interlaced ? 1 : 0];
97 }
98 
100 {
102 }
103 
114 {
115  if (m_valid && m_vrrMin && m_vrrMax)
116  return { m_vrrMin, m_vrrMax, true };
117  if (m_valid && m_vrangeMin && m_vrangeMax)
118  return { m_vrangeMin, m_vrangeMax, false };
119  return { 0, 0, false };
120 }
121 
122 // from QEdidParser
123 static QString ParseEdidString(const quint8* data, bool Replace)
124 {
125  QByteArray buffer(reinterpret_cast<const char *>(data), 13);
126 
127  // Erase carriage return and line feed
128  buffer = buffer.replace('\r', '\0').replace('\n', '\0');
129 
130  // Replace non-printable characters with dash
131  // Earlier versions of QEdidParser got this wrong - so we potentially get
132  // different values for serialNumber from QScreen
133  if (Replace)
134  {
135  for (int i = 0; i < buffer.count(); ++i) {
136  if (buffer[i] < '\040' || buffer[i] > '\176')
137  buffer[i] = '-';
138  }
139  }
140  return QString::fromLatin1(buffer.trimmed());
141 }
142 
144 {
145  // This is adapted from various sources including QEdidParser, edid-decode and xrandr
146  if (!m_data.constData() || m_data.isEmpty())
147  {
148  LOG(VB_GENERAL, LOG_DEBUG, LOC + "Invalid EDID");
149  return;
150  }
151 
152  m_size = static_cast<uint>(m_data.size());
153  const auto *data = reinterpret_cast<const quint8 *>(m_data.constData());
154 
155  // EDID data should be in 128 byte blocks
156  if ((m_size % 0x80) || data[0] != 0x00 || data[1] != 0xff)
157  {
158  LOG(VB_GENERAL, LOG_DEBUG, LOC + "Invalid EDID");
159  return;
160  }
161 
162  // checksum
163  // NOLINTNEXTLINE(modernize-use-transparent-functors)
164  if (auto sum = std::accumulate(m_data.cbegin(), m_data.cend(), 0, std::plus<char>()); (sum % 0xff) != 0)
165  {
166  LOG(VB_GENERAL, LOG_INFO, LOC + "Checksum error");
167  return;
168  }
169 
170  if (!ParseBaseBlock(data))
171  return;
172 
173  // Look at extension blocks
174  uint extensions = data[EXTENSIONS_OFFSET];
175  uint available = (m_size / 128) - 1;
176  if (extensions != available)
177  {
178  LOG(VB_GENERAL, LOG_WARNING, LOC + "Extension count error");
179  return;
180  }
181 
182  if (extensions < 1)
183  return;
184 
185  LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("EDID has %1 extension blocks").arg(extensions));
186  for (uint i = 1; i <= available; ++i)
187  {
188  uint offset = i * 128;
189  switch (data[offset])
190  {
191  case 0x02: m_valid &= ParseCTA861(data, offset); break;
192  default: continue;
193  }
194  }
195 }
196 
197 bool MythEDID::ParseBaseBlock(const quint8* Data)
198 {
199  // retrieve version
200  if (Data[VERSION_OFFSET] != 1)
201  {
202  LOG(VB_GENERAL, LOG_DEBUG, LOC + "Unknown major version number");
203  return false;
204  }
205  m_minorVersion = Data[VERSION_OFFSET + 1];
206 
207  // retrieve serial number. This may be subsequently overridden.
208  // N.B. 0 is a valid serial number.
209  qint32 serial = Data[SERIAL_OFFSET] +
210  (Data[SERIAL_OFFSET + 1] << 8) +
211  (Data[SERIAL_OFFSET + 2] << 16) +
212  (Data[SERIAL_OFFSET + 3] << 24);
213  m_serialNumbers << QString::number(serial);
214 
215  // digital or analog
216  //bool digital = Data[DISPLAY_OFFSET] & 0x80;
217 
218  // Display size
219  if (Data[WIDTH_OFFSET] && Data[HEIGHT_OFFSET])
220  {
221  m_displaySize = QSize(Data[WIDTH_OFFSET] * 10, Data[HEIGHT_OFFSET] * 10);
222  }
223  else if (m_minorVersion >= 4 && (Data[WIDTH_OFFSET] || Data[HEIGHT_OFFSET]))
224  {
225  if (Data[WIDTH_OFFSET])
226  m_displayAspect = 100.0 / (Data[HEIGHT_OFFSET] + 99); // Landscape
227  else
228  m_displayAspect = 100.0 / (Data[WIDTH_OFFSET] + 99); // Portrait
229  }
230 
231  // retrieve gamma
232  quint8 gamma = Data[GAMMA_OFFSET];
233  if (gamma == 0xFF)
234  {
235  // for 1.4 - this means gamma is defined in an extension block
236  if (m_minorVersion < 4)
237  m_gamma = 1.0F;
238  }
239  else
240  {
241  m_gamma = (gamma + 100.0F) / 100.0F;
242  }
243 
244  // Chromaticity
245  // Note - the EDID format introduces slight rounding errors when converting
246  // to sRGB specs. If sRGB is set, the client should use the spec values - not
247  // the computed values
248  m_sRGB = ((Data[FEATURES_OFFSET] & 0x04) != 0);
249  static constexpr std::array<const uint8_t,10> s_sRGB =
250  { 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54 };
251  bool srgb = std::equal(s_sRGB.cbegin(), s_sRGB.cend(), Data + 0x19);
252 
253  if (!m_sRGB && srgb)
254  m_sRGB = true;
255  else if (m_sRGB && !srgb)
256  LOG(VB_GENERAL, LOG_WARNING, LOC + "Chromaticity mismatch!");
257 
258  // Red
259  m_primaries.m_primaries[0][0] = ((Data[0x1B] << 2) | (Data[0x19] >> 6)) / 1024.0F;
260  m_primaries.m_primaries[0][1] = ((Data[0x1C] << 2) | ((Data[0x19] >> 4) & 3)) / 1024.0F;
261  // Green
262  m_primaries.m_primaries[1][0] = ((Data[0x1D] << 2) | ((Data[0x19] >> 2) & 3)) / 1024.0F;
263  m_primaries.m_primaries[1][1] = ((Data[0x1E] << 2) | (Data[0x19] & 3)) / 1024.0F;
264  // Blue
265  m_primaries.m_primaries[2][0] = ((Data[0x1F] << 2) | (Data[0x1A] >> 6)) / 1024.0F;
266  m_primaries.m_primaries[2][1] = ((Data[0x20] << 2) | ((Data[0x1A] >> 4) & 3)) / 1024.0F;
267  // White
268  m_primaries.m_whitePoint[0] = ((Data[0x21] << 2) | ((Data[0x1A] >> 2) & 3)) / 1024.0F;
269  m_primaries.m_whitePoint[1] = ((Data[0x22] << 2) | (Data[0x1A] & 3)) / 1024.0F;
270 
271  // Check whether this is very similar to sRGB and hence if non-exact colourspace
272  // handling is preferred, then just use sRGB.
274  qFuzzyCompare(m_gamma + 1.0F, 2.20F + 1.0F);
275 
276  // Parse blocks
277  for (uint i = 0; i < 5; ++i)
278  {
279  uint offset = DATA_BLOCK_OFFSET + i * 18;
280  if (Data[offset] == 0 || Data[offset + 1] == 0 || Data[offset + 2] == 0)
281  ParseDisplayDescriptor(Data, offset);
282  else
283  ParseDetailedTimingDescriptor(Data, offset);
284  }
285 
286  // Set status
287  m_valid = std::any_of(m_serialNumbers.cbegin(), m_serialNumbers.cend(),
288  [](const QString& Serial) { return !Serial.isEmpty(); });
289  if (!m_valid)
290  LOG(VB_GENERAL, LOG_WARNING, LOC + "No serial number(s) in EDID");
291  return m_valid;
292 }
293 
294 void MythEDID::ParseDisplayDescriptor(const quint8* Data, uint Offset)
295 {
296  auto type = Data[Offset + 3];
297  auto offset = Offset + 5;
299  {
300  m_serialNumbers << ParseEdidString(&Data[offset], false);
301  m_serialNumbers << ParseEdidString(&Data[offset], true);
302  }
303  else if (DESCRIPTOR_PRODUCT_NAME == type)
304  {
305  m_name = ParseEdidString(&Data[offset], true);
306  }
307  else if (DESCRIPTOR_RANGE_LIMITS == type)
308  {
309  auto vminoffset = 0;
310  auto vmaxoffset = 0;
311  if (m_minorVersion > 3)
312  {
313  if (Data[Offset + 4] & 0x02)
314  {
315  vmaxoffset = 255;
316  if (Data[Offset + 4] & 0x01)
317  vminoffset = 255;
318  }
319  }
320  m_vrangeMin = Data[Offset + 5] + vminoffset;
321  m_vrangeMax = Data[Offset + 6] + vmaxoffset;
322  }
323 }
324 
325 void MythEDID::ParseDetailedTimingDescriptor(const quint8* Data, uint Offset)
326 {
327  // We're only really interested in a more accurate display size
328  auto width = Data[Offset + 12] + ((Data[Offset + 14] & 0xF0) << 4);
329  auto height = Data[Offset + 13] + ((Data[Offset + 14] & 0x0F) << 8);
330 
331  // 1.4 may have set an aspect ratio instead of size, otherwise use if this
332  // looks like a more accurate version of our current size
333  if (m_displaySize.isEmpty() ||
334  ((abs(m_displaySize.width() - width) < 10) && (abs(m_displaySize.height() - height) < 10)))
335  {
336  m_displaySize = { width, height };
337  }
338 }
339 
340 bool MythEDID::ParseCTA861(const quint8* Data, uint Offset)
341 {
342  if (Offset >= m_size)
343  return false;
344 
345  bool result = true;
346  quint8 version = Data[Offset + 1];
347  quint8 offset = Data[Offset + 2];
348 
349  if (offset < 4 || version != 3)
350  return result;
351 
352  for (uint i = Offset + 4; (i < (Offset + offset)) && (i < m_size); i += (Data[i] & 0x1F) + 1)
353  result &= ParseCTABlock(Data, i);
354  return result;
355 }
356 
357 bool MythEDID::ParseCTABlock(const quint8* Data, uint Offset)
358 {
359  uint length = Data[Offset] & 0x1F;
360  uint type = (Data[Offset] & 0xE0) >> 5;
361  switch (type)
362  {
363  case 0x01: break; // Audio data block // NOLINT(bugprone-branch-clone)
364  case 0x02: break; // Video data block
365  case 0x03: ParseVSDB(Data, Offset + 1, length); break; // Vendor Specific Data Block
366  case 0x04: break; // Speaker Allocation data block // NOLINT(bugprone-branch-clone)
367  case 0x05: break; // VESA DTC data block
368  case 0x07: ParseExtended(Data, Offset + 1, length); break; // Extended tag. HDR metadata here
369  default: break;
370  }
371  return true;
372 }
373 
374 bool MythEDID::ParseVSDB(const quint8* Data, uint Offset, uint Length)
375 {
376  if (Offset + 3 >= m_size)
377  return false;
378 
379  // N.B. Little endian
380  int registration = Data[Offset] + (Data[Offset + 1] << 8) + (Data[Offset + 2] << 16);
381 
382  // "HDMI Licensing, LLC"
383  while (registration == 0x000C03)
384  {
385  m_isHDMI = true;
386 
387  if (Length < 5 || (Offset + 5 >= m_size))
388  break;
389 
390  // CEC physical address
391  m_physicalAddress = static_cast<uint16_t>((Data[Offset + 3] << 8) + Data[Offset + 4]);
392 
393  if (Length < 6 || (Offset + 6 >= m_size))
394  break;
395 
396  // Deep color
397  m_deepColor = Data[Offset + 5] & 0x78;
398 
399  if (Length < 8 || (Offset + 8 >= m_size))
400  break;
401 
402  // Audio and video latencies
403  m_latencies = ((Data[Offset + 7] & 0x80) != 0);
404  m_interLatencies = ((Data[Offset + 7] & 0x40) != 0) && m_latencies;
405 
406  if (Length < 10 || (Offset + 10 >= m_size))
407  break;
408  if (m_latencies)
409  {
410  quint8 video = Data[Offset + 8];
411  if (video > 0 && video <= 251)
412  m_videoLatency[0] = (video - 1) << 1;
413  quint8 audio = Data[Offset + 9];
414  if (audio > 0 && audio <= 251)
415  m_audioLatency[0] = (audio - 1) << 1;
416  }
417 
418  if (Length < 12 || (Offset + 12 >= m_size))
419  break;
420 
421  if (m_interLatencies)
422  {
423  quint8 video = Data[Offset + 10];
424  if (video > 0 && video <= 251)
425  m_videoLatency[1] = (video - 1) << 1;
426  quint8 audio = Data[Offset + 11];
427  if (audio > 0 && audio <= 251)
428  m_audioLatency[1] = (audio - 1) << 1;
429  }
430 
431  break;
432  }
433 
434  // "HDMI Forum"
435  while (registration == 0xC45DD8)
436  {
437  if (Length < 5 || (Offset + 5 >= m_size))
438  break;
439 
440  // Deep Color 4:2:0
441  m_deepYUV = Data[Offset + 4] & 0x7;
442 
443  if (Length < 11 || (Offset + 11 >= m_size))
444  break;
445 
446  // Variable Refresh Rate
447  m_vrrMin = Data[Offset + 9] & 0x3f;
448  m_vrrMax = ((Data[Offset + 9] & 0xc0) << 2) | Data[Offset + 10];
449  break;
450  }
451 
452  return true;
453 }
454 
455 bool MythEDID::ParseExtended(const quint8* Data, uint Offset, uint Length)
456 {
457  if (Offset + 1 >= m_size)
458  return false;
459 
460  // HDR Static Metadata Data Block
461  if (Data[Offset] == 0x06 && Length)
462  {
463  if (Length >= 3 && (Offset + 3 < m_size))
464  {
465  int hdrsupport = Data[Offset + 1] & 0x3f;
466  if (hdrsupport & HDR10)
468  if (hdrsupport & HLG)
470  m_hdrMetaTypes = Data[Offset + 2] & 0xff;
471  }
472 
473  if (Length >= 4)
474  m_maxLuminance = 50.0 * pow(2, Data[Offset + 3] / 32.0);
475 
476  if (Length >= 5)
477  m_maxAvgLuminance = 50.0 * pow(2, Data[Offset + 4] / 32.0);
478 
479  if (Length >= 6)
480  m_minLuminance = (50.0 * pow(2, Data[Offset + 3] / 32.0)) * pow(Data[Offset + 5] / 255.0, 2) / 100.0;
481  }
482  return true;
483 }
484 
485 void MythEDID::Debug() const
486 {
487  auto deep = [](uint8_t Deep)
488  {
489  QStringList res;
490  if (Deep & 0x08) res << "Y444";
491  if (Deep & 0x10) res << "30bit";
492  if (Deep & 0x20) res << "36bit";
493  if (Deep & 0x40) res << "48bit";
494  return res.join(",");
495  };
496 
497  auto deepyuv = [](uint8_t Deep)
498  {
499  QStringList res;
500  if (Deep & 0x01) res << "10bit";
501  if (Deep & 0x02) res << "12bit";
502  if (Deep & 0x04) res << "16bit";
503  return res.join(",");
504  };
505 
506  if (!m_valid)
507  {
508  LOG(VB_GENERAL, LOG_INFO, LOC + "Invalid EDID");
509  return;
510  }
511 
512  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Version:1.%1 Size:%2 Exensions:%3")
513  .arg(m_minorVersion).arg(m_size).arg(m_size / 128 -1));
514  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Gamma:%1 sRGB:%2")
515  .arg(static_cast<double>(m_gamma)).arg(m_sRGB));
516  LOG(VB_GENERAL, LOG_INFO, LOC + "Display chromaticity:-");
517  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Red:\t%1,\t%2")
518  .arg(static_cast<double>(m_primaries.m_primaries[0][0]), 0, 'f', 4)
519  .arg(static_cast<double>(m_primaries.m_primaries[0][1]), 0, 'f', 4));
520  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Green:\t%1,\t%2")
521  .arg(static_cast<double>(m_primaries.m_primaries[1][0]), 0, 'f', 4)
522  .arg(static_cast<double>(m_primaries.m_primaries[1][1]), 0, 'f', 4));
523  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Blue:\t%1,\t%2")
524  .arg(static_cast<double>(m_primaries.m_primaries[2][0]), 0, 'f', 4)
525  .arg(static_cast<double>(m_primaries.m_primaries[2][1]), 0, 'f', 4));
526  LOG(VB_GENERAL, LOG_INFO, LOC + QString("White:\t%1,\t%2")
527  .arg(static_cast<double>(m_primaries.m_whitePoint[0]), 0, 'f', 4)
528  .arg(static_cast<double>(m_primaries.m_whitePoint[1]), 0, 'f', 4));
529  QString address = !m_physicalAddress ? QString("N/A") :
530  QString("%1.%2.%3.%4").arg((m_physicalAddress >> 12) & 0xF)
531  .arg((m_physicalAddress >> 8) & 0xF)
532  .arg((m_physicalAddress >> 4) & 0xF)
533  .arg(m_physicalAddress & 0xF);
534  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Physical address: %1").arg(address));
535  if (m_deepColor)
536  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Deep color: %1").arg(deep(m_deepColor)));
537  if (m_latencies)
538  {
539  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Latencies: Audio:%1 Video:%2")
540  .arg(m_audioLatency[0]).arg(m_videoLatency[0]));
541  if (m_interLatencies)
542  {
543  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Latencies: Audio:%1 Video:%2 (Interlaced)")
544  .arg(m_audioLatency[1]).arg(m_videoLatency[1]));
545  }
546  }
547  if (m_deepYUV)
548  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Deep YUV 4:2:0 %1").arg(deepyuv(m_deepYUV)));
549  if (m_vrrMin || m_vrrMax)
550  LOG(VB_GENERAL, LOG_INFO, LOC + QString("VRR: %1<->%2").arg(m_vrrMin).arg(m_vrrMax));
551  if (m_hdrSupport)
552  LOG(VB_GENERAL, LOG_INFO, LOC + QString("HDR types: %1").arg(MythHDR::TypesToString(m_hdrSupport).join(",")));
553  if (m_maxLuminance > 0.0 || m_maxAvgLuminance > 0.0)
554  {
555  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Desired luminance: Min: %1 Max: %2 Avg: %3")
556  .arg(m_minLuminance, 3, 'f', 3).arg(m_maxLuminance, 3, 'f', 3).arg(m_maxAvgLuminance, 3, 'f', 3));
557  }
558 }
HEIGHT_OFFSET
#define HEIGHT_OFFSET
Definition: mythedid.cpp:20
DESCRIPTOR_RANGE_LIMITS
#define DESCRIPTOR_RANGE_LIMITS
Definition: mythedid.cpp:13
MythEDID::ParseDetailedTimingDescriptor
void ParseDetailedTimingDescriptor(const quint8 *Data, uint Offset)
Definition: mythedid.cpp:325
MythEDID::m_vrangeMin
int m_vrangeMin
Definition: mythedid.h:70
WIDTH_OFFSET
#define WIDTH_OFFSET
Definition: mythedid.cpp:19
MythColourSpace::m_whitePoint
MythPrimaryFloat m_whitePoint
Definition: mythcolourspace.h:35
MythEDID::m_physicalAddress
uint16_t m_physicalAddress
Definition: mythedid.h:77
MythEDID::PhysicalAddress
uint16_t PhysicalAddress() const
Definition: mythedid.cpp:59
MythEDID::m_vrangeMax
int m_vrangeMax
Definition: mythedid.h:71
MythEDID::ParseDisplayDescriptor
void ParseDisplayDescriptor(const quint8 *Data, uint Offset)
Definition: mythedid.cpp:294
MythColourSpace::s_sRGB
static MythColourSpace s_sRGB
Definition: mythcolourspace.h:21
MythEDID::m_vrrMin
int m_vrrMin
Definition: mythedid.h:84
MythEDID::IsHDMI
bool IsHDMI() const
Definition: mythedid.cpp:69
MythEDID::Debug
void Debug() const
Definition: mythedid.cpp:485
MythEDID::DisplayAspect
double DisplayAspect() const
Definition: mythedid.cpp:54
MythEDID::m_deepYUV
uint8_t m_deepYUV
Definition: mythedid.h:83
MythEDID::Gamma
float Gamma() const
Definition: mythedid.cpp:64
MythColourSpace::m_primaries
MythPrimariesFloat m_primaries
Definition: mythcolourspace.h:34
MythEDID::m_minorVersion
quint8 m_minorVersion
Definition: mythedid.h:65
GAMMA_OFFSET
#define GAMMA_OFFSET
Definition: mythedid.cpp:21
MythEDID::ParseCTABlock
bool ParseCTABlock(const quint8 *Data, uint Offset)
Definition: mythedid.cpp:357
MythColourSpace::Alike
static bool Alike(const MythColourSpace &First, const MythColourSpace &Second, float Fuzz)
Definition: mythcolourspace.cpp:27
ParseEdidString
static QString ParseEdidString(const quint8 *data, bool Replace)
Definition: mythedid.cpp:123
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
EXTENSIONS_OFFSET
#define EXTENSIONS_OFFSET
Definition: mythedid.cpp:23
DESCRIPTOR_PRODUCT_NAME
#define DESCRIPTOR_PRODUCT_NAME
Definition: mythedid.cpp:12
MythEDID::m_displayAspect
double m_displayAspect
Definition: mythedid.h:67
MythEDID::m_size
uint m_size
Definition: mythedid.h:64
MythEDID::ParseVSDB
bool ParseVSDB(const quint8 *Data, uint Offset, uint Length)
Definition: mythedid.cpp:374
MythEDID::m_audioLatency
std::array< int, 2 > m_audioLatency
Definition: mythedid.h:81
MythEDID::ParseBaseBlock
bool ParseBaseBlock(const quint8 *Data)
Definition: mythedid.cpp:197
MythEDID::m_serialNumbers
QStringList m_serialNumbers
Definition: mythedid.h:68
MythHDR::HLG
@ HLG
Definition: mythhdr.h:40
SERIAL_OFFSET
#define SERIAL_OFFSET
Definition: mythedid.cpp:16
MythEDID::IsLikeSRGB
bool IsLikeSRGB() const
Definition: mythedid.cpp:79
MythEDID::Parse
void Parse()
Definition: mythedid.cpp:143
MythEDID::m_isHDMI
bool m_isHDMI
Definition: mythedid.h:76
MythEDID::m_data
QByteArray m_data
Definition: mythedid.h:63
MythColourSpace
Definition: mythcolourspace.h:18
MythEDID::MythEDID
MythEDID()=default
MythEDID::HDR10
@ HDR10
Definition: mythedid.h:49
MythEDID::GetVRRRange
MythVRRRange GetVRRRange() const
Return the range of supported refresh rates.
Definition: mythedid.cpp:113
MythEDID::SerialNumbers
QStringList SerialNumbers() const
Definition: mythedid.cpp:44
MythEDID::m_hdrSupport
MythHDR::HDRTypes m_hdrSupport
Definition: mythedid.h:87
mythlogging.h
MythEDID::m_sRGB
bool m_sRGB
Definition: mythedid.h:73
MythEDID::ParseExtended
bool ParseExtended(const quint8 *Data, uint Offset, uint Length)
Definition: mythedid.cpp:455
MythEDID::ColourPrimaries
MythColourSpace ColourPrimaries() const
Definition: mythedid.cpp:84
MythEDID::m_deepColor
uint8_t m_deepColor
Definition: mythedid.h:78
MythEDID::GetHDRSupport
MythHDRDesc GetHDRSupport() const
Definition: mythedid.cpp:99
MythEDID::Valid
bool Valid() const
Definition: mythedid.cpp:39
MythEDID::m_hdrMetaTypes
int m_hdrMetaTypes
Definition: mythedid.h:86
MythEDID::m_primaries
MythColourSpace m_primaries
Definition: mythedid.h:75
MythEDID::m_minLuminance
double m_minLuminance
Definition: mythedid.h:90
FEATURES_OFFSET
#define FEATURES_OFFSET
Definition: mythedid.cpp:22
MythHDR::HDR10
@ HDR10
Definition: mythhdr.h:39
MythEDID::HLG
@ HLG
Definition: mythedid.h:50
MythEDID::m_videoLatency
std::array< int, 2 > m_videoLatency
Definition: mythedid.h:82
VERSION_OFFSET
#define VERSION_OFFSET
Definition: mythedid.cpp:17
uint
unsigned int uint
Definition: compat.h:144
MythEDID::m_maxLuminance
double m_maxLuminance
Definition: mythedid.h:88
MythEDID::m_interLatencies
bool m_interLatencies
Definition: mythedid.h:80
MythEDID::m_name
QString m_name
Definition: mythedid.h:69
MythVRRRange
std::tuple< int, int, bool > MythVRRRange
Definition: mythedid.h:19
MythEDID::IsSRGB
bool IsSRGB() const
Definition: mythedid.cpp:74
MythEDID::VideoLatency
int VideoLatency(bool Interlaced) const
Definition: mythedid.cpp:94
MythEDID::m_gamma
float m_gamma
Definition: mythedid.h:72
MythHDR::TypesToString
QStringList TypesToString() const
Definition: mythhdr.cpp:82
mythedid.h
MythEDID::m_latencies
bool m_latencies
Definition: mythedid.h:79
LOC
#define LOC
Definition: mythedid.cpp:25
std
Definition: mythchrono.h:23
MythEDID::m_likeSRGB
bool m_likeSRGB
Definition: mythedid.h:74
MythEDID::m_valid
bool m_valid
Definition: mythedid.h:62
MythEDID::m_maxAvgLuminance
double m_maxAvgLuminance
Definition: mythedid.h:89
MythHDRDesc
std::tuple< MythHDR::HDRTypes, double, double, double > MythHDRDesc
Definition: mythedid.h:18
uint16_t
unsigned short uint16_t
Definition: iso6937tables.h:3
DESCRIPTOR_SERIAL_NUMBER
#define DESCRIPTOR_SERIAL_NUMBER
Definition: mythedid.cpp:14
DATA_BLOCK_OFFSET
#define DATA_BLOCK_OFFSET
Definition: mythedid.cpp:15
MythEDID::AudioLatency
int AudioLatency(bool Interlaced) const
Definition: mythedid.cpp:89
MythEDID::ParseCTA861
bool ParseCTA861(const quint8 *Data, uint Offset)
Definition: mythedid.cpp:340
MythEDID::m_displaySize
QSize m_displaySize
Definition: mythedid.h:66
nv_python_libs.bbciplayer.bbciplayer_api.version
string version
Definition: bbciplayer_api.py:81
MythEDID::DisplaySize
QSize DisplaySize() const
Definition: mythedid.cpp:49
MythEDID::m_vrrMax
int m_vrrMax
Definition: mythedid.h:85