MythTV  master
videocolourspace.cpp
Go to the documentation of this file.
1 #include <cmath>
2 
3 #include "compat.h"
4 #include "mythcorecontext.h"
5 #include "mythlogging.h"
6 #include "videocolourspace.h"
7 
8 
9 #define LOC QString("ColourSpace: ")
10 
11 Matrix::Matrix(float m11, float m12, float m13, float m14,
12  float m21, float m22, float m23, float m24,
13  float m31, float m32, float m33, float m34)
14 {
15  m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14;
16  m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24;
17  m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34;
18  m[3][0] = m[3][1] = m[3][2] = m[3][3] = 1.0F;
19 }
20 
22 {
23  setToIdentity();
24 }
25 
27 {
28  for (int i = 0; i < 3; i++)
29  for (int j = 0; j < 4; j++)
30  m[i][j] = (i == j) ? 1.0F : 0.0F;
31 }
32 
33 void Matrix::scale(float val1, float val2, float val3)
34 {
35  Matrix scale;
36  scale.m[0][0] = val1;
37  scale.m[1][1] = val2;
38  scale.m[2][2] = val3;
39  this->operator *=(scale);
40 }
41 
42 void Matrix::translate(float val1, float val2, float val3)
43 {
45  translate.m[0][3] = val1;
46  translate.m[1][3] = val2;
47  translate.m[2][3] = val3;
48  this->operator *=(translate);
49 }
50 
52 {
53  for (int i = 0; i < 3; i++)
54  product(i, r);
55  return *this;
56 }
57 
58 void Matrix::product(int row, const Matrix &r)
59 {
60  float t0, t1, t2, t3;
61  t0 = m[row][0] * r.m[0][0] + m[row][1] * r.m[1][0] + m[row][2] * r.m[2][0];
62  t1 = m[row][0] * r.m[0][1] + m[row][1] * r.m[1][1] + m[row][2] * r.m[2][1];
63  t2 = m[row][0] * r.m[0][2] + m[row][1] * r.m[1][2] + m[row][2] * r.m[2][2];
64  t3 = m[row][0] * r.m[0][3] + m[row][1] * r.m[1][3] + m[row][2] * r.m[2][3] + m[row][3];
65  m[row][0] = t0; m[row][1] = t1; m[row][2] = t2; m[row][3] = t3;
66 }
67 
68 void Matrix::debug(void)
69 {
70  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("%1 %2 %3 %4")
71  .arg(m[0][0], 4, 'f', 4, QLatin1Char('0'))
72  .arg(m[0][1], 4, 'f', 4, QLatin1Char('0'))
73  .arg(m[0][2], 4, 'f', 4, QLatin1Char('0'))
74  .arg(m[0][3], 4, 'f', 4, QLatin1Char('0')));
75  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("%1 %2 %3 %4")
76  .arg(m[1][0], 4, 'f', 4, QLatin1Char('0'))
77  .arg(m[1][1], 4, 'f', 4, QLatin1Char('0'))
78  .arg(m[1][2], 4, 'f', 4, QLatin1Char('0'))
79  .arg(m[1][3], 4, 'f', 4, QLatin1Char('0')));
80  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("%1 %2 %3 %4")
81  .arg(m[2][0], 4, 'f', 4, QLatin1Char('0'))
82  .arg(m[2][1], 4, 'f', 4, QLatin1Char('0'))
83  .arg(m[2][2], 4, 'f', 4, QLatin1Char('0'))
84  .arg(m[2][3], 4, 'f', 4, QLatin1Char('0')));
85 }
86 
88  : m_supported_attributes(kPictureAttributeSupported_None),
89  m_changed(false), m_studioLevels(false), m_brightness(0.0F),
90  m_contrast(1.0F), m_saturation(1.0F), m_hue(0.0F),
91  m_colourSpace(colour_std)
92 {
94  gCoreContext->GetNumSetting("PlaybackBrightness", 50);
96  gCoreContext->GetNumSetting("PlaybackContrast", 50);
98  gCoreContext->GetNumSetting("PlaybackColour", 50);
100  gCoreContext->GetNumSetting("PlaybackHue", 0);
102  gCoreContext->GetNumSetting("PlaybackStudioLevels", 0);
103 
109 }
110 
112 {
113  m_supported_attributes = supported;
114  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("PictureAttributes: %1")
116 }
117 
119 {
120  if (m_db_settings.contains(attribute))
121  return m_db_settings.value(attribute);
122  return -1;
123 }
124 
126 {
127  if (!(m_supported_attributes & toMask(attribute)))
128  return -1;
129 
130  value = std::min(std::max(value, 0), 100);
131 
132  switch (attribute)
133  {
135  SetBrightness(value);
136  break;
138  SetContrast(value);
139  break;
141  SetSaturation(value);
142  break;
144  SetHue(value);
145  break;
147  value = std::min(std::max(value, 0), 1);
148  SetStudioLevels(value > 0);
149  break;
150  default:
151  value = -1;
152  }
153 
154  if (value >= 0)
155  SaveValue(attribute, value);
156 
157  return value;
158 }
159 
161 {
162  float luma_range = m_studioLevels ? 255.0F : 219.0F;
163  float chroma_range = m_studioLevels ? 255.0F : 224.0F;
164  float luma_offset = m_studioLevels ? 0.0F : -16.0F / 255.0F;
165  float chroma_offset = -128.0F / 255.0F;
166 
167  float uvcos = m_saturation * cosf(m_hue);
168  float uvsin = m_saturation * sinf(m_hue);
169  float brightness = m_brightness * 255.0F / luma_range;
170  float luma_scale = 255.0F / luma_range;
171  float chroma_scale = 255.0F / chroma_range;
172 
173  Matrix csc;
174  switch (m_colourSpace)
175  {
176  case kCSTD_SMPTE_240M:
177  csc = Matrix(1.000F, ( 0.0000F * uvcos) + ( 1.5756F * uvsin),
178  ( 1.5756F * uvcos) - ( 0.0000F * uvsin), 0.0F,
179  1.000F, (-0.2253F * uvcos) + ( 0.5000F * uvsin),
180  ( 0.5000F * uvcos) - (-0.2253F * uvsin), 0.0F,
181  1.000F, ( 1.8270F * uvcos) + ( 0.0000F * uvsin),
182  ( 0.0000F * uvcos) - ( 1.8270F * uvsin), 0.0F);
183  break;
184 
185  case kCSTD_ITUR_BT_709:
186  csc = Matrix(1.000F, ( 0.0000F * uvcos) + ( 1.5701F * uvsin),
187  ( 1.5701F * uvcos) - ( 0.0000F * uvsin), 0.0F,
188  1.000F, (-0.1870F * uvcos) + (-0.4664F * uvsin),
189  (-0.4664F * uvcos) - (-0.1870F * uvsin), 0.0F,
190  1.000F, ( 1.8556F * uvcos) + ( 0.0000F * uvsin),
191  ( 0.0000F * uvcos) - ( 1.8556F * uvsin), 0.0F);
192  break;
193 
194  case kCSTD_ITUR_BT_601:
195  default:
196  csc = Matrix(1.000F, ( 0.0000F * uvcos) + ( 1.4030F * uvsin),
197  ( 1.4030F * uvcos) - ( 0.0000F * uvsin), 0.0F,
198  1.000F, (-0.3440F * uvcos) + (-0.7140F * uvsin),
199  (-0.7140F * uvcos) - (-0.3440F * uvsin), 0.0F,
200  1.000F, ( 1.7730F * uvcos) + ( 0.0000F * uvsin),
201  ( 0.0000F * uvcos) - ( 1.7730F * uvsin), 0.0F);
202  }
203 
205  m_matrix.translate(brightness, brightness, brightness);
207  m_matrix *= csc;
208  m_matrix.scale(luma_scale, chroma_scale, chroma_scale);
209  m_matrix.translate(luma_offset, chroma_offset, chroma_offset);
210  m_changed = true;
211  Debug();
212 }
213 
215 {
216  LOG(VB_PLAYBACK, LOG_DEBUG, LOC +
217  QString("Brightness: %1 Contrast: %2 Saturation: %3 Hue: %4 "
218  "StudioLevels: %5")
219  .arg(m_brightness, 2, 'f', 4, QLatin1Char('0'))
220  .arg(m_contrast , 2, 'f', 4, QLatin1Char('0'))
221  .arg(m_saturation, 2, 'f', 4, QLatin1Char('0'))
222  .arg(m_hue , 2, 'f', 4, QLatin1Char('0'))
223  .arg(m_studioLevels));
224  m_matrix.debug();
225 }
226 
228 {
229  m_colourSpace = csp;
230  Update();
231 }
232 
234 {
235  m_studioLevels = studio;
236  Update();
237 }
238 
240 {
241  m_brightness = (value * 0.02F) - 1.0F;
242  Update();
243 }
244 
246 {
247  m_contrast = value * 0.02F;
248  Update();
249 }
250 
252 {
253  m_hue = value * (-3.6 * M_PI / 180.0);
254  Update();
255 }
256 
258 {
259  m_saturation = value * 0.02F;
260  Update();
261 }
262 
263 void VideoColourSpace::SaveValue(PictureAttribute attributeType, int value)
264 {
265  QString dbName;
266  if (kPictureAttribute_Brightness == attributeType)
267  dbName = "PlaybackBrightness";
268  else if (kPictureAttribute_Contrast == attributeType)
269  dbName = "PlaybackContrast";
270  else if (kPictureAttribute_Colour == attributeType)
271  dbName = "PlaybackColour";
272  else if (kPictureAttribute_Hue == attributeType)
273  dbName = "PlaybackHue";
274  else if (kPictureAttribute_StudioLevels == attributeType)
275  dbName = "PlaybackStudioLevels";
276 
277  if (!dbName.isEmpty())
278  gCoreContext->SaveSetting(dbName, value);
279 
280  m_db_settings[attributeType] = value;
281 }
PictureAttributeSupported
QString toString(MarkTypes type)
void SetHue(int value)
void SaveSetting(const QString &key, int newValue)
void product(int row, const Matrix &r)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOC
unsigned char r
Definition: ParseText.cpp:329
void SaveValue(PictureAttribute attribute, int value)
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
VideoColourSpace(VideoCStd colour_std=kCSTD_ITUR_BT_601)
void SetSaturation(int value)
PictureAttribute
Definition: videoouttypes.h:89
void SetBrightness(int value)
void SetColourSpace(VideoCStd csp=kCSTD_Unknown)
void translate(float val1, float val2, float val3)
void setToIdentity(void)
#define M_PI
Definition: goom_tools.h:5
int GetNumSetting(const QString &key, int defaultval=0)
PictureAttributeSupported toMask(PictureAttribute pictureattribute)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
PictureAttributeSupported m_supported_attributes
void SetSupportedAttributes(PictureAttributeSupported supported)
VideoCStd
float m[4][4]
void debug(void)
VideoCStd m_colourSpace
void SetContrast(int value)
int GetPictureAttribute(PictureAttribute attribute)
Matrix & operator*=(const Matrix &r)
void scale(float val1, float val2, float val3)
QMap< PictureAttribute, int > m_db_settings
int SetPictureAttribute(PictureAttribute attribute, int value)
void SetStudioLevels(bool studio)