Commit Graph

64 Commits

Author SHA1 Message Date
wm4 0063d94927 vo_opengl: glsl: remove trailing \
This should be no problem... but it _might_ help with #1536, so it's
worth a try.
2015-02-16 21:00:03 +01:00
Niklas Haas 4fed18e81e
vo_opengl: add support for linear scaling without CMS
This introduces a new option linear-scaling, which is now implied by
srgb, icc-profile and sigmoid-upscaling.

Notably, this means (sigmoidized) linear upscaling is now enabled by
default in opengl-hq mode. The impact should be negligible, and there
has been no observation of negative side effects of sigmoidized scaling,
so it feels safe to do so.
2015-02-06 03:37:21 +01:00
wm4 98828886d4 vo_opengl: change initialization of gamma option
Make the lazy gamma initialization less weird, and make the default
value of the "gamma" sub-option 1.0. This means --vo=opengl:help will
list the actual default value.

Also change the lower bound to 0.1 - avoids a division by zero (I don't
know how shaders handle NaN, but it's probably not a good idea to give
them this value).
2015-02-03 17:19:34 +01:00
wm4 f296dcb248 csputils, vo_opengl: remove per-component gamma
There was some code accounting for different gamma values for R/G/B.
It's inherited from an old, undocumented MPlayer feature, which was at
some point disabled for convenience by myself (meaning you couldn't
actually set separate gamma because it was removed from the property
interface - mp_csp_copy_equalizer_values() just set them to the same
value). Get rid of these meaningless leftovers.
2015-02-03 16:52:44 +01:00
Niklas Haas fa1698cb9a vo_opengl: always clamp the video to range 0-1
Before this, enabling :gamma in combination with :sigmoid and probably a few
other things results in ugly artifacts because the video isn't clamped until
after the :gamma was applied (or at all, if the cms_matrix is unused).
2015-02-03 08:47:48 +01:00
wm4 bf8abc0ca9 vo_opengl: fix shader issue with Intel drivers
Windows Intel drivers seem to reject some (AFAIK) valid GLSL. Make them
happy.

<rossy> GL_RENDERER='Intel(R) HD Graphics 4400'
<rossy> GL_VERSION='3.0.0 - Build 10.18.14.4080'
<rossy> GL_SHADING_LANGUAGE_VERSION='1.30 - Build 10.18.14.4080'
2015-01-29 15:15:14 +01:00
wm4 acb40644db vo_opengl: change the way unaligned chroma size is handled
This deals with subsampled YUV video that has odd sizes, for example a
5x5 image with 4:2:0 subsampling.

It would be easy to handle if we actually passed separate texture
coordinates for each plane to the shader, but as of now the luma
coordinates are implicitly rescaled to chroma one. If luma and chroma
sizes don't match up, and this is not handled, you'd get a chroma shift
by 1 pixel.

The existing hack worked, but broke separable scaling. This was exposed
by a recent commit which switched to GL_NEAREST sampling for FBOs. The
rendering was accidentally scaled by 1 pixel, because the FBO size used
the original video size, while textures_sizes[0] was set to the padded
texture size (i.e. one pixel larger).

It could be fixed by setting the padded texture size only on the first
shader. But somehow that is annoying, so do something else. Don't pad
textures anymore, and rescale the chroma coordinates in the shader
instead.

Seems like this somehow doesn't work with rectangle textures (and
introduces a chroma shift), but since it's only used when doing VDA
hardware decoding, and the bug occurs only with unaligned video sizes, I
don't care much.

Fixes #1523.
2015-01-27 18:09:03 +01:00
Stefano Pigozzi c29ab5a46b vo_opengl: add smoothmotion frame blending
SmoothMotion is a way to time and blend frames made popular by MadVR. It's
intended behaviour is to remove stuttering caused by mismatches between the
display refresh rate and the video fps, while preserving the video's original
artistic qualities (no soap opera effect). It's supposed to make 24fps video
playback on 60hz monitors as close as possible to a 24hz monitor.

Instead of drawing a frame once once it's pts has passed the vsync time, we
redraw at the display refresh rate, and if we detect the vsync is between two
frames we interpolated them (depending on their position relative to the vsync).
We actually interpolate as few frames as possible to avoid a blur effect as
much as possible. For example, if we were to play back a 1fps video on a 60hz
monitor, we would blend at most on 1 vsync for each frame (while the other 59
vsyncs would be rendered as is).

Frame interpolation is always done before scaling and in linear light when
possible (an ICC profile is used, or :srgb is used).
2015-01-23 09:14:41 +01:00
Niklas Haas 8eb9ddd868 vo_opengl: rename all scale options to make more sense
This emphasizes the fact that scale is used for *all* image upscaling,
with cscale only serving a minor role for subsampled material.
2015-01-22 19:40:04 +01:00
Niklas Haas 02df9886ea vo_opengl: switch to nearest neighbour for trivial resampling
This is significantly faster for FBOs on most modern GPUs, although it
did not result in a huge difference for the video source texture on the
sizes I tested. It might be more significant for 1080p or 4K content, so
it's worth revisiting this in the future.

It also renames SAMPLE_BILINEAR to SAMPLE_TRIVIAL to match the
semantics.
2015-01-22 19:40:04 +01:00
Niklas Haas 2d182fdea0
vo_opengl: implement naive anti-ringing
This is not quite the same thing as madVR's antiringing algorithm, but
it essentially does something similar.

Porting madVR's approach to elliptic coordinates will take some amount
of thought.
2015-01-22 19:39:58 +01:00
Niklas Haas 6c250505fe vo_opengl: unroll ewa_lanczos to avoid looping and unnecessary samples
This speeds up performance by a factor of something like 10%,
since it omits unnecessary checks.

This will also make adding anti-ringing easier.
2015-01-22 19:29:23 +01:00
Niklas Haas f5e48f0235 vo_opengl: clean up ewa_lanczos code
This fixes compatibility with GLES 2.0 and makes the code a bit neater
in general. It also properly forces indirect scaling for subsampled
video regardless of the lscale setting.
2015-01-22 19:29:23 +01:00
wm4 a0caadd512 vo_opengl: handle grayscale input better, add YA16 support
Simply clamp off the U/V components in the colormatrix, instead of doing
something special in the shader.

Also, since YA8/YA16 gave a plane_bits value of 16/32, and a colormatrix
calculation overflowed with 32, add a component_bits field to the image
format descriptor, which for YA8/YA16 returns 8/16 (the wrong value had
no bad consequences otherwise).
2015-01-21 19:29:18 +01:00
wm4 46a3974200 vo_opengl: remove 1D texture usage
Broke operation with GLSL.

Since 1D texture usage was apparently (and mysteriously) good for speed,
it might be added back, but it's unknown how to do so in a clean way.
2015-01-18 16:28:41 +01:00
Niklas Haas 61f5a80f10
vo_opengl: get rid of approx-gamma and make it the default as per BT.1886
After finding out more about how video mastering is done in the real
world it dawned upon me why the "hack" we figured out in #534 looks so
much better.

Since mastering studios have historically been using only CRTs, the
practice adopted for backwards compatibility was to simulate CRT
responses even on modern digital monitors, a practice so ubiquitous that
the ITU-R formalized it in R-Rec BT.1886 to be precisely gamma 2.40.

As such, we finally have enough proof to get rid of the option
altogether and just always do that.

The value 1.961 is a rounded version of my experimentally obtained
approximation of the BT.709 curve, which resulted in a value of around
1.9610336. This is the closest average match to the source brightness
while preserving the nonlinear response of the BT.1886 ideal monitor.

For playback in dark environments, it's expected that the gamma shift
should be reproduced by a user controlled setting, up to a maximum of
1.224 (2.4/1.961) for a pitch black environment.

More information:
https://developer.apple.com/library/mac/technotes/tn2257/_index.html
2015-01-16 02:17:19 +01:00
Niklas Haas 26baf5b9da
vo_opengl: add ewa_lanczos upscaler (aka jinc)
This is the polar (elliptic weighted average) version of lanczos.
This introduces a general new form of polar filters.
2015-01-15 21:20:27 +01:00
Niklas Haas 286340d7d0 video: Add sigmoidal upscaling to avoid ringing artifacts
This avoids issues when upscaling directly in linear light, and is the
recommended way to upscale images according to imagemagick.

The default slope of 6.5 offers a reasonable compromise between
ringing artifacts eliminated and ringing artifacts introduced by
sigmoid-upscaling. Same goes for the default center of 0.75.
2015-01-09 03:18:21 +01:00
Niklas Haas d66598eeed video: Remove some stale CMS code, minor cosmetics
This removes an old code path that was disabled in 016bb14.
2015-01-07 14:22:17 +01:00
wm4 d5e744d4b8 vo_opengl: remove obsolete comment in shader 2015-01-04 19:04:45 +01:00
wm4 d5a7ad630f vo_opengl: improve fallback handling with GLES
Whether we have texture_rg doesn't matter much anymore; the scaler
should be fine with this. But on ES 2.0, 1st class arrays are missing,
so even if filterable float textures should be available, it won't work.

Dithering (at least the "fruit" variant) will not work either, because
it uses floats.
2014-12-21 23:46:54 +01:00
wm4 f6dac5d884 vo_opengl: GLES does not support GL_BGRA
Apparently GLES 2 and 3 do not support this. (The implementations I
tested with were derived from desktop OpenGL and were not overly strict
with this.)

This is no problem; just use GL_RGBA and mangle the channels in the
shader.

Also disable direct support for image formats like IMGFMT_RGB555 with
GLES; at least some of them are not supported in this form, and the
formats aren't important anyway.
2014-12-20 19:23:17 +01:00
wm4 a0051b9da2 vo_opengl: add GLES 2 support
Rather basic support. Almost nothing works, and even if it does, it's
bound to be inefficient (due to texture upload). This was tested with
the nVidia desktop binary drivers, which provide GLES 2 support only.
However, nVidia is not known to be very strict about OpenGL, and the
driver is very new too, so the vo_opengl code will have bugs too.
2014-12-19 01:21:19 +01:00
wm4 1b766ab208 vo_opengl: do not use 4x3 matrix
This was a nice trick to get the mpv colormatrix directly into OpenGL,
because the memory representation happened to match.

Unfortunately, OpenGL ES 2 doesn't have glUniformMatrix4x3fv().

Even more unfortunately, the memory representation is now incompatible.
It would be nice to change it, but that would mean getting into a big
mess.
2014-12-18 22:24:45 +01:00
wm4 541f6731a0 vo_opengl: simplify the case without texture_rg
If GL_RED was not available, we used GL_ALPHA. But this is an
unnecessary complication, and it's easier to use GL_LUMINANCE instead.
With the latter, a texture will return the .r component set, and as long
as the shader doesn't look at the other components, the shader doesn't
need any changes.

Some of the changes added in 0e8fbdbd are now unneeeded.

Also, realign the entire gl_byte_formats_legacy table.
2014-12-18 14:46:59 +01:00
wm4 10befa26d9 vo_opengl: GLES 3 support
Tested with MESA on software emulation. Seems to work well, although the
default FBO format in opengl-hq disables most interesting features. I
have no idea how well it will work on real hardware (or if it does at
all).

Unfortunately, some features, including playback of 10 bit video, are
not supported. Not sure what to do about this.

GLES 2 or 1 do not work.
2014-12-17 21:48:23 +01:00
wm4 631ec3cc33 vo_opengl: glsl: stricter typing
Older GLSL dialects as well as GLES3 do not support the following things
in expressions:

- implicit conversions of integer constants to float
- arithmetic of float*vecN
2014-12-17 21:30:03 +01:00
wm4 0e8fbdbdb1 vo_opengl: remove requirement for RG textures
Features not supported are disabled (although with a misleading error
message).
2014-12-16 18:55:20 +01:00
wm4 08e9bbe3dd vo_opengl: use all filter sizes possible with the shaders
Not all filter sizes the shaders could handle were in the filter_sizes
list. The shader can handle any multiple of 4 (the sizes 2 and 6 are
special-cased to keep it simple).

Add all possible filter sizes, up to 64. 64 is ridiculously high anyway.
Most of the larger filter sizes are completely useless for upscaling,
but help with the fancy-downscaling option. (Although it would still be
more efficient to use cascaded scalers to handle downscaling better.)

I considered doing something less stupid than the hardcoded array, but
it seems this is still the simplest solution.
2014-12-08 17:08:26 +01:00
wm4 9c484cb080 vo_opengl: refactor: instantiate scaler functions at runtime
Before this commit, the convolution scaler shader functions were pre-
instantiated in the shader file. For every filter size, a corresponding
function (with the filter size as suffix) had to be present.

Change this, and make the C code emit the necessary bits.

This means the shader code is much reduced. (Although hopefully it
doesn't make shader compilation faster - it would require a really dumb
compiler if it spends its time on dead code.)

It also makes it more flexible, which is the main goal.

The DEF_SCALER0 stuff is needed because the C code writes the header of
the shader, at a point where scaler macros are not defined yet.
2014-12-08 16:24:38 +01:00
wm4 4a95be014b vo_opengl: never use 1D textures for lookup textures
This was a microoptimization for small filters which need 4 or less
weights per sample point. When I originally wrote this code, using a 1D
texture seemed to give a slight speed gain, but now I couldn't measure
any difference.

Remove this to simplify the code.
2014-12-08 15:23:21 +01:00
wm4 4cae83db76 vo_opengl: refactor: merge convolution function and sampler entrypoint
There's not much of a reason to have the actual convolution code in a
separate function. Merging them actually simplifies the code a bit, and
gets rid of the repetitious macro invocations to define the functions
for each filter size.

There should be no changes in behavior or output.
2014-12-08 14:59:57 +01:00
wm4 6adaddbe63 vo_opengl: extend filter size to 64
For better downscaling.

Maybe the list of filter sizes shouldn't be static...
2014-12-06 23:59:54 +01:00
wm4 115b165b98 vo_opengl: extend filter size to 32
Also replace the weights calculations for 8/12/16 with the generic
weight function definition macro. (The weights 2/4/6 follow slightly
different rules.)
2014-12-06 01:45:39 +01:00
Niklas Haas b584802813 vo_opengl: Linearize non-RGB sRGB files correctly (eg. JPEG)
Signed-off-by: wm4 <wm4@nowhere>
2014-11-26 21:44:36 +01:00
Niklas Haas 7e62f2b052 vo_opengl: Reword comment in shader
I didn't quite understand this comment after looking at the code again
months later, so I reworded it for better clarity.
2014-11-26 20:31:59 +01:00
wm4 aa6b7fa07b vo_opengl: draw OSD twice in 3D mode case
Apparently this is needed for correct 3D mode subtitles. In general,
it seems you need to duplicate the whole "GUI", so it's done for all
OSD elements.

This doesn't handle the "duplication" of the mouse pointer. Instead,
the mouse can be used for the top/left field only. Also, it's possible
that we should "compress" the OSD in the direction it's duplicated, but
I don't know about that.

Fixes #1124, at least partially.
2014-10-29 23:14:46 +01:00
Bin Jin 225f2e67b7 vo_opengl: remove macro operator from shader
Removes '##' operator from OpenGL shader code.
2014-08-29 20:56:03 +02:00
wm4 2c99464b47 vo_opengl: fix shader
Regression since commit f14722a4. For some reason, this worked on
nvidia, but rightfully failed on mesa.

At least in C, the ## operator indeed needs two macro arguments, and
you can't just concatenate with non-arguments.

This change will most likely fix it.

CC: @bjin
2014-08-28 00:40:37 +02:00
Bin Jin f14722a40f vo_opengl: add cparam1 and cparam2 options
Although cscale is rarely used, it's possible that params of cscale
are accidentally set to lparam1 and lparam2, which might cause
unexpected results.
2014-08-26 22:19:27 +02:00
Niklas Haas 856b57e418 vo_opengl: Make approx-gamma affect OSD/sub
Close #837

Signed-off-by: wm4 <wm4@nowhere>
2014-06-22 19:07:02 +02:00
Niklas Haas 17762a1919 video: Generate an accurate CMS matrix instead of hard-coding
This also avoids an extra matrix multiplication when using :srgb, making
that path both more efficient and also eliminating more hard-coded
values.

In addition, the previously hard-coded XYZ to RGB matrix will be
dynamically generated.
2014-06-22 19:02:06 +02:00
Niklas Haas 204fed4d5b video: Support BT.2020 constant luminance system
Signed-off-by: wm4 <wm4@nowhere>
2014-06-22 19:02:00 +02:00
Niklas Haas 70f50ddc5e video: Add support for non-BT.709 primaries
This add support for reading primary information from lavc, categorized
into BT.601-525, BT.601-625, BT.709 and BT.2020; and passes it on to the
vo. In vo_opengl, we always generate the 3dlut against the wider BT.2020
and transform our source into this colorspace in the shader.
2014-06-22 19:00:38 +02:00
Niklas Haas 86d3d11a68 video: Add BT.2020-NCL colorspace and transfer function
Source: http://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2020-0-201208-I!!PDF-E.pdf
2014-06-22 19:00:38 +02:00
Niklas Haas 6a833797db vo_opengl: Simplify and clarify color correction code
This commit:

- Changes some of the #define and variable names for clarification and
  adds comments where appropriate.
- Unifies :srgb and :icc-profile, making them fit into the same step of
  the decoding process and removing the weird interactions between both
  of them.
- Makes :icc-profile take precedence over :srgb (to significantly reduce
  the number of confusing and useless special cases)
- Moves BT709 decompanding (approximate or actual) to the shader in all
  cases, making it happen before upscaling (instead of the old 0.45
  gamma function). This is the simpler and more proper way to do it.
- Enables the approx gamma function to work with :srgb as well due to
  this (since they now share the gamma expansion code).
- Renames :icc-approx-gamma to :approx-gamma since it is no longer tied
  to the ICC options or LittleCMS.
- Uses gamma 2.4 as input space for the actual 3DLUT, this is now a
  pretty arbitrary factor but I picked 2.4 mainly because a higher pure
  power value here seems to produce visually better results with wide
  gamut profiles, rather then the previous 1.95 or BT.709.
- Adds the input gamma space to the 3dlut cache header in case we change
  it more in the future, or even make it user customizable (though I
  don't see why the latter would really be necessary).
- Fixes the OSD's gamma when using :srgb, which was previously still
  using the old (0.45) approximation in all cases.
- Updates documentation on :srgb, it was still mentioning the old
  behavior from circa a year ago.

This commit should serve to both open up and make the CMS/shader code much
more accessible and less confusing/error-prone and simultaneously also
improve the performance of 3DLUTs with wide gamut color spaces.

I would liked to have made it more modular but almost all of these
changes are interdependent, save for the documentation updates.

Note: Right now, the "3DLUT takes precedence over SRGB" logic is just
coded into gl_lcms.c's compile_shaders function. Ideally, this should be
done earlier, when parsing the options (by overriding the actual
opts.srgb flag) and output a warning to the user.

Note: I'm not sure how well this works together with real-world
subtitles that may need to be color corrected as well. I'm not sure
whether :approx-gamma needs to apply to subtitles as well. I'll need to
test this on proper files later.

Note: As of now, linear light scaling is still intrinsically tied to
either :srgb or :icc-profile. It would be thinkable to have this as an
extra option, :linear-scaling or similar, that could be used with or
without the two color management options.
2014-03-10 22:56:25 +01:00
Niklas Haas 76554ca62a vo_opengl: Use bt709_expand on OSD for :srgb
This affects the OSD only when :srgb is enabled, this still used the old
gamma approximation of 2.22 previously.
2014-03-10 22:56:25 +01:00
nand 55f4b592d1 vo_opengl: make :srgb decompand the BT.709 values correctly
This is the same issue as addressed by 257d9f1, except this time for
the :srgb option as well. (257d9f1 only addressed :icc-profile)

The conditions of the srgb_compand mix() call are also flipped to
prevent an off-by-one error.
2014-02-12 22:00:42 +01:00
wm4 dc582f2505 vo_opengl: add support for rectangle textures
This allows vo_opengl to use GL_TEXTURE_RECTANGLE textures, either by
enabling it with the 'rectangle-textures' sub-option, or by having a
hwdec backend force it. By default it's off.

The _only_ reason we're adding this is because VDA can export rectangle
textures only.
2013-12-01 23:39:13 +01:00
wm4 93feffad15 vo_opengl: blend alpha components by default
Improves display of images and video with alpha channel, especially if
the transparent regions contain (supposed to be invisible) garbage
color values.
2013-09-19 17:03:03 +02:00