Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 306661
Collapse All | Expand All

(-)language/English/strings.xml (-2 / +3 lines)
Lines 1554-1569 Link Here
1554
  <string id="16304">Lanczos2</string>
1554
  <string id="16304">Lanczos2</string>
1555
  <string id="16305">Lanczos3</string>
1555
  <string id="16305">Lanczos3</string>
1556
  <string id="16306">Sinc8</string>
1556
  <string id="16306">Sinc8</string>
1557
1558
  <string id="16307">Bicubic (software)</string>
1557
  <string id="16307">Bicubic (software)</string>
1559
  <string id="16308">Lanczos (software)</string>
1558
  <string id="16308">Lanczos (software)</string>
1560
  <string id="16309">Sinc (software)</string>
1559
  <string id="16309">Sinc (software)</string>
1561
1562
  <string id="16310">(VDPAU)Temporal</string>
1560
  <string id="16310">(VDPAU)Temporal</string>
1563
  <string id="16311">(VDPAU)Temporal/Spatial</string>
1561
  <string id="16311">(VDPAU)Temporal/Spatial</string>
1564
  <string id="16312">(VDPAU)Noise Reduction</string>
1562
  <string id="16312">(VDPAU)Noise Reduction</string>
1565
  <string id="16313">(VDPAU)Sharpness</string>
1563
  <string id="16313">(VDPAU)Sharpness</string>
1566
  <string id="16314">Inverse Telecine</string>
1564
  <string id="16314">Inverse Telecine</string>
1565
  <string id="16315">Lanczos3 optimized</string>
1566
  <string id="16316">Auto</string>
1567
1567
  <string id="17500">Display sleep timeout</string>
1568
  <string id="17500">Display sleep timeout</string>
1568
1569
1569
  <string id="19000">Switch to channel</string>
1570
  <string id="19000">Switch to channel</string>
(-)system/shaders/convolution-6x6.glsl (+69 lines)
Line 0 Link Here
1
uniform sampler2D img;
2
uniform float     stepx;
3
uniform float     stepy;
4
5
#if (HAS_FLOAT_TEXTURE)
6
uniform sampler1D kernelTex;
7
8
vec3 weight(float pos)
9
{
10
  return texture1D(kernelTex, pos).rgb;
11
}
12
#else
13
uniform sampler2D kernelTex;
14
15
vec3 weight(float pos)
16
{
17
  //row 0 contains the high byte, row 1 contains the low byte
18
  return ((texture2D(kernelTex, vec2(pos, 0.0)) * 256.0 + texture2D(kernelTex, vec2(pos, 1.0)))).rgb / 128.5 - 1.0;
19
}
20
#endif
21
22
vec3 pixel(float xpos, float ypos)
23
{
24
  return texture2D(img, vec2(xpos, ypos)).rgb;
25
}
26
27
vec3 line (float ypos, vec3 xpos1, vec3 xpos2, vec3 linetaps1, vec3 linetaps2)
28
{
29
  vec3  pixels;
30
31
  pixels  = pixel(xpos1.r, ypos) * linetaps1.r;
32
  pixels += pixel(xpos1.g, ypos) * linetaps2.r;
33
  pixels += pixel(xpos1.b, ypos) * linetaps1.g;
34
  pixels += pixel(xpos2.r, ypos) * linetaps2.g;
35
  pixels += pixel(xpos2.g, ypos) * linetaps1.b;
36
  pixels += pixel(xpos2.b, ypos) * linetaps2.b;
37
38
  return pixels;
39
}
40
41
void main()
42
{
43
  float xf = fract(gl_TexCoord[0].x / stepx);
44
  float yf = fract(gl_TexCoord[0].y / stepy);
45
46
  vec3 linetaps1   = weight((1.0 - xf) / 2.0);
47
  vec3 linetaps2   = weight((1.0 - xf) / 2.0 + 0.5);
48
  vec3 columntaps1 = weight((1.0 - yf) / 2.0);
49
  vec3 columntaps2 = weight((1.0 - yf) / 2.0 + 0.5);
50
51
  vec3 xpos1 = vec3(
52
      (-1.5 - xf) * stepx + gl_TexCoord[0].x,
53
      (-0.5 - xf) * stepx + gl_TexCoord[0].x,
54
      ( 0.5 - xf) * stepx + gl_TexCoord[0].x);
55
  vec3 xpos2 = vec3(
56
      ( 1.5 - xf) * stepx + gl_TexCoord[0].x,
57
      ( 2.5 - xf) * stepx + gl_TexCoord[0].x,
58
      ( 3.5 - xf) * stepx + gl_TexCoord[0].x);
59
60
  gl_FragColor.rgb  = line((-1.5 - yf) * stepy + gl_TexCoord[0].y, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.r;
61
  gl_FragColor.rgb += line((-0.5 - yf) * stepy + gl_TexCoord[0].y, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.r;
62
  gl_FragColor.rgb += line(( 0.5 - yf) * stepy + gl_TexCoord[0].y, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.g;
63
  gl_FragColor.rgb += line(( 1.5 - yf) * stepy + gl_TexCoord[0].y, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.g;
64
  gl_FragColor.rgb += line(( 2.5 - yf) * stepy + gl_TexCoord[0].y, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.b;
65
  gl_FragColor.rgb += line(( 3.5 - yf) * stepy + gl_TexCoord[0].y, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.b;
66
67
  gl_FragColor.a = gl_Color.a;
68
}
69
(-)system/shaders/bicubic.glsl (+47 lines)
Line 0 Link Here
1
uniform sampler2D img;
2
uniform float stepx;
3
uniform float stepy;
4
uniform sampler2D kernelTex;
5
6
vec4 cubicFilter(float xValue, vec4 c0, vec4 c1, vec4 c2, vec4 c3)
7
{
8
  vec4 h = texture2D(kernelTex, vec2(xValue, 0.5));
9
  vec4 r = c0 * h.r;
10
  r += c1 * h.g;
11
  r += c2 * h.b;
12
  r += c3 * h.a;
13
  return r;
14
}
15
16
void main()
17
{
18
  vec2 f = vec2(gl_TexCoord[0].x / stepx , gl_TexCoord[0].y / stepy);
19
  f = fract(f);
20
  vec4 t0 = cubicFilter(f.x,
21
  texture2D(img, gl_TexCoord[0].xy + vec2(-stepx,    -stepy)),
22
  texture2D(img, gl_TexCoord[0].xy + vec2(0.0,       -stepy)),
23
  texture2D(img, gl_TexCoord[0].xy + vec2(stepx,     -stepy)),
24
  texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, -stepy)));
25
26
  vec4 t1 = cubicFilter(f.x,
27
  texture2D(img, gl_TexCoord[0].xy + vec2(-stepx,    0.0)),
28
  texture2D(img, gl_TexCoord[0].xy + vec2(0.0,       0.0)),
29
  texture2D(img, gl_TexCoord[0].xy + vec2(stepx,     0.0)),
30
  texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, 0.0)));
31
32
  vec4 t2 = cubicFilter(f.x,
33
  texture2D(img, gl_TexCoord[0].xy + vec2(-stepx,    stepy)),
34
  texture2D(img, gl_TexCoord[0].xy + vec2(0.0,       stepy)),
35
  texture2D(img, gl_TexCoord[0].xy + vec2(stepx,     stepy)),
36
  texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, stepy)));
37
38
  vec4 t3 = cubicFilter(f.x,
39
  texture2D(img, gl_TexCoord[0].xy + vec2(-stepx,    2.0*stepy)),
40
  texture2D(img, gl_TexCoord[0].xy + vec2(0,         2.0*stepy)),
41
  texture2D(img, gl_TexCoord[0].xy + vec2(stepx,     2.0*stepy)),
42
  texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, 2.0*stepy)));
43
44
  gl_FragColor = cubicFilter(f.y, t0, t1, t2, t3);   
45
  gl_FragColor.a = gl_Color.a;
46
}
47
(-)system/shaders/convolution-4x4.glsl (+60 lines)
Line 0 Link Here
1
uniform sampler2D img;
2
uniform float     stepx;
3
uniform float     stepy;
4
5
#if (HAS_FLOAT_TEXTURE)
6
uniform sampler1D kernelTex;
7
8
vec4 weight(float pos)
9
{
10
  return texture1D(kernelTex, pos);
11
}
12
#else
13
uniform sampler2D kernelTex;
14
15
vec4 weight(float pos)
16
{
17
  //row 0 contains the high byte, row 1 contains the low byte
18
  return (texture2D(kernelTex, vec2(pos, 0.0)) * 256.0 + texture2D(kernelTex, vec2(pos, 1.0))) / 128.5 - 1.0;
19
}
20
#endif
21
22
vec3 pixel(float xpos, float ypos)
23
{
24
  return texture2D(img, vec2(xpos, ypos)).rgb;
25
}
26
27
vec3 line (float ypos, vec4 xpos, vec4 linetaps)
28
{
29
  vec3  pixels;
30
31
  pixels  = pixel(xpos.r, ypos) * linetaps.r;
32
  pixels += pixel(xpos.g, ypos) * linetaps.g;
33
  pixels += pixel(xpos.b, ypos) * linetaps.b;
34
  pixels += pixel(xpos.a, ypos) * linetaps.a;
35
36
  return pixels;
37
}
38
39
void main()
40
{
41
  float xf = fract(gl_TexCoord[0].x / stepx);
42
  float yf = fract(gl_TexCoord[0].y / stepy);
43
44
  vec4 linetaps   = weight(1.0 - xf);
45
  vec4 columntaps = weight(1.0 - yf);
46
47
  vec4 xpos = vec4(
48
      (-0.5 - xf) * stepx + gl_TexCoord[0].x,
49
      ( 0.5 - xf) * stepx + gl_TexCoord[0].x,
50
      ( 1.5 - xf) * stepx + gl_TexCoord[0].x,
51
      ( 2.5 - xf) * stepx + gl_TexCoord[0].x);
52
53
  gl_FragColor.rgb  = line((-0.5 - yf) * stepy + gl_TexCoord[0].y, xpos, linetaps) * columntaps.r;
54
  gl_FragColor.rgb += line(( 0.5 - yf) * stepy + gl_TexCoord[0].y, xpos, linetaps) * columntaps.g;
55
  gl_FragColor.rgb += line(( 1.5 - yf) * stepy + gl_TexCoord[0].y, xpos, linetaps) * columntaps.b;
56
  gl_FragColor.rgb += line(( 2.5 - yf) * stepy + gl_TexCoord[0].y, xpos, linetaps) * columntaps.a;
57
58
  gl_FragColor.a = gl_Color.a;
59
}
60
(-)xbmc/settings/VideoSettings.h (-2 / +5 lines)
Lines 51-59 Link Here
51
{
51
{
52
  VS_SCALINGMETHOD_NEAREST=0,
52
  VS_SCALINGMETHOD_NEAREST=0,
53
  VS_SCALINGMETHOD_LINEAR,
53
  VS_SCALINGMETHOD_LINEAR,
54
  
54
55
  VS_SCALINGMETHOD_CUBIC,
55
  VS_SCALINGMETHOD_CUBIC,
56
  VS_SCALINGMETHOD_LANCZOS2,
56
  VS_SCALINGMETHOD_LANCZOS2,
57
  VS_SCALINGMETHOD_LANCZOS3_FAST,
57
  VS_SCALINGMETHOD_LANCZOS3,
58
  VS_SCALINGMETHOD_LANCZOS3,
58
  VS_SCALINGMETHOD_SINC8,
59
  VS_SCALINGMETHOD_SINC8,
59
  VS_SCALINGMETHOD_NEDI,
60
  VS_SCALINGMETHOD_NEDI,
Lines 61-67 Link Here
61
  VS_SCALINGMETHOD_BICUBIC_SOFTWARE,
62
  VS_SCALINGMETHOD_BICUBIC_SOFTWARE,
62
  VS_SCALINGMETHOD_LANCZOS_SOFTWARE,
63
  VS_SCALINGMETHOD_LANCZOS_SOFTWARE,
63
  VS_SCALINGMETHOD_SINC_SOFTWARE,
64
  VS_SCALINGMETHOD_SINC_SOFTWARE,
64
  VS_SCALINGMETHOD_VDPAU_HARDWARE
65
  VS_SCALINGMETHOD_VDPAU_HARDWARE,
66
67
  VS_SCALINGMETHOD_AUTO
65
};
68
};
66
69
67
class CVideoSettings
70
class CVideoSettings
(-)xbmc/cores/VideoRenderers/VideoShaders/VideoFilterShader.cpp (-52 / +112 lines)
Lines 21-26 Link Here
21
#include "system.h"
21
#include "system.h"
22
#include "VideoFilterShader.h"
22
#include "VideoFilterShader.h"
23
#include "utils/log.h"
23
#include "utils/log.h"
24
#include "ConvolutionKernels.h"
24
25
25
#include <string>
26
#include <string>
26
#include <math.h>
27
#include <math.h>
Lines 63-122 Link Here
63
64
64
BicubicFilterShader::BicubicFilterShader(float B, float C)
65
BicubicFilterShader::BicubicFilterShader(float B, float C)
65
{
66
{
66
  string shaderf = 
67
  PixelShader()->LoadSource("bicubic.glsl");
67
    "uniform sampler2D img;"
68
    "uniform float stepx;"
69
    "uniform float stepy;"
70
    "uniform sampler2D kernelTex;"
71
    
72
    "vec4 cubicFilter(float xValue, vec4 c0, vec4 c1, vec4 c2, vec4 c3)"
73
    "{"
74
    " vec4 h = texture2D(kernelTex, vec2(xValue, 0.5));"
75
    " vec4 r = c0 * h.r;"
76
    " r += c1 * h.g;"
77
    " r += c2 * h.b;"
78
    " r += c3 * h.a;"
79
    " return r;"
80
    "}"
81
    ""
82
    "void main()"
83
    "{"
84
    "vec2 f = vec2(gl_TexCoord[0].x / stepx , gl_TexCoord[0].y / stepy);"
85
    "f = fract(f);"
86
    "vec4 t0 = cubicFilter(f.x,"
87
    "texture2D(img, gl_TexCoord[0].xy + vec2(-stepx, -stepy)),"
88
    "texture2D(img, gl_TexCoord[0].xy + vec2(0.0, -stepy)),"
89
    "texture2D(img, gl_TexCoord[0].xy + vec2(stepx, -stepy)),"
90
    "texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, -stepy)));"
91
    ""
92
    "vec4 t1 = cubicFilter(f.x,"
93
    "texture2D(img, gl_TexCoord[0].xy + vec2(-stepx, 0.0)),"
94
    "texture2D(img, gl_TexCoord[0].xy + vec2(0.0, 0.0)),"
95
    "texture2D(img, gl_TexCoord[0].xy + vec2(stepx, 0.0)),"
96
    "texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, 0.0)));"
97
    ""
98
    "vec4 t2 = cubicFilter(f.x,"
99
    "texture2D(img, gl_TexCoord[0].xy + vec2(-stepx, stepy)),"
100
    "texture2D(img, gl_TexCoord[0].xy + vec2(0.0, stepy)),"
101
    "texture2D(img, gl_TexCoord[0].xy + vec2(stepx, stepy)),"
102
    "texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, stepy)));"
103
    ""
104
    "vec4 t3 = cubicFilter(f.x,"
105
    "texture2D(img, gl_TexCoord[0].xy + vec2(-stepx, 2.0*stepy)),"
106
    "texture2D(img, gl_TexCoord[0].xy + vec2(0, 2.0*stepy)),"
107
    "texture2D(img, gl_TexCoord[0].xy + vec2(stepx, 2.0*stepy)),"
108
    "texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, 2.0*stepy)));"
109
    
110
    "gl_FragColor = cubicFilter(f.y, t0, t1, t2, t3) ;"    
111
    "gl_FragColor.a = gl_Color.a;"
112
    "}";
113
  PixelShader()->SetSource(shaderf);
114
  m_kernelTex1 = 0;
68
  m_kernelTex1 = 0;
115
  m_B = B;
69
  m_B = B;
116
  m_C = C;
70
  m_C = C;
117
  if (B<=0)
71
  if (B<0)
118
    m_B=1.0f/3.0f;
72
    m_B=1.0f/3.0f;
119
  if (C<=0)
73
  if (C<0)
120
    m_C=1.0f/3.0f;
74
    m_C=1.0f/3.0f;
121
}
75
}
122
76
Lines 209-216 Link Here
209
  glBindTexture(GL_TEXTURE_2D, m_kernelTex1);
163
  glBindTexture(GL_TEXTURE_2D, m_kernelTex1);
210
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
164
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
211
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
165
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
212
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
166
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
213
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
167
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
214
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, size, 1, 0, GL_RGBA, GL_FLOAT, img);
168
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, size, 1, 0, GL_RGBA, GL_FLOAT, img);
215
169
216
  glActiveTexture(GL_TEXTURE0);
170
  glActiveTexture(GL_TEXTURE0);
Lines 254-257 Link Here
254
  return val;
208
  return val;
255
}
209
}
256
210
211
ConvolutionFilterShader::ConvolutionFilterShader(ESCALINGMETHOD method)
212
{
213
  m_method = method;
214
  m_kernelTex1 = 0;
215
216
  string shadername;
217
  string defines;
218
219
  if (m_method == VS_SCALINGMETHOD_CUBIC ||
220
      m_method == VS_SCALINGMETHOD_LANCZOS2 ||
221
      m_method == VS_SCALINGMETHOD_LANCZOS3_FAST)
222
    shadername = "convolution-4x4.glsl";
223
  else if (m_method == VS_SCALINGMETHOD_LANCZOS3)
224
    shadername = "convolution-6x6.glsl";
225
226
  m_floattex = glewIsSupported("GL_ARB_texture_float");
227
228
  if (m_floattex)
229
    defines = "#define HAS_FLOAT_TEXTURE 1\n";
230
  else
231
    defines = "#define HAS_FLOAT_TEXTURE 0\n";
232
233
  CLog::Log(LOGDEBUG, "GL: ConvolutionFilterShader: using %s defines: %s", shadername.c_str(), defines.c_str());
234
  PixelShader()->LoadSource(shadername, defines);
235
}
236
237
void ConvolutionFilterShader::OnCompiledAndLinked()
238
{
239
  // obtain shader attribute handles on successfull compilation
240
  m_hSourceTex = glGetUniformLocation(ProgramHandle(), "img");
241
  m_hStepX     = glGetUniformLocation(ProgramHandle(), "stepx");
242
  m_hStepY     = glGetUniformLocation(ProgramHandle(), "stepy");
243
  m_hKernTex   = glGetUniformLocation(ProgramHandle(), "kernelTex");
244
245
  CConvolutionKernel kernel(m_method, 256);
246
247
  if (m_kernelTex1)
248
  {
249
    glDeleteTextures(1, &m_kernelTex1);
250
    m_kernelTex1 = 0;
251
  }
252
253
  glGenTextures(1, &m_kernelTex1);
254
255
  if ((m_kernelTex1<=0))
256
  {
257
    CLog::Log(LOGERROR, "GL: ConvolutionFilterShader: Error creating kernel texture");
258
    return;
259
  }
260
261
  glActiveTexture(GL_TEXTURE2);
262
263
  //if float textures are supported, we can load the kernel as a 1d float texture
264
  //if not, we load it as a 2d texture with 2 rows, where row 0 contains the high byte
265
  //and row 1 contains the low byte, which can be converted in the shader
266
  if (m_floattex)
267
  {
268
    glBindTexture(GL_TEXTURE_1D, m_kernelTex1);
269
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
270
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
271
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
272
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
273
    glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16F_ARB, kernel.GetSize(), 0, GL_RGBA, GL_FLOAT, kernel.GetFloatPixels());
274
  }
275
  else
276
  {
277
    glBindTexture(GL_TEXTURE_2D, m_kernelTex1);
278
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
279
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
280
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
281
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
282
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kernel.GetSize(), 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kernel.GetIntFractPixels());
283
  }
284
285
  glActiveTexture(GL_TEXTURE0);
286
287
  VerifyGLState();
288
}
289
290
bool ConvolutionFilterShader::OnEnabled()
291
{
292
  // set shader attributes once enabled
293
  glActiveTexture(GL_TEXTURE2);
294
295
  if (m_floattex)
296
    glBindTexture(GL_TEXTURE_1D, m_kernelTex1);
297
  else
298
    glBindTexture(GL_TEXTURE_2D, m_kernelTex1);
299
300
  glActiveTexture(GL_TEXTURE0);
301
  glUniform1i(m_hSourceTex, m_sourceTexUnit);
302
  glUniform1i(m_hKernTex, 2);
303
  glUniform1f(m_hStepX, m_stepX);
304
  glUniform1f(m_hStepY, m_stepY);
305
  VerifyGLState();
306
  return true;
307
}
308
309
void ConvolutionFilterShader::Free()
310
{
311
  if (m_kernelTex1)
312
    glDeleteTextures(1, &m_kernelTex1);
313
  m_kernelTex1 = 0;
314
  BaseVideoFilterShader::Free();
315
}
316
257
#endif
317
#endif
(-)xbmc/cores/VideoRenderers/VideoShaders/ConvolutionKernels.cpp (+226 lines)
Line 0 Link Here
1
/*
2
 *      Copyright (C) 2005-2008 Team XBMC
3
 *      http://www.xbmc.org
4
 *
5
 *  This Program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2, or (at your option)
8
 *  any later version.
9
 *
10
 *  This Program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with XBMC; see the file COPYING.  If not, write to
17
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18
 *  http://www.gnu.org/copyleft/gpl.html
19
 *
20
 */
21
#ifdef _WIN32
22
  #define _USE_MATH_DEFINES
23
#endif
24
25
#include "ConvolutionKernels.h"
26
#include "MathUtils.h"
27
28
#define SINC(x) (sin(M_PI * (x)) / (M_PI * (x)))
29
30
CConvolutionKernel::CConvolutionKernel(ESCALINGMETHOD method, int size)
31
{
32
  m_size = size;
33
  m_floatpixels = new float[m_size * 4];
34
35
  if (method == VS_SCALINGMETHOD_LANCZOS2)
36
    Lanczos2();
37
  else if (method == VS_SCALINGMETHOD_LANCZOS3_FAST)
38
    Lanczos3Fast();
39
  else if (method == VS_SCALINGMETHOD_LANCZOS3)
40
    Lanczos3();
41
  else if (method == VS_SCALINGMETHOD_CUBIC) 
42
    Bicubic(1.0 / 3.0, 1.0 / 3.0);
43
44
  ToIntFract();
45
}
46
47
CConvolutionKernel::~CConvolutionKernel()
48
{
49
  delete [] m_floatpixels;
50
  delete [] m_intfractpixels;
51
}
52
53
//generate a lanczos2 kernel which can be loaded with RGBA format
54
//each value of RGBA has one tap, so a shader can load 4 taps with a single pixel lookup
55
void CConvolutionKernel::Lanczos2()
56
{
57
  for (int i = 0; i < m_size; i++)
58
  {
59
    double x = (double)i / (double)m_size;
60
61
    //generate taps
62
    for (int j = 0; j < 4; j++)
63
      m_floatpixels[i * 4 + j] = (float)LanczosWeight(x + (double)(j - 2), 2.0);
64
65
    //any collection of 4 taps added together needs to be exactly 1.0
66
    //for lanczos this is not always the case, so we take each collection of 4 taps
67
    //and divide those taps by the sum of the taps
68
    float weight = 0.0;
69
    for (int j = 0; j < 4; j++)
70
      weight += m_floatpixels[i * 4 + j];
71
72
    for (int j = 0; j < 4; j++)
73
      m_floatpixels[i * 4 + j] /= weight;
74
  }
75
}
76
77
//generate a lanczos3 kernel which can be loaded with RGBA format
78
//each value of RGBA has one tap, so a shader can load 4 taps with a single pixel lookup
79
//the two outer lobes of the lanczos3 kernel are added to the two lobes one step to the middle
80
//this basically looks the same as lanczos3, but the kernel only has 4 taps,
81
//so it can use the 4x4 convolution shader which is twice as fast as the 6x6 one
82
void CConvolutionKernel::Lanczos3Fast()
83
{
84
  for (int i = 0; i < m_size; i++)
85
  {
86
    double a = 3.0;
87
    double x = (double)i / (double)m_size;
88
89
    //generate taps
90
    m_floatpixels[i * 4 + 0] = (float)(LanczosWeight(x - 2.0, a) + LanczosWeight(x - 3.0, a));
91
    m_floatpixels[i * 4 + 1] = (float) LanczosWeight(x - 1.0, a);
92
    m_floatpixels[i * 4 + 2] = (float) LanczosWeight(x      , a);
93
    m_floatpixels[i * 4 + 3] = (float)(LanczosWeight(x + 1.0, a) + LanczosWeight(x + 2.0, a));
94
95
    //any collection of 4 taps added together needs to be exactly 1.0
96
    //for lanczos this is not always the case, so we take each collection of 4 taps
97
    //and divide those taps by the sum of the taps
98
    float weight = 0.0;
99
    for (int j = 0; j < 4; j++)
100
      weight += m_floatpixels[i * 4 + j];
101
102
    for (int j = 0; j < 4; j++)
103
      m_floatpixels[i * 4 + j] /= weight;
104
  }
105
}
106
107
//generate a lanczos3 kernel which can be loaded with RGBA format
108
//each value of RGB has one tap, so a shader can load 3 taps with a single pixel lookup
109
void CConvolutionKernel::Lanczos3()
110
{
111
  for (int i = 0; i < m_size; i++)
112
  {
113
    double x = (double)i / (double)m_size;
114
115
    //generate taps
116
    for (int j = 0; j < 3; j++)
117
      m_floatpixels[i * 4 + j] = (float)LanczosWeight(x * 2.0 + (double)(j * 2 - 3), 3.0);
118
119
    m_floatpixels[i * 4 + 3] = 0.0;
120
  }
121
122
  //any collection of 6 taps added together needs to be exactly 1.0
123
  //for lanczos this is not always the case, so we take each collection of 6 taps
124
  //and divide those taps by the sum of the taps
125
  for (int i = 0; i < m_size / 2; i++)
126
  {
127
    float weight = 0.0;
128
    for (int j = 0; j < 3; j++)
129
    {
130
      weight += m_floatpixels[i * 4 + j];
131
      weight += m_floatpixels[(i + m_size / 2) * 4 + j];
132
    }
133
    for (int j = 0; j < 3; j++)
134
    {
135
      m_floatpixels[i * 4 + j] /= weight;
136
      m_floatpixels[(i + m_size / 2) * 4 + j] /= weight;
137
    }
138
  }
139
}
140
141
//generate a bicubic kernel which can be loaded with RGBA format
142
//each value of RGBA has one tap, so a shader can load 4 taps with a single pixel lookup
143
void CConvolutionKernel::Bicubic(double B, double C)
144
{
145
  for (int i = 0; i < m_size; i++)
146
  {
147
    double x = (double)i / (double)m_size;
148
149
    //generate taps
150
    for (int j = 0; j < 4; j++)
151
      m_floatpixels[i * 4 + j] = (float)BicubicWeight(x + (double)(j - 2), B, C);
152
  }
153
}
154
155
double CConvolutionKernel::LanczosWeight(double x, double radius)
156
{
157
  double ax = fabs(x);
158
159
  if (ax == 0.0)
160
    return 1.0;
161
  else if (ax < radius)
162
    return SINC(ax) * SINC(ax / radius);
163
  else
164
    return 0.0;
165
}
166
167
double CConvolutionKernel::BicubicWeight(double x, double B, double C)
168
{
169
  double ax = fabs(x);
170
171
  if (ax<1.0)
172
  {
173
    return ((12 - 9*B - 6*C) * ax * ax * ax +
174
            (-18 + 12*B + 6*C) * ax * ax +
175
            (6 - 2*B))/6;
176
  }
177
  else if (ax<2.0)
178
  {
179
    return ((-B - 6*C) * ax * ax * ax + 
180
            (6*B + 30*C) * ax * ax + (-12*B - 48*C) * 
181
             ax + (8*B + 24*C)) / 6;
182
  }
183
  else
184
  {
185
    return 0.0;
186
  }
187
}
188
189
190
//convert float to high byte/low byte, so the kernel can be loaded into an 8 bit texture
191
//with height 2 and converted back to real float in the shader
192
//it only works when the kernel texture uses nearest neighbour, but there's almost no difference
193
//between that and linear interpolation
194
void CConvolutionKernel::ToIntFract()
195
{
196
  m_intfractpixels = new uint8_t[m_size * 8];
197
198
  for (int i = 0; i < m_size * 4; i++)
199
  {
200
    int value = MathUtils::round_int((m_floatpixels[i] + 1.0) / 2.0 * 65535.0);
201
    if (value < 0)
202
      value = 0;
203
    else if (value > 65535)
204
      value = 65535;
205
    
206
    int integer = value / 256;
207
    int fract   = value % 256;
208
209
    m_intfractpixels[i] = (uint8_t)integer;
210
    m_intfractpixels[i + m_size * 4] = (uint8_t)fract;
211
  }
212
213
#if 0
214
  for (int i = 0; i < 4; i++)
215
  {
216
    for (int j = 0; j < m_size; j++)
217
    {
218
      printf("%i %f %f\n",
219
          i * m_size + j,
220
          ((double)m_intfractpixels[j * 4 + i] + (double)m_intfractpixels[j * 4 + i + m_size * 4] / 255.0) / 255.0 * 2.0 - 1.0,
221
          m_floatpixels[j * 4 + i]);
222
    }
223
  }
224
#endif
225
}
226
(-)xbmc/cores/VideoRenderers/VideoShaders/VideoFilterShader.h (-1 / +21 lines)
Lines 4-9 Link Here
4
#ifdef HAS_GL
4
#ifdef HAS_GL
5
5
6
#include "../../../../guilib/Shader.h"
6
#include "../../../../guilib/Shader.h"
7
#include "../../../settings/VideoSettings.h"
7
8
8
using namespace Shaders;
9
using namespace Shaders;
9
10
Lines 35-41 Link Here
35
  class BicubicFilterShader : public BaseVideoFilterShader
36
  class BicubicFilterShader : public BaseVideoFilterShader
36
  {
37
  {
37
  public:
38
  public:
38
    BicubicFilterShader(float B=0.0f, float C=0.0f);
39
    BicubicFilterShader(float B=-1.0f, float C=-1.0f);
39
    void OnCompiledAndLinked();
40
    void OnCompiledAndLinked();
40
    bool OnEnabled();
41
    bool OnEnabled();
41
    void Free();
42
    void Free();
Lines 55-60 Link Here
55
    float m_C;
56
    float m_C;
56
  };
57
  };
57
58
59
  class ConvolutionFilterShader : public BaseVideoFilterShader
60
  {
61
  public:
62
    ConvolutionFilterShader(ESCALINGMETHOD method);
63
    void OnCompiledAndLinked();
64
    bool OnEnabled();
65
    void Free();
66
67
  protected:
68
    // kernel textures
69
    GLuint m_kernelTex1;
70
71
    // shader handles to kernel textures
72
    GLint m_hKernTex;
73
74
    ESCALINGMETHOD m_method;
75
    bool           m_floattex; //if float textures are supported
76
  };
77
58
} // end namespace
78
} // end namespace
59
79
60
#endif
80
#endif
(-)xbmc/cores/VideoRenderers/VideoShaders/ConvolutionKernels.h (+55 lines)
Line 0 Link Here
1
/*
2
 *      Copyright (C) 2005-2008 Team XBMC
3
 *      http://www.xbmc.org
4
 *
5
 *  This Program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2, or (at your option)
8
 *  any later version.
9
 *
10
 *  This Program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with XBMC; see the file COPYING.  If not, write to
17
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18
 *  http://www.gnu.org/copyleft/gpl.html
19
 *
20
 */
21
22
#ifndef CONVOLUTIONKERNELS
23
#define CONVOLUTIONKERNELS
24
25
#include "system.h"
26
#include "../../../settings/VideoSettings.h"
27
28
class CConvolutionKernel
29
{
30
  public:
31
    CConvolutionKernel(ESCALINGMETHOD method, int size);
32
    ~CConvolutionKernel();
33
34
    int      GetSize()           { return m_size; }
35
    float*   GetFloatPixels()    { return m_floatpixels; }
36
    uint8_t* GetIntFractPixels() { return m_intfractpixels; }
37
38
  private:
39
40
    void Lanczos2();
41
    void Lanczos3Fast();
42
    void Lanczos3();
43
    void Bicubic(double B, double C);
44
45
    double LanczosWeight(double x, double radius);
46
    double BicubicWeight(double x, double B, double C);
47
48
    void ToIntFract();
49
50
    int      m_size;
51
    float*   m_floatpixels;
52
    uint8_t* m_intfractpixels;
53
};
54
55
#endif //CONVOLUTIONKERNELS
(-)xbmc/cores/VideoRenderers/VideoShaders/Makefile (-1 / +1 lines)
Lines 1-5 Link Here
1
INCLUDES=-I. -I.. -I../../ -I../../../ -I../../../linux -I../../../../guilib
1
INCLUDES=-I. -I.. -I../../ -I../../../ -I../../../linux -I../../../../guilib
2
SRCS=YUV2RGBShader.cpp VideoFilterShader.cpp
2
SRCS=YUV2RGBShader.cpp VideoFilterShader.cpp ConvolutionKernels.cpp
3
3
4
LIB=VideoShaders.a
4
LIB=VideoShaders.a
5
5
(-)xbmc/cores/VideoRenderers/LinuxRendererGL.cpp (-17 / +28 lines)
Lines 886-891 Link Here
886
886
887
  VerifyGLState();
887
  VerifyGLState();
888
888
889
  if (m_scalingMethod == VS_SCALINGMETHOD_AUTO)
890
  {
891
    bool scaleSD = (int)m_sourceWidth < m_upscalingWidth && (int)m_sourceHeight < m_upscalingHeight &&
892
                   m_sourceHeight < 720 && m_sourceWidth < 1280;
893
894
    if (Supports(VS_SCALINGMETHOD_VDPAU_HARDWARE))
895
      m_scalingMethod = VS_SCALINGMETHOD_VDPAU_HARDWARE;
896
    else if (Supports(VS_SCALINGMETHOD_LANCZOS3_FAST) && scaleSD)
897
      m_scalingMethod = VS_SCALINGMETHOD_LANCZOS3_FAST;
898
    else
899
      m_scalingMethod = VS_SCALINGMETHOD_LINEAR;
900
  }
901
889
  switch (m_scalingMethod)
902
  switch (m_scalingMethod)
890
  {
903
  {
891
  case VS_SCALINGMETHOD_NEAREST:
904
  case VS_SCALINGMETHOD_NEAREST:
Lines 898-910 Link Here
898
    m_renderQuality = RQ_SINGLEPASS;
911
    m_renderQuality = RQ_SINGLEPASS;
899
    return;
912
    return;
900
913
914
  case VS_SCALINGMETHOD_LANCZOS2:
915
  case VS_SCALINGMETHOD_LANCZOS3_FAST:
916
  case VS_SCALINGMETHOD_LANCZOS3:
901
  case VS_SCALINGMETHOD_CUBIC:
917
  case VS_SCALINGMETHOD_CUBIC:
902
    if(!glewIsSupported("GL_ARB_texture_float"))
903
    {
904
      CLog::Log(LOGERROR, "GL: hardware doesn't support GL_ARB_texture_float");
905
      break;
906
    }
907
908
    if (!m_fbo.Initialize())
918
    if (!m_fbo.Initialize())
909
    {
919
    {
910
      CLog::Log(LOGERROR, "GL: Error initializing FBO");
920
      CLog::Log(LOGERROR, "GL: Error initializing FBO");
Lines 917-923 Link Here
917
      break;
927
      break;
918
    }
928
    }
919
929
920
    m_pVideoFilterShader = new BicubicFilterShader(0.3f, 0.3f);
930
    m_pVideoFilterShader = new ConvolutionFilterShader(m_scalingMethod);
921
    if (!m_pVideoFilterShader->CompileAndLink())
931
    if (!m_pVideoFilterShader->CompileAndLink())
922
    {
932
    {
923
      CLog::Log(LOGERROR, "GL: Error compiling and linking video filter shader");
933
      CLog::Log(LOGERROR, "GL: Error compiling and linking video filter shader");
Lines 928-935 Link Here
928
    m_renderQuality = RQ_MULTIPASS;
938
    m_renderQuality = RQ_MULTIPASS;
929
    return;
939
    return;
930
940
931
  case VS_SCALINGMETHOD_LANCZOS2:
932
  case VS_SCALINGMETHOD_LANCZOS3:
933
  case VS_SCALINGMETHOD_SINC8:
941
  case VS_SCALINGMETHOD_SINC8:
934
  case VS_SCALINGMETHOD_NEDI:
942
  case VS_SCALINGMETHOD_NEDI:
935
    CLog::Log(LOGERROR, "GL: TODO: This scaler has not yet been implemented");
943
    CLog::Log(LOGERROR, "GL: TODO: This scaler has not yet been implemented");
Lines 1895-1910 Link Here
1895
bool CLinuxRendererGL::Supports(ESCALINGMETHOD method)
1903
bool CLinuxRendererGL::Supports(ESCALINGMETHOD method)
1896
{
1904
{
1897
  if(method == VS_SCALINGMETHOD_NEAREST
1905
  if(method == VS_SCALINGMETHOD_NEAREST
1898
  || method == VS_SCALINGMETHOD_LINEAR)
1906
  || method == VS_SCALINGMETHOD_LINEAR
1907
  || method == VS_SCALINGMETHOD_AUTO)
1899
    return true;
1908
    return true;
1900
1909
1901
1910
  if(method == VS_SCALINGMETHOD_CUBIC
1902
  if(method == VS_SCALINGMETHOD_CUBIC 
1911
  || method == VS_SCALINGMETHOD_LANCZOS2
1903
  && glewIsSupported("GL_ARB_texture_float")
1912
  || method == VS_SCALINGMETHOD_LANCZOS3_FAST
1904
  && glewIsSupported("GL_EXT_framebuffer_object")
1913
  || method == VS_SCALINGMETHOD_LANCZOS3)
1905
  && m_renderMethod == RENDER_GLSL)
1914
  {
1906
    return true;
1915
    if (glewIsSupported("GL_EXT_framebuffer_object") && (m_renderMethod & RENDER_GLSL))
1907
1916
      return true;
1917
  }
1918
 
1908
  if (g_advancedSettings.m_videoHighQualityScaling != SOFTWARE_UPSCALING_DISABLED)
1919
  if (g_advancedSettings.m_videoHighQualityScaling != SOFTWARE_UPSCALING_DISABLED)
1909
  {
1920
  {
1910
    if(method == VS_SCALINGMETHOD_BICUBIC_SOFTWARE
1921
    if(method == VS_SCALINGMETHOD_BICUBIC_SOFTWARE
(-)xbmc/GUIDialogVideoSettings.cpp (+2 lines)
Lines 103-108 Link Here
103
    entries.push_back(make_pair(VS_SCALINGMETHOD_LINEAR           , 16302));
103
    entries.push_back(make_pair(VS_SCALINGMETHOD_LINEAR           , 16302));
104
    entries.push_back(make_pair(VS_SCALINGMETHOD_CUBIC            , 16303));
104
    entries.push_back(make_pair(VS_SCALINGMETHOD_CUBIC            , 16303));
105
    entries.push_back(make_pair(VS_SCALINGMETHOD_LANCZOS2         , 16304));
105
    entries.push_back(make_pair(VS_SCALINGMETHOD_LANCZOS2         , 16304));
106
    entries.push_back(make_pair(VS_SCALINGMETHOD_LANCZOS3_FAST    , 16315));
106
    entries.push_back(make_pair(VS_SCALINGMETHOD_LANCZOS3         , 16305));
107
    entries.push_back(make_pair(VS_SCALINGMETHOD_LANCZOS3         , 16305));
107
    entries.push_back(make_pair(VS_SCALINGMETHOD_SINC8            , 16306));
108
    entries.push_back(make_pair(VS_SCALINGMETHOD_SINC8            , 16306));
108
//    entries.push_back(make_pair(VS_SCALINGMETHOD_NEDI             , ?????));
109
//    entries.push_back(make_pair(VS_SCALINGMETHOD_NEDI             , ?????));
Lines 110-115 Link Here
110
    entries.push_back(make_pair(VS_SCALINGMETHOD_LANCZOS_SOFTWARE , 16308));
111
    entries.push_back(make_pair(VS_SCALINGMETHOD_LANCZOS_SOFTWARE , 16308));
111
    entries.push_back(make_pair(VS_SCALINGMETHOD_SINC_SOFTWARE    , 16309));
112
    entries.push_back(make_pair(VS_SCALINGMETHOD_SINC_SOFTWARE    , 16309));
112
    entries.push_back(make_pair(VS_SCALINGMETHOD_VDPAU_HARDWARE   , 13120));
113
    entries.push_back(make_pair(VS_SCALINGMETHOD_VDPAU_HARDWARE   , 13120));
114
    entries.push_back(make_pair(VS_SCALINGMETHOD_AUTO             , 16316));
113
115
114
    /* remove unsupported methods */
116
    /* remove unsupported methods */
115
    for(vector<pair<int, int> >::iterator it = entries.begin(); it != entries.end();)
117
    for(vector<pair<int, int> >::iterator it = entries.begin(); it != entries.end();)
(-)xbmc/Settings.cpp (-1 / +1 lines)
Lines 772-778 Link Here
772
    GetInteger(pElement, "interlacemethod", interlaceMethod, VS_INTERLACEMETHOD_NONE, VS_INTERLACEMETHOD_NONE, VS_INTERLACEMETHOD_INVERSE_TELECINE);
772
    GetInteger(pElement, "interlacemethod", interlaceMethod, VS_INTERLACEMETHOD_NONE, VS_INTERLACEMETHOD_NONE, VS_INTERLACEMETHOD_INVERSE_TELECINE);
773
    m_stSettings.m_defaultVideoSettings.m_InterlaceMethod = (EINTERLACEMETHOD)interlaceMethod;
773
    m_stSettings.m_defaultVideoSettings.m_InterlaceMethod = (EINTERLACEMETHOD)interlaceMethod;
774
    int scalingMethod;
774
    int scalingMethod;
775
    GetInteger(pElement, "scalingmethod", scalingMethod, VS_SCALINGMETHOD_LINEAR, VS_SCALINGMETHOD_NEAREST, VS_SCALINGMETHOD_CUBIC);
775
    GetInteger(pElement, "scalingmethod", scalingMethod, VS_SCALINGMETHOD_LINEAR, VS_SCALINGMETHOD_NEAREST, VS_SCALINGMETHOD_AUTO);
776
    m_stSettings.m_defaultVideoSettings.m_ScalingMethod = (ESCALINGMETHOD)scalingMethod;
776
    m_stSettings.m_defaultVideoSettings.m_ScalingMethod = (ESCALINGMETHOD)scalingMethod;
777
777
778
    GetInteger(pElement, "viewmode", m_stSettings.m_defaultVideoSettings.m_ViewMode, VIEW_MODE_NORMAL, VIEW_MODE_NORMAL, VIEW_MODE_CUSTOM);
778
    GetInteger(pElement, "viewmode", m_stSettings.m_defaultVideoSettings.m_ViewMode, VIEW_MODE_NORMAL, VIEW_MODE_NORMAL, VIEW_MODE_CUSTOM);

Return to bug 306661