diff options
-rw-r--r-- | DOCS/interface-changes.rst | 7 | ||||
-rw-r--r-- | DOCS/man/options.rst | 799 | ||||
-rw-r--r-- | DOCS/man/vo.rst | 849 | ||||
-rw-r--r-- | options/m_config.c | 56 | ||||
-rw-r--r-- | options/m_config.h | 4 | ||||
-rw-r--r-- | options/m_option.c | 17 | ||||
-rw-r--r-- | options/m_option.h | 13 | ||||
-rw-r--r-- | options/options.c | 7 | ||||
-rw-r--r-- | options/options.h | 3 | ||||
-rw-r--r-- | player/command.c | 9 | ||||
-rw-r--r-- | player/main.c | 27 | ||||
-rw-r--r-- | video/out/opengl/video.c | 163 | ||||
-rw-r--r-- | video/out/opengl/video.h | 5 | ||||
-rw-r--r-- | video/out/vo.c | 3 | ||||
-rw-r--r-- | video/out/vo.h | 1 | ||||
-rw-r--r-- | video/out/vo_opengl.c | 199 | ||||
-rw-r--r-- | video/out/vo_opengl_cb.c | 78 |
17 files changed, 1139 insertions, 1101 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index 6d33c4afad..c4dfc5fe28 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -38,6 +38,13 @@ Interface changes - remove deprecated "hwdec-active" and "hwdec-detected" properties - remove "pre-shaders", "post-shaders" and "scale-shader": deprecated in favor of "user-shaders" + - remove all vo_opengl suboptions. Use global options with the same name + instead, e.g.: --vo=opengl:scale=nearest => --scale=nearest + Some options are prefixed with "opengl-", e.g. --opengl-pbo. + - remove --vo=opengl-hq. Set --profile=opengl-hq instead. Note that this + profile does not force the VO. This means if you use the --vo option to + set another VO, it won't work. But this also means it can be used with + opengl-cb. --- mpv 0.20.0 --- - add --image-display-duration option - this also means that image duration is not influenced by --mf-fps anymore in the general case (this is an diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index e723d5cbbe..a4310208c5 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -3597,6 +3597,805 @@ DVB Default: ``no`` +OpenGL renderer options +----------------------- + +The following video options are currently all specific to ``--vo=opengl`` and +``-vo=opengl-cb`` only, which are the only VOs that implement them. + +``--opengl-dumb-mode=<yes|no>`` + This mode is extremely restricted, and will disable most extended OpenGL + features. This includes high quality scalers and custom shaders! + + It is intended for hardware that does not support FBOs (including GLES, + which supports it insufficiently), or to get some more performance out of + bad or old hardware. + + This mode is forced automatically if needed, and this option is mostly + useful for debugging. It's also enabled automatically if nothing uses + features which require FBOs. + + This option might be silently removed in the future. + +``--scale=<filter>`` + + ``bilinear`` + Bilinear hardware texture filtering (fastest, very low quality). This + is the default for compatibility reasons. + + ``spline36`` + Mid quality and speed. This is the default when using ``opengl-hq``. + + ``lanczos`` + Lanczos scaling. Provides mid quality and speed. Generally worse than + ``spline36``, but it results in a slightly sharper image which is good + for some content types. The number of taps can be controlled with + ``scale-radius``, but is best left unchanged. + + (This filter is an alias for ``sinc``-windowed ``sinc``) + + ``ewa_lanczos`` + Elliptic weighted average Lanczos scaling. Also known as Jinc. + Relatively slow, but very good quality. The radius can be controlled + with ``scale-radius``. Increasing the radius makes the filter sharper + but adds more ringing. + + (This filter is an alias for ``jinc``-windowed ``jinc``) + + ``ewa_lanczossharp`` + A slightly sharpened version of ewa_lanczos, preconfigured to use an + ideal radius and parameter. If your hardware can run it, this is + probably what you should use by default. + + ``mitchell`` + Mitchell-Netravali. The ``B`` and ``C`` parameters can be set with + ``--scale-param1`` and ``--scale-param2``. This filter is very good at + downscaling (see ``--dscale``). + + ``oversample`` + A version of nearest neighbour that (naively) oversamples pixels, so + that pixels overlapping edges get linearly interpolated instead of + rounded. This essentially removes the small imperfections and judder + artifacts caused by nearest-neighbour interpolation, in exchange for + adding some blur. This filter is good at temporal interpolation, and + also known as "smoothmotion" (see ``--tscale``). + + ``linear`` + A ``--tscale`` filter. + + There are some more filters, but most are not as useful. For a complete + list, pass ``help`` as value, e.g.:: + + mpv --scale=help + +``--scale-param1=<value>``, ``--scale-param2=<value>`` + Set filter parameters. Ignored if the filter is not tunable. Currently, + this affects the following filter parameters: + + bcspline + Spline parameters (``B`` and ``C``). Defaults to 0.5 for both. + + gaussian + Scale parameter (``t``). Increasing this makes the result blurrier. + Defaults to 1. + + oversample + Minimum distance to an edge before interpolation is used. Setting this + to 0 will always interpolate edges, whereas setting it to 0.5 will + never interpolate, thus behaving as if the regular nearest neighbour + algorithm was used. Defaults to 0.0. + +``--scale-blur=<value>`` + Kernel scaling factor (also known as a blur factor). Decreasing this makes + the result sharper, increasing it makes it blurrier (default 0). If set to + 0, the kernel's preferred blur factor is used. Note that setting this too + low (eg. 0.5) leads to bad results. It's generally recommended to stick to + values between 0.8 and 1.2. + +``--scale-radius=<value>`` + Set radius for tunable filters, must be a float number between 0.5 and + 16.0. Defaults to the filter's preferred radius if not specified. Doesn't + work for every scaler and VO combination. + + Note that depending on filter implementation details and video scaling + ratio, the radius that actually being used might be different (most likely + being increased a bit). + +``--scale-antiring=<value>`` + Set the antiringing strength. This tries to eliminate ringing, but can + introduce other artifacts in the process. Must be a float number between + 0.0 and 1.0. The default value of 0.0 disables antiringing entirely. + + Note that this doesn't affect the special filters ``bilinear`` and + ``bicubic_fast``. + +``--scale-window=<window>`` + (Advanced users only) Choose a custom windowing function for the kernel. + Defaults to the filter's preferred window if unset. Use + ``--scale-window=help`` to get a list of supported windowing functions. + +``--scale-wparam=<window>`` + (Advanced users only) Configure the parameter for the window function given + by ``--scale-window``. Ignored if the window is not tunable. Currently, + this affects the following window parameters: + + kaiser + Window parameter (alpha). Defaults to 6.33. + blackman + Window parameter (alpha). Defaults to 0.16. + gaussian + Scale parameter (t). Increasing this makes the window wider. Defaults + to 1. + +``--scaler-lut-size=<4..10>`` + Set the size of the lookup texture for scaler kernels (default: 6). The + actual size of the texture is ``2^N`` for an option value of ``N``. So the + lookup texture with the default setting uses 64 samples. + + All weights are linearly interpolated from those samples, so increasing + the size of lookup table might improve the accuracy of scaler. + +``--scaler-resizes-only`` + Disable the scaler if the video image is not resized. In that case, + ``bilinear`` is used instead of whatever is set with ``--scale``. Bilinear + will reproduce the source image perfectly if no scaling is performed. + Enabled by default. Note that this option never affects ``--cscale``. + +``--opengl-pbo`` + Enable use of PBOs. On some drivers this can be faster, especially if the + source video size is huge (e.g. so called "4K" video). On other drivers it + might be slower or cause latency issues. + + In theory, this can sometimes lead to sporadic and temporary image + corruption (because reupload is not retried when it fails). + +``--dither-depth=<N|no|auto>`` + Set dither target depth to N. Default: no. + + no + Disable any dithering done by mpv. + auto + Automatic selection. If output bit depth cannot be detected, 8 bits per + component are assumed. + 8 + Dither to 8 bit output. + + Note that the depth of the connected video display device cannot be + detected. Often, LCD panels will do dithering on their own, which conflicts + with this option and leads to ugly output. + +``--dither-size-fruit=<2-8>`` + Set the size of the dither matrix (default: 6). The actual size of the + matrix is ``(2^N) x (2^N)`` for an option value of ``N``, so a value of 6 + gives a size of 64x64. The matrix is generated at startup time, and a large + matrix can take rather long to compute (seconds). + + Used in ``--dither=fruit`` mode only. + +``--dither=<fruit|ordered|no>`` + Select dithering algorithm (default: fruit). (Normally, the + ``--dither-depth`` option controls whether dithering is enabled.) + +``--temporal-dither`` + Enable temporal dithering. (Only active if dithering is enabled in + general.) This changes between 8 different dithering patterns on each frame + by changing the orientation of the tiled dithering matrix. Unfortunately, + this can lead to flicker on LCD displays, since these have a high reaction + time. + +``--temporal-dither-period=<1-128>`` + Determines how often the dithering pattern is updated when + ``--temporal-dither`` is in use. 1 (the default) will update on every video + frame, 2 on every other frame, etc. + +``--opengl-debug`` + Check for OpenGL errors, i.e. call ``glGetError()``. Also, request a + debug OpenGL context (which does nothing with current graphics drivers + as of this writing). + +``--interpolation`` + Reduce stuttering caused by mismatches in the video fps and display refresh + rate (also known as judder). + + .. warning:: This requires setting the ``--video-sync`` option to one + of the ``display-`` modes, or it will be silently disabled. + This was not required before mpv 0.14.0. + + This essentially attempts to interpolate the missing frames by convoluting + the video along the temporal axis. The filter used can be controlled using + the ``--tscale`` setting. + + Note that this relies on vsync to work, see ``--opengl-swapinterval`` for + more information. + +``--opengl-swapinterval=<n>`` + Interval in displayed frames between two buffer swaps. 1 is equivalent to + enable VSYNC, 0 to disable VSYNC. Defaults to 1 if not specified. + + Note that this depends on proper OpenGL vsync support. On some platforms + and drivers, this only works reliably when in fullscreen mode. It may also + require driver-specific hacks if using multiple monitors, to ensure mpv + syncs to the right one. Compositing window managers can also lead to bad + results, as can missing or incorrect display FPS information (see + ``--display-fps``). + +``--dscale=<filter>`` + Like ``--scale``, but apply these filters on downscaling instead. If this + option is unset, the filter implied by ``--scale`` will be applied. + +``--cscale=<filter>`` + As ``--scale``, but for interpolating chroma information. If the image is + not subsampled, this option is ignored entirely. + +``--tscale=<filter>`` + The filter used for interpolating the temporal axis (frames). This is only + used if ``--interpolation`` is enabled. The only valid choices for + ``--tscale`` are separable convolution filters (use ``--tscale=help`` to + get a list). The default is ``mitchell``. + + Note that the maximum supported filter radius is currently 3, due to + limitations in the number of video textures that can be loaded + simultaneously. + +``--tscale-clamp`` + Clamp the ``--tscale`` filter kernel's value range to [0-1]. This reduces + excessive ringing artifacts in the temporal domain (which typically + manifest themselves as short flashes or fringes of black, mostly around + moving edges) in exchange for potentially adding more blur. + +``--interpolation-threshold=<0..1,-1>`` + Threshold below which frame ratio interpolation gets disabled (default: + ``0.0001``). This is calculated as ``abs(disphz/vfps - 1) < threshold``, + where ``vfps`` is the speed-adjusted display FPS, and ``disphz`` the + display refresh rate. + + The default is intended to almost always enable interpolation if the + playback rate is even slightly different from the display refresh rate. But + note that if you use e.g. ``--video-sync=display-vdrop``, small deviations + in the rate can disable interpolation and introduce a discontinuity every + other minute. + + Set this to ``-1`` to disable this logic. + +``--dscale-radius``, ``--cscale-radius``, ``--tscale-radius``, etc. + Set filter parameters for ``--dscale``, ``--cscale`` and ``--tscale``, + respectively. + + See the corresponding options for ``--scale``. + +``--linear-scaling`` + Scale in linear light. It should only be used with a + ``--opengl-fbo-format`` that has at least 16 bit precision. + +``--correct-downscaling`` + When using convolution based filters, extend the filter size when + downscaling. Increases quality, but reduces performance while downscaling. + + This will perform slightly sub-optimally for anamorphic video (but still + better than without it) since it will extend the size to match only the + milder of the scale factors between the axes. + +``--opengl-shaders=<files>`` + Custom GLSL hooks. These are a flexible way to add custom fragment shaders, + which can be injected at almost arbitrary points in the rendering pipeline, + and access all previous intermediate textures. + + .. admonition:: Warning + + The syntax is not stable yet and may change any time. + + The general syntax of a user shader looks like this:: + + //!METADATA ARGS... + //!METADATA ARGS... + + vec4 hook() { + ... + return something; + } + + //!METADATA ARGS... + //!METADATA ARGS... + + ... + + Each block of metadata, along with the non-metadata lines after it, defines + a single pass. Each pass can set the following metadata: + + HOOK <name> (required) + The texture which to hook into. May occur multiple times within a + metadata block, up to a predetermined limit. See below for a list of + hookable textures. + + BIND <name> + Loads a texture and makes it available to the pass, and sets up macros + to enable accessing it. See below for a list of set macros. By default, + no textures are bound. The special name HOOKED can be used to refer to + the texture that triggered this pass. + + SAVE <name> + Gives the name of the texture to save the result of this pass into. By + default, this is set to the special name HOOKED which has the effect of + overwriting the hooked texture. + + WIDTH <szexpr>, HEIGHT <szexpr> + Specifies the size of the resulting texture for this pass. ``szexpr`` + refers to an expression in RPN (reverse polish notation), using the + operators + - * / > < !, floating point literals, and references to + sizes of existing texture and OUTPUT (such as MAIN.width or + CHROMA.height). By default, these are set to HOOKED.w and HOOKED.h, + respectively. + + WHEN <szexpr> + Specifies a condition that needs to be true (non-zero) for the shader + stage to be evaluated. If it fails, it will silently be omitted. (Note + that a shader stage like this which has a dependency on an optional + hook point can still cause that hook point to be saved, which has some + minor overhead) + + OFFSET ox oy + Indicates a pixel shift (offset) introduced by this pass. These pixel + offsets will be accumulated and corrected during the next scaling pass + (``cscale`` or ``scale``). The default values are 0 0 which correspond + to no shift. Note that offsets are ignored when not overwriting the + hooked texture. + + COMPONENTS n + Specifies how many components of this pass's output are relevant and + should be stored in the texture, up to 4 (rgba). By default, this value + is equal to the number of components in HOOKED. + + Each bound texture (via ``BIND``) will make available the following + definitions to that shader pass, where NAME is the name of the bound + texture: + + vec4 NAME_tex(vec2 pos) + The sampling function to use to access the texture at a certain spot + (in texture coordinate space, range [0,1]). This takes care of any + necessary normalization conversions. + vec4 NAME_texOff(vec2 offset) + Sample the texture at a certain offset in pixels. This works like + NAME_tex but additionally takes care of necessary rotations, so that + sampling at e.g. vec2(-1,0) is always one pixel to the left. + vec2 NAME_pos + The local texture coordinate of that texture, range [0,1]. + vec2 NAME_size + The (rotated) size in pixels of the texture. + mat2 NAME_rot + The rotation matrix associated with this texture. (Rotates pixel space + to texture coordinates) + vec2 NAME_pt + The (unrotated) size of a single pixel, range [0,1]. + sampler NAME_raw + The raw bound texture itself. The use of this should be avoided unless + absolutely necessary. + + In addition to these parameters, the following uniforms are also globally + available: + + float random + A random number in the range [0-1], different per frame. + int frame + A simple count of frames rendered, increases by one per frame and never + resets (regardless of seeks). + vec2 image_size + The size in pixels of the input image. + vec2 target_size + The size in pixels of the visible part of the scaled (and possibly + cropped) image. + + Internally, vo_opengl may generate any number of the following textures. + Whenever a texture is rendered and saved by vo_opengl, all of the passes + that have hooked into it will run, in the order they were added by the + user. This is a list of the legal hook points: + + RGB, LUMA, CHROMA, ALPHA, XYZ (resizable) + Source planes (raw). Which of these fire depends on the image format of + the source. + + CHROMA_SCALED, ALPHA_SCALED (fixed) + Source planes (upscaled). These only fire on subsampled content. + + NATIVE (resizable) + The combined image, in the source colorspace, before conversion to RGB. + + MAINPRESUB (resizable) + The image, after conversion to RGB, but before + ``--blend-subtitles=video`` is applied. + + MAIN (resizable) + The main image, after conversion to RGB but before upscaling. + + LINEAR (fixed) + Linear light image, before scaling. This only fires when + ``--linear-scaling`` is in effect. + + SIGMOID (fixed) + Sigmoidized light, before scaling. This only fires when + ``--sigmoid-upscaling`` is in effect. + + PREKERNEL (fixed) + The image immediately before the scaler kernel runs. + + POSTKERNEL (fixed) + The image immediately after the scaler kernel runs. + + SCALED (fixed) + The final upscaled image, before color management. + + OUTPUT (fixed) + The final output image, after color management but before dithering and + drawing to screen. + + Only the textures labelled with ``resizable`` may be transformed by the + pass. When overwriting a texture marked ``fixed``, the WIDTH, HEIGHT and + OFFSET must be left at their default values. + +``--deband`` + Enable the debanding algorithm. This greatly reduces the amount of visible + banding, blocking and other quantization artifacts, at the expensive of + very slightly blurring some of the finest details. In practice, it's + virtually always an improvement - the only reason to disable it would be + for performance. + +``--deband-iterations=<1..16>`` + The number of debanding steps to perform per sample. Each step reduces a + bit more banding, but takes time to compute. Note that the strength of each + step falls off very quickly, so high numbers (>4) are practically useless. + (Default 1) + +``--deband-threshold=<0..4096>`` + The debanding filter's cut-off threshold. Higher numbers increase the + debanding strength dramatically but progressively diminish image details. + (Default 64) + +``--deband-range=<1..64>`` + The debanding filter's initial radius. The radius increases linearly for + each iteration. A higher radius will find more gradients, but a lower + radius will smooth more aggressively. (Default 16) + + If you increase the ``--deband-iterations``, you should probably decrease + this to compensate. + +``--deband-grain=<0..4096>`` + Add some extra noise to the image. This significantly helps cover up + remaining quantization artifacts. Higher numbers add more noise. (Default + 48) + +``--sigmoid-upscaling`` + When upscaling, use a sigmoidal color transform to avoid emphasizing + ringing artifacts. This also implies ``--linear-scaling``. + +``--sigmoid-center`` + The center of the sigmoid curve used for ``--sigmoid-upscaling``, must be a + float between 0.0 and 1.0. Defaults to 0.75 if not specified. + +``--sigmoid-slope`` + The slope of the sigmoid curve used for ``--sigmoid-upscaling``, must be a + float between 1.0 and 20.0. Defaults to 6.5 if not specified. + +``--sharpen=<value>`` + If set to a value other than 0, enable an unsharp masking filter. Positive + values will sharpen the image (but add more ringing and aliasing). Negative + values will blur the image. If your GPU is powerful enough, consider + alternatives like the ``ewa_lanczossharp`` scale filter, or the + ``--scale-blur`` option. + +``--opengl-glfinish`` + Call ``glFinish()`` before and after swapping buffers (default: disabled). + Slower, but might improve results when doing framedropping. Can completely + ruin performance. The details depend entirely on the OpenGL driver. + +``--opengl-waitvsync`` + Call ``glXWaitVideoSyncSGI`` after each buffer swap (default: disabled). + This may or may not help with video timing accuracy and frame drop. It's + possible that this makes video output slower, or has no effect at all. + + X11/GLX only. + +``--opengl-vsync-fences=<N>`` + Synchronize the CPU to the Nth past frame using the ``GL_ARB_sync`` + extension. A value of 0 disables this behavior (default). A value of 1 + means it will synchronize to the current frame after rendering it. Like + ``--glfinish`` and ``--waitvsync``, this can lower or ruin performance. Its + advantage is that it can span multiple frames, and effectively limit the + number of frames the GPU queues ahead (which also has an influence on + vsync). + +``--opengl-dwmflush=<no|windowed|yes|auto>`` + Calls ``DwmFlush`` after swapping buffers on Windows (default: auto). It + also sets ``SwapInterval(0)`` to ignore the OpenGL timing. Values are: no + (disabled), windowed (only in windowed mode), yes (also in full screen). + + The value ``auto`` will try to determine whether the compositor is active, + and calls ``DwmFlush`` only if it seems to be. + + This may help to get more consistent frame intervals, especially with + high-fps clips - which might also reduce dropped frames. Typically, a value + of ``windowed`` should be enough, since full screen may bypass the DWM. + + Windows only. + +``--opengl-dcomposition=<yes|no>`` + Allows DirectComposition when using the ANGLE backend (default: yes). + DirectComposition implies flip-model presentation, which can improve + rendering efficiency on Windows 8+ by avoiding a copy of the video frame. + mpv uses it by default where possible, but it can cause poor behaviour with + some drivers, such as a black screen or graphical corruption when leaving + full-screen mode. Use "no" to disable it. + + Windows with ANGLE only. + +``--opengl-sw`` + Continue even if a software renderer is detected. + +``--opengl-backend=<sys>`` + The value ``auto`` (the default) selects the windowing backend. You can + also pass ``help`` to get a complete list of compiled in backends (sorted + by autoprobe order). + + auto + auto-select (default) + cocoa + Cocoa/OS X + win + Win32/WGL + angle + Direct3D11 through the OpenGL ES translation layer ANGLE. This supports + almost everything the ``win`` backend does (if the ANGLE build is new + enough). + dxinterop (experimental) + Win32, using WGL for rendering and Direct3D 9Ex for presentation. Works + on Nvidia and AMD. Newer Intel chips with the latest drivers may also + work. + x11 + X11/GLX + wayland + Wayland/EGL + drm-egl + DRM/EGL + x11egl + X11/EGL + +``--opengl-es=<mode>`` + Select whether to use GLES: + + yes + Try to prefer ES over Desktop GL + no + Try to prefer desktop GL over ES + auto + Use the default for each backend (default) + +``--opengl-fbo-format=<fmt>`` + Selects the internal format of textures used for FBOs. The format can + influence performance and quality of the video output. ``fmt`` can be one + of: rgb8, rgb10, rgb10_a2, rgb16, rgb16f, rgb32f, rgba12, rgba16, rgba16f, + rgba32f. Default: ``auto``, which maps to rgba16 on desktop GL, and rgba16f + or rgb10_a2 on GLES (e.g. ANGLE), unless GL_EXT_texture_norm16 is + available. + +``--opengl-gamma=<0.1..2.0>`` + Set a gamma value (default: 1.0). If gamma is adjusted in other ways (like + with the ``--gamma`` option or key bindings and the ``gamma`` property), + the value is multiplied with the other gamma value. + + Recommended values based on the environmental brightness: + + 1.0 + Brightly illuminated (default) + 0.9 + Slightly dim + 0.8 + Pitch black room + + NOTE: Typical movie content (Blu-ray etc.) already contains a gamma drop of + about 0.8, so specifying it here as well will result in even even darker + image than intended! + +``--gamma-auto`` + Automatically corrects the gamma value depending on ambient lighting + conditions (adding a gamma boost for dark rooms). + + With ambient illuminance of 64lux, mpv will pick the 1.0 gamma value (no + boost), and slightly increase the boost up until 0.8 for 16lux. + + NOTE: Only implemented on OS X. + +``--target-prim=<value>`` + Specifies the primaries of the display. Video colors will be adapted to + this colorspace when ICC color management is not being used. Valid values + are: + + auto + Disable any adaptation (default) + bt.470m + ITU-R BT.470 M + bt.601-525 + ITU-R BT.601 (525-line SD systems, eg. NTSC), SMPTE 170M/240M + bt.601-625 + ITU-R BT.601 (625-line SD systems, eg. PAL/SECAM), ITU-R BT.470 B/G + bt.709 + ITU-R BT.709 (HD), IEC 61966-2-4 (sRGB), SMPTE RP177 Annex B + bt.2020 + ITU-R BT.2020 (UHD) + apple + Apple RGB + adobe + Adobe RGB (1998) + prophoto + ProPhoto RGB (ROMM) + cie1931 + CIE 1931 RGB (not to be confused with CIE XYZ) + dci-p3 + DCI-P3 (Digital Cinema Colorspace), SMPTE RP431-2 + v-gamut + Panasonic V-Gamut (VARICAM) primaries + +``--target-trc=<value>`` + Specifies the transfer characteristics (gamma) of the display. Video colors + will be adjusted to this curve when ICC color management is not being used. + Valid values are: + + auto + Disable any adaptation (default) + bt.1886 + ITU-R BT.1886 curve (assuming infinite contrast) + srgb + IEC 61966-2-4 (sRGB) + linear + Linear light output + gamma1.8 + Pure power curve (gamma 1.8), also used for Apple RGB + gamma2.2 + Pure power curve (gamma 2.2) + gamma2.8 + Pure power curve (gamma 2.8), also used for BT.470-BG + prophoto + ProPhoto RGB (ROMM) + st2084 + SMPTE ST2084 (HDR) curve, PQ OETF + std-b67 + ARIB STD-B67 (Hybrid Log-gamma) curve, also known as BBC/NHK HDR + v-log + Panasonic V-Log (VARICAM) curve + + NOTE: When using HDR output formats, mpv will encode to the specified + curve but it will not set any HDMI flags or other signalling that + might be required for the target device to correctly display the + HDR signal. The user should independently guarantee this before + using these signal formats for display. + +``--target-brightness=<1..100000>`` + Specifies the display's approximate brightness in cd/m^2. When playing HDR + content on a SDR display (or SDR content on an HDR display), video colors + will be tone mapped to this target brightness using the algorithm specified + by ``--hdr-tone-mapping``. The default of 250 cd/m^2 corresponds to a + typical consumer display. + +``--hdr-tone-mapping=<value>`` + Specifies the algorithm used for tone-mapping HDR images onto the target + display. Valid values are: + + clip + Hard-clip any out-of-range values. + reinhard + Reinhard tone mapping algorithm. Very simple continuous curve. + Preserves dynamic range and peak but uses nonlinear contrast. + hable + Similar to ``reinhard`` but preserves dark contrast better (slightly + sigmoidal). Developed by John Hable for use in video games. (default) + gamma + Fits a logarithmic transfer between the tone curves. + linear + Linearly stretches the entire reference gamut to (a linear multiple of) + the display. + +``--tone-mapping-param=<value>`` + Set tone mapping parameters. Ignored if the tone mapping algorithm is not + tunable. This affects the following tone mapping algorithms: + + reinhard + Specifies the local contrast coefficient at the display peak. Defaults + to 0.5, which means that in-gamut values will be about half as bright + as when clipping. + gamma + Specifies the exponent of the function. Defaults to 1.8. + linear + Specifies the scale factor to use while stretching. Defaults to 1.0. + +``--icc-profile=<file>`` + Load an ICC profile and use it to transform video RGB to screen output. + Needs LittleCMS 2 support compiled in. This option overrides the + ``--target-prim``, ``--target-trc`` and ``--icc-profile-auto`` options. + +``--icc-profile-auto`` + Automatically select the ICC display profile currently specified by the + display settings of the operating system. + + NOTE: On Windows, the default profile must be an ICC profile. WCS profiles + are not supported. + +``--icc-cache-dir=<dirname>`` + Store and load the 3D LUTs created from the ICC profile in this directory. + This can be used to speed up loading, since LittleCMS 2 can take a while to + create a 3D LUT. Note that these files contain uncompressed LUTs. Their + size depends on the ``--icc-3dlut-size``, and can be very big. + + NOTE: This is not cleaned automatically, so old, unused cache files may + stick around indefinitely. + +``--icc-intent=<value>`` + Specifies the ICC intent used for the color transformation (when using + ``--icc-profile``). + + 0 + perceptual + 1 + relative colorimetric (default) + 2 + saturation + 3 + absolute colorimetric + +``--icc-3dlut-size=<r>x<g>x<b>`` + Size of the 3D LUT generated from the ICC profile in each dimension. + Default is 64x64x64. Sizes may range from 2 to 512. + +``--icc-contrast=<0-100000>`` + Specifies an upper limit on the target device's contrast ratio. This is + detected automatically from the profile if possible, but for some profiles + it might be missing, causing the contrast to be assumed as infinite. As a + result, video may appear darker than intended. This only affects BT.1886 + content. The default of 0 means no limit. + +``--blend-subtitles=<yes|video|no>`` + Blend subtitles directly onto upscaled video frames, before interpolation + and/or color management (default: no). Enabling this causes subtitles to be + affected by ``--icc-profile``, ``--target-prim``, ``--target-trc``, + ``--interpolation``, ``--opengl-gamma`` and ``--post-shader``. It also + increases subtitle performance when using ``--interpolation``. + + The downside of enabling this is that it restricts subtitles to the visible + portion of the video, so you can't have subtitles exist in the black + margins below a video (for example). + + If ``video`` is selected, the behavior is similar to ``yes``, but subs are + drawn at the video's native resolution, and scaled along with the video. + + .. warning:: This changes the way subtitle colors are handled. Normally, + subtitle colors are assumed to be in sRGB and color managed as + such. Enabling this makes them treated as being in the video's + color space instead. This is good if you want things like + softsubbed ASS signs to match the video colors, but may cause + SRT subtitles or similar to look slightly off. + +``--alpha=<blend-tiles|blend|yes|no>`` + Decides what to do if the input has an alpha component. + + blend-tiles + Blend the frame against a 16x16 gray/white tiles background (default). + blend + Blend the frame against a black background. + yes + Try to create a framebuffer with alpha component. This only makes sense + if the video contains alpha information (which is extremely rare). May + not be supported on all platforms. If alpha framebuffers are + unavailable, it silently falls back on a normal framebuffer. Note that + if you set the ``--opengl-fbo-format`` option to a non-default value, a + format with alpha must be specified, or this won't work. + no + Ignore alpha component. + +``--opengl-rectangle-textures`` + Force use of rectangle textures (default: no). Normally this shouldn't have + any advantages over normal textures. Note that hardware decoding overrides + this flag. + +``--background=<color>`` + Color used to draw parts of the mpv window not covered by video. See + ``--osd-color`` option how colors are defined. + Miscellaneous ------------- diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index 2c7b995843..afbcbaec6a 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -20,7 +20,7 @@ normal driver parameters. See ``--vo=help`` for a list of compiled-in video output drivers. - The recommended output driver is ``--vo=opengl-hq``. All other drivers are + The recommended output driver is ``--vo=opengl``. All other drivers are for compatibility or special purposes. By default, ``--vo=opengl`` is used, but if that appears not to work, it fallback to other drivers (in the same order as listed by ``--vo=help``). @@ -276,9 +276,12 @@ Available video output drivers are: OpenGL video output driver. It supports extended scaling methods, dithering and color management. - By default, it tries to use fast and fail-safe settings. Use the alias - ``opengl-hq`` to use this driver with defaults set to high quality - rendering. + See `OpenGL renderer options`_ for options specific to this VO. + + By default, it tries to use fast and fail-safe settings. Use the + ``opengl-hq`` profile to use this driver with defaults set to high + quality rendering. (This profile is also the replacement for + ``--vo=opengl-hq``.) Requires at least OpenGL 2.1. @@ -293,838 +296,12 @@ Available video output drivers are: the hardware decoder APIs. ``opengl`` makes use of FBOs by default. Sometimes you can achieve better - quality or performance by changing the ``fbo-format`` suboption to + quality or performance by changing the ``--opengl-fbo-format`` option to ``rgb16f``, ``rgb32f`` or ``rgb``. Known problems include Mesa/Intel not accepting ``rgb16``, Mesa sometimes not being compiled with float texture support, and some OS X setups being very slow with ``rgb16`` but fast - with ``rgb32f``. If you have problems, you can also try passing the - ``dumb-mode=yes`` sub-option. - - ``dumb-mode=<yes|no>`` - This mode is extremely restricted, and will disable most extended - OpenGL features. This includes high quality scalers and custom - shaders! - - It is intended for hardware that does not support FBOs (including GLES, - which supports it insufficiently), or to get some more performance out - of bad or old hardware. - - This mode is forced automatically if needed, and this option is mostly - useful for debugging. It's also enabled automatically if nothing uses - features which require FBOs. - - This option might be silently removed in the future. - - ``scale=<filter>`` - - ``bilinear`` - Bilinear hardware texture filtering (fastest, very low quality). - This is the default for compatibility reasons. - - ``spline36`` - Mid quality and speed. This is the default when using ``opengl-hq``. - - ``lanczos`` - Lanczos scaling. Provides mid quality and speed. Generally worse - than ``spline36``, but it results in a slightly sharper image - which is good for some content types. The number of taps can be - controlled with ``scale-radius``, but is best left unchanged. - - This filter corresponds to the old ``lanczos3`` alias if the default - radius is used, while ``lanczos2`` corresponds to a radius of 2. - - (This filter is an alias for ``sinc``-windowed ``sinc``) - - ``ewa_lanczos`` - Elliptic weighted average Lanczos scaling. Also known as Jinc. - Relatively slow, but very good quality. The radius can be - controlled with ``scale-radius``. Increasing the radius makes the - filter sharper but adds more ringing. - - (This filter is an alias for ``jinc``-windowed ``jinc``) - - ``ewa_lanczossharp`` - A slightly sharpened version of ewa_lanczos, preconfigured to use - an ideal radius and parameter. If your hardware can run it, this is - probably what you should use by default. - - ``mitchell`` - Mitchell-Netravali. The ``B`` and ``C`` parameters can be set with - ``scale-param1`` and ``scale-param2``. This filter is very good at - downscaling (see ``dscale``). - - ``oversample`` - A version of nearest neighbour that (naively) oversamples pixels, - so that pixels overlapping edges get linearly interpolated instead - of rounded. This essentially removes the small imperfections and - judder artifacts caused by nearest-neighbour interpolation, in - exchange for adding some blur. This filter is good at temporal - interpolation, and also known as "smoothmotion" (see ``tscale``). - - ``linear`` - A ``tscale`` filter. - - ``custom`` - A user-defined custom shader (see ``scale-shader``). - - There are some more filters, but most are not as useful. For a complete - list, pass ``help`` as value, e.g.:: - - mpv --vo=opengl:scale=help - - ``scale-param1=<value>``, ``scale-param2=<value>`` - Set filter parameters. Ignored if the filter is not tunable. - Currently, this affects the following filter parameters: - - bcspline - Spline parameters (``B`` and ``C``). Defaults to 0.5 for both. - - gaussian - Scale parameter (``t``). Increasing this makes the result blurrier. - Defaults to 1. - - oversample - Minimum distance to an edge before interpolation is used. Setting - this to 0 will always interpolate edges, whereas setting it to 0.5 - will never interpolate, thus behaving as if the regular nearest - neighbour algorithm was used. Defaults to 0.0. - - ``scale-blur=<value>`` - Kernel scaling factor (also known as a blur factor). Decreasing this - makes the result sharper, increasing it makes it blurrier (default 0). - If set to 0, the kernel's preferred blur factor is used. Note that - setting this too low (eg. 0.5) leads to bad results. It's generally - recommended to stick to values between 0.8 and 1.2. - - ``scale-radius=<value>`` - Set radius for filters listed below, must be a float number between 0.5 - and 16.0. Defaults to the filter's preferred radius if not specified. - - ``sinc`` and derivatives, ``jinc`` and derivatives, ``gaussian``, ``box`` and ``triangle`` - - Note that depending on filter implementation details and video scaling - ratio, the radius that actually being used might be different - (most likely being increased a bit). - - ``scale-antiring=<value>`` - Set the antiringing strength. This tries to eliminate ringing, but can - introduce other artifacts in the process. Must be a float number - between 0.0 and 1.0. The default value of 0.0 disables antiringing - entirely. - - Note that this doesn't affect the special filters ``bilinear`` and - ``bicubic_fast``. - - ``scale-window=<window>`` - (Advanced users only) Choose a custom windowing function for the kernel. - Defaults to the filter's preferred window if unset. Use - ``scale-window=help`` to get a list of supported windowing functions. - - ``scale-wparam=<window>`` - (Advanced users only) Configure the parameter for the window function - given by ``scale-window``. Ignored if the window is not tunable. - Currently, this affects the following window parameters: - - kaiser - Window parameter (alpha). Defaults to 6.33. - blackman - Window parameter (alpha). Defaults to 0.16. - gaussian - Scale parameter (t). Increasing this makes the window wider. - Defaults to 1. - - ``scaler-lut-size=<4..10>`` - Set the size of the lookup texture for scaler kernels (default: 6). - The actual size of the texture is ``2^N`` for an option value of ``N``. - So the lookup texture with the default setting uses 64 samples. - - All weights are bilinearly interpolated from those samples, so - increasing the size of lookup table might improve the accuracy of - scaler. - - ``scaler-resizes-only`` - Disable the scaler if the video image is not resized. In that case, - ``bilinear`` is used instead whatever is set with ``scale``. Bilinear - will reproduce the source image perfectly if no scaling is performed. - Enabled by default. Note that this option never affects ``cscale``. - - ``pbo`` - Enable use of PBOs. On some drivers this can be faster, especially if - the source video size is huge (e.g. so called "4K" video). On other - drivers it might be slower or cause latency issues. - - In theory, this can sometimes lead to sporadic and temporary image - corruption (because reupload is not retried when it fails). - - ``dither-depth=<N|no|auto>`` - Set dither target depth to N. Default: no. - - no - Disable any dithering done by mpv. - auto - Automatic selection. If output bit depth cannot be detected, - 8 bits per component are assumed. - 8 - Dither to 8 bit output. - - Note that the depth of the connected video display device cannot be - detected. Often, LCD panels will do dithering on their own, which - conflicts with ``opengl``'s dithering and leads to ugly output. - - ``dither-size-fruit=<2-8>`` - Set the size of the dither matrix (default: 6). The actual size of - the matrix is ``(2^N) x (2^N)`` for an option value of ``N``, so a - value of 6 gives a size of 64x64. The matrix is generated at startup - time, and a large matrix can take rather long to compute (seconds). - - Used in ``dither=fruit`` mode only. - - ``dither=<fruit|ordered|no>`` - Select dithering algorithm (default: fruit). (Normally, the - ``dither-depth`` option controls whether dithering is enabled.) - - ``temporal-dither`` - Enable temporal dithering. (Only active if dithering is enabled in - general.) This changes between 8 different dithering patterns on each - frame by changing the orientation of the tiled dithering matrix. - Unfortunately, this can lead to flicker on LCD displays, since these - have a high reaction time. - - ``temporal-dither-period=<1-128>`` - Determines how often the dithering pattern is updated when - ``temporal-dither`` is in use. 1 (the default) will update on every - video frame, 2 on every other frame, etc. - - ``debug`` - Check for OpenGL errors, i.e. call ``glGetError()``. Also, request a - debug OpenGL context (which does nothing with current graphics drivers - as of this writing). - - ``interpolation`` - Reduce stuttering caused by mismatches in the video fps and display - refresh rate (also known as judder). - - .. warning:: This requires setting the ``--video-sync`` option to one - of the ``display-`` modes, or it will be silently disabled. - This was not required before mpv 0.14.0. - - This essentially attempts to interpolate the missing frames by - convoluting the video along the temporal axis. The filter used can be - controlled using the ``tscale`` setting. - - Note that this relies on vsync to work, see ``swapinterval`` for more - information. - - ``swapinterval=<n>`` - Interval in displayed frames between two buffer swaps. - 1 is equivalent to enable VSYNC, 0 to disable VSYNC. Defaults to 1 if - not specified. - - Note that this depends on proper OpenGL vsync support. On some platforms - and drivers, this only works reliably when in fullscreen mode. It may - also require driver-specific hacks if using multiple monitors, to - ensure mpv syncs to the right one. Compositing window managers can - also lead to bad results, as can missing or incorrect display FPS - information (see ``--display-fps``). - - ``dscale=<filter>`` - Like ``scale``, but apply these filters on downscaling instead. If this - option is unset, the filter implied by ``scale`` will be applied. - - ``cscale=<filter>`` - As ``scale``, but for interpolating chroma information. If the image - is not subsampled, this option is ignored entirely. - - ``tscale=<filter>`` - The filter used for interpolating the temporal axis (frames). This is - only used if ``interpolation`` is enabled. The only valid choices - for ``tscale`` are separable convolution filters (use ``tscale=help`` - to get a list). The default is ``mitchell``. - - Note that the maximum supported filter radius is currently 3, due to - limitations in the number of video textures that can be loaded - simultaneously. - - ``tscale-clamp`` - Clamp the ``tscale`` filter kernel's value range to [0-1]. This reduces - excessive ringing artifacts in the temporal domain (which typically - manifest themselves as short flashes or fringes of black, mostly - around moving edges) in exchange for potentially adding more blur. - - ``interpolation-threshold=<0..1,-1>`` - Threshold below which frame ratio interpolation gets disabled (default: - ``0.0001``). This is calculated as ``abs(disphz/vfps - 1) < threshold``, - where ``vfps`` is the speed-adjusted display FPS, and ``disphz`` the - display refresh rate. - - The default is intended to almost always enable interpolation if the - playback rate is even slightly different from the display refresh rate. - But note that if you use e.g. ``--video-sync=display-vdrop``, small - deviations in the rate can disable interpolation and introduce a - discontinuity every other minute. - - Set this to ``-1`` to disable this logic. - - ``dscale-radius``, ``cscale-radius``, ``tscale-radius``, etc. - Set filter parameters for ``dscale``, ``cscale`` and ``tscale``, - respectively. - - See the corresponding options for ``scale``. - - ``linear-scaling`` - Scale in linear light. It should only be used with a ``fbo-format`` - that has at least 16 bit precision. - - ``correct-downscaling`` - When using convolution based filters, extend the filter size - when downscaling. Increases quality, but reduces performance while - downscaling. - - This will perform slightly sub-optimally for anamorphic video (but still - better than without it) since it will extend the size to match only the - milder of the scale factors between the axes. - - ``user-shaders=<files>`` - Custom GLSL hooks. These are a flexible way to add custom fragment - shaders, which can be injected at almost arbitrary points in the - rendering pipeline, and access all previous intermediate textures. - - .. admonition:: Warning - - The syntax is not stable yet and may change any time. - - The general syntax of a user shader looks like this:: - - //!METADATA ARGS... - //!METADATA ARGS... - - vec4 hook() { - ... - return something; - } - - //!METADATA ARGS... - //!METADATA ARGS... - - ... - - Each block of metadata, along with the non-metadata lines after it, - defines a single pass. Each pass can set the following metadata: - - HOOK <name> (required) - The texture which to hook into. May occur multiple times within a - metadata block, up to a predetermined limit. See below for a list - of hookable textures. - - BIND <name> - Loads a texture and makes it available to the pass, and sets up - macros to enable accessing it. See below for a list of set macros. - By default, no textures are bound. The special name HOOKED can be - used to refer to the texture that triggered this pass. - - SAVE <name> - Gives the name of the texture to save the result of this pass - into. By default, this is set to the special name HOOKED which has - the effect of overwriting the hooked texture. - - WIDTH <szexpr>, HEIGHT <szexpr> - Specifies the size of the resulting texture for this pass. - ``szexpr`` refers to an expression in RPN (reverse polish - notation), using the operators + - * / > < !, floating point - literals, and references to sizes of existing texture and OUTPUT - (such as MAIN.width or CHROMA.height). By default, these are set to - HOOKED.w and HOOKED.h, respectively. - - WHEN <szexpr> - Specifies a condition that needs to be true (non-zero) for the - shader stage to be evaluated. If it fails, it will silently be - omitted. (Note that a shader stage like this which has a dependency - on an optional hook point can still cause that hook point to be - saved, which has some minor overhead) - - OFFSET ox oy - Indicates a pixel shift (offset) introduced by this pass. These - pixel offsets will be accumulated and corrected during the - next scaling pass (``cscale`` or ``scale``). The default values - are 0 0 which correspond to no shift. Note that offsets are ignored - when not overwriting the hooked texture. - - COMPONENTS n - Specifies how many components of this pass's output are relevant - and should be stored in the texture, up to 4 (rgba). By default, - this value is equal to the number of components in HOOKED. - - Each bound texture (via ``BIND``) will make available the following - definitions to that shader pass, where NAME is the name of the bound - texture: - - vec4 NAME_tex(vec2 pos) - The sampling function to use to access the texture at a certain - spot (in texture coordinate space, range [0,1]). This takes care - of any necessary normalization conversions. - vec4 NAME_texOff(vec2 offset) - Sample the texture at a certain offset in pixels. This works like - NAME_tex but additionally takes care of necessary rotations, so - that sampling at e.g. vec2(-1,0) is always one pixel to the left. - vec2 NAME_pos - The local texture coordinate of that texture, range [0,1]. - vec2 NAME_size - The (rotated) size in pixels of the texture. - mat2 NAME_rot - The rotation matrix associated with this texture. (Rotates - pixel space to texture coordinates) - vec2 NAME_pt - The (unrotated) size of a single pixel, range [0,1]. - sampler NAME_raw - The raw bound texture itself. The use of this should be - avoided unless absolutely necessary. - - In addition to these parameters, the following uniforms are also - globally available: - - float random - A random number in the range [0-1], different per frame. - int frame - A simple count of frames rendered, increases by one per frame and - never resets (regardless of seeks). - vec2 image_size - The size in pixels of the input image. - vec2 target_size - The size in pixels of the visible part of the scaled (and possibly - cropped) image. - - Internally, vo_opengl may generate any number of the following - textures. Whenever a texture is rendered and saved by vo_opengl, all of - the passes that have hooked into it will run, in the order they were - added by the user. This is a list of the legal hook points: - - RGB, LUMA, CHROMA, ALPHA, XYZ (resizable) - Source planes (raw). Which of these fire depends on the image - format of the source. - - CHROMA_SCALED, ALPHA_SCALED (fixed) - Source planes (upscaled). These only fire on subsampled content. - - NATIVE (resizable) - The combined image, in the source colorspace, before conversion - to RGB. - - MAINPRESUB (resizable) - The image, after conversion to RGB, but before - ``blend-subtitles=video`` is applied. - - MAIN (resizable) - The main image, after conversion to RGB but before upscaling. - - LINEAR (fixed) - Linear light image, before scaling. This only fires when - ``linear-scaling`` is in effect. - - SIGMOID (fixed) - Sigmoidized light, before scaling. This only fires when - ``sigmoid-upscaling`` is in effect. - - PREKERNEL (fixed) - The image immediately before the scaler kernel runs. - - POSTKERNEL (fixed) - The image immediately after the scaler kernel runs. - - SCALED (fixed) - The final upscaled image, before color management. - - OUTPUT (fixed) - The final output image, after color management but before - dithering and drawing to screen. - - Only the textures labelled with ``resizable`` may be transformed by the - pass. When overwriting a texture marked ``fixed``, the WIDTH, HEIGHT - and OFFSET must be left at their default values. - - ``deband`` - Enable the debanding algorithm. This greatly reduces the amount of - visible banding, blocking and other quantization artifacts, at the - expensive of very slightly blurring some of the finest details. In - practice, it's virtually always an improvement - the only reason to - disable it would be for performance. - - ``deband-iterations=<1..16>`` - The number of debanding steps to perform per sample. Each step reduces - a bit more banding, but takes time to compute. Note that the strength - of each step falls off very quickly, so high numbers (>4) are - practically useless. (Default 1) - - ``deband-threshold=<0..4096>`` - The debanding filter's cut-off threshold. Higher numbers increase the - debanding strength dramatically but progressively diminish image - details. (Default 64) - - ``deband-range=<1..64>`` - The debanding filter's initial radius. The radius increases linearly - for each iteration. A higher radius will find more gradients, but - a lower radius will smooth more aggressively. (Default 16) - - If you increase the ``deband-iterations``, you should probably - decrease this to compensate. - - ``deband-grain=<0..4096>`` - Add some extra noise to the image. This significantly helps cover up - remaining quantization artifacts. Higher numbers add more noise. - (Default 48) - - ``sigmoid-upscaling`` - When upscaling, use a sigmoidal color transform to avoid emphasizing - ringing artifacts. This also implies ``linear-scaling``. - - ``sigmoid-center`` - The center of the sigmoid curve used for ``sigmoid-upscaling``, must - be a float between 0.0 and 1.0. Defaults to 0.75 if not specified. - - ``sigmoid-slope`` - The slope of the sigmoid curve used for ``sigmoid-upscaling``, must - be a float between 1.0 and 20.0. Defaults to 6.5 if not specified. - - ``sharpen=<value>`` - If set to a value other than 0, enable an unsharp masking filter. - Positive values will sharpen the image (but add more ringing and - aliasing). Negative values will blur the image. If your GPU is powerful - enough, consider alternatives like the ``ewa_lanczossharp`` scale - filter, or the ``scale-blur`` sub-option. - - (This feature is the replacement for the old ``sharpen3`` and - ``sharpen5`` scalers.) - - ``glfinish`` - Call ``glFinish()`` before and after swapping buffers (default: disabled). - Slower, but might improve results when doing framedropping. - Can completely ruin performance. The details depend entirely on the - OpenGL driver. - - ``waitvsync`` - Call ``glXWaitVideoSyncSGI`` after each buffer swap (default: disabled). - This may or may not help with video timing accuracy and frame drop. It's - possible that this makes video output slower, or has no effect at all. - - X11/GLX only. - - ``vsync-fences=<N>`` - Synchronize the CPU to the Nth past frame using the ``GL_ARB_sync`` - extension. A value of 0 disables this behavior (default). A value of - 1 means it will synchronize to the current frame after rendering it. - Like ``glfinish`` and ``waitvsync``, this can lower or ruin performance. - Its advantage is that it can span multiple frames, and effectively limit - the number of frames the GPU queues ahead (which also has an influence - on vsync). - - ``dwmflush=<no|windowed|yes|auto>`` - Calls ``DwmFlush`` after swapping buffers on Windows (default: auto). - It also sets ``SwapInterval(0)`` to ignore the OpenGL timing. Values - are: no (disabled), windowed (only in windowed mode), yes (also in - full screen). - - The value ``auto`` will try to determine whether the compositor is - active, and calls ``DwmFlush`` only if it seems to be. - - This may help to get more consistent frame intervals, especially with - high-fps clips - which might also reduce dropped frames. Typically, a - value of ``windowed`` should be enough, since full screen may bypass the - DWM. - - Windows only. - - ``dcomposition=<yes|no>`` - Allows DirectComposition when using the ANGLE backend (default: yes). - DirectComposition implies flip-model presentation, which can improve - rendering efficiency on Windows 8+ by avoiding a copy of the video frame. - mpv uses it by default where possible, but it can cause poor behaviour - with some drivers, such as a black screen or graphical corruption when - leaving full-screen mode. Use "no" to disable it. - - Windows with ANGLE only. - - ``sw`` - Continue even if a software renderer is detected. - - ``backend=<sys>`` - The value ``auto`` (the default) selects the windowing backend. You - can also pass ``help`` to get a complete list of compiled in backends - (sorted by autoprobe order). - - auto - auto-select (default) - cocoa - Cocoa/OS X - win - Win32/WGL - angle - Direct3D11 through the OpenGL ES translation layer ANGLE. This - supports almost everything the ``win`` backend does (if the ANGLE - build is new enough). - dxinterop (experimental) - Win32, using WGL for rendering and Direct3D 9Ex for presentation. - Works on Nvidia and AMD. Newer Intel chips with the latest drivers - may also work. - x11 - X11/GLX - wayland - Wayland/EGL - drm-egl - DRM/EGL - x11egl - X11/EGL - - ``es=<mode>`` - Select whether to use GLES: - - yes - Try to prefer ES over Desktop GL - no - Try to prefer desktop GL over ES - auto - Use the default for each backend (default) - - ``fbo-format=<fmt>`` - Selects the internal format of textures used for FBOs. The format can - influence performance and quality of the video output. - ``fmt`` can be one of: rgb8, rgb10, rgb10_a2, rgb16, rgb16f, - rgb32f, rgba12, rgba16, rgba16f, rgba32f. - Default: ``auto``, which maps to rgba16 on desktop GL, and rgba16f or - rgb10_a2 on GLES (e.g. ANGLE), unless GL_EXT_texture_norm16 is - available. - - ``gamma=<0.1..2.0>`` - Set a gamma value (default: 1.0). If gamma is adjusted in other ways - (like with the ``--gamma`` option or key bindings and the ``gamma`` - property), the value is multiplied with the other gamma value. - - Recommended values based on the environmental brightness: - - 1.0 - Brightly illuminated (default) - 0.9 - Slightly dim - 0.8 - Pitch black room - - NOTE: Typical movie content (Blu-ray etc.) already contains a gamma - drop of about 0.8, so specifying it here as well will result in even - even darker image than intended! - - ``gamma-auto`` - Automatically corrects the gamma value depending on ambient lighting - conditions (adding a gamma boost for dark rooms). - - With ambient illuminance of 64lux, mpv will pick the 1.0 gamma value - (no boost), and slightly increase the boost up until 0.8 for 16lux. - - NOTE: Only implemented on OS X. - - ``target-prim=<value>`` - Specifies the primaries of the display. Video colors will be adapted to - this colorspace when ICC color management is not being used. Valid - values are: - - auto - Disable any adaptation (default) - bt.470m - ITU-R BT.470 M - bt.601-525 - ITU-R BT.601 (525-line SD systems, eg. NTSC), SMPTE 170M/240M - bt.601-625 - ITU-R BT.601 (625-line SD systems, eg. PAL/SECAM), ITU-R BT.470 B/G - bt.709 - ITU-R BT.709 (HD), IEC 61966-2-4 (sRGB), SMPTE RP177 Annex B - bt.2020 - ITU-R BT.2020 (UHD) - apple - Apple RGB - adobe - Adobe RGB (1998) - prophoto - ProPhoto RGB (ROMM) - cie1931 - CIE 1931 RGB (not to be confused with CIE XYZ) - dci-p3 - DCI-P3 (Digital Cinema Colorspace), SMPTE RP431-2 - v-gamut - Panasonic V-Gamut (VARICAM) primaries - - ``target-trc=<value>`` - Specifies the transfer characteristics (gamma) of the display. Video - colors will be adjusted to this curve when ICC color management is - not being used. Valid values are: - - auto - Disable any adaptation (default) - bt.1886 - ITU-R BT.1886 curve (assuming infinite contrast) - srgb - IEC 61966-2-4 (sRGB) - linear - Linear light output - gamma1.8 - Pure power curve (gamma 1.8), also used for Apple RGB - gamma2.2 - Pure power curve (gamma 2.2) - gamma2.8 - Pure power curve (gamma 2.8), also used for BT.470-BG - prophoto - ProPhoto RGB (ROMM) - st2084 - SMPTE ST2084 (HDR) curve, PQ OETF - std-b67 - ARIB STD-B67 (Hybrid Log-gamma) curve, also known as BBC/NHK HDR - v-log - Panasonic V-Log (VARICAM) curve - - NOTE: When using HDR output formats, mpv will encode to the specified - curve but it will not set any HDMI flags or other signalling that - might be required for the target device to correctly display the - HDR signal. The user should independently guarantee this before - using these signal formats for display. - - ``target-brightness=<1..100000>`` - Specifies the display's approximate brightness in cd/m^2. When playing - HDR content on a SDR display (or SDR content on an HDR display), video - colors will be tone mapped to this target brightness using the - algorithm specified by ``hdr-tone-mapping``. The default of 250 cd/m^2 - corresponds to a typical consumer display. - - ``hdr-tone-mapping=<value>`` - Specifies the algorithm used for tone-mapping HDR images onto the - target display. Valid values are: - - clip - Hard-clip any out-of-range values. - reinhard - Reinhard tone mapping algorithm. Very simple continuous curve. - Preserves dynamic range and peak but uses nonlinear contrast. - hable - Similar to ``reinhard`` but preserves dark contrast better - (slightly sigmoidal). Developed by John Hable for use in video - games. (default) - gamma - Fits a logarithmic transfer between the tone curves. - linear - Linearly stretches the entire reference gamut to (a linear multiple - of) the display. - - ``tone-mapping-param=<value>`` - Set tone mapping parameters. Ignored if the tone mapping algorithm is - not tunable. This affects the following tone mapping algorithms: - - reinhard - Specifies the local contrast coefficient at the display peak. - Defaults to 0.5, which means that in-gamut values will be about - half as bright as when clipping. - gamma - Specifies the exponent of the function. Defaults to 1.8. - linear - Specifies the scale factor to use while stretching. Defaults to - 1.0. - - ``icc-profile=<file>`` - Load an ICC profile and use it to transform video RGB to screen output. - Needs LittleCMS 2 support compiled in. This option overrides the - ``target-prim``, ``target-trc`` and ``icc-profile-auto`` options. - - ``icc-profile-auto`` - Automatically select the ICC display profile currently specified by - the display settings of the operating system. - - NOTE: On Windows, the default profile must be an ICC profile. WCS - profiles are not supported. - - ``icc-cache-dir=<dirname>`` - Store and load the 3D LUTs created from the ICC profile in this directory. - This can be used to speed up loading, since LittleCMS 2 can take a while - to create a 3D LUT. Note that these files contain uncompressed LUTs. - Their size depends on the ``3dlut-size``, and can be very big. - - NOTE: This is not cleaned automatically, so old, unused cache files - may stick around indefinitely. - - ``icc-intent=<value>`` - Specifies the ICC intent used for the color transformation (when using - ``icc-profile``). - - 0 - perceptual - 1 - relative colorimetric (default) - 2 - saturation - 3 - absolute colorimetric - - ``3dlut-size=<r>x<g>x<b>`` - Size of the 3D LUT generated from the ICC profile in each dimension. - Default is 64x64x64. Sizes may range from 2 to 512. - - ``icc-contrast=<0-100000>`` - Specifies an upper limit on the target device's contrast ratio. - This is detected automatically from the profile if possible, but for - some profiles it might be missing, causing the contrast to be assumed - as infinite. As a result, video may appear darker than intended. This - only affects BT.1886 content. The default of 0 means no limit. - - ``blend-subtitles=<yes|video|no>`` - Blend subtitles directly onto upscaled video frames, before - interpolation and/or color management (default: no). Enabling this - causes subtitles to be affected by ``icc-profile``, ``target-prim``, - ``target-trc``, ``interpolation``, ``gamma`` and ``post-shader``. It - also increases subtitle performance when using ``interpolation``. - - The downside of enabling this is that it restricts subtitles to the - visible portion of the video, so you can't have subtitles exist in the - black margins below a video (for example). - - If ``video`` is selected, the behavior is similar to ``yes``, but subs - are drawn at the video's native resolution, and scaled along with the - video. - - .. warning:: This changes the way subtitle colors are handled. Normally, - subtitle colors are assumed to be in sRGB and color managed - as such. Enabling this makes them treated as being in the - video's color space instead. This is good if you want - things like softsubbed ASS signs to match the video colors, - but may cause SRT subtitles or similar to look slightly off. - - ``alpha=<blend-tiles|blend|yes|no>`` - Decides what to do if the input has an alpha component. - - blend-tiles - Blend the frame against a 16x16 gray/white tiles background (default). - blend - Blend the frame against a black background. - yes - Try to create a framebuffer with alpha component. This only makes sense - if the video contains alpha information (which is extremely rare). May - not be supported on all platforms. If alpha framebuffers are - unavailable, it silently falls back on a normal framebuffer. Note - that if you set the ``fbo-format`` option to a non-default value, - a format with alpha must be specified, or this won't work. - no - Ignore alpha component. - - ``rectangle-textures`` - Force use of rectangle textures (default: no). Normally this shouldn't - have any advantages over normal textures. Note that hardware decoding - overrides this flag. - - ``background=<color>`` - Color used to draw parts of the mpv window not covered by video. - See ``--osd-color`` option how colors are defined. - -``opengl-hq`` - Same as ``opengl``, but with default settings for high quality rendering. - - This is equivalent to:: - - --vo=opengl:scale=spline36:cscale=spline36:dscale=mitchell:dither-depth=auto:correct-downscaling:sigmoid-upscaling:deband:es=no - - Note that some cheaper LCDs do dithering that gravely interferes with - ``opengl``'s dithering. Disabling dithering with ``dither-depth=no`` helps. + with ``rgb32f``. If you have problems, you can also try enabling the + ``--opengl-dumb-mode=yes`` option. ``sdl`` SDL 2.0+ Render video output driver, depending on system with or without @@ -1260,10 +437,7 @@ Available video output drivers are: For use with libmpv direct OpenGL embedding; useless in any other contexts. (See ``<mpv/opengl_cb.h>``.) - This also supports many of the suboptions the ``opengl`` VO has. Run - ``mpv --vo=opengl-cb:help`` for a list. - - This also supports the ``vo-cmdline`` command. + This also supports many of the options the ``opengl`` VO has. ``rpi`` (Raspberry Pi) Native video output on the Raspberry Pi using the MMAL API. @@ -1304,3 +478,4 @@ Available video output drivers are: ``mode=<number>`` Mode ID to use (resolution, bit depth and frame rate). (default: 0) + diff --git a/options/m_config.c b/options/m_config.c index 19eb61d082..125702c362 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -257,39 +257,44 @@ struct m_config *m_config_from_obj_desc_noalloc(void *talloc_ctx, return m_config_new(talloc_ctx, log, 0, desc->priv_defaults, desc->options); } -static int m_config_set_obj_params(struct m_config *conf, char **args) +static int m_config_set_obj_params(struct m_config *config, struct mp_log *log, + struct mpv_global *global, char **args) { for (int n = 0; args && args[n * 2 + 0]; n++) { - int r = m_config_set_option(conf, bstr0(args[n * 2 + 0]), - bstr0(args[n * 2 + 1])); - if (r < 0) - return r; + const char *opt = args[n * 2 + 0]; + const char *val = args[n * 2 + 1]; + struct m_config_option *co = m_config_get_co(config, bstr0(opt)); + struct m_config *target = config; + if (co && co->opt->type == &m_option_type_subopt_legacy) { + const char *newopt = co->opt->priv; + assert(global); + target = mp_get_root_config(global); + mp_warn(log, "Using suboptions is deprecated. Use the global '--%s' " + "option instead of '%s' suboption.\n", newopt, opt); + opt = newopt; + } + if (m_config_set_option(target, bstr0(opt), bstr0(val)) < 0) + return -1; } + return 0; } -static int m_config_apply_defaults(struct m_config *config, const char *name, - struct m_obj_settings *defaults) +struct m_config *m_config_from_obj_desc_and_args(void *ta_parent, + struct mp_log *log, struct mpv_global *global, struct m_obj_desc *desc, + const char *name, struct m_obj_settings *defaults, char **args) { - int r = 0; + struct m_config *config = m_config_from_obj_desc(ta_parent, log, desc); + for (int n = 0; defaults && defaults[n].name; n++) { struct m_obj_settings *entry = &defaults[n]; if (name && strcmp(entry->name, name) == 0) { - r = m_config_set_obj_params(config, entry->attribs); - break; + if (m_config_set_obj_params(config, log, global, entry->attribs) < 0) + goto error; } } - return r; -} -struct m_config *m_config_from_obj_desc_and_args(void *ta_parent, - struct mp_log *log, struct mpv_global *global, struct m_obj_desc *desc, - const char *name, struct m_obj_settings *defaults, char **args) -{ - struct m_config *config = m_config_from_obj_desc(ta_parent, log, desc); - if (m_config_apply_defaults(config, name, defaults) < 0) - goto error; - if (m_config_set_obj_params(config, args) < 0) + if (m_config_set_obj_params(config, log, global, args) < 0) goto error; return config; @@ -1143,6 +1148,17 @@ void m_config_notify_change_co(struct m_config *config, mp_msg_update_msglevels(config->global); } +bool m_config_is_in_group(struct m_config *config, + const struct m_sub_options *group, + struct m_config_option *co) +{ + for (int n = 0; n < config->num_groups; n++) { + if (config->groups[n].group == group) + return is_group_included(config, co->group, n); + } + return false; +} + void *mp_get_config_group(void *ta_parent, struct mpv_global *global, const struct m_sub_options *group) { diff --git a/options/m_config.h b/options/m_config.h index e1fbb758b6..7a4c15a08e 100644 --- a/options/m_config.h +++ b/options/m_config.h @@ -208,6 +208,10 @@ int m_config_option_requires_param(struct m_config *config, bstr name); void m_config_notify_change_co(struct m_config *config, struct m_config_option *co); +bool m_config_is_in_group(struct m_config *config, + const struct m_sub_options *group, + struct m_config_option *co); + // Return all (visible) option names as NULL terminated string list. char **m_config_list_options(void *ta_parent, const struct m_config *config); diff --git a/options/m_option.c b/options/m_option.c index a44ca0012d..3cd9a1fb8c 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -2653,8 +2653,11 @@ static int get_obj_param(struct mp_log *log, bstr opt_name, bstr obj_name, { int r; - if (!config) - return 0; // skip + if (!config) { + *out_name = name; // preserve args for opengl-hq legacy handling + *out_val = val; + return 1; + } // va.start != NULL => of the form name=val (not positional) // If it's just "name", and the associated option exists and is a flag, @@ -3356,3 +3359,13 @@ const m_option_type_t m_option_type_alias = { const m_option_type_t m_option_type_removed = { .name = "removed", }; + +static int parse_dummy(struct mp_log *log, const m_option_t *opt, + struct bstr name, struct bstr param, void *dst) +{ + return 1; +} +const m_option_type_t m_option_type_subopt_legacy = { + .name = "legacy suboption", + .parse = parse_dummy, +}; diff --git a/options/m_option.h b/options/m_option.h index 548db319a1..d1426467e7 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -63,6 +63,7 @@ extern const m_option_type_t m_option_type_size_box; extern const m_option_type_t m_option_type_channels; extern const m_option_type_t m_option_type_aspect; extern const m_option_type_t m_option_type_node; +extern const m_option_type_t m_option_type_subopt_legacy; // Used internally by m_config.c extern const m_option_type_t m_option_type_alias; @@ -694,6 +695,12 @@ extern const char m_option_path_separator; .type = &m_option_type_subconfig, \ .priv = (void*)&subconf) +// Same as above, but for legacy suboption usage, which have no associated +// field (no actual data anywhere). +#define OPT_SUBSTRUCT_LEGACY(optname, subconf) \ + {.name = optname, .offset = -1, .type = &m_option_type_subconfig, \ + .priv = (void*)&subconf} + // Provide a another name for the option. #define OPT_ALIAS(optname, newname) \ {.name = optname, .type = &m_option_type_alias, .priv = newname, \ @@ -710,4 +717,10 @@ extern const char m_option_path_separator; {.name = optname, .type = &m_option_type_removed, .priv = msg, \ .deprecation_message = "", .offset = -1} +// Redirect a suboption (e.g. from --vo) to a global option. The redirection +// is handled as a special case instead of being applied automatically. +#define OPT_SUBOPT_LEGACY(optname, globalname) \ + {.name = optname, .type = &m_option_type_subopt_legacy, .priv = globalname, \ + .offset = -1} + #endif /* MPLAYER_M_OPTION_H */ diff --git a/options/options.c b/options/options.c index bd16a0a025..37e6c9fd61 100644 --- a/options/options.c +++ b/options/options.c @@ -73,6 +73,8 @@ extern const struct m_sub_options ad_lavc_conf; extern const struct m_sub_options input_config; extern const struct m_sub_options encode_config; extern const struct m_sub_options image_writer_conf; +extern const struct m_sub_options gl_video_conf; +extern const struct m_sub_options vo_opengl_conf; extern const struct m_obj_list vf_obj_list; extern const struct m_obj_list af_obj_list; @@ -641,6 +643,11 @@ const m_option_t mp_opts[] = { OPT_SUBSTRUCT("", vo, vo_sub_opts, 0), +#if HAVE_GL + OPT_SUBSTRUCT("", gl_video_opts, gl_video_conf, 0), + OPT_SUBSTRUCT("", vo_opengl_opts, vo_opengl_conf, 0), +#endif + #if HAVE_ENCODING OPT_SUBSTRUCT("", encode_opts, encode_config, 0), #endif diff --git a/options/options.h b/options/options.h index d450675e61..59ed7b4a43 100644 --- a/options/options.h +++ b/options/options.h @@ -331,6 +331,9 @@ typedef struct MPOpts { char *ipc_path; char *input_file; + + struct gl_video_opts *gl_video_opts; + struct vo_opengl_opts *vo_opengl_opts; } MPOpts; extern const m_option_t mp_opts[]; diff --git a/player/command.c b/player/command.c index 379ce07edb..b2ca9c0360 100644 --- a/player/command.c +++ b/player/command.c @@ -5481,7 +5481,16 @@ void mp_notify(struct MPContext *mpctx, int event, void *arg) mp_client_broadcast_event(mpctx, event, arg); } +extern const struct m_sub_options gl_video_conf; + void mp_notify_property(struct MPContext *mpctx, const char *property) { + struct m_config_option *co = m_config_get_co(mpctx->mconfig, bstr0(property)); + if (co) { + if (m_config_is_in_group(mpctx->mconfig, &gl_video_conf, co)) { + if (mpctx->video_out) + vo_control(mpctx->video_out, VOCTRL_UPDATE_RENDER_OPTS, NULL); + } + } mp_client_property_change(mpctx, property); } diff --git a/player/main.c b/player/main.c index b60c522cb0..5f20ae9891 100644 --- a/player/main.c +++ b/player/main.c @@ -134,6 +134,16 @@ static const char def_config[] = "osc=no\n" "framedrop=no\n" #endif + "\n" + "[opengl-hq]\n" + "scale=spline36\n" + "cscale=spline36\n" + "dscale=mitchell\n" + "dither-depth=auto\n" + "correct-downscaling=yes\n" + "sigmoid-upscaling=yes\n" + "deband=yes\n" + "opengl-es=no\n" ; static pthread_mutex_t terminal_owner_lock = PTHREAD_MUTEX_INITIALIZER; @@ -314,6 +324,21 @@ static bool handle_help_options(struct MPContext *mpctx) return opt_exit; } +static void handle_deprecated_options(struct MPContext *mpctx) +{ + struct MPOpts *opts = mpctx->opts; + struct m_obj_settings *vo = opts->vo->video_driver_list; + if (vo && vo->name && strcmp(vo->name, "opengl-hq") == 0) { + MP_WARN(mpctx, + "--vo=opengl-hq is deprecated! Use --profile=opengl-hq instead.\n"); + // Fudge it. This will replace the --vo option too, which is why we + // unset/safe it, and later restore it. + talloc_free(vo->name); + vo->name = talloc_strdup(NULL, "opengl"); + m_config_set_profile(mpctx->mconfig, "opengl-hq", 0); + } +} + static int cfg_include(void *ctx, char *filename, int flags) { struct MPContext *mpctx = ctx; @@ -425,6 +450,8 @@ int mp_initialize(struct MPContext *mpctx, char **options) if (handle_help_options(mpctx)) return -2; + handle_deprecated_options(mpctx); + if (!print_libav_versions(mp_null_log, 0)) { // Using mismatched libraries can be legitimate, but even then it's // a bad idea. We don't acknowledge its usefulness and stability. diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index 56005e77eb..44092897bf 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -170,6 +170,7 @@ struct gl_video { struct mp_log *log; struct gl_video_opts opts; struct gl_video_opts *opts_alloc; + struct m_config_cache *opts_cache; struct gl_lcms *cms; bool gl_debug; @@ -298,7 +299,7 @@ static const struct packed_fmt_entry mp_packed_formats[] = { {0}, }; -const struct gl_video_opts gl_video_opts_def = { +static const struct gl_video_opts gl_video_opts_def = { .dither_algo = DITHER_FRUIT, .dither_depth = -1, .dither_size = 6, @@ -324,35 +325,6 @@ const struct gl_video_opts gl_video_opts_def = { .tone_mapping_param = NAN, }; -const struct gl_video_opts gl_video_opts_hq_def = { - .dither_algo = DITHER_FRUIT, - .dither_depth = 0, - .dither_size = 6, - .temporal_dither_period = 1, - .fbo_format = 0, - .correct_downscaling = 1, - .sigmoid_center = 0.75, - .sigmoid_slope = 6.5, - .sigmoid_upscaling = 1, - .scaler = { - {{"spline36", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // scale - {{"mitchell", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // dscale - {{"spline36", .params={NAN, NAN}}, {.params = {NAN, NAN}}}, // cscale - {{"mitchell", .params={NAN, NAN}}, {.params = {NAN, NAN}}, - .clamp = 1, }, // tscale - }, - .scaler_resizes_only = 1, - .scaler_lut_size = 6, - .interpolation_threshold = 0.0001, - .alpha_mode = ALPHA_BLEND_TILES, - .background = {0, 0, 0, 255}, - .gamma = 1.0f, - .deband = 1, - .target_brightness = 250, - .hdr_tone_mapping = TONE_MAPPING_HABLE, - .tone_mapping_param = NAN, -}; - static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt, struct bstr name, struct bstr param); @@ -374,8 +346,8 @@ static int validate_window_opt(struct mp_log *log, const m_option_t *opt, const struct m_sub_options gl_video_conf = { .opts = (const m_option_t[]) { - OPT_FLAG("dumb-mode", dumb_mode, 0), - OPT_FLOATRANGE("gamma", gamma, 0, 0.1, 2.0), + OPT_FLAG("opengl-dumb-mode", dumb_mode, 0), + OPT_FLOATRANGE("opengl-gamma", gamma, 0, 0.1, 2.0), OPT_FLAG("gamma-auto", gamma_auto, 0), OPT_CHOICE_C("target-prim", target_prim, 0, mp_csp_prim_names), OPT_CHOICE_C("target-trc", target_trc, 0, mp_csp_trc_names), @@ -387,7 +359,7 @@ const struct m_sub_options gl_video_conf = { {"gamma", TONE_MAPPING_GAMMA}, {"linear", TONE_MAPPING_LINEAR})), OPT_FLOAT("tone-mapping-param", tone_mapping_param, 0), - OPT_FLAG("pbo", pbo, 0), + OPT_FLAG("opengl-pbo", pbo, 0), SCALER_OPTS("scale", SCALER_SCALE), SCALER_OPTS("dscale", SCALER_DSCALE), SCALER_OPTS("cscale", SCALER_CSCALE), @@ -399,7 +371,7 @@ const struct m_sub_options gl_video_conf = { OPT_FLAG("sigmoid-upscaling", sigmoid_upscaling, 0), OPT_FLOATRANGE("sigmoid-center", sigmoid_center, 0, 0.0, 1.0), OPT_FLOATRANGE("sigmoid-slope", sigmoid_slope, 0, 1.0, 20.0), - OPT_CHOICE("fbo-format", fbo_format, 0, + OPT_CHOICE("opengl-fbo-format", fbo_format, 0, ({"rgb8", GL_RGB8}, {"rgba8", GL_RGBA8}, {"rgb10", GL_RGB10}, @@ -426,7 +398,7 @@ const struct m_sub_options gl_video_conf = { {"yes", ALPHA_YES}, {"blend", ALPHA_BLEND}, {"blend-tiles", ALPHA_BLEND_TILES})), - OPT_FLAG("rectangle-textures", use_rectangle, 0), + OPT_FLAG("opengl-rectangle-textures", use_rectangle, 0), OPT_COLOR("background", background, 0), OPT_FLAG("interpolation", interpolation, 0), OPT_FLOAT("interpolation-threshold", interpolation_threshold, 0), @@ -434,42 +406,105 @@ const struct m_sub_options gl_video_conf = { ({"no", BLEND_SUBS_NO}, {"yes", BLEND_SUBS_YES}, {"video", BLEND_SUBS_VIDEO})), - OPT_STRINGLIST("user-shaders", user_shaders, 0), + OPT_STRINGLIST("opengl-shaders", user_shaders, 0), OPT_FLAG("deband", deband, 0), OPT_SUBSTRUCT("deband", deband_opts, deband_conf, 0), OPT_FLOAT("sharpen", unsharp, 0), OPT_SUBSTRUCT("", icc_opts, mp_icc_conf, 0), + {0} + }, + .size = sizeof(struct gl_video_opts), + .defaults = &gl_video_opts_def, +}; + +#define LEGACY_SCALER_OPTS(n) \ + OPT_SUBOPT_LEGACY(n, n), \ + OPT_SUBOPT_LEGACY(n"-param1", n"-param1"), \ + OPT_SUBOPT_LEGACY(n"-param2", n"-param2"), \ + OPT_SUBOPT_LEGACY(n"-blur", n"-blur"), \ + OPT_SUBOPT_LEGACY(n"-wparam", n"-wparam"), \ + OPT_SUBOPT_LEGACY(n"-clamp", n"-clamp"), \ + OPT_SUBOPT_LEGACY(n"-radius", n"-radius"), \ + OPT_SUBOPT_LEGACY(n"-antiring", n"-antiring"), \ + OPT_SUBOPT_LEGACY(n"-window", n"-window") + +const struct m_sub_options gl_video_conf_legacy = { + .opts = (const m_option_t[]) { + OPT_SUBOPT_LEGACY("dumb-mode", "opengl-dumb-mode"), + OPT_SUBOPT_LEGACY("gamma", "opengl-gamma"), + OPT_SUBOPT_LEGACY("gamma-auto", "gamma-auto"), + OPT_SUBOPT_LEGACY("target-prim", "target-prim"), + OPT_SUBOPT_LEGACY("target-trc", "target-trc"), + OPT_SUBOPT_LEGACY("target-brightness", "target-brightness"), + OPT_SUBOPT_LEGACY("hdr-tone-mapping", "hdr-tone-mapping"), + OPT_SUBOPT_LEGACY("tone-mapping-param", "tone-mapping-param"), + OPT_SUBOPT_LEGACY("pbo", "opengl-pbo"), + LEGACY_SCALER_OPTS("scale"), + LEGACY_SCALER_OPTS("dscale"), + LEGACY_SCALER_OPTS("cscale"), + LEGACY_SCALER_OPTS("tscale"), + OPT_SUBOPT_LEGACY("scaler-lut-size", "scaler-lut-size"), + OPT_SUBOPT_LEGACY("scaler-resizes-only", "scaler-resizes-only"), + OPT_SUBOPT_LEGACY("linear-scaling", "linear-scaling"), + OPT_SUBOPT_LEGACY("correct-downscaling", "correct-downscaling"), + OPT_SUBOPT_LEGACY("sigmoid-upscaling", "sigmoid-upscaling"), + OPT_SUBOPT_LEGACY("sigmoid-center", "sigmoid-center"), + OPT_SUBOPT_LEGACY("sigmoid-slope", "sigmoid-slope"), + OPT_SUBOPT_LEGACY("fbo-format", "opengl-fbo-format"), + OPT_SUBOPT_LEGACY("dither-depth", "dither-depth"), + OPT_SUBOPT_LEGACY("dither", "dither"), + OPT_SUBOPT_LEGACY("dither-size-fruit", "dither-size-fruit"), + OPT_SUBOPT_LEGACY("temporal-dither", "temporal-dither"), + OPT_SUBOPT_LEGACY("temporal-dither-period", "temporal-dither-period"), + OPT_SUBOPT_LEGACY("alpha", "alpha"), + OPT_SUBOPT_LEGACY("rectangle-textures", "opengl-rectangle-textures"), + OPT_SUBOPT_LEGACY("background", "background"), + OPT_SUBOPT_LEGACY("interpolation", "interpolation"), + OPT_SUBOPT_LEGACY("interpolation-threshold", "interpolation-threshold"), + OPT_SUBOPT_LEGACY("blend-subtitles", "blend-subtitles"), + OPT_SUBOPT_LEGACY("user-shaders", "opengl-shaders"), + OPT_SUBOPT_LEGACY("deband", "deband"), + OPT_SUBOPT_LEGACY("deband-iterations", "deband-iterations"), + OPT_SUBOPT_LEGACY("deband-threshold", "deband-threshold"), + OPT_SUBOPT_LEGACY("deband-range", "deband-range"), + OPT_SUBOPT_LEGACY("deband-grain", "deband-grain"), + OPT_SUBOPT_LEGACY("sharpen", "sharpen"), + OPT_SUBOPT_LEGACY("icc-profile", "icc-profile"), + OPT_SUBOPT_LEGACY("icc-profile-auto", "icc-profile-auto"), + OPT_SUBOPT_LEGACY("icc-cache-dir", "icc-cache-dir"), + OPT_SUBOPT_LEGACY("icc-intent", "icc-intent"), + OPT_SUBOPT_LEGACY("icc-contrast", "icc-contrast"), + OPT_SUBOPT_LEGACY("3dlut-size", "icc-3dlut-size"), + OPT_REMOVED("approx-gamma", "this is always enabled now"), OPT_REMOVED("cscale-down", "chroma is never downscaled"), OPT_REMOVED("scale-sep", "this is set automatically whenever sane"), OPT_REMOVED("indirect", "this is set automatically whenever sane"), OPT_REMOVED("srgb", "use target-prim=bt709:target-trc=srgb instead"), OPT_REMOVED("source-shader", "use :deband to enable debanding"), - OPT_REMOVED("prescale-luma", "use user shaders for prescaling"), - OPT_REMOVED("scale-shader", "use user-shaders instead"), - OPT_REMOVED("pre-shaders", "use user-shaders instead"), - OPT_REMOVED("post-shaders", "use user-shaders instead"), - - OPT_REPLACED("lscale", "scale"), - OPT_REPLACED("lscale-down", "scale-down"), - OPT_REPLACED("lparam1", "scale-param1"), - OPT_REPLACED("lparam2", "scale-param2"), - OPT_REPLACED("lradius", "scale-radius"), - OPT_REPLACED("lantiring", "scale-antiring"), - OPT_REPLACED("cparam1", "cscale-param1"), - OPT_REPLACED("cparam2", "cscale-param2"), - OPT_REPLACED("cradius", "cscale-radius"), - OPT_REPLACED("cantiring", "cscale-antiring"), - OPT_REPLACED("smoothmotion", "interpolation"), - OPT_REPLACED("smoothmotion-threshold", "tscale-param1"), - OPT_REPLACED("scale-down", "dscale"), - OPT_REPLACED("fancy-downscaling", "correct-downscaling"), + OPT_REMOVED("prescale-luma", "use opengl-shaders for prescaling"), + OPT_REMOVED("scale-shader", "use opengl-shaders instead"), + OPT_REMOVED("pre-shaders", "use opengl-shaders instead"), + OPT_REMOVED("post-shaders", "use opengl-shaders instead"), + + OPT_SUBOPT_LEGACY("lscale", "scale"), + OPT_SUBOPT_LEGACY("lscale-down", "scale-down"), + OPT_SUBOPT_LEGACY("lparam1", "scale-param1"), + OPT_SUBOPT_LEGACY("lparam2", "scale-param2"), + OPT_SUBOPT_LEGACY("lradius", "scale-radius"), + OPT_SUBOPT_LEGACY("lantiring", "scale-antiring"), + OPT_SUBOPT_LEGACY("cparam1", "cscale-param1"), + OPT_SUBOPT_LEGACY("cparam2", "cscale-param2"), + OPT_SUBOPT_LEGACY("cradius", "cscale-radius"), + OPT_SUBOPT_LEGACY("cantiring", "cscale-antiring"), + OPT_SUBOPT_LEGACY("smoothmotion", "interpolation"), + OPT_SUBOPT_LEGACY("smoothmotion-threshold", "tscale-param1"), + OPT_SUBOPT_LEGACY("scale-down", "dscale"), + OPT_SUBOPT_LEGACY("fancy-downscaling", "correct-downscaling"), {0} }, - .size = sizeof(struct gl_video_opts), - .defaults = &gl_video_opts_def, }; static void uninit_rendering(struct gl_video *p); @@ -3382,8 +3417,10 @@ struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct mpv_global *g) .cms = gl_lcms_init(p, log, g), .texture_16bit_depth = 16, .sc = gl_sc_create(gl, log), + .opts_cache = m_config_cache_alloc(p, g, &gl_video_conf), }; - set_options(p, NULL); + set_options(p, p->opts_cache->opts); + gl_lcms_set_options(p->cms, p->opts.icc_opts); for (int n = 0; n < SCALER_COUNT; n++) p->scaler[n] = (struct scaler){.index = n}; gl_video_set_debug(p, true); @@ -3417,12 +3454,12 @@ static void set_options(struct gl_video *p, struct gl_video_opts *src) p->opts = *p->opts_alloc; } -// Set the options, and possibly update the filter chain too. -// Note: assumes all options are valid and verified by the option parser. -void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts) +void gl_video_update_options(struct gl_video *p) { - set_options(p, opts); - reinit_from_options(p); + if (m_config_cache_update(p->opts_cache)) { + set_options(p, p->opts_cache->opts); + reinit_from_options(p); + } } static void reinit_from_options(struct gl_video *p) diff --git a/video/out/opengl/video.h b/video/out/opengl/video.h index b21112ac9f..a6c7ca2898 100644 --- a/video/out/opengl/video.h +++ b/video/out/opengl/video.h @@ -138,8 +138,7 @@ struct gl_video_opts { }; extern const struct m_sub_options gl_video_conf; -extern const struct gl_video_opts gl_video_opts_hq_def; -extern const struct gl_video_opts gl_video_opts_def; +extern const struct m_sub_options gl_video_conf_legacy; struct gl_video; struct vo_frame; @@ -147,7 +146,7 @@ struct vo_frame; struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct mpv_global *g); void gl_video_uninit(struct gl_video *p); void gl_video_set_osd_source(struct gl_video *p, struct osd_state *osd); -void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts); +void gl_video_update_options(struct gl_video *p); bool gl_video_check_format(struct gl_video *p, int mp_format); void gl_video_config(struct gl_video *p, struct mp_image_params *params); void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b); diff --git a/video/out/vo.c b/video/out/vo.c index b8b55ca58e..ee554f0e6d 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -48,7 +48,6 @@ extern const struct vo_driver video_out_x11; extern const struct vo_driver video_out_vdpau; extern const struct vo_driver video_out_xv; extern const struct vo_driver video_out_opengl; -extern const struct vo_driver video_out_opengl_hq; extern const struct vo_driver video_out_opengl_cb; extern const struct vo_driver video_out_null; extern const struct vo_driver video_out_image; @@ -105,7 +104,6 @@ const struct vo_driver *const video_out_drivers[] = &video_out_lavc, #endif #if HAVE_GL - &video_out_opengl_hq, &video_out_opengl_cb, #endif NULL @@ -188,7 +186,6 @@ const struct m_obj_list vo_obj_list = { .description = "video outputs", .aliases = { {"gl", "opengl"}, - {"gl3", "opengl-hq"}, {0} }, .allow_unknown_entries = true, diff --git a/video/out/vo.h b/video/out/vo.h index 96de569bc1..3714fbf9ca 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -102,6 +102,7 @@ enum mp_voctrl { VOCTRL_SCREENSHOT_WIN, // struct mp_image** VOCTRL_SET_COMMAND_LINE, // char** + VOCTRL_UPDATE_RENDER_OPTS, VOCTRL_GET_ICC_PROFILE, // bstr* VOCTRL_GET_AMBIENT_LUX, // int* diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index 300a3a76d0..83f5840caa 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -48,39 +48,65 @@ #define NUM_VSYNC_FENCES 10 +struct vo_opengl_opts { + int use_glFinish; + int waitvsync; + int use_gl_debug; + int allow_sw; + int swap_interval; + int dwm_flush; + int allow_direct_composition; + int vsync_fences; + char *backend; + int es; + int pattern[2]; +}; + +#define OPT_BASE_STRUCT struct vo_opengl_opts +const struct m_sub_options vo_opengl_conf = { + .opts = (const m_option_t[]) { + OPT_FLAG("opengl-glfinish", use_glFinish, 0), + OPT_FLAG("opengl-waitvsync", waitvsync, 0), + OPT_INT("opengl-swapinterval", swap_interval, 0), + OPT_CHOICE("opengl-dwmflush", dwm_flush, 0, + ({"no", -1}, {"auto", 0}, {"windowed", 1}, {"yes", 2})), + OPT_FLAG("opengl-dcomposition", allow_direct_composition, 0), + OPT_FLAG("opengl-debug", use_gl_debug, 0), + OPT_STRING_VALIDATE("opengl-backend", backend, 0, + mpgl_validate_backend_opt), + OPT_FLAG("opengl-sw", allow_sw, 0), + OPT_CHOICE("opengl-es", es, 0, ({"no", -1}, {"auto", 0}, {"yes", 1})), + OPT_INTPAIR("opengl-check-pattern", pattern, 0), + OPT_INTRANGE("opengl-vsync-fences", vsync_fences, 0, + 0, NUM_VSYNC_FENCES), + + {0} + }, + .defaults = &(const struct vo_opengl_opts){ + .swap_interval = 1, + .allow_direct_composition = 1, + }, + .size = sizeof(struct vo_opengl_opts), +}; + struct gl_priv { struct vo *vo; struct mp_log *log; MPGLContext *glctx; GL *gl; + struct vo_opengl_opts *opts; + struct gl_video *renderer; struct gl_hwdec *hwdec; int events; - void *original_opts; - - // Options - struct gl_video_opts *renderer_opts; - int use_glFinish; - int waitvsync; - int use_gl_debug; - int allow_sw; - int swap_interval; - int dwm_flush; - int allow_direct_composition; - int opt_vsync_fences; - - char *backend; - int es; - int frames_rendered; unsigned int prev_sgi_sync_count; // check-pattern sub-option; for testing/debugging - int opt_pattern[2]; int last_pattern; int matches, mismatches; @@ -107,7 +133,7 @@ static void resize(struct gl_priv *p) static void check_pattern(struct vo *vo, int item) { struct gl_priv *p = vo->priv; - int expected = p->opt_pattern[p->last_pattern]; + int expected = p->opts->pattern[p->last_pattern]; if (item == expected) { p->last_pattern++; if (p->last_pattern >= 2) @@ -125,7 +151,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) struct gl_priv *p = vo->priv; GL *gl = p->gl; - if (gl->FenceSync && p->num_vsync_fences < p->opt_vsync_fences) { + if (gl->FenceSync && p->num_vsync_fences < p->opts->vsync_fences) { GLsync fence = gl->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);; if (fence) p->vsync_fences[p->num_vsync_fences++] = fence; @@ -133,7 +159,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) gl_video_render_frame(p->renderer, frame, gl->main_fb); - if (p->use_glFinish) + if (p->opts->use_glFinish) gl->Finish(); } @@ -145,30 +171,30 @@ static void flip_page(struct vo *vo) mpgl_swap_buffers(p->glctx); p->frames_rendered++; - if (p->frames_rendered > 5 && !p->use_gl_debug) + if (p->frames_rendered > 5 && !p->opts->use_gl_debug) gl_video_set_debug(p->renderer, false); - if (p->use_glFinish) + if (p->opts->use_glFinish) gl->Finish(); - if (p->waitvsync || p->opt_pattern[0]) { + if (p->opts->waitvsync || p->opts->pattern[0]) { if (gl->GetVideoSync) { unsigned int n1 = 0, n2 = 0; gl->GetVideoSync(&n1); - if (p->waitvsync) + if (p->opts->waitvsync) gl->WaitVideoSync(2, (n1 + 1) % 2, &n2); int step = n1 - p->prev_sgi_sync_count; p->prev_sgi_sync_count = n1; MP_DBG(vo, "Flip counts: %u->%u, step=%d\n", n1, n2, step); - if (p->opt_pattern[0]) + if (p->opts->pattern[0]) check_pattern(vo, step); } else { MP_WARN(vo, "GLX_SGI_video_sync not available, disabling.\n"); - p->waitvsync = 0; - p->opt_pattern[0] = 0; + p->opts->waitvsync = 0; + p->opts->pattern[0] = 0; } } - while (p->opt_vsync_fences > 0 && p->num_vsync_fences >= p->opt_vsync_fences) { + while (p->opts->vsync_fences > 0 && p->num_vsync_fences >= p->opts->vsync_fences) { gl->ClientWaitSync(p->vsync_fences[0], GL_SYNC_FLUSH_COMMANDS_BIT, 1e9); gl->DeleteSync(p->vsync_fences[0]); MP_TARRAY_REMOVE_AT(p->vsync_fences, p->num_vsync_fences, 0); @@ -248,34 +274,6 @@ static void get_and_update_ambient_lighting(struct gl_priv *p) } } -static const struct m_option options[]; - -static const struct m_sub_options opengl_conf = { - .opts = options, - .size = sizeof(struct gl_priv), -}; - -static bool reparse_cmdline(struct vo *vo, char *args) -{ - struct gl_priv *p = vo->priv; - int r = 0; - - struct gl_priv *opts = p; - - if (strcmp(args, "-") == 0) { - opts = p->original_opts; - } else { - r = m_config_parse_suboptions(vo->config, "opengl", args); - } - - gl_video_set_options(p->renderer, opts->renderer_opts); - get_and_update_icc_profile(p); - gl_video_configure_queue(p->renderer, p->vo); - p->vo->want_redraw = true; - - return r >= 0; -} - static int control(struct vo *vo, uint32_t request, void *data) { struct gl_priv *p = vo->priv; @@ -316,9 +314,12 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_LOAD_HWDEC_API: request_hwdec_api(vo, data); return true; - case VOCTRL_SET_COMMAND_LINE: { - char *arg = data; - return reparse_cmdline(vo, arg); + case VOCTRL_UPDATE_RENDER_OPTS: { + gl_video_update_options(p->renderer); + get_and_update_icc_profile(p); + gl_video_configure_queue(p->renderer, p->vo); + p->vo->want_redraw = true; + return true; } case VOCTRL_RESET: gl_video_reset(p->renderer); @@ -390,35 +391,39 @@ static int preinit(struct vo *vo) struct gl_priv *p = vo->priv; p->vo = vo; p->log = vo->log; + p->opts = mp_get_config_group(vo, vo->global, &vo_opengl_conf); int vo_flags = 0; - if (p->renderer_opts->alpha_mode == 1) + int alpha_mode; + mp_read_option_raw(vo->global, "alpha", &m_option_type_choice, &alpha_mode); + + if (alpha_mode == 1) vo_flags |= VOFLAG_ALPHA; - if (p->use_gl_debug) + if (p->opts->use_gl_debug) vo_flags |= VOFLAG_GL_DEBUG; - if (p->es == 1) + if (p->opts->es == 1) vo_flags |= VOFLAG_GLES; - if (p->es == -1) + if (p->opts->es == -1) vo_flags |= VOFLAG_NO_GLES; - if (p->allow_sw) + if (p->opts->allow_sw) vo_flags |= VOFLAG_SW; - if (p->allow_direct_composition) + if (p->opts->allow_direct_composition) vo_flags |= VOFLAG_ANGLE_DCOMP; - p->glctx = mpgl_init(vo, p->backend, vo_flags); + p->glctx = mpgl_init(vo, p->opts->backend, vo_flags); if (!p->glctx) goto err_out; p->gl = p->glctx->gl; - p->glctx->dwm_flush_opt = p->dwm_flush; + p->glctx->dwm_flush_opt = p->opts->dwm_flush; if (p->gl->SwapInterval) { - p->gl->SwapInterval(p->swap_interval); + p->gl->SwapInterval(p->opts->swap_interval); } else { MP_VERBOSE(vo, "swap_control extension missing.\n"); } @@ -427,7 +432,6 @@ static int preinit(struct vo *vo) if (!p->renderer) goto err_out; gl_video_set_osd_source(p->renderer, vo->osd); - gl_video_set_options(p->renderer, p->renderer_opts); gl_video_configure_queue(p->renderer, vo); get_and_update_icc_profile(p); @@ -445,8 +449,6 @@ static int preinit(struct vo *vo) gl_video_set_hwdec(p->renderer, p->hwdec); } - p->original_opts = m_sub_options_copy(p, &opengl_conf, p); - return 0; err_out: @@ -454,31 +456,26 @@ err_out: return -1; } -#define OPT_BASE_STRUCT struct gl_priv -static const struct m_option options[] = { - OPT_FLAG("glfinish", use_glFinish, 0), - OPT_FLAG("waitvsync", waitvsync, 0), - OPT_INT("swapinterval", swap_interval, 0, OPTDEF_INT(1)), - OPT_CHOICE("dwmflush", dwm_flush, 0, - ({"no", -1}, {"auto", 0}, {"windowed", 1}, {"yes", 2})), - OPT_FLAG("dcomposition", allow_direct_composition, 0, OPTDEF_INT(1)), - OPT_FLAG("debug", use_gl_debug, 0), - OPT_STRING_VALIDATE("backend", backend, 0, mpgl_validate_backend_opt), - OPT_FLAG("sw", allow_sw, 0), - OPT_CHOICE("es", es, 0, ({"no", -1}, {"auto", 0}, {"yes", 1})), - OPT_INTPAIR("check-pattern", opt_pattern, 0), - OPT_INTRANGE("vsync-fences", opt_vsync_fences, 0, 0, NUM_VSYNC_FENCES), - - OPT_SUBSTRUCT("", renderer_opts, gl_video_conf, 0), +static const struct m_option legacy_options[] = { + OPT_SUBOPT_LEGACY("glfinish", "opengl-glfinish"), + OPT_SUBOPT_LEGACY("waitvsync", "opengl-waitvsync"), + OPT_SUBOPT_LEGACY("swapinterval", "opengl-swapinterval"), + OPT_SUBOPT_LEGACY("dwmflush", "opengl-dwmflush"), + OPT_SUBOPT_LEGACY("dcomposition", "opengl-dcomposition"), + OPT_SUBOPT_LEGACY("debug", "opengl-debug"), + OPT_SUBOPT_LEGACY("backend", "opengl-backend"), + OPT_SUBOPT_LEGACY("sw", "opengl-sw"), + OPT_SUBOPT_LEGACY("es", "opengl-es"), + OPT_SUBOPT_LEGACY("check-pattern", "opengl-check-pattern"), + OPT_SUBOPT_LEGACY("vsync-fences", "opengl-vsync-fences"), + OPT_SUBSTRUCT_LEGACY("", gl_video_conf_legacy), {0}, }; -#define CAPS VO_CAP_ROTATE90 - const struct vo_driver video_out_opengl = { .description = "Extended OpenGL Renderer", .name = "opengl", - .caps = CAPS, + .caps = VO_CAP_ROTATE90, .preinit = preinit, .query_format = query_format, .reconfig = reconfig, @@ -489,25 +486,5 @@ const struct vo_driver video_out_opengl = { .wakeup = wakeup, .uninit = uninit, .priv_size = sizeof(struct gl_priv), - .options = options, -}; - -const struct vo_driver video_out_opengl_hq = { - .description = "Extended OpenGL Renderer (high quality rendering preset)", - .name = "opengl-hq", - .caps = CAPS, - .preinit = preinit, - .query_format = query_format, - .reconfig = reconfig, - .control = control, - .draw_frame = draw_frame, - .flip_page = flip_page, - .wait_events = wait_events, - .wakeup = wakeup, - .uninit = uninit, - .priv_size = sizeof(struct gl_priv), - .priv_defaults = &(const struct gl_priv){ - .renderer_opts = (struct gl_video_opts *)&gl_video_opts_hq_def, - }, - .options = options, + .options = legacy_options, }; diff --git a/video/out/vo_opengl_cb.c b/video/out/vo_opengl_cb.c index 776d4485ba..c2d3be78e6 100644 --- a/video/out/vo_opengl_cb.c +++ b/video/out/vo_opengl_cb.c @@ -47,13 +47,7 @@ */ struct vo_priv { - struct vo *vo; - struct mpv_opengl_cb_context *ctx; - - // Immutable after VO init - int use_gl_debug; - struct gl_video_opts *renderer_opts; }; struct mpv_opengl_cb_context { @@ -82,8 +76,6 @@ struct mpv_opengl_cb_context { bool imgfmt_supported[IMGFMT_END - IMGFMT_START]; struct mp_vo_opts vo_opts; bool update_new_opts; - struct vo_priv *new_opts; // use these options, instead of the VO ones - struct m_config *new_opts_cfg; bool eq_changed; struct mp_csp_equalizer eq; struct vo *active; @@ -234,9 +226,6 @@ int mpv_opengl_cb_uninit_gl(struct mpv_opengl_cb_context *ctx) ctx->hwdec_devs = NULL; talloc_free(ctx->gl); ctx->gl = NULL; - talloc_free(ctx->new_opts_cfg); - ctx->new_opts = NULL; - ctx->new_opts_cfg = NULL; return 0; } @@ -275,15 +264,14 @@ int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int vp_w, int vp_h) ctx->eq_changed = true; } if (ctx->update_new_opts) { - struct vo_priv *p = vo ? vo->priv : NULL; - struct vo_priv *opts = ctx->new_opts ? ctx->new_opts : p; - if (opts) { - gl_video_set_options(ctx->renderer, opts->renderer_opts); - if (vo) - gl_video_configure_queue(ctx->renderer, vo); - ctx->gl->debug_context = opts->use_gl_debug; - gl_video_set_debug(ctx->renderer, opts->use_gl_debug); - } + gl_video_update_options(ctx->renderer); + if (vo) + gl_video_configure_queue(ctx->renderer, vo); + int debug; + mp_read_option_raw(ctx->global, "opengl-debug", &m_option_type_flag, + &debug); + ctx->gl->debug_context = debug; + gl_video_set_debug(ctx->renderer, debug); if (gl_video_icc_auto_enabled(ctx->renderer)) MP_ERR(ctx, "icc-profile-auto is not available with opengl-cb\n"); } @@ -445,41 +433,6 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) return 0; } -// list of options which can be changed at runtime -#define OPT_BASE_STRUCT struct vo_priv -static const struct m_option change_opts[] = { - OPT_FLAG("debug", use_gl_debug, 0), - OPT_SUBSTRUCT("", renderer_opts, gl_video_conf, 0), - {0} -}; -#undef OPT_BASE_STRUCT - -static bool reparse_cmdline(struct vo_priv *p, char *args) -{ - struct m_config *cfg = NULL; - struct vo_priv *opts = NULL; - int r = 0; - - pthread_mutex_lock(&p->ctx->lock); - const struct vo_priv *vodef = p->vo->driver->priv_defaults; - cfg = m_config_new(NULL, p->vo->log, sizeof(*opts), vodef, change_opts); - opts = cfg->optstruct; - r = m_config_parse_suboptions(cfg, "opengl-cb", args); - - if (r >= 0) { - talloc_free(p->ctx->new_opts_cfg); - p->ctx->new_opts = opts; - p->ctx->new_opts_cfg = cfg; - p->ctx->update_new_opts = true; - cfg = NULL; - update(p); - } - - talloc_free(cfg); - pthread_mutex_unlock(&p->ctx->lock); - return r >= 0; -} - static int control(struct vo *vo, uint32_t request, void *data) { struct vo_priv *p = vo->priv; @@ -522,10 +475,12 @@ static int control(struct vo *vo, uint32_t request, void *data) update(p); pthread_mutex_unlock(&p->ctx->lock); return VO_TRUE; - case VOCTRL_SET_COMMAND_LINE: { - char *arg = data; - return reparse_cmdline(p, arg); - } + case VOCTRL_UPDATE_RENDER_OPTS: + pthread_mutex_lock(&p->ctx->lock); + p->ctx->update_new_opts = true; + update(p); + pthread_mutex_unlock(&p->ctx->lock); + return VO_TRUE; } return VO_NOTIMPL; @@ -547,7 +502,6 @@ static void uninit(struct vo *vo) static int preinit(struct vo *vo) { struct vo_priv *p = vo->priv; - p->vo = vo; p->ctx = vo->extra.opengl_cb_context; if (!p->ctx) { MP_FATAL(vo, "No context set.\n"); @@ -575,8 +529,8 @@ static int preinit(struct vo *vo) #define OPT_BASE_STRUCT struct vo_priv static const struct m_option options[] = { - OPT_FLAG("debug", use_gl_debug, 0), - OPT_SUBSTRUCT("", renderer_opts, gl_video_conf, 0), + OPT_SUBOPT_LEGACY("debug", "opengl-debug"), + OPT_SUBSTRUCT_LEGACY("", gl_video_conf_legacy), {0}, }; |