2013-03-01 20:19:20 +00:00
|
|
|
/*
|
|
|
|
* This file is part of mpv.
|
|
|
|
*
|
2016-01-07 09:48:04 +00:00
|
|
|
* mpv is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2013-03-01 20:19:20 +00:00
|
|
|
*
|
|
|
|
* mpv is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2016-01-07 09:48:04 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2013-03-01 20:19:20 +00:00
|
|
|
*
|
2016-01-07 09:48:04 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2013-03-01 20:19:20 +00:00
|
|
|
*/
|
2016-01-07 09:48:04 +00:00
|
|
|
|
2013-03-01 20:19:20 +00:00
|
|
|
#ifndef MP_GL_VIDEO_H
|
|
|
|
#define MP_GL_VIDEO_H
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
2014-12-09 20:34:01 +00:00
|
|
|
#include "options/m_option.h"
|
2013-11-24 11:58:06 +00:00
|
|
|
#include "sub/osd.h"
|
2015-08-29 02:12:56 +00:00
|
|
|
#include "common.h"
|
2015-09-05 12:03:00 +00:00
|
|
|
#include "utils.h"
|
|
|
|
#include "video/out/filter_kernels.h"
|
|
|
|
|
|
|
|
// Texture units 0-5 are used by the video, and for free use by the passes
|
|
|
|
#define TEXUNIT_VIDEO_NUM 6
|
|
|
|
|
|
|
|
// Other texture units are reserved for specific purposes
|
|
|
|
#define TEXUNIT_SCALERS TEXUNIT_VIDEO_NUM
|
|
|
|
#define TEXUNIT_3DLUT (TEXUNIT_SCALERS+4)
|
|
|
|
#define TEXUNIT_DITHER (TEXUNIT_3DLUT+1)
|
2013-03-01 20:19:20 +00:00
|
|
|
|
|
|
|
struct lut3d {
|
|
|
|
uint16_t *data;
|
|
|
|
int size[3];
|
|
|
|
};
|
|
|
|
|
vo_opengl: refactor scaler configuration
This merges all of the scaler-related options into a single
configuration struct, and also cleans up the way they're passed through
the code. (For example, the scaler index is no longer threaded through
pass_sample, just the scaler configuration itself, and there's no longer
duplication of the params etc.)
In addition, this commit makes scale-down more principled, and turns it
into a scaler in its own right - so there's no longer an ugly separation
between scale and scale-down in the code.
Finally, the radius stuff has been made more proper - filters always
have a radius now (there's no more radius -1), and get a new .resizable
attribute instead for when it's tunable.
User-visible changes:
1. scale-down has been renamed dscale and now has its own set of config
options (dscale-param1, dscale-radius) etc., instead of reusing
scale-param1 (which was arguably a bug).
2. The default radius is no longer fixed at 3, but instead uses that
filter's preferred radius by default. (Scalers with a default radius
other than 3 include sinc, gaussian, box and triangle)
3. scale-radius etc. now goes down to 0.5, rather than 1.0. 0.5 is the
smallest radius that theoretically makes sense, and indeed it's used
by at least one filter (nearest).
Apart from that, it should just be internal changes only.
Note that this sets up for the refactor discussed in #1720, which would
be to merge scaler and window configurations (include parameters etc.)
into a single, simplified string. In the code, this would now basically
just mean getting rid of all the OPT_FLOATRANGE etc. lines related to
scalers and replacing them by a single function that parses a string and
updates the struct scaler_config as appropriate.
2015-03-26 00:55:32 +00:00
|
|
|
struct scaler_fun {
|
|
|
|
char *name;
|
|
|
|
float params[2];
|
|
|
|
float blur;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct scaler_config {
|
|
|
|
struct scaler_fun kernel;
|
|
|
|
struct scaler_fun window;
|
|
|
|
float radius;
|
|
|
|
float antiring;
|
2015-08-20 19:45:58 +00:00
|
|
|
int clamp;
|
vo_opengl: refactor scaler configuration
This merges all of the scaler-related options into a single
configuration struct, and also cleans up the way they're passed through
the code. (For example, the scaler index is no longer threaded through
pass_sample, just the scaler configuration itself, and there's no longer
duplication of the params etc.)
In addition, this commit makes scale-down more principled, and turns it
into a scaler in its own right - so there's no longer an ugly separation
between scale and scale-down in the code.
Finally, the radius stuff has been made more proper - filters always
have a radius now (there's no more radius -1), and get a new .resizable
attribute instead for when it's tunable.
User-visible changes:
1. scale-down has been renamed dscale and now has its own set of config
options (dscale-param1, dscale-radius) etc., instead of reusing
scale-param1 (which was arguably a bug).
2. The default radius is no longer fixed at 3, but instead uses that
filter's preferred radius by default. (Scalers with a default radius
other than 3 include sinc, gaussian, box and triangle)
3. scale-radius etc. now goes down to 0.5, rather than 1.0. 0.5 is the
smallest radius that theoretically makes sense, and indeed it's used
by at least one filter (nearest).
Apart from that, it should just be internal changes only.
Note that this sets up for the refactor discussed in #1720, which would
be to merge scaler and window configurations (include parameters etc.)
into a single, simplified string. In the code, this would now basically
just mean getting rid of all the OPT_FLOATRANGE etc. lines related to
scalers and replacing them by a single function that parses a string and
updates the struct scaler_config as appropriate.
2015-03-26 00:55:32 +00:00
|
|
|
};
|
|
|
|
|
2015-09-05 12:03:00 +00:00
|
|
|
struct scaler {
|
|
|
|
int index;
|
|
|
|
struct scaler_config conf;
|
|
|
|
double scale_factor;
|
|
|
|
bool initialized;
|
|
|
|
struct filter_kernel *kernel;
|
|
|
|
GLuint gl_lut;
|
|
|
|
GLenum gl_target;
|
|
|
|
struct fbotex sep_fbo;
|
|
|
|
bool insufficient;
|
2015-12-05 18:54:25 +00:00
|
|
|
int lut_size;
|
2015-09-05 12:03:00 +00:00
|
|
|
|
|
|
|
// kernel points here
|
|
|
|
struct filter_kernel kernel_storage;
|
|
|
|
};
|
|
|
|
|
2013-03-01 20:19:20 +00:00
|
|
|
struct gl_video_opts {
|
2015-09-08 20:46:36 +00:00
|
|
|
int dumb_mode;
|
vo_opengl: refactor scaler configuration
This merges all of the scaler-related options into a single
configuration struct, and also cleans up the way they're passed through
the code. (For example, the scaler index is no longer threaded through
pass_sample, just the scaler configuration itself, and there's no longer
duplication of the params etc.)
In addition, this commit makes scale-down more principled, and turns it
into a scaler in its own right - so there's no longer an ugly separation
between scale and scale-down in the code.
Finally, the radius stuff has been made more proper - filters always
have a radius now (there's no more radius -1), and get a new .resizable
attribute instead for when it's tunable.
User-visible changes:
1. scale-down has been renamed dscale and now has its own set of config
options (dscale-param1, dscale-radius) etc., instead of reusing
scale-param1 (which was arguably a bug).
2. The default radius is no longer fixed at 3, but instead uses that
filter's preferred radius by default. (Scalers with a default radius
other than 3 include sinc, gaussian, box and triangle)
3. scale-radius etc. now goes down to 0.5, rather than 1.0. 0.5 is the
smallest radius that theoretically makes sense, and indeed it's used
by at least one filter (nearest).
Apart from that, it should just be internal changes only.
Note that this sets up for the refactor discussed in #1720, which would
be to merge scaler and window configurations (include parameters etc.)
into a single, simplified string. In the code, this would now basically
just mean getting rid of all the OPT_FLOATRANGE etc. lines related to
scalers and replacing them by a single function that parses a string and
updates the struct scaler_config as appropriate.
2015-03-26 00:55:32 +00:00
|
|
|
struct scaler_config scaler[4];
|
2015-12-05 19:14:23 +00:00
|
|
|
int scaler_lut_size;
|
vo_opengl: refactor shader generation (part 2)
This adds stuff related to gamma, linear light, sigmoid, BT.2020-CL,
etc, as well as color management. Also adds a new gamma function (gamma22).
This adds new parameters to configure the CMS settings, in particular
letting us target simple colorspaces without requiring usage of a 3DLUT.
This adds smoothmotion. Mostly working, but it's still sensitive to
timing issues. It's based on an actual queue now, but the queue size
is kept small to avoid larger amounts of latency.
Also makes “upscale before blending” the default strategy.
This is justified because the "render after blending" thing doesn't seme
to work consistently any way (introduces stutter due to the way vsync
timing works, or something), so this behavior is a bit closer to master
and makes pausing/unpausing less weird/jumpy.
This adds the remaining scalers, including bicubic_fast, sharpen3,
sharpen5, polar filters and antiringing. Apparently, sharpen3/5 also
consult scale-param1, which was undocumented in master.
This also implements cropping and chroma transformation, plus
rotation/flipping. These are inherently part of the same logic, although
it's a bit rough around the edges in some case, mainly due to the fallback
code paths (for bilinear scaling without indirection).
2015-03-12 21:18:16 +00:00
|
|
|
float gamma;
|
|
|
|
int gamma_auto;
|
|
|
|
int target_prim;
|
|
|
|
int target_trc;
|
2015-02-06 02:37:21 +00:00
|
|
|
int linear_scaling;
|
2015-11-07 16:49:14 +00:00
|
|
|
int correct_downscaling;
|
2015-01-06 09:47:26 +00:00
|
|
|
int sigmoid_upscaling;
|
|
|
|
float sigmoid_center;
|
|
|
|
float sigmoid_slope;
|
2013-05-25 21:47:55 +00:00
|
|
|
int scaler_resizes_only;
|
2013-03-01 20:19:20 +00:00
|
|
|
int pbo;
|
|
|
|
int dither_depth;
|
2013-05-25 23:48:39 +00:00
|
|
|
int dither_algo;
|
|
|
|
int dither_size;
|
|
|
|
int temporal_dither;
|
2015-07-20 17:09:22 +00:00
|
|
|
int temporal_dither_period;
|
2013-03-01 20:19:20 +00:00
|
|
|
int fbo_format;
|
2013-09-19 14:55:56 +00:00
|
|
|
int alpha_mode;
|
2013-12-01 22:39:13 +00:00
|
|
|
int use_rectangle;
|
2014-12-09 20:34:01 +00:00
|
|
|
struct m_color background;
|
2015-03-13 18:30:31 +00:00
|
|
|
int interpolation;
|
2016-01-27 20:07:17 +00:00
|
|
|
float interpolation_threshold;
|
2015-03-23 01:42:19 +00:00
|
|
|
int blend_subs;
|
2015-03-27 12:27:40 +00:00
|
|
|
char *scale_shader;
|
|
|
|
char **pre_shaders;
|
|
|
|
char **post_shaders;
|
2015-09-05 15:39:27 +00:00
|
|
|
int deband;
|
|
|
|
struct deband_opts *deband_opts;
|
2015-09-23 20:43:27 +00:00
|
|
|
float unsharp;
|
2015-10-26 22:43:48 +00:00
|
|
|
int prescale;
|
|
|
|
int prescale_passes;
|
|
|
|
float prescale_downscaling_threshold;
|
|
|
|
struct superxbr_opts *superxbr_opts;
|
vo_opengl: implement NNEDI3 prescaler
Implement NNEDI3, a neural network based deinterlacer.
The shader is reimplemented in GLSL and supports both 8x4 and 8x6
sampling window now. This allows the shader to be licensed
under LGPL2.1 so that it can be used in mpv.
The current implementation supports uploading the NN weights (up to
51kb with placebo setting) in two different way, via uniform buffer
object or hard coding into shader source. UBO requires OpenGL 3.1,
which only guarantee 16kb per block. But I find that 64kb seems to be
a default setting for recent card/driver (which nnedi3 is targeting),
so I think we're fine here (with default nnedi3 setting the size of
weights is 9kb). Hard-coding into shader requires OpenGL 3.3, for the
"intBitsToFloat()" built-in function. This is necessary to precisely
represent these weights in GLSL. I tried several human readable
floating point number format (with really high precision as for
single precision float), but for some reason they are not working
nicely, bad pixels (with NaN value) could be produced with some
weights set.
We could also add support to upload these weights with texture, just
for compatibility reason (etc. upscaling a still image with a low end
graphics card). But as I tested, it's rather slow even with 1D
texture (we probably had to use 2D texture due to dimension size
limitation). Since there is always better choice to do NNEDI3
upscaling for still image (vapoursynth plugin), it's not implemented
in this commit. If this turns out to be a popular demand from the
user, it should be easy to add it later.
For those who wants to optimize the performance a bit further, the
bottleneck seems to be:
1. overhead to upload and access these weights, (in particular,
the shader code will be regenerated for each frame, it's on CPU
though).
2. "dot()" performance in the main loop.
3. "exp()" performance in the main loop, there are various fast
implementation with some bit tricks (probably with the help of the
intBitsToFloat function).
The code is tested with nvidia card and driver (355.11), on Linux.
Closes #2230
2015-10-28 01:37:55 +00:00
|
|
|
struct nnedi3_opts *nnedi3_opts;
|
2013-03-01 20:19:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct m_sub_options gl_video_conf;
|
2013-10-24 20:20:16 +00:00
|
|
|
extern const struct gl_video_opts gl_video_opts_hq_def;
|
2014-12-09 20:34:01 +00:00
|
|
|
extern const struct gl_video_opts gl_video_opts_def;
|
2013-03-01 20:19:20 +00:00
|
|
|
|
|
|
|
struct gl_video;
|
2015-07-01 17:24:28 +00:00
|
|
|
struct vo_frame;
|
2013-03-01 20:19:20 +00:00
|
|
|
|
2015-03-27 12:27:40 +00:00
|
|
|
struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct mpv_global *g);
|
2013-03-01 20:19:20 +00:00
|
|
|
void gl_video_uninit(struct gl_video *p);
|
2015-03-23 15:32:59 +00:00
|
|
|
void gl_video_set_osd_source(struct gl_video *p, struct osd_state *osd);
|
2015-07-16 20:43:40 +00:00
|
|
|
void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts);
|
2013-11-03 23:00:18 +00:00
|
|
|
bool gl_video_check_format(struct gl_video *p, int mp_format);
|
2013-06-07 23:35:44 +00:00
|
|
|
void gl_video_config(struct gl_video *p, struct mp_image_params *params);
|
2013-03-01 20:19:20 +00:00
|
|
|
void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b);
|
|
|
|
void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d);
|
2015-07-01 17:24:28 +00:00
|
|
|
void gl_video_render_frame(struct gl_video *p, struct vo_frame *frame, int fbo);
|
vo_opengl: refactor shader generation (part 1)
The basic idea is to use dynamically generated shaders instead of a
single monolithic file + a ton of ifdefs. Instead of having to setup
every aspect of it separately (like compiling shaders, setting uniforms,
perfoming the actual rendering steps, the GLSL parts), we generate the
GLSL on the fly, and perform the rendering at the same time. The GLSL
is regenerated every frame, but the actual compiled OpenGL-level shaders
are cached, which makes it fast again. Almost all logic can be in a
single place.
The new code is significantly more flexible, which allows us to improve
the code clarity, performance and add more features easily.
This commit is incomplete. It drops almost all previous code, and
readds only the most important things (some of them actually buggy).
The next commit will complete it - it's separate to preserve authorship
information.
2015-03-12 20:57:54 +00:00
|
|
|
void gl_video_resize(struct gl_video *p, int vp_w, int vp_h,
|
2013-03-01 20:19:20 +00:00
|
|
|
struct mp_rect *src, struct mp_rect *dst,
|
vo_opengl: refactor shader generation (part 1)
The basic idea is to use dynamically generated shaders instead of a
single monolithic file + a ton of ifdefs. Instead of having to setup
every aspect of it separately (like compiling shaders, setting uniforms,
perfoming the actual rendering steps, the GLSL parts), we generate the
GLSL on the fly, and perform the rendering at the same time. The GLSL
is regenerated every frame, but the actual compiled OpenGL-level shaders
are cached, which makes it fast again. Almost all logic can be in a
single place.
The new code is significantly more flexible, which allows us to improve
the code clarity, performance and add more features easily.
This commit is incomplete. It drops almost all previous code, and
readds only the most important things (some of them actually buggy).
The next commit will complete it - it's separate to preserve authorship
information.
2015-03-12 20:57:54 +00:00
|
|
|
struct mp_osd_res *osd);
|
2015-01-06 16:34:29 +00:00
|
|
|
struct mp_csp_equalizer;
|
|
|
|
struct mp_csp_equalizer *gl_video_eq_ptr(struct gl_video *p);
|
|
|
|
void gl_video_eq_update(struct gl_video *p);
|
2013-03-01 20:19:20 +00:00
|
|
|
|
|
|
|
void gl_video_set_debug(struct gl_video *p, bool enable);
|
|
|
|
|
2015-02-07 12:54:18 +00:00
|
|
|
float gl_video_scale_ambient_lux(float lmin, float lmax,
|
|
|
|
float rmin, float rmax, float lux);
|
|
|
|
void gl_video_set_ambient_lux(struct gl_video *p, int lux);
|
|
|
|
|
2014-12-09 16:47:02 +00:00
|
|
|
void gl_video_set_gl_state(struct gl_video *p);
|
|
|
|
void gl_video_unset_gl_state(struct gl_video *p);
|
2014-11-23 19:06:05 +00:00
|
|
|
void gl_video_reset(struct gl_video *p);
|
2015-02-04 22:37:38 +00:00
|
|
|
bool gl_video_showing_interpolated_frame(struct gl_video *p);
|
2014-12-09 16:47:02 +00:00
|
|
|
|
2013-11-03 23:00:18 +00:00
|
|
|
struct gl_hwdec;
|
|
|
|
void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec);
|
2013-03-01 20:19:20 +00:00
|
|
|
|
2015-07-16 20:43:40 +00:00
|
|
|
struct vo;
|
|
|
|
void gl_video_configure_queue(struct gl_video *p, struct vo *vo);
|
|
|
|
|
2013-03-01 20:19:20 +00:00
|
|
|
#endif
|