View Full Version : Video player Shaders guide (MPC-HC, mpc-BE, mpv)


butterw2
29th June 2020, 14:34
Video player Shaders (unofficial guide)

Video Adjustment shaders Pack (dx9, dx11 hlsl and mpv glsl.hook): [A-Pack] v1.50 Released (2023-11) (https://forum.doom9.org/showthread.php?t=184996)
Contrast adaptive Sharpening (AMD CAS) shader (dx9/dx11). (https://forum.doom9.org/showthread.php?p=1993947#post1993947)
Filmgrain Shaders (https://forum.doom9.org/showthread.php?p=1994369#post1994369) grain.hlsl (dx9/dx11), mpv


In addition to video player shaders, this topic covers configuration, user interface and performance of open-source video players available on Windows.
MPC-HC MPC-BE, mpv, mpv.net are feature packed video players that offer great features and performance, together with extensive configuration options.

Post index:
# Comparison of shader features in video players (https://forum.doom9.org/showthread.php?p=1919502#post1919502)
# Shaders Folder, Paths & extensions (https://forum.doom9.org/showthread.php?p=1929231#post1929231)
# New Shader features in Mpc-hc (v1.9.8.65) (https://forum.doom9.org/showthread.php?p=1930240#post1930240)
# Custom hotkeys, Seeking, Chapters, Playlist (https://forum.doom9.org/showthread.php?p=1931840#post1931840)
# Screenshots (https://forum.doom9.org/showthread.php?p=1931990#post1931990)
# Comparison of video player features (Win10) (https://forum.doom9.org/showthread.php?p=1932940#post1932940)
# Mpc Command Line Switches (https://forum.doom9.org/showthread.php?p=1927315#post1927315)
# Video Player installation https://forum.doom9.org/showthread.php?p=1934473#post1934473
# Color mapping with Shaders https://forum.doom9.org/showthread.php?p=1935482#post1935482
# (custom) windowed zoom: 150% (https://forum.doom9.org/showthread.php?p=1987810#post1987810)
# Time display formats (https://forum.doom9.org/showthread.php?p=1990821#post1990821), ex: 01:25 / 53:15

MPC video-renderer, Mpc-vr
# Shader support in mpc video renderer (mpc-vr) (https://forum.doom9.org/showthread.php?p=1927466#post1927466)
# Surface/texture format (https://forum.doom9.org/showthread.php?p=1992643#post1992643)

MPV
# mpv (windows): my tips (https://forum.doom9.org/showthread.php?p=1996300#post1996300) New
# Mpv shader basics (https://forum.doom9.org/showthread.php?p=1926639#post1926639)
# mpv hotkeys (https://forum.doom9.org/showthread.php?p=1929051#post1929051)
# mpv built-in scalers (https://forum.doom9.org/showthread.php?p=1936377#post1936377) (2023-10) new Defaults !
# mpv Auto-Profiles (https://forum.doom9.org/showthread.php?p=1929848#post1929848)
# How to change settings/properties at runtime with mpv (https://forum.doom9.org/showthread.php?p=1936710#post1936710)
# default input.conf. --no-input-default-bindings (https://forum.doom9.org/showthread.php?p=1990542#post1990542)
# custom OSD in mpv (https://forum.doom9.org/showthread.php?p=1990436#post1990436)
# mpv script: avg-bitrate.js (https://forum.doom9.org/showthread.php?p=1990487#post1990487)
# more mpv custom OSD scripts (https://forum.doom9.org/showthread.php?p=1990763#post1990763)
# mpv-android (https://forum.doom9.org/showthread.php?p=1990911#post1990911)
# restart-mpv (https://forum.doom9.org/showthread.php?p=1994854#post1994854)
# custom context menu (https://forum.doom9.org/showthread.php?p=1995031#post1995031)
# custom overlay: modern progress bar (https://forum.doom9.org/showthread.php?p=1995689#post1995689)
# mpv scripts: lua or js ? (https://forum.doom9.org/showthread.php?p=1995935#post1995935)
# mpv script: short time format OSD, btime.js (https://forum.doom9.org/showthread.php?p=1996141#post1996141)

# Cartoon Shaders https://forum.doom9.org/showthread.php?p=1928755#post1928755

Videohelp:
# What shaders should I use in potplayer? (https://forum.videohelp.com/threads/411833-What-shaders-should-I-use-in-potplayer)
# Pixel-shaders for video playback (.hlsl, .glsl) (https://forum.videohelp.com/threads/397797-Pixel-shaders-for-video-playback-%28-hlsl-glsl%29)
---

Fix Mpc-hc issues with evr-cp (dx9) on intel Xe driver (used by 11th gen and later intel igpu, ex: intel uhd730)
Issue: Broken seeking after reaching end of file, repeat doesn't work. Affects all versions of mpc-hc.
Fix: rename mpc-hc64.exe to mpc.exe.

Mpc-hc + Shaders install (with default dx9 EVR-CP renderer) unofficial guide
32 vs 64 bit program version doesn't matter for shaders.

Mpc-hc installs the default shaders in the player directory Shaders subfolder. They are not required to run mpc-hc (they can be modified/deleted as required). It is also possible to download shader files available on the internet or write your own. Files with .hlsl extension in Shaders subfolder are listed in `Option->Shaders` submenu.

Install directory does matter.
To be able to modify shader parameters you need to have write access to the directory where the shader.hlsl file is located (by default the Shaders subfolder).
Also to have the option to use mpc-hc.ini, mpc-hc must have write access to the Install directory (if not the option is greyed out). This will not be the case for a standard user on Win10 by default with a `c:\Program Files\MPC-HC` install. To get around this, you need to either re-install to a user directory or change folder permissions. For testing, the simplest solution is to copy a portable version + mpc.ini in its own directory (no-install required).


How to get corresponding Shaders Menu when you install Shaders files ?
To be able to apply Effects quickly, they need to be saved as Shader Presets. You can then change Effects through the Shaders right-click Menu
Shader presets can be created/saved by using the `Select Shaders...` menu option, but by editing mpc-hc.ini we can get a ready to use Shaders Menu directly.

https://raw.githubusercontent.com/butterw/bShaders/master/MPC-HC_Shaders-Menu.jpg

Mpc-hc Shader Menu mod guide:
Mpc-hc settings are stored either in the registry or in an .ini file, based on setting `Mpc-hc->Options->Player->Store settings in .ini file.`. This option will be greyed out, if mpc-hc doesn't have write access to the install folder.

Editing mpc-hc.ini (Close Mpc-hc before you start. It is advisable to make a backup copy before making any changes)

With a text editor, search for the Shaders\Presets section. Here is an example of what you might have:
[Shaders\Presets]
0= Disable
1=Sepia
2=Luma+Grain
3=Pixelate
PostResize0=
PostResize1=
PostResize2=.\LumaSharpen.hlsl;.\PS_Noise.hlsl
PostResize3=
PreResize0=
PreResize1=.\Sepia.hlsl
PreResize2=
PreResize3=.\bPixelate.hlsl

You can directly edit preset names, Pre and PostResize shader chain filepaths. Be careful that all numbers must remain available: deleting 1=Sepia would cause issue here !
Shaders Menu display order: Preset names are sorted alphabetically. To control the display order, preset names could be numbered (00, 01, etc.).
For more advanced users, Shader Presets can be used to setup Multi-Pass shaders.


Modifying shader files
.hlsl files contain the Shader function and parameter values. In most cases, the effect has parameter values that can be modified. This can be done with any text editor (I use Notepad++, a multitabbed editor which offers c-syntaxic coloring). After saving the changes, they are applied instantly to the video playing.
In the case of LumaSharpen.hlsl which was developed for SweetFX game shaders pack, the default parameter values are not those recommended in this forum for video content playback.
If you want to switch between different parameter values for the same shader without editing, you can create a new shader with the desired parameter values, ex: LumaSharpen_3-1.20-0.015.hlsl. With this approach the Shaders subfolder (and the shader list) can quickly become overcrowded, so it is important to know which shaders you want to use, together with the associated parameter values.

v0lt
30th June 2020, 04:27
I think there isn’t enough shader compilation checking.

For DirectX 9
fxc.exe /T ps_3_0 /Fc "Shader9.txt" "Shader9.hlsl"
For DirectX 11
fxc.exe /T ps_4_0 /Fc "Shader11.txt" "Shader11.hlsl"

butterw2
30th June 2020, 08:31
I haven't tried the external dx11 renderer so far, but I understand it requires dx11 shaders, which have a slightly different syntax than dx9 shaders.

Doesn't the compiler have a backwards compatibility mode (fxc /Gec ?) to enable use of dx9 shader files in dx11 ?

All the currently available third party .hlsl shaders available online were written for dx9.

butterw2
7th July 2020, 03:05
Optimized 2-pass Gaussian Blur (9-tap) shader:
bShaders (https://github.com/butterw/bShaders)\blurGauss.hlsl >> blurGauss_Y.hlsl
the kernel is hardcoded so you can't adjust parameters. Run it multiple times to achieve a stronger effect (ex: 5x).

below are Blur Gaussian and Blur Gaussian (5x) shader presets for mpc-hc.

mpc-hc.ini:
[Shaders\Presets]
0= Disable
1=Blur Gaussian
2=Blur Gaussian (5x)
PostResize0=
PostResize1=
PostResize2=
PreResize0=
PreResize1=.\blurGauss.hlsl;.\blurGauss_Y.hlsl
PreResize2=.\blurGauss.hlsl;.\blurGauss_Y.hlsl;.\blurGauss.hlsl;.\blurGauss_Y.hlsl;.\blurGauss.hlsl;.\blurGauss_Y.hlsl;.\blurGauss.hlsl;.\blurGauss_Y.hlsl;.\blurGauss.hlsl;.\blurGauss_Y.hlsl

For a near gaussian blur with an adjustable parameter, use boxBlur (3x) based on 2pass blurMean.
A multipass Kawase blur, also can approximate a gaussian depending on parameters.
For best performance with Heavy bluring, Dual-Kawase downsizes the video, blurs, and resizes-up.

butterw2
15th July 2020, 15:43
Mpc-hc and mpc-be have a "View>Pan&Scan" zoom-crop built-in feature. This transformation happens before user shaders.

Editing PnS Presets: specify center (x,y) and zoom (x, y).
- center (0.5, 0.5): middle of the screen
- zoomX and zoomY should be equal to keep the source Aspect Ratio. 1: no magnification.

The most useful preset is probably "Zoom to widescreen" which will crop horizontal and vertical borders on the corresponding 4/3 source material when displayed on a 16/9 screen.

- `Numpad 5` hotkey: resets PnS zoom (also displays source AR). PnS zoom is also reset when you close the player.
- You can manually adjust zoom using Numpad 9(+) and 1(-) hotkeys.


Observations:
- Center of Screen PnS fixed zoom works well, whatever the source Aspect Ratio.
- I initially tried to display only part of the source image with Pan&Scan (ex: fill the screen with first quarter of frame), but found pre-resize shaders more capable for this use case.
The issue with PnS (beside the confusing x, y values) is black bars on resize, when the source doesn't have screen 16/9 AR (ex: 21/9 film content, 9/16 vertical video).

Quarter zoom PnS presets: x, y values (zoom: 2, 2), works well for 16/9 input.
- top left Quarter: 1, 1, - top right: 0, 1.
- bottom left Quarter: 1, 0 - bottom right: 0, 0.

Fs2xRightSide PnS preset could be used for right side offset 2x zoom for non 16/9 landscape.

in mpc-hc.ini: [Settings\PnSPresets]
Preset0=Widescreen zoom,0.500,0.500,1.333,1.333
Preset1=Quarter Top-L,1,1,2,2
Preset2=Fs2xRightSide-L,0,0.5,2,2

You can generally combine user pixel shaders with any mpc-hc zoom feature (including Right-Click: Video Frame > xxx and Zoom > xxx).

"Video Frame > Touch window from outside" is a centered fullscreen crop mode based on the input video Aspect Ratio. Fills the window/screen by zooming and cropping the video.

butterw2
22nd July 2020, 17:44
Linear sampling is a performance optimization technique for gpu pixel shader. The idea is to reduce the number of pixel (texture) fetches required by an algorithm by sampling between pixels and exploiting hardware linear interpolation.

a 2-pass pre-resize shader test was performed:
https://github.com/butterw/bShaders/tree/master/test_linearSampling
- pass-1 generate a black and white stripe test motif,
- pass-2 use linear sampling

Expected: interpolation, colored Red
Result: no interpolation (Nearest Neighbor). If the offset is set to 0.5 pixel: produces some rounding artefacts !

https://raw.githubusercontent.com/butterw/bShaders/master/test_linearSampling/Offset%200.5%20Sampling%20artefact_zoomed.png

Software and hardware setup
- mpc-hc v1.9.6 + EVR-CP. Also tested in mpc-be
- old intel igpu (hd4400), not the latest Win10 + drivers


## Linear Sampling (in hlsl): tex2D(s0, tex + k*p1) where k is non integer
the effect of Nearest Neighbor sampling is to round k.x, k.y to the nearest integer. If k.x or k.y is a half, you then get some rounding artefacts.
While it certainly is possible to get rid of the rounding artefacts, they are a symptom of the larger problem: Linear Sampling not being supported, which has major implications for the math analysis.

Linear sampling is exploited by perf optimized convolution kernel shaders (such as: Luma Sharpen, gaussian blur, etc.). If it isn't supported, the shaders still produce an output, but a suboptimal one. The provided test allows for the user to test whether linear sampling is actually supported.

Edit (linear sampling works in mpv): the same test using rgb32 png input was performed on the same configuration with a glsl shader (mpv video player, vo=gpu), and I'm getting the expected result there !
https://github.com/butterw/bShaders/tree/master/test_linearSampling

Edit2 (hw linear sampling isn't supported in mpc-hc/be): hw linear sampling also not working as expected in mpc-hc/be with mpc-vr as video renderer in dx9 and dx11 modes.
https://github.com/clsid2/mpc-hc/issues/748
This impacts shaders such as LumaSharpen.hlsl

VictorLS
22nd July 2020, 20:11
butterw2
Can you help us (SAT amateurs) in writing HLGtoSDR(BT.709) hlsl shader https://forum.doom9.org/showthread.php?t=176909 i.e. adopt libplacebo (https://code.videolan.org/videolan/libplacebo/-/blob/master/src/shaders/colorspace.c#L819) to MPC-HC's shader we can use in SmartDVB - quality of present shaders is bad - but VLC and MPV players give good enough quality while playing HLG files on SDR monitor?

butterw2
22nd July 2020, 22:19
If glsl fragment shader code exists for the desired color transformation that would mostly autotranslate to hlsl usable in mpc-hc/be.

VictorLS
22nd July 2020, 22:39
I know but result of that translation is bad enough or some 'know how' must be known to get it working well.
Besides - I don't really sure libplacebo (only?) do desirable color transformation (HLGtoSDR) or VLC uses something else - I'm not programmer at all and moreover I'm not shader programmer (
Here's somehow working HLGtoSDR shaders https://transfiles.ru/svler - Convert HDR to SDR.hlsl in HDR folder work well enough but for ordinary HDR files like 23_Samsung_HDR_Wonderland.mkv (97 MB) https://yadi.sk/i/ZgkOWjcEwWQNkQ - not for HLG files like 20190831-160457_RTL UHD.mkv (135 MB) https://yadi.sk/i/SRloXWrOP-L-xA
I even don't know that (not in HDR folder) shaders was taken from libplacebo or somewhere else ;)
PS. Here's long time (more than 4 minutes) test files https://forum.doom9.org/showthread.php?p=1919134#post1919134

butterw2
23rd July 2020, 11:32
I'm afraid, my experience on the subject of HDR to SDR tonemapping is rather limited.
mpc-be does some tonemapping by default (using hlsl shaders I believe). If I understand you correctly, you claim that the method used by vlc and mpv gives more accurate results ?

If there was a mpv glsl .hook file, that might be a better starting point for a port than libplacebo (c file with inlined GLSL).
I've tried the provided "Convert HDR to SDR.hlsl" shader in mpc-hc. The colors seem oversaturated for my taste (while the colors are washed out without it). The processing is not that complex (~100 lines of actual code), so it should be achievable to get the shader part working if a reference glsl implementation exists.

Regarding the provided sample files:
- 20190831-160457_RTL UHD.mkv is UHD-50 hevc 10bit HDR 41Mbps
- 23_Samsung_HDR_Wonderland.mkv UHD hevc 10bit HDR 22.5Mbps
Without considering the issue of tonemapping, these files do not play smoothly on an old pc/integrated graphics + 1080p SDR screen like mine.

For testing purposes, short samples are probably fine, I would suggest downconverting the most relevant ones to 1080p, reducing the bitrate 10/20x, maybe remove the audio, provide screenshots (with frame timestamp/frame number) of what you regard as desirable (from mpv, avisynth) vs what was achieved and host this with the code on a server that will not delete your files.

VictorLS
23rd July 2020, 14:02
Thanks for reply.
I'm afraid, my experience on the subject of HDR to SDR tonemapping is rather limited
It's a pity but I believe in you ;)
Btw I have SDR (BT.709) monitor too - that's why I want to find good HLGtoSDR shader but couldn't yet (
20190831-160457_RTL UHD.mkv is UHD-50 hevc 10bit HDR 41Mbps
Not only ordinary HDR, but HLG same time - that's why working with ordinary HDR video like
23_Samsung_HDR_Wonderland.mkv UHD hevc 10bit HDR 22.5Mbps
Convert HDR to SDR.hlsl shader gives good result but with HLG 20190831-160457_RTL UHD.mkv oversaturated.
mpc-be does some tonemapping by default (using hlsl shaders I believe)
Yes, you're quiet right (btw MPC-HC must output to madVR or use Convert HDR to SDR.hlsl shader with any other renderer to achieve such results - am I right?)
If there was a mpv glsl .hook file, that might be a better starting point for a port than libplacebo (c file with inlined GLSL)
From MPC-BE developers I've heard mpv does it on a fly so they are couldn't extract using by mpv shader while playing HLG file (btw they are looking at my researching for HLGtoSDR shader and ready to implement it in MPC-BE like now HDR if result will be positive). Besides quality of tonemapping depends of version of mpv - older than August 2019 are better (newer gives some rose instead of red) on my own so I'd prefer shader extracted from VLC ;)
For testing purposes, short samples are probably fine
I agree in your case - you can find them in the bottom of first post https://forum.doom9.org/showthread.php?t=176909
I would suggest downconverting the most relevant ones to 1080p
I guess it's wrong way because HLG metadata can be lost during any conversion so see first post (https://forum.doom9.org/showthread.php?t=176909) for your other wishes ;)

butterw2
23rd July 2020, 17:22
Tone mapping is required to correctly display any HDR encoding (typ 1080p Hevc 10bit HDR encode from UHD bluray) displayed on a Standard Dynamic Range computer screen (almost all current monitors are non-HDR).

mpc-hc doesn't do any tone mapping by default: so colors look washed out. If you enable the provided Convert HDR to SDR.hlsl shader, the results seem quite watchable for HDR content. It's also a reasonably lightweight shader (1 texture, 44 arithmetic).
Edit: the code likely comes from mpc-be and has 2 tuning parameters (LuminancePeak_Gain, Gamma).
Such a shader can improve the viewing of a washed-out color video (ex: encode of an HDR source to SDR with no tonemapping applied, or undersatured SDR video). It shouldn't be used otherwise.

mpc-be and vlc come with built-in SDR Tone mapping, which is applied automatically (there doesn't seem to be a setting to deactivate it !).

The samples (RTL title screen) in your first post here https://forum.doom9.org/showthread.php?t=176909
seem like a good starting point regarding the specific case of Hybrid Log-Gamma (HLG) HDR used in UHD satellite broadcasts .

- 23_Samsung_HDR_Wonderland.mkv (UHD hevc 10bit HDR 22.5Mbps)
-20190831-160457_RTL UHD.mkv (UHD-50 hevc 10bit HLG HDR 41Mbps): quite specific sample because it contains a lot of white smoke. I actually prefer no tone mapping on this sample vs oversaturated result.

Also, on my PC performance is awful with VLC with these 2 samples.

VictorLS
23rd July 2020, 21:26
Tone mapping is required to correctly display any HDR encoding (typ 1080p Hevc 10bit HDR encode from UHD bluray) displayed on a Standard Dynamic Range computer screen (almost all current monitors are non-HDR)
mpc-hc doesn't do any tone mapping by default: so colors look washed out. If you enable the provided Convert HDR to SDR.hlsl shader, the results seem quite watchable for HDR content. It's also a reasonably lightweight shader (1 texture, 44 arithmetic).
So, I was right when wrote "MPC-HC must output to madVR or use Convert HDR to SDR.hlsl shader with any other renderer to achieve such results"
mpc-be and vlc come with built-in SDR Tone mapping, which is applied automatically (there doesn't seem to be a setting to deactivate it).
You're right.
The samples in your first post here https://forum.doom9.org/showthread.php?t=176909
seem like a good starting point regarding the specific case of Hybrid Log-Gamma (HLG) HDR used in some satellite broadcasts(RTL title screen).
Some people said this is bad point so I hard work to write red-flagged F1 to someone do right shader with colorimeter ;)
SDR FullHD H.264 20190511-130113_ARENA HD_flag.ts (38 MB) https://yadi.sk/i/HiuZ5Rb2RKkc0g
HLG 4K H.265 20190511-152944_RTL UHD_flag.ts (67 MB) https://yadi.sk/i/985DVw34OHQrrA
-20190831-160457_RTL UHD.mkv (UHD-50 hevc 10bit HLG HDR 41Mbps): quite specific sample because it contains a lot of white smoke.
I've uploaded that to see how new HLGtoSDR shader shows grass - it's looking ugly now with or without tonemapping in ordinary DirectShow players.
I actually prefer no tone mapping on this sample vs oversaturated result.
You're right but I'd want get VLC (OpengGL output in Win7 or D3D11 output in Win8-10) colors with HLGtoSDR shader
Also, on my PC performance is awful with VLC with these 2 samples.
and weak PC can't stop experiments with colors because of watching mostly in pause mode ;)

butterw2
27th July 2020, 00:34
# Comparison of user shader features in the main video players for Windows

To Everyone: Please point out any mistakes/changes, so I can update this guide as needed. The reason for this thread is that the available documentation is sparse and mostly buried in very old/long threads.
You don't need to be a C++ dev to customize or write pixel shaders.

## directX hlsl shaders:
VLC v3.10 in dx9 video output mode
- only one user shader (post resize) !
built-in effects/filters only work in dx11 mode !
shader is set in config options > advanced, but can also be set via command-line
! code: the output alpha channel must be != zero, otherwise black screen output.
shader modification: stop/start video.

MPC-HC v1.9.6 (EVR-CP) -- Recommended for shader dev, New features added in dev build --
- Configurable Shader Presets: a named/saved user defined shader chain.
- in menu Select shaders (uses Options shortcut "O")
- switch shader presets via contextual Menu in fullscreen mode
- pre and post resize pixel shader chains
- multipass shaders possible
- Shader modification: new parameters are applied immediatedly (! or next frame in the case where you empty the shader chain).
- Compiler output with Debug Shaders (+ shortcut)
- time in seconds since application start available and updated every frame.

- KMPlayer 4.0.7.1 can fully operate with shaders when paused


MPC-BE v1.5.4 (EVR-CP)
- ! No Shader Presets: single pre and post resize shader chains
- Shortcuts to enable/disable pre and post resize shader chains (CTRL-P, CTRL-ALT-P)
- "Save output image" Screenshot includes shader output (Shift+F5)
- ! Shader modification: close/restart player.
- ! unlike mpc-hc, Alpha Channel is initially set to 1 (because of this, some shaders that assume initial alpha is 0 will not work properly without correction).


---
## glsl fragment shaders intro here (https://forum.videohelp.com/threads/397797-Pixel-shaders-for-video-playback-(-hlsl-glsl)#post2597322)

Mpv .hook (vo=gpu, gpu-api=d3d11)
set via glsl-shader in config file mpv.conf.
(Shift-I, Shift-2) to display the processing chain. Hotkeys can be added in input.conf (https://forum.doom9.org/showthread.php?p=1929051#post1929051) to switch individual shaders, disable/enable shaders or list active shaders.
- Output is a blue-screen if a shader has a syntax error. You need to restart player to modify shaders.
- user shaders with custom hook points: source shaders (Luma, Chroma), chroma upsampling, custom resizers, pre and post resize RGB.
- multipass shaders in a single file, can downsample textures, can re-use the output of previous passes.
- complex shader chain possible by saving textures.
- uniform variable "random" available (PRNG) and updated each frame
- compute shaders
! few .hook effect shaders currently available (vs hlsl, glsl), but easy enough to adapt .frag glsl to .hook

butterw2
3rd August 2020, 11:36
# Video playback pipeline on Windows in Standard Dynamic Range (SDR, Video+Display)

Mpc-hc works in 8-bit by default.

0) Graphics Driver Settings (mostly disabled >> set to "Application Settings")
- features supported by gpu hardware.
- Output should be set to the same as your display (typ for PC: RGB full range)

1) Video File (container: .mp4, .mkv)
- Video (Codec: x264, x265)
- typ. YUV420 (chroma channels are subsampled), Gamma-Encoded 8/10bits,
- Resolution+Progressive+Framerate, ex: 720p30,
- color primaries and matrix: bt709 (HDTV)
- color range: Limited (Low: 16-235), (vs Full/PC: 0-255)
...streaming/bluray movies and TV shows are mastered in Limited range.
- Audio channels
- Subtitle channels
Mpc-hc/be Menu: File > Properties: MediaInfo.dll file information.

2) DirectShow player x86 or x64 (ex: mpc-hc, etc.)
- Features: window, play, seeking, configuration/Menu/Hotkeys, shaders, screenshots

Modern video players come with the decoders required to play any standard video without the need to install codecs/codec packs.
- DShow graph: Splitter > Decoder* > Renderer*
2a) LAV Filters - ffmpeg based DirectShow Splitter and Decoders (LAV Splitter >> LAV Video + LAV Audio)
MPC-HC/BE Menu: Play > Filters > Video Decoder
The decoder defines the color space at the renderer input (typ. same as source: YUV or RGB, 8, 10, 16bits)

2b) Renderer: DirectX 9 EVR-CP (Enhanced Video Renderer-Custom Presenter >Win8) + DXVA2 gpu hw Acceleration*
- default in MPC-HC

MPC-HC/BE Menu: View > Renderer Settings > Display Statistics (Ctrl+J) overlay
Input, ex: NV12, YV12
- Save Image... (Alt+I) input Screenshot
- YUV >> RGB Conversion
2c) RGB Processing Surface: int8, int10, float16
- Color Controls (Brightness, Contrast, Hue, Saturation)
- Zoom, Pan&Scan
- Rotation
- Pixel Shaders (gpu)
- RGBA float4(32, 32, 32, 32)
- Pre-resize user Pixel Shader chain
- Resizer (ex: bicubic A=-0.75, to 1080p)
- Post-resize user Pixel Shader chain (in Screen Space)
BackBuffer/Display ?

2d) Overlay (Alpha blended)
- Subtitles
- OSD, On Screen Display

MPC-BE (Shift+F5): Save Displayed Image (auto) - output Screenshot
Mixer Output ?

3) Output interface/cable: typ. hdmi
> RGB Monitor/HDTV (Resolution/Framerate, reported bit depth: 8 or 10bit), ex: 1920x1080, 60Hz, 8bit
- Settings on Monitor. (Brightness/Contrast/Gamma, RGB Range, etc.)
- SDR (sRGB), color: bt709.
- Gamma-decode

v0lt
4th August 2020, 13:23
Mixer Output ?
EVR Mixer usually requires a specific output format. See "DXVA Checker -> Processor device -> DXVA1/2 -> OutputFormat" for details. This is essential for AMD and Intel graphics cards to function properly. For Nvidia video cards, we may use some "unsupported" formats as output.

butterw2
9th August 2020, 18:06
# Playing a video file from .avs (Avisynth)
- Video players such as mpc-hc/be can play .avs files.
- Frameservers such as Avisynth can be used to process video (they are widely used pre-encoding).
So, can you process video files for realtime display using .avs and is there any benefit to do so ?

Avisynth processing is done primarily on the cpu vs pixel shaders, which use gpu processing.
- For many basic video related operations this is less efficient, even with multi-threading, but it also has fewer limitations.
- Avisynth scripts rely mainly on high quality existing internal/external functions/libraries (compiled .dll C++ plugins).


.avs Display Pipeline:
Video file (.mp4, ex: x264/x265 1080p, YUV420) >> .avs: source Filter(video_filename): Avisynth cpu processing: Output (ex: YV12 or RGB32)
>> Input of Video Player: Video Player processing (RGB), ex: gpu pixel shaders >> Monitor (RGB)

Performance:
- as expected, significant cpu overhead with an .avs script vs normal playing. Depending on the Avisynth filters used, realtime playback may however be achieveable.
- Avisynth filters can be used in complement to gpu pixel shaders.

Software configuration: Win10 x64
- DirectShow Video player: Mpc-be x64, EVR-CP renderer
- Avisynth+ v3.6.1 x64
- external Source plugin: LSMASHSource.dll x64, based on libavcodec, with gpu hw decoding support.
My tests were performed with Avisynth, but the more recent python script alternative Vapoursynth looks promising. It offers direct access to the python software stack (ex: numpy vector math, matplotlib plots, etc.).

## Limitations:
- LSMASHVideoSource / LSMASHAudioSource only support mp4/mov input ! Wider input file format support is available (ex: mkv) with LWLibavVideoSource, but input file must initially be indexed (ex: 10s) !
- video_filename is typically changed by editing the .avs script ! To avoid this, video_filename.avs can be coded so as to load video_filename.mp4 by default.
- On script syntax error, you only get "Cannot render the File" message in video player ! To get full error msg you need to use either AvsPmod, Virtualdub2 or AvsMeter.

Conclusion:
It is currently possible, but not very practical to play an avs script in a video player. This would probably only make sense if the same effect was not possible as a pixel shader and an equivalent player feature was not available.
Using a per-file script does mean file-specific processing settings are saved. Undesirable lossy re-encoding of a compressed source may be avoided.

Avisynth input can however be useful as a test tool for video (https://github.com/butterw/bShaders/tree/master/test_LimitedRange):
- YUV-to-RGB colorspace conversion can be performed in Avisynth (with rec709 range expansion by default). In this case the YUV-to-RGB conversion at the video player input is bypassed.
- Resize frame
- Generate test-patterns (ex: ColorBarsHD).
- Go to a specific frame (vs Directshow video player: seeking is not guaranteed to be frame accurate !).
- Supports multiple video inputs. You could also use multiple clips from the same source (ex: could be used for a split-screen effect or to highlight differences)
- Load/process/save images (ex: lossless .png screenshots) with the same code.
- Output data files (ex: .csv)

butterw2
18th August 2020, 15:33
# Typical PC Display (Color Range) Pipeline :
Compressed video file (yuv420p8, Limited Range, Color range: Limited or untagged) >> mpc-hc Video player (Range expanded to Full Range at yuv-rgb32 conversion at renderer input)
>> graphics driver (rgb32 Output, Full Range) >> Hdmi >> Monitor (Full Range)

- Historically TV/HDTV have used limited range input vs PC monitor full RGB range.
- Most current displays should allow you to set the desired input range (if you change this value, you probably also need to adjust brightness, contrast, gamma for good results).
For accurate representation of grey levels and colors your monitor/HDTV and graphic card settings should match: Full-PC or Limited-Low.
Display range can be checked on screen with a pixel picker and a generated SMPTE ColorBarsHD test pattern input. (https://github.com/butterw/bShaders/blob/master/test_LimitedRange/Readme.md)

If the input video file is Full Range but lacks the correct video stream tag (Color range: Full) in the Mediainfo properties, mpc-hc/be will treat it as Limited range !
To avoid a clipped color levels output, you should correct the tagging, which can be done losslessly for x264/x265 using ffmpeg:
ffmpeg -i "input.mp4" -c:v copy -bsf:v h264_metadata=video_full_range_flag=1 "output_full.mp4"
(for x265): -bsf:v hevc_metadata=video_full_range_flag=1

More info about ffmpeg video bitstream filters here: https://ffmpeg.org/ffmpeg-bitstream-filters.html#h264_005fmetadata
This can be used to crop a displayed video file without having to re-encode it for instance.

An out-of-range highlighting pixel shader such as https://github.com/butterw/bShaders/blob/master/test_LimitedRange/bHighL.hlsl can be used to highlight pixels that are out of the defined range.
Pixel shaders can of course be used to alter levels at playback, but this is not typically necessary.

chros
19th August 2020, 10:17
If the input video file is Full Range but lacks the correct video stream tag (Color range: Full) in the Mediainfo properties, mpc-hc/be will treat it as Limited range !
To avoid a clipped color levels output, you should correct the tagging, which can be done losslessly for x264/x265 using ffmpeg:
ffmpeg -i "input.mp4" -c:v copy -bsf:v h264_metadata=video_full_range_flag=1 "output_full.mp4"
(for x265): -bsf:v hevc_metadata=video_full_range_flag=1
I think this is excatly what I need for my "issue" (https://forum.doom9.org/showthread.php?t=181702).
Do you know how to list all the video properties of a file with ffmpeg?
You can reply there as well, thanks!

SirMaster
25th September 2020, 16:37
Hi @butterw2

I see you have some experience in writing HLSL.

I am interested in writing some of my own shaders but I find myself pretty lost with the syntax.

I am a developer, so I have a lot of programming experience, but maybe you help me get off to a start.

I found this shader which works, but I would like to start by simplifying it.

https://pastebin.com/VMfh8tNL

This shader allows performing RGB color convergence adjustment (useful for 3 chip projectors).

However I notice that when I enable it, it seems to always be blending pixels which screws up 1:1 pixel mapping.

I think this is due to the fact that this shader allows for sorts of scaling and geometric adjustments of the color which I don't need at all.

I would like to modify the shader to only do simple whole pixel adjustments of the red and blue colors.

If you have time, do you think you can help me get started?

butterw2
25th September 2020, 17:46
hlsl pixel shader Intro (dx9)

If you have time, do you think you can help me get started?
It's actually incredibly simple if you are familiar with c syntax, provided you understand what you are trying to do. Some knowledge of vector math will be useful for more advanced image processing.

I wrote a basic intro here (also details limitations):
https://forum.videohelp.com/threads/397797-Pixel-shaders-for-video-playback-(-hlsl)#post2587323

Checking out/modifying existing shaders is a good way to get started.
You can have multiple return statements: use the screen to display your intermediate results and comment them out as required.
define your user parameters with #define

For dev, I would recommend mpc-hc/ notepad++ with an extended c syntaxic coloring for .hlsl.
Notepad++ > Settings > Style Configurator...
C .hlsl user-defined
- instructions: main tex2D saturate dot pow max min lerp mul frac sign step sqrt clamp
- types: sampler float4 float3 float2 float3x3

User Defined Language hlsl (https://raw.githubusercontent.com/butterw/bShaders/master/img/scr_syntaxic_coloring_npp.png).xml is also possible (but it is a bit flaky)

mpc-hc allows you to display the debug output / perf of your code.

----
// This shader can perform software alignment by Catmull-Rom spline6 interpolation for a 3LCD projector's red and blue panels
// This file is part of Video pixel shader pack. // (C) 2011 Jan-Willem Krans (janwillem32 <at> hotmail.com)
I must say I have no idea what this pixel shader is used for (some type of projector calibration ?).

// This shader should be run as a screen space pixel shader.
- screen space pixel shader: use as post-resize shader.

// This shader is meant to work with linear RGB input and output. Regular R'G'B' with a video gamma encoding will have to be converted with the linear gamma shaders to work properly.
see https://forum.doom9.org/showthread.php?t=181651
There is an overhead to converting to linear gamma, so if the effect is negligible in practice you might want to just ignore it, but it could affect the accuracy of the result.
If this is the only shader you intend to use, you could integrate the linear gamma conversion into the shader. Otherwise, I typically use a 10bit integer surface for processing in mpc-hc to avoid too much precision loss with the shader chain.

SirMaster
25th September 2020, 20:13
Thanks, I actually just e-mailed Jan-Willem Krans this afternoon asking about it and he whipped up a simple shader to do what I wanted in this case.

#define RedControls 0
#define BlueControls 0
// RedShiftLeftToRight and BlueShiftLeftToRight, a value of 3. will shift three pixels to the right, 0 is disabled
#define RedShiftLeftToRight 0.
#define BlueShiftLeftToRight 0.
// RedShiftTopToBottom and BlueShiftTopToBottom, a value of 3. will shift three pixels to the bottom, 0 is disabled
#define RedShiftTopToBottom 0.
#define BlueShiftTopToBottom 0.

sampler s0;
float2 c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
float4 s1 = tex2D(s0, tex);// base pixel
#if RedControls == 1
s1.r = tex2D(s0, tex+c1*float2(RedShiftLeftToRight, RedShiftTopToBottom)).r;// base red pixel
#endif
#if BlueControls == 1
s1.b = tex2D(s0, tex+c1*float2(BlueShiftLeftToRight, BlueShiftTopToBottom)).b;// base blue pixel
#endif
return s1;
}

And yes, this sort of shader is useful for fixing the RGB panel convergence in 3-chip projectors where the 3 color producing panels are not in perfect alignment.

Basically a projector can look like this:

https://lowtek.ca/roo/wp-content/uploads/2008/03/avsbad3.jpg

Some higher end projectors have internal software corrections for this sort of issue that you can adjust, but others do not, and that's where this shader comes in.

I used his shader that you posted, but that one has complex pixel interpolation and breaks the perfect 1:1 pixel mapping that I wanted. this new simple shader he wrote or me does exactly what I wanted now.


I do have some other ideas for some simple shaders that I want to try making and I may post here if I have questions about how to do something as I start tinkering around with them.

butterw2
25th September 2020, 21:48
You just wanted a configurable (x, y) pixel offset on red and blue channels. Very simple indeed using a pixel shader. This could also be used as an effect of sorts, I suppose.

if I can add anything at all, p1 would be a more common name for the pixel offset:
float2 p1: register(c1);

SirMaster
30th September 2020, 17:51
Here is a shader I made for simple 4 way masking.

#define width 1920.
#define height 1080.

#define left 0
#define right 0
#define top 0
#define bottom 0

sampler s0;

float4 main(float2 tex : TEXCOORD0) : COLOR
{
if(tex.x >= (left/width) && tex.x <= 1-(right/width) && tex.y >= (top/height) && tex.y <= 1-(bottom/height)) return tex2D(s0, tex);
return float4(0, 0, 0, 1);
}

This sort of video masking is a feature found in most higher-end projectors as there can be reasons why you may want to mask parts of the image for certain projection screen sizes and shapes and aspect ratios and such.

This is useful for projectors that don't have a built in 4 way masking control.

butterw2
30th September 2020, 18:27
Here's my own optimized implementation from barMask.hlsl (Mode==112)
"if" conditionals are quite inefficient with pixel shaders, so the code uses a boolean insideBox function instead.
All functions in HLSL are inline. An inline function generates a copy of the function body (when compiling) for each function call. #define macro functions are also commonly used.

/* Custom Border Mask defined in pixels
(1 texture, 10 arithmetic)
barMask.hlsl (Mode==112)
*/


#define BorderColor 0
#define Top 0
#define Left 0
#define Bottom 0
#define Right 0

sampler s0: register(s0);
float2 p1: register(c1);

bool insideBox(float2 tex, float2 topLeft, float2 bottomRight){
/* returns true if tex coordinates inside the box, returns false otherwise. !insideBox: outsideBox */
float2 s = step(topLeft, tex) - step(bottomRight, tex);
return s.x * s.y;
}

/* --- Main --- */
float4 main(float2 tex: TEXCOORD0): COLOR {
if (insideBox(tex, p1*float2(Left, Top), 1-p1*float2(Right, Bottom))) return tex2D(s0, tex);
return BorderColor;
}

SirMaster
30th September 2020, 19:14
Here's my own optimized implementation from barMask.hlsl (Mode==112)
if conditionals are quite inefficient with pixel shaders.

Oh, awesome!

SirMaster
30th September 2020, 21:11
hlsl pixel shader Intro (dx9)


// This shader is meant to work with linear RGB input and output. Regular R'G'B' with a video gamma encoding will have to be converted with the linear gamma shaders to work properly.
see https://forum.doom9.org/showthread.php?t=181651
There is an overhead to converting to linear gamma, so if the effect is negligible in practice you might want to just ignore it, but it could affect the accuracy of the result.
If this is the only shader you intend to use, you could integrate the linear gamma conversion into the shader. Otherwise, I typically use a 10bit integer surface for processing in mpc-hc to avoid too much precision loss with the shader chain.

I am confused by this part.

I normally have the whole chain set to RGB full range (lav filters / madVR, GPU output, and display).

And everything is set to and calibrated to 2.2 power law gamma.

So do I need to be concerned about doing some sort of linear gamma conversion?

I am not sure why simply shifting the colored pixel channels around and adding black border masking would need to worry about anything like this.

butterw2
30th September 2020, 21:39
# Linear Gamma Conversion https://forum.doom9.org/showthread.php?t=181651 was mentioned in the original LCD calibration source code you linked and yes it can be confusing.

If you are just moving pixels around or masking the frame: it is not necessary.

Then there are many cases where it might be theoretically necessary (any processing of pixel values), but it makes little or no difference to the end result: just ignore.

In a few cases however it is necessary to convert to linear gamma before processing and then gamma encode when you are done.

Incorrect processing is so common however, that the result will sometimes look "strange/wrong" when you go through the trouble/overhead of doing it right.

Alexkral
2nd October 2020, 17:17
Hi @butterw2

Maybe you can help me with this.

I'm using a Lanczos 3 shader that I found on the internet to do the VDSR scaling in my app. The results are very good, quite similar to AviSynth and Matlab, and using Lanczos instead of Bicubic as is done on the VDSR paper, allows the final result to be much sharper. This is the code:

/*
Copyright (C) 2010 Team XBMC
http://www.xbmc.org
Copyright (C) 2011 Stefanos A.
http://www.opentk.com

This Program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This Program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this library.

*/

sampler s0 : register(s0);
float4 p2 : register(c2);

#define get(x, y) tex2D(s0, float2(x, y)).rgb
#define FIX(c) max(abs(c), 1e-5);
static const float PI = 3.141592653;

float3 weight3(float x)
{
const float radius = 3.0;
float s1 = FIX(2.0 * PI * (x - 1.5));
float s2 = FIX(2.0 * PI * (x - 0.5));
float s3 = FIX(2.0 * PI * (x + 0.5));
float3 sample = float3(s1, s2, s3);
return sin(sample) * sin(sample / radius) / (sample * sample);
}

float3 line_run(float ypos, float3 xpos1, float3 xpos2, float3 linetaps1, float3 linetaps2)
{
return
get(xpos1.r, ypos) * linetaps1.r +
get(xpos1.g, ypos) * linetaps2.r +
get(xpos1.b, ypos) * linetaps1.g +
get(xpos2.r, ypos) * linetaps2.g +
get(xpos2.g, ypos) * linetaps1.b +
get(xpos2.b, ypos) * linetaps2.b;
}

float4 main(float2 tex : TEXCOORD0) : COLOR
{
float2 pos = tex + p2.zw * 0.5;
float2 f = frac(pos / p2.zw);

float3 linetaps1 = weight3(0.5 - f.x * 0.5);
float3 linetaps2 = weight3(1.0 - f.x * 0.5);
float3 columntaps1 = weight3(0.5 - f.y * 0.5);
float3 columntaps2 = weight3(1.0 - f.y * 0.5);

float suml = dot(linetaps1, float3(1, 1, 1)) + dot(linetaps2, float3(1, 1, 1));
float sumc = dot(columntaps1, float3(1, 1, 1)) + dot(columntaps2, float3(1, 1, 1));
linetaps1 /= suml;
linetaps2 /= suml;
columntaps1 /= sumc;
columntaps2 /= sumc;

float2 xystart = (-2.5 - f) * p2.zw + pos;
float3 xpos1 = float3(xystart.x, xystart.x + p2.z, xystart.x + p2.z * 2.0);
float3 xpos2 = float3(xystart.x + p2.z * 3.0, xystart.x + p2.z * 4.0, xystart.x + p2.z * 5.0);

return float4(
line_run(xystart.y , xpos1, xpos2, linetaps1, linetaps2) * columntaps1.r +
line_run(xystart.y + p2.w , xpos1, xpos2, linetaps1, linetaps2) * columntaps2.r +
line_run(xystart.y + p2.w * 2.0 , xpos1, xpos2, linetaps1, linetaps2) * columntaps1.g +
line_run(xystart.y + p2.w * 3.0 , xpos1, xpos2, linetaps1, linetaps2) * columntaps2.g +
line_run(xystart.y + p2.w * 4.0 , xpos1, xpos2, linetaps1, linetaps2) * columntaps1.b +
line_run(xystart.y + p2.w * 5.0 , xpos1, xpos2, linetaps1, linetaps2) * columntaps2.b, 1.0);
}


Since Sinc resampling is sharper than Lanczos, what I would like now is to try a Sinc shader, but honestly, I don't understand all the math involved. So far I have only tried to change the weight3 function like this:

float3 weight3(float x)
{
const float radius = 3.0;
float s1 = FIX(2.0 * PI * (x - 1.5));
float s2 = FIX(2.0 * PI * (x - 0.5));
float s3 = FIX(2.0 * PI * (x + 0.5));
float3 sample = float3(s1, s2, s3);
return sin(sample) / sample;
}

This works, but the result is more blurry, so I'm assuming the shader needs a more in-depth change, or even a rewrite.

I'm not even sure anyway that it will serve to improve the results, since the VDSR network is more limited in what it can improve when using good scaling, and the models that I'm using are quite reduced, but I think that it may be worth the try.

Once again thank you in advance for you help.

EDIT: p2 are the dimensions: (width, height, 1/width, 1/height)

butterw2
2nd October 2020, 22:57
Your AviSynthAiUpscale project seems interesting, VDSR (Very Deep Super Resolution) is a deep learning approach for enlarging an image, but I haven't done anything with pixel shader resizers beyond bicubic so far. The reason being that Lanczos-3 requires a large kernel and is theoretically non separable (2D sinc-windowed sinc: k(r) with r polar coordinate).

Bicubic methods use a (4x4) convolution kernel req 16 texture taps. A simple improvement is to separate the horizontal and vertical passes, bringing it down to 8 taps.

Lanczos-3 (kernel: 2a*2a, a=3) req 36 taps, as demonstrated by your code (36 texture, 199 arithmetic).
Your code comes from xbmc, Kodi. Do you have an url ? Seems similar to https://github.com/xbmc/xbmc/blob/master/system/shaders/convolution-6x6_d3d.fx

However mpc-be has a 2-pass "compensated Lanczos3" implementation resizer_lanczos3_x.hlsl which seems to be 6+6 ? https://sourceforge.net/p/mpcbe/code/HEAD/tree/trunk/src/Shaders/Resizers/resizer_lanczos3_x.hlsl
I'm assuming you care more about quality than performance, but it may still be worth checking out.

by Sinc method do you mean SincResize from Avisynth ?
"uses the truncated sinc function. It is very sharp, but prone to ringing artifacts. "

Once you have the correct kernel, implementation shouldn't be too challenging.
If you are trying to implement the avisynth method, validation of the shader would be straightforward enough as you just need to compare to the avisynth reference.


# Pixel shader resizers in video players
Video player can use pixel shaders to perform scaling/resize (vs cpu sw scaling or fixed hw gpu scaling). Mpv allows user-defined scaling shaders, enabling the use of high-quality upscalers (a discrete gpu would be recommended for these shaders as they are not lightweight).
Mpc-hc/be does not allow user-defined resize shaders with the EVR-CP renderer: you must use one of the pre-defined resize methods. A pixel shader cannot change the frame resolution, but you can still test a scaling shader, by zooming in to the top left quarter screen for instance, ex: 1080p screen resolution and 1080p input video in fullscreen (no scaling by video player).
A resize shader will map the output coordinates (tex) to the corresponding input pixels to interpolate output pixel values. This is typically implemented using a convolution kernel (a more efficient 2-pass horizontal then vertical resizing approach is possible if the kernel is separable).
Note: resize operations should theoretically be performed in linear gamma.

Alexkral
3rd October 2020, 16:14
Ok, thanks for your answer anyway.

Your code comes from xbmc, that's from Kodi. Do you have an url ?

Yes, I adapted it from this: https://github.com/libretro/common-shaders/blob/master/windowed/shaders/lanczos6.cg

However mpc-be seems to have a 2-pass "compensated Lanczos3" implementation which seems to be 6+6, look for Resizers\resizer_lanczos3_x.hlsl ?

I didn't know about this, I'll take a look at it.

by Sinc method do you mean SincResize from Avisynth ?
"uses the truncated sinc function. It is very sharp, but prone to ringing artifacts. "

Yes, everything is explained here (http://avisynth.nl/index.php/Resampling) as well as the other resampling methods, but I find it too complicated, and as I told you I'm not even sure that it can be useful, maybe when I have more time I will try again. I was hoping that since the Sinc kernel is simpler than the Lanczos kernel, maybe it could be done by slightly modifying the Lanczos code, but without really knowing how it works it seems that it will not be possible.

butterw2
3rd October 2020, 19:00
I was hoping that since the Sinc kernel is simpler than the Lanczos kernel, maybe it could be done by slightly modifying the Lanczos code, but without really knowing how it works it seems that it will not be possible.

It's not fundamentally very complicated, but this code implementation is maybe not the simplest. They use .r, .b, .g instead of [0], [1], [2] for instance.
Switching kernel functions should just work, but performance will not be dramatically improved.
For reference, a 2-pass Catmull-rom resizer only requires (8 texture, 44 arithmetic).


# Convolution Kernels
A convolution kernel k(x, y) is a table of weights of size X*Y (ex: 3x3, 5x5 or 7x7). In a pixel shader, a convolution kernel might be calculated from parameters using the kernel function (if symmetry is present, it can be used to reduce the number of calculations required) or if constant the kernel can be hardcoded. The kernel is typically normalized so that the sum of weights is equal to one.
To calculate each output pixel value, the corresponding X*Y input pixels values are sampled and multiplied by their corresponding kernel weight to finally be summed.
A 2D separable kernel can be written as kh(x)*kv(y)=k(x, y) with kh and kv 1D-kernels. This allows 2D processing to be performed as 2 successive 1D-shader passes resulting in much more efficient operation in the case of large kernels.

butterw2
6th October 2020, 18:00
# Split screen display with pixel/fragment shaders:
This simple code modification can be applied to any pixel shader, and is useful to adjust parameter values and visualize what a shader actually does...
ex: Edge detection from Edge Sharpen https://raw.githubusercontent.com/butterw/bShaders/master/img/hsplit_scr_Edge_Detect_1080p.jpg

float4 main(float2 tex: TEXCOORD0): COLOR {
color=tex2D(s0, tex); //source pixel
/* horizontal split screen, left-half: no effect, right-half: with effect */
if (tex.x<0.5) return color;
...
}

It's of course possible to modify the code to display the same half-frame (with and without effect):
if (tex.x<0.5) return tex2D(s0, tex+float2(0.5, 0)); //Comparison Splitscreen: no effect

Note: This technique can be used pre or post-resize in mpc-hc/be (but post-resize, it only fully works in fullscreen).


it can also be applied to a mpv glsl .hook: https://github.com/butterw/bShaders/blob/master/mpv/bSide.hook.glsl
vec4 hook() {
vec4 color=HOOKED_tex(HOOKED_pos);
if (HOOKED_pos.x<0.5) return color;
...
}

Vertical split screen: if (tex.y<0.5) return color; //top-half: no Effect


For a sharpening filter, enabling/disabling the shader might be more effective to grasp the visual difference.


It's also of course possible to take screenshots (https://forum.doom9.org/showthread.php?p=1931990#post1931990) for comparisons.

butterw2
8th October 2020, 18:52
# Edge Detection

I've posted a couple of edge detection shaders based on convolution kernels at https://gist.github.com/butterw

- Edge_Sharpen.hlsl: mpc-hc Edge Sharpen optimization and luma edge detection mod (GPL v3 licensed)
Screenshot linked in preceding post.
Edge sharpening can help a soft source which is a bit soft without generating artifacts, it is one of the applications of edge detection.

On a clean high-res source, the following luma edge detection methods work very well on text, objects, hair, but maybe not so great on teeth.
- Frei-Chen edge detection in luma (mpv .hook shader)
can be used in combination with NoChroma.hook
Directly processing source luma seems to give better result (vs obtaining luma from rgb).



- Sobel/Canny Edge detection:
https://github.com/butterw/bShaders/bSobel_Edge.hlsl,
I've also made available a mpv .hook port of a glsl version of Sobel (in rgb).
Sobel is the most common algorithm for edge detection. It can be used stand-alone or as part of the Canny algorithm. The final stages of Canny are better implemented on cpu or compute shader however.

Canny edge detection video filter in ffmpeg (cpu): https://ffmpeg.org/ffmpeg-filters.html#edgedetect
mpv --vf=lavfi="[edgedetect=low=0.1:high=0.4]" input.mp4

These filters are also available (apply a grayscale filter on output):
mpv --vf=sobel input.mp4
mpv --vf=prewitt input.mp4
mpv --vf=roberts input.mp4

Alexkral
8th October 2020, 20:04
Switching kernel functions should just work

So I gave this another try (not knowing how it works yet). As I see it, the kernel is in the weight3 function, so I have changed it again like this:

float3 weight3(float x)
{
const float radius = 3.0;
float s1 = 2.0 * PI * (x - 1.5);
float s2 = 2.0 * PI * (x - 0.5);
float s3 = 2.0 * PI * (x + 0.5);
float ret1 = (abs(s1) < 2.0 * radius) ? sin(s1) / s1 : 0;
float ret2 = (abs(s2) < 2.0 * radius) ? sin(s2) / s2 : 0;
float ret3 = (abs(s3) < 2.0 * radius) ? sin(s3) / s3 : 0;
return float3(ret1, ret2, ret3);
}


I don't know why the samples are multiplied by two, but since it seems that it's needed, I also multiply the taps by two. This produces a VERY sharp result, even sharper than AviSynth's SincResize, so I think I'm on the right track. But if I debug the shader, I see 16 texture, 150 arithmetic, so I don't know what I should call it :p. Maybe it could be Sinc 2 taps? If I change 2.0 * radius to 7.0, the result is very similar and the code compiles to 36 texture, 209 arithmetic.

The metrics are not good but that doesn't matter too much to me, I'll use it to train some networks and then we'll see what the result is.

butterw2
8th October 2020, 22:39
# Optimizing gpu arithmetic operations

Whether variable x is float or float4, mad (multiply addition) counts as a single operation on gpu, ex: x*x + y, 2*x +3*4.2 (1 arithmetic op)

Weight3 is the kernel function, yes, but the code uses vectorized float3 operations, which can make it more difficult to understand.
I don't know how poorly a naive (brute force) implementation performs. There doesn't seem to be other code available for a single pass lanczos-3 pixel shader.
If you want to try it out, I can upload the 2-pass lanczos-3 shader code from mpc-be (which I've adapted to run in mpc-hc). Texture fetches hit the gpu harder than arithmetic ops, but it is still useful to reduce arithmetic ops when possible.

You need to help out the compiler in some cases, check the compiler output to see if this saves one operation for instance:
float s1 = 2.0 * PI * (x - 1.5);
can be written as:
float s1 = 2 * PI * x - 2 * PI *1.5; //1 arithmetic

Instead of floats s1, s2, s3
you could use one vector operation to calculate float3 s
and then use s.x, s.y, s.z

# Cost of hlsl functions (in arithmetic operations)
Single op: A*B+C (mad), float dot(A, B), frac(A), saturate(A)
2: lerp(A, B, 0.5 ), floor(A), step(A, 0.5), clamp(0.2, 0.8, A)
3: float length(A)
4: fmod(A, 2)
4,5: smoothstep(0, 1.0, A)
trunc(A)
---
ops>8: If multiple operations on float variables are needed, look at packing a vector.
sqrt(A)
sin(A)

Alexkral
8th October 2020, 23:55
If you want to try it out, I can upload the 2-pass lanczos-3 shader code from mpc-be (which I've adapted to run in mpc-hc).

Yes please, that could be helpful, most of what I've learned has been just looking at the code.

Instead of floats s1, s2, s3
you could use one vector operation to calculate float3 s
and then use s.x, s.y, s.z

I needed to change that from the original code (the link I posted) because the max function gave wrong results, but you are right, now it can be done this way.

butterw2
9th October 2020, 00:58
Compensated Lanczos3 pass X (from mpc-be, adapted for mpc-hc user shader with 2x magnification):
https://gist.github.com/butterw/8190fe5f9c24687ee96bb6f188b9222b
You'll also need the second pass (pass-Y), which is the same as pass-X, but applied to y-axis.

In hlsl, texel centers (tex) are situated at half-pixel coordinates. If you don't need 2x magnification, don't start from my adaptation, start from the original code (just define dxdy as required, I prefer using p (or p1) for this, the pixel widths are then p.x, p.y).

float4 p2: register(c2); //in this application, c2 contains: (width, height, 1/width, 1/height)
#define p p2.zw //pixel widths (p.x, p.y)




# Testing a shader with a png image input
A good way to test a video player shader is to use a png image as input. Output will update automatically when you modify/save the shader and an output screenshot can be saved for comparison if required.
Input: RGB(A) png (preferably of same resolution as the output screen), shader (preferably pre-resize shader), output (fullscreen preferred for screenshot in windows)
The idea is to bypass compression artifacts (png is lossless), yuv2rgb conversion/range expansion, video player scaling, so as to only test the pixel shader.

Alexkral
9th October 2020, 02:29
Thanks, I'll have some time in the next few days to take a look at all this, hopefully soon I will understand a little bit more.

Alexkral
12th October 2020, 05:08
So I didn't have much luck trying to change this code either, but it's ok, I don't want to keep trying or filling this thread with posts related to this. I just wanted to point out that the mpc-be code is wrong, the changes you made fixed it, but it still produces a half pixel shift to the left (same as the xbmc code but in the opposite direction), you can fix it like this:

float coord = (tex.x - p1.x)*0.5*p0.x;

Other than this, the performance of the mpc-be shader is only slightly worse than the other implementations.

butterw2
12th October 2020, 11:35
The mpc-be resizer uses pixel scale for the tex.x coordinate.
ex tex.x: 421.5 for a 1000x1000 output frame, whereas the typical hlsl scale, used in mpc-hc/be user shaders is [0, 1.]

For 2x magnification, the corresponding input texel center would be at: 210.75 -0.75 +0.5=210.5 in output frame coordinates, given the half-pixel offset of texel centers in hlsl.

The perf of my port is (6 texture, 79 arithmetic) for X-pass (I've removed the t==0 case because it's not required).
I would expect a significant perf improvement in 2-pass (12 texture, 158 arithmetic) vs xbmc(36, 199) because the number of texture fetches is much lower.
That said I haven't measured frame times, the bottleneck may be different on igpu (vs dgpu) and going 2-pass (vs single pass) may introduce additional overhead with avisynthshader.

I am not clear how you use the lanczos shader in your app, is it fixed 2x upscaling, arbitrary ratio resize or is it 1x interpolation ?

float4 p2: register(c2); //(W, H, px, py)
Does the avisynth script define the content of the registers ? Why does avisynthshader need the c2 register here ? Is there a difference between c2 and the values in c0 and c1 (as used by mpc-hc) ?

While it isn't off-topic here (an avisynthshader script could potentially be used for testing and maybe even in realtime ?), you are welcome to reply in your own thread if you wish.


# Mpc-hc/be Registers

player(cpu).>> registers
.................>> frame (ex: RGBA) >> pixel Shader1(gpu) >> processing surface >> pixel Shader2 >> Output

Shaders must be compiled, before they are executed (ex .cso). They can be cached on disk.
The application executing the shader can pass parameters to it through registers.

Registers contains read-only data set by the application. They can be updated every frame and are readable by user pixel shaders.
These parameters are made available by mpc-hc/be: all individual values are floats
sampler s0: register(s0); //the input frame texture
float4 p0: register(c0);
#define W p0.x //(p0[0]) //image Width
#define H p0.y //p0[1]) //image Height
#define Counter (p0[2]) //frame counter, ! it doesn't get reset when you stop video.
#define Clock (p0[3]) //time counter in seconds
float2 p1: register(c1); //p1.xy
#define px p1.x //1/W
#define py p1.y //1/H

Testing parameter/variable values
A crude method to test the content of H would be as follows:
if (abs(H-1080)<0.001) return float4(1, 0, 0, 1); //return a red pixel/screen if H is close to 1080
rounding point error means testing for equality doesn't always work with floats !
In this case (and with int variables) it is safe to write: if (H==1080) return float4(1, 0, 0, 1);

Alexkral
12th October 2020, 21:11
I was referring to the metrics (psnr and ssim), I didn't test the speed.

The VDSR network learns to estimate a residual image, which is the difference between a high-resolution reference image and a low-resolution image that has been upscaled to match the size of the reference image. The low-resolution image in usually upscaled using bicubic interpolation, but I have obtained better results using Lanczos. I trained several models with different scaling factors, which are used depending on the upscaling ratio. VDSR allows for multiscale training, but it hasn't worked well for me. So it is arbitrary ratio.

In AviSynth Shader, when using the Width and Height parameters to resize the texture, the c0 and c1 registers are set to the output values, so I need to use another parameter to set another register with the input values.

butterw2
14th October 2020, 09:01
What is the benefit of training with a pixel shader resizer vs the built-in avisynth cpu implementation ?

The code for a 2-pass separable resizer (an approximation in this case) is maybe easier to understand because you only deal with 1 dimension at a time. I'm not sure how far you want to go with this or if it is even desirable, but I would assume it is possible to modify the code to achieve a larger kernel (lanczos4, etc.) without degrading performance (meaning speed) vs xbmc lanczos3.

Edit: Since you are an AvisynthShader user, are there any adaptation steps needed to made shaders compatible or does any hlsl effects shader for mpc-hc work by default ?

Alexkral
14th October 2020, 16:16
There is no benefit when training, the results of the shader and the AviSynth and Matlab implementations are very similar, in fact I use Matlab's Lanczos for training and then the shader for testing in the app. The benefit comes when testing, because the bottleneck in AviSynth Shader is in the memory transfers between the CPU and the GPU, so it is slower to send the upscaled texture, than to upscale it in the GPU. This is what prevents me from using AviSynth's SincResize.

Anyway, I'm doing some tests now with the modified xbmc code and the difference in the results doesn't seem to be too significant, so I don't think using Lanczos4 would make any difference.

As for AviSynth Shader, other than what I said about the registers, I think there are only a few issues with some color formats. Using RGB as input/output, the order of the channels in the shader is changed to BGRA and they must be returned in that order.

butterw2
15th October 2020, 12:52
# Effects available as video pixel shaders (gpu) Grayscale and bi-color Effects

The effects listed here are meant to be used in video players (.hlsl: mpc-hc/be, etc., .hook/glsl: mpv). It may also be possible to use them for processing/encoding of video or images. Typical video player input is compressed yuv420 (color video with chroma subsampling). Mpc-hc shaders operate on pre or post resize RGB, whereas mpv shaders can additionnaly operate on source YUV (or RGB).
Many effects have parameters that can be adjusted in the source file, and some guidance will be provided as to further customizations.

Effects apply a visual style to a video. They modify the aspect of the displayed content to change the viewing experience. They are not meant to be used permanently.
Some effects are deliberately designed to degrade the displayed video quality or imitate the elements of past video/film technology.
Some are intended for use with specific types content (Internet Videos, Music Videos, Home Captures) rather than Movies.


## Grayscale Effects (in 8bit output is 256 shades of gray)

Monochrome
- In mpv, you can zero the chroma channels from the source YUV (NoChroma.hook). This is the recommended approach if the content is in fact grayscale.
- The more general approach is to calculate luma = dot(color_RGB, LumaCoeff_RGB). The value of LumaCoeff will change how the picture looks (SweetFx.Monochrome
provides values corresponding to different film types, ex: Agfa 200X). The sum of the R, G And B components of LumaCoeff should be equal to 1.

Edge Detection
Most edge detection methods work on and output Luma. The algorithms use an adjustable detection Threshold.
- Sobel_Edge.hlsl, Sobel.hook
- Frei-Chen.hook
- Edge_Sharpen.hlsl (mod/perf optimization of mpc-hc version).
One application of Edge Detection is edge sharpening. Colored Edges can also be overlayed on the original image for stylistic effect.

Halftone dots.hlsl art effect, for video rather than movies
greyscale (mostly black and white) dot pattern, can be used twice. The mpv version (dots.hook) keeps chroma by default.



A color tinted image can be obtained from grayscale, by using the grayscale values as one of the color channels, ex: red channel.
To obtain a tinted image of any tint (ex: Sepia): color_RGB = luma * TintCoeff_RGB;
A sepia effect should ideally not change the original brightness. The white color from the original should not be changed too much. https://github.com/butterw/bShaders/blob/master/Effects/Sepia.md

In mpv, the source chroma NoChroma shader could be modified to apply small offset to the grayscale value (0.5, 0.5) to get tint.


## Bi-Color Effects (Output palette only contains 2 colors)
These effects typically output Black + White output by default, but this can be changed to any color combination.

bi-Threshold.
A Binary Threshold applied to a greyscale image (typ. luma)
To avoid a full-range black and white, which can be glaring, you can clamp the output, for instance to 16-235 RGB levels.

Stipple Effect
Grayscale dithering: A grayscale image can be transformed into a bw (2-color) image with an error-diffusion algorithm (ex: atkinson, floyd-steinberg). These algorithms cannot be efficiently implemented as pixel shaders as they are not parallel, but it may be possible to use compute shaders.


# Color desaturation
The intermediate image between the color original (C) and the grayscale version (G) is a desaturated color image. It is obtained by performing a linear interpolation between C and G with s the desired strength of the effect (s is a weight between [0, 1.0] 0: C, 1: G).
desaturated_color = lerp(C, G, s); // in glsl: mix(C, G, s)

lerp(x, y, s) = x*(1-s) + y*s = x + s(y-x), with x, y: RGB vectors.

# Alpha Blending (Transparency)
The same function is used for RGB alpha blending between the color image (C) and the background (B):
alpha between [0, 1.0] 0: B (transparent image), 1.0:C (opaque)
alpha_blended_RGB = lerp(B, C, alpha)

Note: the alpha channel is present but unused in mpc-hc and mpv RGBA colors.

butterw2
19th October 2020, 15:38
# Lightweight Noise/FilmGrain Shaders

On a low intensity setting, Noise/FilmGrain improves perceptual quality of most compressed videos. In particular content with low or no noise, (ex: the source noise may have been removed at encoding to improve compressibility). It may also help mask artifacts.

The main reason not to use Filmgrain in mpc-hc/be was the performance hit on lower end systems. These new shaders offer a major speed improvement over previously available shaders without creating a visible noise pattern.

https://github.com/butterw/bShaders/tree/master/FilmGrain_Noise
- bNoise.hlsl (1 texture, 12 arithmetic)
- FilmGrain1.hlsl (1 texture, 30 arithmetic) mpv FilmGrain.glsl port.

FilmGrain/Noise refers to dynamic additive grayscale noise with a gaussian distribution for FilmGrain and a band-limited uniform distribution for Noise.

Some limited quality testing was done based on the output noise histogram obtained through screenshots, but more feedback would be welcome.

butterw2
23rd October 2020, 09:28
# Unfocused Effect (ex: Large Kernel Gaussian Blur)

Implementation in mpc-hc of a pixel shader preset for fast multipass blurring was previously discussed page1 (separable kernel, blurring a downsized image, hw linear sampling, approximate gaussian algorithms: Boxblur, Kawase Blur). It's certainly possible, but not that simple to achieve high quality, high performance blur.

When upscaling, Blur should always be performed pre-resize (less pixels to handle, stronger blur effect on a lower resolution image for a fixed Kernel size). When downscaling (ex: 4K content to 1080p) Blur should be performed post-resize.
For larger kernel sizes (k), a 2-pass separable kernel approach (horizontal pass, followed by vertical pass) performs much better than a single pass 2D-convolution:
O(2k) vs O(k^2) texture fetches required, with k the kernel size.

In Mpv
mpv can apply ffmpeg libavfilter video filters to its input (uses mainly cpu). However the boxblur filter doesn't seem to work for me. It does work in ffmpeg/ffplay (a simple SDL cross-platform media player using ffmpeg): ffplay -i "video.mp4" -vf boxblur=10:10

mpv supports extra features with regard to shaders vs default mpc-hc (hw linear sampling, multipass in a single shader, multiple textures with custom resolutions, compute shaders), which means it should be possible to implement fast high quality blur shaders (https://github.com/butterw/bShaders/tree/master/blur).

Downsizing the frame (W, H)/2 at the input of the blur shader enables stronger blurs for the same gpu usage. However decreasing the resolution too low (y<240 ?) will impact the quality of the effect.

EDIT: Blurred sidebars, which are popular on mp4 internet videos (ex: 1:1 AR displayed fullscreen on a 16/9 monitor) can be achieved using a realtime avisynth script (https://github.com/butterw/bShaders/blob/master/blur/fill_bb.avs) (cpu) playable in in mpc-hc/be or mpv.

butterw2
24th October 2020, 17:59
# Mpv shader basics

Tests performed with a portable version of mpv-x64 on Win10:
https://mpv.io/installation/
this default mpv version doesn't come with a GUI like mpc-hc/be: it's exe (+command-line) + On-Screen-Controller + Hotkeys.

Install directory (ensure it has write permission).
create ./portable_config for configuration files:
- mpv.conf (config file, not provided by default, but you do really need one !!!)
- input.conf (custom hotkeys will override defaults)

you can put shaders directly in the install dir or you can use a subfolder. No user shaders are provided by default.

There are 3 ways to select/control shaders in mpv:
- default configuration (mpv.conf)
- launch command-line (can add shaders or override default configuration)
- hotkeys


Example ./portable_config/mpv.conf (vo=gpu d3d11 with dxva2-copy on Win10):
#-- Shaders --------
glsl-shader="noChroma.hook"
glsl-shader="./shaders/CrossHatch.hk"
# glsl-shader="./shaders/freichen.hk"
# glsl-shader="./shaders/cs_wkgroups.hk.glsl"
--gpu-shader-cache-dir="C:\Temp" # ! set the shader cache to a directory with write access

#-- Video ------
hwdec=dxva2-copy #hwdec=d3d11va-copy
hwdec-codecs=all
gpu-api=d3d11
gpu-context=d3d11
vo=gpu
#profile=fast
audio-device=auto

#-- Scalers -- Luma/Rgb scale (dscale), Chroma (cscale)
dscale = mitchell #cscale= bilinear
scale = catmull_rom

##-- Screenshots --------
screenshot-format=png
screenshot-jpeg-quality=96

## --Window settings--------
# Start in fullscreen mode by default. #fs=yes
# force starting with centered window #geometry=50%:50%
# geometry=720x720 #fixed window size
# don't allow a new window to have a size larger than 90% of the screen size # autofit-larger=90%x90%
# mpv doesn't have an enforceable option to start at 100% scale:
autofit-larger=1280

keep-open=yes # Do not close the window on exit.

butterw2
25th October 2020, 15:42
Mpv shaders are written in glsl using a specific .hook syntax, they can contain a number of independent passes each with associated HOOK points.
Intro here: https://forum.videohelp.com/threads/397797-Pixel-shaders-for-video-playback-(-hlsl-glsl)#post2597322
The main hook points in the processing pipeline are: LUMA, CHROMA (source yuv), NATIVE(yuv), MAIN (pre-resize RGB) and OUTPUT (post-resize RGB).
A single .hook file can contain multiple passes. To disable a pass, you can specify a non-existing HOOK point (ex: None).

A Pre-scaler (custom Luma or Chroma Upscaling Shader) works as follows:
Source Resolution, ex:1080p >> user Shader (ex: HOOK LUMA) >> texture resolution (ex: 2x W, H) >> (built-in scaler) >> Screen Resolution 2160p

## Using custom shaders in mpv
default shaders are configured in mpv.conf (with multiple glsl-shader= lines or a single glsl-shaders line).
Shader configuration can additionnally be configured with command-line launch parameters.

to append a shader for playback (ex: chromaOff):
mpv --glsl-shader="./shaders/NoChroma.hook" "video.mp4"

to desactivate or override config file shaders:
mpv --glsl-shaders="" "video.mp4"

If an enabled shader has a syntax error, you will get a blue screen display and the compiler error output in the launch terminal.

butterw2
1st November 2020, 18:55
mpc-hc > Help > Command Line Switches lists available command line options.
They can also used by editing the properties of the Windows launch icon.

The following launches mpc-hc
sets the shader preset named "Blur",
opens video1,
followed by video2 in the playlist:

mpc-hc /shaderpreset "Blur" "video1.mp4" "video2.mp4"

butterw2
3rd November 2020, 20:53
shader support in MPC video renderer (MPC-vr)
- newer open-source directshow renderer (uses dx11 by default on Win8+) vs default dx9 only EVR-CP
- good performance.
- x64 and x86 versions
- good integration with mpc-hc/be, but requires additional download + system install of .ax directshow filter (as admin).
- built-in shaders up/down scalers (catmull-rom, lanczos3, jinc2m, etc) for luma/chroma can be used instead of the video processor.
- built in HDR to SDR conversion.
- surface: 8, 10bit integer or 16 bit floating point.

You will need to restart the player for the following changes to be taken into account:
- Set the renderer in mpc > options > output.
- configure in : mpc > Play > Filters > mpc video renderer
-dx11 mode (requires shaders written with dx11 syntax, currently only supports post-resize user shaders !!!) or dx9

Pixel-shader support:
- User shaders are post-resize only.
- Shaders do not apply to the black borders in fullscreen mode, which can be beneficial (vs EVR-CP).
- dx11 compute shaders not supported.
- Modified shaders are only taken into account when you close/reopen mpc-hc !!!

butterw2
21st November 2020, 20:22
# Comic-book/Toon realtime Shaders

Transform the input video for a comic book style look. This typically involves reducing the color palette and/or enhancing edges. Black and white ink techniques such as hatching can be used.

More details and some screenshots in this thread: https://forum.doom9.org/showthread.php?p=1928755#post1928755

.hlsl (tested in mpc-hc/be) and mpv .hook will be made available at bShaders/Effects.
- bStipple.hlsl: works quite well for 720p, 480p video input (use pre-resize).

butterw2
24th November 2020, 15:34
# mpv shader hotkeys

Mpv comes with a number of predefined keyboard shortcuts. (https://github.com/mpv-player/mpv/blob/master/etc/input.conf) You can add new shorcuts and individually override pre-existing ones by creating an input.conf file.

./portable_config/input.conf :

# Display the list of active shaders:
CTRL+0 show-text "Shaders: ${glsl-shaders:}"

# Switch to a new shader chain:
CTRL+9 change-list glsl-shaders set "NoChroma.hook"

# Associate a hotkey to a shader, so it can be toggled on/off:
CTRL+1 change-list glsl-shaders toggle "./shaders/gSmooth.hook"

# Clear all Shaders (there are 2 ways to do it, with slightly different results):
CTRL+DEL change-list glsl-shaders set "" #glsl-shaders will be a table containing an empty string, same as --glsl-shaders=""
CTRL+p change-list glsl-shaders clr all; show-text "Shaders Cleared" #glsl-shaders will be an empty table, same as --glsl-shaders-clr


Switching or Disabling shaders through a hotkey can be done without restarting the player and also works in paused mode.
EDIT:! When shaders are cleared, the previous shader chain is lost (it can't be re-enabled, it has to be re-created). To avoid this the external script shaders-switch.js can be used: https://github.com/mpv-player/mpv/issues/8512 and bound to CTRL-P.
! To force modified shaders to recompile, you have to restart-mpv (https://forum.doom9.org/showthread.php?p=1994854#post1994854).

butterw2
27th November 2020, 13:39
#Shaders Folder, Paths and extensions

In mpv
- shaders can use any paths or file extension (.hook is typically used).
- because shaders can be specified at the command line:
---avoid spaces in filepaths.
---keep paths short
examples using a relative path from the program directory:
bw.hook
"shaders/shade.hook"



In Mpc-hc
mpc-hc uses ./Shaders for dx9 shaders.
The Select Shaders... Interface, (https://raw.githubusercontent.com/butterw/bShaders/master/img/mpc-hc_Select_Shaders_Menu.png) (O) Options... > Playback > Shaders shows .hlsl files in ./Shaders and its subdirs.
If you have a lot of shaders, it is useful to move the less frequently used ones to subdirs. An empty shader named
z------------------------------------------------------------------------------------.hlsl can be used as a separator.

The interface also allows to load and save Shader presets.

butterw2
4th December 2020, 20:29
# mpv Auto-Profiles
The following is an example of an automatic profile in mpv.conf based on video file properties.

The profile is triggered when profile-cond (a lua expression based on file properties) is true.
ex: profile-cond=width>=1280

in mpv.conf:

#mpv auto-profile example
[filename_wsz]
profile-desc= 4/3>>16/9 fullscreen PnS if _wsz in filename
profile-cond= string.match(filename, "_wsz")~=nil
video-zoom=0.42
fs=yes
profile-restore=copy

When a filename containing the string "_wsz" is opened, the file is automatically displayed in fullscreen with the required Pan&Scan to remove the hardcoded black bars.
Nice.:cool:

EDIT: it's also possible to create and use a custom .wsz extension associated with mpv. In which case it's even simpler:

[extension.wsz]
profile-desc= 4/3>>16/9 PnS for files with .wsz extension
video-zoom=0.42

chros
5th December 2020, 07:58
I used an auto-profile script (I think) when I played with it, but it was pretty finicky to set up more than 10 profiles based on fps, resolution, hdr, etc. But it worked in the end.
But big question is how to auto change the refresh rate of the display, displays in profiles, etc.

butterw2
5th December 2020, 14:25
Profiles are a great concept: switch between different configurations using a single configuration file.
https://mpv.io/manual/stable/#profiles

Auto-Profiles on the other hand is not something I plan to use much. You have to be careful about which profile conditions are potentially triggered for any given video.

Regarding your monitor issues: it's probably worth keeping an eye on the progress of external lua scripts and the related workaround discussions for any current limitations.

butterw2
8th December 2020, 19:08
# New Shader features in current Nightly build of Mpc-hc
mpc-hc dev 1.9.8.65 (Dec 5 2020) https://github.com/clsid2/mpc-hc/releases

New menu entry (and shortcuts) to enable/disable shaders:
- Right-click > Shaders > Enable Pre-Resize Shaders (CTRL-P)
- Right-click > Shaders > Enable Post-Resize Shaders (CTRL-ALT-P)
The menu entry is greyed out if no shaders are present in the corresponding chain.
Disabling shaders is effective immediately even if the player is paused.

The settings' state is stored in mpc.ini:
PostSizeShadersEnabled=1
PreSizeShadersEnabled=1

Multi-pass Shaders (2P):
If a shader is named xxx_pass1.hlsl, with xxx_pass2.hlsl, etc. also present in the shaders directory, the shader will appear in the Shader-list as xxx (nP), where n is the total number of passes.
The shaders' first and subsequent passes are now loaded and removed together in a single step in the "Select Shaders..." interface.

Blur Shaders added (use pre-resize for more effective blur)
- Smoothing filter: Gaussian Blur 3x3.hlsl
- Gaussian Blur (2P), separable 7x7 Gaussian Blur, different sigma values can be selected.
Use multiple instances to achieve a stronger blur.

Finally, hardware linear sampling doesn't work in mpc-hc/be, it uses nearest neighbor sampling instead (test (https://github.com/butterw/bShaders/blob/master/test_linearSampling/bSmooth_test.hlsl), not sure why).

butterw2
26th December 2020, 11:33
# Custom hotkeys, Seeking, Chapters, Playlist

Customizing hotkeys and mouse actions in mpc-hc/be: Options (O) > Player > Keys
Some of the commands are only accessible through hotkeys.
Non-default hotkey values are stored in windows registry or mpc.ini under [Commands2], the list isn't in human readable form however.
mpc-hc v1.9.8:
- Added support for using Ctrl/Alt/Shift modifiers for mouse actions
- Duplicate hotkeys are now highlighted in red (only the first action gets executed)

Default Hotkeys for seeking (Jump):
mpc-hc (O) > Player > Keys > enter: jump
- Jump (medium): Left/Right arrow
- Jump (large): Ctrl + up/down mouse Wheel
- Jump (small): none
- Jump (keyframe): Shift + Left/Right arrow. Seek to previous/next keyframe
- Jump to beginning: Home
- Stop ■: .
- Frame-step |▶: Ctrl + Left/Right arrow

O > Tweaks > set Jump distances (small, medium, large. Default values in ms: 1000, 5000, 20000)


Chapter and Playlist Navigation, mpc Menu > Navigate
by default plays files in the same folder sorted by filename, without looping.
- Next ▶▶|: Page Down. Next chapter if applicable, otherwise Next file
- Next File: CTRL + Page Down

O > Tweaks > Show Chapter Marks in seek bar
O > Player (History) > Remember Last Playlist (you can reopen last opened file by pressing play after launching mpc-hc)


vs. Mpv:
mpv has different defaults but can be made to operate similarly to mpc using a custom input.conf hotkey configuration file.
Ex: mpv default seeking is by keyframe, to implement mpc Jump large(20s): Ctrl+WHEEL_UP osd-msg seek 20 exact
remaining differences:
- next chapter and playlist-next have independent hotkeys
- mpv doesn't display a black screen on Stop

Playlists in mpv allow seamless video playback
play folder (and subfolders !) sorted by filename: mpv b:\videos
play from a plain-text playlist file: mpv --playlist=play.txt

Default playlist hotkeys (override in input.conf):
< playlist-prev # skip to previous file
> playlist-next # skip to next file
ENTER playlist-next # multiple hotkeys for the same command are possible in mpv

butterw2
29th December 2020, 10:12
# Screenshots

mpc-hc/be Source screenshot (Alt+I) Save Image...
...set the output parameters (stored in .ini/registry): jpg (ex: 96% JpegQuality) or .png (lossless), the output directory (SnapshotPath)
To take Output Screenshot (resized, with shaders and subtitles):
in fullscreen: Win+PrnScr (Win10 Screenshot, saved in Pictures\Screenshots)
Screenshot of window (to clipboard): Alt+PrnScr
...to get only the video frame, first Set View>Preset...>Minimal (1)
...(3) returns to Normal View
mpc-be (Shift+F5): Save Displayed Image (auto), ! this feature is not available in mpc-hc

Given that Directshow doesn't guarantee frame accurate seeking, it is preferable to select a keyframe for repeatable screenshots:
-Shift+Left/Right: Prev/Next keyframe
-Ctrl-G: Go to time/frame

---
mpv
start time, paused > mpv --start=01:00:47.102 --pause

Output screenshot (Ctrl-s)
-s: output screenshot, but with same resolution as the source file
(mpv manual) "by default: Files named mpv-shotNNNN.jpg will be saved in the working directory, using the first available number - no files will be overwritten."

The default screenshot settings can be set in mpv.conf, ex:
screenshot-format=png
screenshot-jpeg-quality=96

butterw2
9th January 2021, 10:54
# Comparison of video player features (Win10)

- mpc-hc/be are Windows Directshow based players whereas mpv and vlc are cross-platform players.
- All are open-source, are actively developed and come with all the required codecs for playing audio/video files (with support for hardware acceleration).
- All have portable versions and an optional installer.
- All have configurable hotkeys (incl. mouse).
- the default build for vlc on windows is still 32bit (a 64bit build with the same features is of course available).
- mpv doesn't have a GUI by default (beyond its window and libass based OSD). It uses configuration files and hotkeys (and optionally a console output). Every option can also be set from command-line. For those who do want a GUI, some mpv-based players are available.
- mpv.net offers a fully user-customizable right-click menu.
- A context menu can be added to mpv v0.37 with mpv-menu-plugin
- base mpv doesn't support single-instance mode !!! mpv.net does.
- mpv is built on top of ffmpeg and can use ffmpeg filters on its input. I needed --hwdec= d3d11va-copy or dxva2-copy for this to work.
- mpc-hc/be and mpv can open .avs scripts. If the script has an error, Mpv displays the Avisynth exception in the console.
- mpc-hc doesn't do HDR2SDR tonemapping by default.
- vlc doesn't support user pixel shaders with it's default dx11 video output. It does have built-in video filters (ex: FilmGrain) configurable through a multi-tab GUI.
- mpv has the most complete user shader support: YUV pre-scale and RGB, a working hardware linear sampling mode, embedded textures and compute shaders. vo=gpu-next adds shader parameters.
- mpc-hc and mpv have shader presets (multiple user configurable shader chains).
- mpc-hc shaders auto-update when their source file is modified. In mpv, you need to restart the player (but this can be done with a hotkey)
- vlc has built-in audio filters (equalizer, compressor, etc.) with sliders.

pirlouy
9th January 2021, 13:49
Eheh, dangerous to compare features between players. It would need a specific thread, and there would be blood in this thread. :p
Some will say players are missing in your list. Some will say it is biased.

One example: For me, mpv (the player I use) has a GUI: In OSD, there's not only seekbar, but some useful buttons like cycling subtitles/audio. But indeed, no contextual or main menu. You have to bind commands in a file with hotkeys.

Sometimes, features are specific to someone. For example, in madVR, screen resolution can be changed according to fps, whereas it's not possible in mpv. So I launch some files with MPC then close and open them with mpv.

But anyway, now that you made your comparison, I'm curious, what's your preferred player ?

stax76
9th January 2021, 15:40
There are GUI frontends like mpv.net and GUI scripts like uosc.

https://github.com/stax76/mpv.net

https://github.com/darsain/uosc

https://github.com/mpv-player/mpv/wiki/Applications-using-mpv

butterw2
9th January 2021, 16:36
As pirlouy points out a full feature comparison of every available player would be quite the ambitious undertaking, and beyond the scope of this shader thread.
If there are any mistakes in my post I'm certainly happy to correct them. But I will only comment on the players and the limited feature set I use.
There are a number of decent players available and I would simply recommend using at least two and selecting the one best suited for each task.

#the mpv GUI
From the mpv manual: "mpv has no official GUI, other than the OSC (ON SCREEN CONTROLLER), which is not a full GUI and is not meant to be."
For those who don't want a GUI, mpv is certainly a good candidate (the OSC can be disabled with --no-osc). For those who expect a GUI, there are multiple frontend options to choose from (such as mpv.net) and also some OSC.lua replacements (ex: https://github.com/maoiscat/mpv-osc-morden maybe with --no-border).
And contrary to mpv, mpv.net has a config GUI and does support by default: single instance mode, play files in folder, and Stop ■ (well at least it doesn't quit like with base mpv...).

butterw2
10th January 2021, 12:58
Regarding the mpv seekbar (osc.lua): IMO the default should be to match the standard of web (html5) video players and just provide a few configuration options.
Web video players can achieve a simple uncluttered interface, which isn't typically available in desktop video players. One of the issues is that the latter have a lot more available features.
Yet providing the option for a simple beautiful interface should be a focus for modern video player development.


# Menu options
One thing I would like to see in video player UI is configurable menu options, in particular for the right-click menu. This pop-up menu can be very useful in fullscreen mode to launch commands without the need for keyboard hotkeys.

- html5 players don't use menus, but they typically do have a settings button.
- base mpv has no menus or settings interface.
- mpv.net has a right-click menu and a settings interface. !!! config file changes do require a restart of the player.
- mpc-hc/be has a window menu by default, and offers 2 different options for the pop-up menu (configured through the O > Keys interface).
The mpc-hc/be menu displays the associated hotkey next to the commands and is generally well-thought out, but it is also very cluttered and this is true also of 2 different variants of the right-click menu (all the same commands, organised differently). An option for greatly cut down right-click menu would be appreciated. It should ideally be user-customizable, just like hotkeys are configurable.

pirlouy
10th January 2021, 13:37
mpv is so fast when you launch a video it is enjoyable and you prefer not to have a GUI.

It takes time to create the file with all shortcuts (input.conf), but once done, you realize you use little functions/buttons and keyboard/mouse shortcuts are enough.
But I'm aware it's only for advanced people, and mpv.net is a good choice for those coming from classic players with lots of options (like MPC).

butterw2
27th January 2021, 16:44
# Video Player installation

What a video player installer does on Windows:
0) Copies files to the chosen application folder
1) Creates a shortcut
2) [Registry] associates itself with filetype extensions (opened by double-click)
3) [Registry] changes filetype icons
4) [Registry] changes contextual menus: folder playlist-options, per filetype Open With
5) [Registry] Sets-up default settings
6) Creates an uninstaller !

This seemingly convenient automatic one-click solution has its pitfalls.

Custom manual portable installs are preferable in many cases.

Some info/advice:
- Install to folders were you and the program will have write permission (also for shaders subfolder). ! This isn't the case for c:\Program Files by default.
- a simpler/shorter path is preferable. Spaces can be troublesome for command-line.
- Changing your default video and audio players is OK, but changing per filetype associations can be troublesome (in particular icons per filetype).
- Use portable install for your non-default players, this allows using many different video player versions.
- Each portable install should be in its own folder. To test a development build, it's typically enough to copy the exe to an existing install folder (rename the .exe to switch between versions).
- Why register every possible audio, video extension that ever existed ?
- SendTo contextual menu is easy to configure (find sendTo folder location by running shell:sendTo, then copy/delete shortcuts in folder).
- ! Avoid changing installation paths
- Using Registry all player versions will use the same settings.
- Saving settings to .ini rather than registry makes it easier to backup, compare, modify, substitute (ex: reset to default) configurations
- You can replace the default shortcut icon for a player easily (but not the application window icon which would require hacking the exe).
- Shortcut properties can be edited to specify startup options or startup folder
- The default icon used for filetypes associated with a program can be changed in the registry.

butterw2
7th February 2021, 18:29
# Color mapping with Shaders
input pixel (typ. RGB) >>color transformation, out=f(in) >> RGB output pixel

- Color Controls for basic adjustments (Brightness, Contrast, Hue, Saturation), Gamma.
- Color Filters: Saturated rgb, Nightvision, Color Temperature, Tint, etc.
- Color to Black&White transformation (using a custom LumaCoef)
- Luma/Chroma Contrast curve without clipping (ex: SweetFx.Curves)
- ToneMapping

mpv additionally allows embedded textures in shaders, which can be used for fast LUT (Look-Up Table) transformations
ex: CLut(Vivid, Old Photo) or gr.Lut (Sepia), simple 1D LUT with linear interpolation: 256 rgba values hex-encoded
Applying the LUT requires just 1 texture tap for gr.LUT, and 3 texture taps for CLUT
EDIT: A better approach for Color Luts is to use 3D textures with 3D linear interpolation (also supported by mpv shaders)
In this case applying a CLut requires just 1 instruction (with one 3D-interpolated texture tap).
- ! texture format must be supported by the gpu driver, which can be an issue cross-platform for floating point formats (vs lightweight rgba8 texture format which is simple to encode and widely supported)
- Luts come in different formats and sizes (typ. from 4^3=64 to 64^3 colors). Filesize reaches 2MB for a clut-64, so using clut-36 for shaders would be more reasonable. clut-4 might be usable in some cases.
Many awesome free luts are available on the internet, the main issue is the required format conversion !

To change the color-look of a video, a pack of 10 to 15 distinctive shaders would cover most use cases:
- Technicolor
- Vintage KODACHROME (1936-1962) https://frankglencairn.wordpress.com/2014/01/15/everything-looks-better-on-kodachrome-k-tone-lut/
- Old Film
- Sepia
- black&white Agfa 200X
- black&white Rollei (high-contrast)
- etc.

butterw2
9th February 2021, 00:56
# Main formats used for CLuts (Color Look-Up Table)
- Haldclut a square .png ex: level8, 512x512x24bit (or 48bit), 64^3 RGB colors.
- RGB lookup .png, (8x8 cube slices of 64x64 colors) 512x512x24bit
- .cube RGB floating point values (in text format).
- png cluts are used in photo-editing applications (ImageMagick and GMIC plugin use haldclut, XnViewMP>Film Simulation uses haldclut or RGB lookup).
- Adobe .cube format is used more in video-editing applications. One advantage seems to be that it can use values outside of the range [0, 1], but the filesize of .cube quickly becomes large with size.
- ImageMagick and GMIC can convert .cube to the Haldclut of corresponding level via command-line.
In a graphics program, the identity clut image can be used as input to capture/save the transformation clut.
When this clut is applied to an input image, the output should then match the result of the transformation. A 64x64x64 clut was enough to achieve transparency. Filesize was 200KB for png haldclut, 1MB for uncompressed rgb32, and 7MB for .cube !

ffmpeg supports haldclut and .cube (and other text-based formats) cluts.
ffplay -vf "movie=KODACHROME.png, [in] haldclut" video.mp4

Mpv can play cube format (input is converted to rgb24): ! use a relative path with / for the lut file
mpv --vf=lut3d=clut.cube video.mp4

However, this is quite cpu intensive at higher resolutions/framerates, so a shader based approach would be preferable (see previous post).

EDIT: With vo=gpu-next you can directly apply a .cube lut without having to create a shader embedding the clut:
> mpv --vo=gpu-next --target-lut=lut/clut.cube video.mp4

stax76
9th February 2021, 01:21
# Video Player installation

What a video player installer does on Windows:
0) Copies files to the chosen application folder
1) Creates a shortcut
2) [Registry] associates itself with filetype extensions (opened by double-click)
3) [Registry] changes filetype icons
4) [Registry] changes contextual menus: folder playlist-options, per filetype Open With
5) [Registry] Sets-up default settings
6) Creates an uninstaller !

This seemingly convenient automatic one-click solution has its pitfalls.

Custom manual portable installs are preferable in many cases.

Some info/advice:
- Install to folders were you and the program will have write permission (also for shaders subfolder). ! This isn't the case for c:\Program Files by default.
- a simpler/shorter path is preferable. Spaces can be troublesome for command-line.
- Changing your default video and audio players is OK, but changing per filetype associations can be troublesome (in particular icons per filetype).
- Use portable install for your non-default players, this allows using many different video player versions.
- Each portable install should be in its own folder. To test a development build, it's typically enough to copy the exe to an existing install folder (rename the .exe to switch between versions).
- Why register every possible audio, video extension that ever existed ?
- SendTo contextual menu is easy to configure (find sendTo folder location by running shell:sendTo, then copy/delete shortcuts in folder).
- ! Avoid changing installation paths
- Using Registry all player versions will use the same settings.
- Saving settings to .ini rather than registry makes it easier to backup, compare, modify, substitute (ex: reset to default) configurations
- You can replace the default shortcut icon for a player easily (but not the application window icon which would require hacking the exe).
- Shortcut properties can be edited to specify startup options or startup folder
- The default icon used for filetypes associated with a program can be changed in the registry.

Just personal taste, not everything true.

butterw2
9th February 2021, 09:32
Few things are ever true (and probably not for everyone). What are you disagreeing with specifically ?

stax76
9th February 2021, 13:37
Install to folders were you and the program will have write permission (also for shaders subfolder). ! This isn't the case for c:\Program Files by default.

If you move a folder into 'c:\Program Files', you still have full write access in the folder, and it's sub folders.

Saving settings to .ini rather than registry makes it easier to backup, compare, modify, substitute (ex: reset to default) configurations

For a mpv user using reg.exe instead of robocopy.exe isn't harder.

butterw2
9th February 2021, 15:10
I use base mpv, which makes very limited (if any) use of registry.
There is an optional install .bat registry script, which can be trimmed down significantly to just make it available as a media player/Open With and change the default icon.
Also provided is a manual program update .bat script.
Mpv uses configuration files mpv.conf and input.conf in the portable_config subfolder and doesn't save it's settings. Backing up a mpv configuration would consist in making a backup of ./portable_config and shaders.

Hacking registry is probably less of a hazard than it used to be, but for non-expert windows users remains more complex IMO than comparing/switching a single complete settings file.

stax76
9th February 2021, 15:39
May I ask why you choose base mpv over mpv.net?

butterw2
9th February 2021, 17:51
I typically launch mpv from command-line and it works very well for this use on Windows/Linux. Mpc is my main windows GUI player.

For me, an mpv GUI would have to provide 100% of base mpv + some genuinely useful additions:
- A text editor like notepad++ can handle .conf files very well (all you need to know is which parameter/values to use).
- the default OSC in mpv isn't great
- hotkeys are preferable vs cluttered menus IMO. Maybe the pop-up menu could be made user configurable (in a config file) ?
- Support in mpv.net for recent files, single-instance, files in folder, command-list are certainly of interest vs base mpv.

stax76
9th February 2021, 18:29
Maybe the pop-up menu could be made user configurable (in a config file) ?

You mean the context menu? That is defined in input.conf, all this is well documented.

butterw2
9th February 2021, 19:55
https://github.com/stax76/mpv.net
Customizable context menu defined in the same file as the key bindings (input.conf)
That's a great feature which is not currently available in mpc.

I could re-use my existing mpv.conf.
From a quick test of the 24/12/2020 beta, something seemed off with portrait mode video in windowed mode (window doesn't adjust to video dimensions ?)
mpvnet --version didn't return the expected info.

stax76
9th February 2021, 20:42
From a quick test of the 24/12/2020 beta, something seemed off with portrait mode video in windowed mode (window doesn't adjust to video dimensions ?)

There is a mpv.net specific window feature called:

minimum-aspect-ratio

<float> Minimum aspect ratio, if the AR is smaller than the defined value then the window AR is set to 16/9.
This avoids a square window for Music with cover art. Default: 1.2 (mpv.net specific setting)

Press c to show the config editor, enter mini in the search field, define 0.5 for minimum-aspect-ratio. This setting can be found in Screen section of the config editor, it is mpv.net specific, so is persisted not in mpv.conf but in mpvnet.conf.

butterw2
11th February 2021, 01:52
mpvnet.conf:
minimum-aspect-ratio = 0.5 #resize the window when the input is portrait-mode AR.
As a suggestion, why not list all the mpvnet-specific config parameter with their defaults in this file ?

--
I also got multiple popup errors when opening mpvnet (I had syntax errors in mpv.conf): I probably shouldn't get more than one of these, and the message does seem a little cryptic.
Uppercase char detected: R
mpv properties using the command line and the mpv.conf config file are required to be lowercase.

I also got these when launching from command-line: it would probably be better to just print the error and continue in this case. If I type garbage in mpv.conf, base mpv provides much clearer and more precise error info.

--
Next I'm going to copy my input.conf and maybe try to customize (meaning trim down) the context menu.

butterw2
20th February 2021, 17:46
#mpv built-in scalers

mpv has a number of built-in scalers (they can be listed with mpv --scale=help), which can be specified via command-line or mpv.conf:
--scale=catmull_rom #spline16
--cscale=bilinear
--dscale=mitchell

The scaler is used when the output resolution on screen is different from the source resolution.
- scale is used for upscaling, and also downscaling (if dscale isn't specified)
- dscale is used for downscaling
- cscale is used for chroma upsampling.

How often is scaling used ?
- cscale is almost always used (chroma upsampling) but the scaler choice is not critical.
- downscaling isn't all that common and most scalers will provide an OK result.
Upscaling is the most critical as this is a common use case (ex: upscaling 720p to view on a 1080p screen), and a sharp output is typically desired.

These settings should be OK for integrated gpus: (first: make sure --hwdec is enabled and working for the supported codecs)
Bilinear (was the default) is the fastest but doesn't give great results,
fairly lightweight: mitchell (B=1/3., C=1/3.) is smooth, catmull_rom (mitchell-netvrali with B=0, C=0.5) and spline16 are quite sharp.

gpu-hq profile used spline36 for scale, cscale and mitchell for dscale. lanczos can be used instead of spline36 if desired.
spline36 / catmull_rom / mitchell runs on a recent igpu such as intel uhd730 without issues.

Possibly overkill:
- spline64
- ewa_lanczos and ewa_lanczossharp. They use significantly more resources.
The sharpest scalers can be detrimental depending on the source, you may need to use a scale-antiring value (available in gpu-next).

! EDIT: new defaults in mpv v0.37
now (2023-11): lanczos/lanczos (implicit) / hermite (bicubic with b=0, c=0).
dither-depth=auto
hdr-compute-peak=auto
correct-downscaling=yes
linear-downscaling=yes
sigmoid-upscaling=yes
Weaker machines (ex: old laptop with integrated graphics) should use --profile=fast. Scaling is then done with bilinear by default, but this can be overriden with the scale setting.
Also try --vo=gpu-next rather than the default --vo=gpu as the new renderer has some significant performance optimizations.

Mpv doesn't have the fastest scalers (ex: performance of 1080p video upscaled to 1440p compares defavorably to other players), but by default the result is very decent.
To avoid wasting ressources on chroma, you can explicitly set cscale (ex: catmull-rom or even bilinear).
If you are using a sharp downscaler (ex: catmull-rom or lanczos), you can set --no-linear-downscaling to limit ringing.

It is possible to define hotkeys in input.conf to switch between scalers at runtime, ex:
F8 cycle-values scale bilinear mitchell catmull_rom lanczos
or to set new scalers, ex:
F9 set scale spline36 ; set dscale catmull_rom ; set cscale catmull_rom

A .jpg image file or a paused video frame can be used as input for testing. The difference are visible (especially on elements such as text) but not that huge with typical (1.5x ratio) upscaling. This applies to general purpose videos, Anime may have specific requirements.

butterw2
25th February 2021, 13:14
#Change settings/properties in mpv https://mpv.io/manual/master/#properties

1) Initial settings (determined by: program defaults < mpv.conf < command-line options incl. profile)
2) Runtime changes (via hotkey/command): current settings, disable/restore settings (via script)
3) Show settings
4) quit-watch-later: partial save of per file settings

Motivation for changing settings at runtime:
- tweak settings based on the video being displayed
- improve performance on some files (ex: on integrated graphics)
- try out effects
Runtime settings do not persist beyond the current session.

How to change settings at runtime ?
- with input.conf custom hotkey/commands or scripts
- Multiple [profiles] can be defined in mpv.conf (startup profile can be specified via command-line option).
- (Almost all ?) settings can be changed at runtime without restarting mpv through hotkey/commands (ex: switch profiles, or change a video filter/or glsl shader setting).
- Partial per file settings persistence is possible via watch-later folder: some pre-defined settings (the list is user-customizable) can be written to disk and will then be used by default the next time the same file is played.

Display pipeline: video.mp4 (ex: 720p, yuv420) > --vf (ex: hqnd3d) > color controls (ex: --saturation) > LUMA, CHROMA (ex: noChroma.hook) > cscale > rgb: MAIN (ex: clut shader kodachrome-9.hk;bw.hook) > scale > OUTPUT (ex: Filmgrain.hk) > rgba display (ex: 1080p)

Changing/displaying mpv settings at runtime with input.conf (custom hotkey/commands):
- toggle individual filters/shaders in the chain, ex: F1 change-list glsl-shaders toggle "noChroma.hk"
- set values, ex: CTRL+DEL change-list glsl-shaders set "",
- cycle between chosen values, ex: F8 cycle-values scale bilinear mitchell catmull_rom lanczos
- commands can be added via external script functions
...Scripts (lua or javascript or c-plugin) in ./scripts folder are autoloaded by default
...stats.lua and osc.lua are built-in scripts. They can be configured in ./script-opts
- Save/restore current settings (with an external script), ex: CTRL+p script-message switch-shaders (https://github.com/butterw/bShaders/tree/master/mpv/settings/scripts)
- Display current settings (show-text on OSD or print-text to the terminal, or display in the window title bar or the terminal status line)

butterw2
28th February 2021, 19:23
#Custom contextual menu in mpvnet

In mpv.net, input.conf defines the key and mouse bindings and the context menu, so it's easy to create a custom contextual menu.
The menu gives access to the recent file list, the chapters list and the open file dialog. The default menu felt a bit cluttered, so I wanted to create a more minimalistic one.
Original menu (https://files.videohelp.com/u/295418/mpvnet_default-menu.png) / my version (https://files.videohelp.com/u/295418/mpvnet_menu.jpg)

https://files.videohelp.com/u/295418/mpvnet_command-palette.png
Mpvnet has a searchable command palette component listing all available commands. This allows to keep a large number of commands available.
Unlike in mpv, runtime commands do not have to be associated to hotkeys (they can still be launched through the menu or the command-palette).

butterw2
8th March 2021, 20:00
#hqdn3d fast spatio-temporal denoiser

Most shader implementations have the limitation that only the current frame is available as input. This means temporal algorithms cannot be implemented.
This obviously isn't a problem when adapting algorithms which originate from image processing, however temporal issues do often have a big impact on the result achieved with video input (vs a fixed image).
To limit this problem, it makes sense to clean the source of temporal fluctuations as much as possible. While spatio-temporal denoising should be applied prior to encoding or to an extent by the codec itself (with modern codecs), there is frequently a benefit to apply further spatio-temporal source denoising before further processing is applied by shaders.

hqdn3d (hq mplayer spatio-temporal denoise) is a low cost cpu spatio-temporal denoiser. It is widely available, including in ffmpeg and as a result can be used in mpv.
hqdn3d(2) is equivalent to hqdn3d(ls=2, cs=1.5, lt=3, ct=2.25), the default is ls=4.0
I would recommend switching it on with lower setting on sources which require it. It runs well on 720p videos even on an old cpu.
add the following to input.conf, and turn it on with hotkey h:
h vf toggle "hqdn3d=2"

It should be noted that while temporal methods are great to remove temporal noise on backgrounds, they are not applicable to sources with fast motion.

stax76
9th March 2021, 10:48
minimum-aspect-ratio = 0.5 #resize the window when the input is portrait-mode AR.
As a suggestion, why not list all the mpvnet-specific config parameter with their defaults in this file ?

You can find mpv.net specific options in the conf editor using the search feature searching for 'mpv.net', but I also added now all mpv.net specific options to the mpv.net manual:

mpv.net specific options (https://github.com/stax76/mpv.net/blob/master/Manual.md#mpvnet-specific-options)

I also got multiple popup errors when opening mpvnet (I had syntax errors in mpv.conf): I probably shouldn't get more than one of these, and the message does seem a little cryptic.
Uppercase char detected: R
mpv properties using the command line and the mpv.conf config file are required to be lowercase.

I also got these when launching from command-line: it would probably be better to just print the error and continue in this case. If I type garbage in mpv.conf, base mpv provides much clearer and more precise error info.

I agree the mpv message on the command line is sufficient, next build has this message box warning removed.

Next I'm going to copy my input.conf and maybe try to customize (meaning trim down) the context menu.

I'm using mostly the defaults, OK it was created by me. 🙂

Thank you for the feedback.

butterw2
9th March 2021, 13:29
You can find mpv.net specific options in the conf editor using the search feature searching for 'mpv.net', but I also added now all mpv.net specific options to the mpv.net manual:

mpv.net specific options (https://github.com/stax76/mpv.net/blob/master/Manual.md#mpvnet-specific-options)

I've downloaded 5.4.8.7 Beta (2021-03-09) from dropbox, but the link was hard to find: the mpv.net manual is where to look.

mpvnet has a number of Window Limitations vs regular mpv.
some window properties are ignored, ex: --title which I use to display information in mpv. But also window-scale, etc.

--video-file-extensions=<string>
please provide example values, including how to disable picture files in auto-load-folder
mpvnet.conf:
image-file-extensions = jpg png
image-file-extensions = #disables image files
#image-file-extensions = #go back to default (all ext)

stax76
9th March 2021, 18:16
Download can be found on the front page:

https://github.com/stax76/mpv.net#table-of-contents

Not sure what else I could do.

There is an implementation for window-scale in mpv.net, but it works differently on purpose because I found the mpv behavior useless, what's the point of scaling based on the native video size? I'm not getting it but can try to implement it if people care.

--title might be something that is easy to implement.

I can try fixing both.

please provide example values, including how to disable picture files in auto-load-folder

image-file-extensions = nothing

image-file-extensions = jpg bmp

The file extensions can be separated by space, comma and semicolon.

butterw2
9th March 2021, 19:38
There is an implementation for window-scale in mpv.net, but it works differently on purpose because I found the mpv behavior useless, what's the point of scaling based on the native video size? I'm not getting it but can try to implement it if people care.


window-scale: if you have an old 4/3 360p video it may look quite ugly when scaled fullscreen.
This is the same as mpc-hc: View > zoom which has 3 main values: 50%, 100% and 200%.
100% zoom turns off scaling.
200% zoom should still look OK and is integer ratio scaling.
It's a useful feature on some files, not something meant to be used by default.

stax76
10th March 2021, 13:30
Providing a direct link to the beta (in the 1st or last post) of your forum thread would help.

I like to keep my first posts as simple as possible.

There is a new hotfix online:

- The mpv window-scale property works now exactly like in mpv.
- Implementation for the mpv title property.

https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L144

Btw. I noticed the mpv implementation of window-scale is buggy, which supports my claim that it's useless in the first place. I start mpv passing a video file to play, I set window-scale 1.0, nothing happens, very useful feature.

I try not to lament, but every second request on my issue tracker is window related, 9 out of 10 window requests are strange, I've already wasted a ridiculous amount of time working on these requests.

butterw2
10th March 2021, 15:27
I like to keep my first posts as simple as possible.

There is a new hotfix online:

- The mpv window-scale property works now exactly like in mpv.
- Implementation for the mpv title property.

https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L144

Btw. I noticed the mpv implementation of window-scale is buggy, which supports my claim that it's useless in the first place. I start mpv passing a video file to play, I set window-scale 1.0, nothing happens, very useful feature.


In mpv, window-scale isn't a useful as a startup option as it gets overriden, but I do find it useful at runtime (for low-res or extra high-res videos).
I use this in my mpv.conf (1x size window, unless the video is wider than 1280):
# window will not have a width larger than 1280pixels:
autofit-larger=1280

Window and frame size isn't all that simple:
mpc-hc for instance has many different ways to specify the window size, aspect-ratio, crop, zoom behavior... and some of these parameters are not exclusive.


The mpvnet version of window-scale is now identified differently from the mpv original, which is less confusing.

EDIT: window-scale seems to work as expected in latest hotfix mpvnet.exe

stax76
11th March 2021, 19:25
I want to improve the command palette, if you show the command palette in VS Code or Windows Terminal with Ctrl+Shift+P you see a command palette that looks much nicer than the one in mpv.net. It's going to be difficult to code, and might need migrating to .NET 5 and give up Win 7 and old Windows 10 versions, hopefully not. It's too much work to build a dedicated playlist dialog, but I can re-use the command palette infrastructure as playlist UI.

This title issue turned out to be fairly complex, I can try to get it, but need a small break first anyway, staxrip maintenance caused some stress lately.

If this thread is about shaders, better post in the other mpv thread.

butterw2
12th March 2021, 10:10
It's going to be difficult to code, and might need migrating to .NET 5 and give up Win 7 and old Windows 10 versions, hopefully not.

I run an old Win10 version, so I wouldn't be able to use it.

One of the issues with user shaders is that passing parameters to individual shaders in the chain isn't simple (the player needs to set uniforms/registers). The workaround in mpv has been to create multiple versions of each shader with different sets of parameter values. While this works, its also hard to use.
One of the benefits of having a GUI is allowing user runtime configuration of shaders (ex: turn on and increase the strength of filmgrain, because the source requires it).
The command palette interface is easy to use and allows having many commands available without a cluttered GUI.

ericgl
22nd April 2021, 10:44
Hello,
Is there a shader that can fix the colors of DolbyVision movies?
I don't have any monitors or TVs that support DolbyVision HDR.
The colors are off - Everything looks green and red.
I was hoping there's a shader that can fix that...

Upon further investigation, it seems that DolbyVision content without the EL component displays wrong/shifted colors.
In the following screenshot, you can see that this DolbyVision content only has the BL+RPU components:

https://i.ibb.co/WW8LKB0/Missing-EL-wrong-colors.png (https://ibb.co/99K7Yyh)

A user called "Doofussy2" found this issue and reported it on github: https://github.com/mpv-player/mpv/issues/7326

butterw2
22nd April 2021, 12:29
Try mpc-be which has some built-in HDRtoSDR shaders.
HDR10 and HLG should work with a recent version, but I don't know about HDR10+: You can ask the devs about this in the mpc-be thread.

Dolby vision comes up in encoding topics also.

Aleksoid1978
22nd April 2021, 13:20
There is no software player that support pure DolbyVision, except Windows 10 "Movie and TV".

ericgl
22nd April 2021, 14:06
Try mpc-be which has some built-in HDRtoSDR shaders.
HDR10 and HLG should work with a recent version, but I don't know about HDR10+: You can ask the devs about this in the mpc-be thread.

Dolby vision comes up in encoding topics also.

If you look at the screenshot, I am using MPC-BE.

@Aleksoid,
OK, I will check DolbyVision content with the "Movie and TV" app on Win10. Thanks!

Dragonkris
9th June 2021, 10:56
Hey does anyone know if there is a .hlsl shaders code for Transpose & Anti-Transpose (Flip Video) like in VLC player?

butterw2
9th June 2021, 13:34
It's often called rotate (90°) and yes most video players have this feature.

It's not typically done with user pixel shaders though, as they can't change the size/AR of the frame.

Dragonkris
11th June 2021, 01:27
Hmm so from what I’m getting at is the Pns Rotations for Y & Z were removed from MPC-BE, is there anyway to add them back in?

butterw2
11th June 2021, 10:04
A Mirror operation is trivial to achieve with shaders. The difficulty with rotate is caused by the necessary resizing of the frame (assuming W!=H).
I would expect a rotate feature to be available in a video players, but there might be bugs/limitations. You can ask your question in the mpc-be thread.
The main use case for rotate is to correct for videos captured with a tilted camera/phone (ex: mp4 rotation flag).

Acba
21st October 2021, 23:52
I would like some existing mpc-hc shaders, like "luma sharpen" or "lcd angle correction", to have effect just in the left half of a video, when the video is displayed in full screen.

Is there a way to add some lines to the beginning of the shader code so that it only acts in the left/right/top/bottom half of my screen?

v0lt
22nd October 2021, 04:02
I would like some existing mpc-hc shaders, like "luma sharpen" or "lcd angle correction", to have effect just in the left half of a video, when the video is displayed in full screen.
Here's an example.
float4 main(float2 tex : TEXCOORD0) : COLOR
{
if (tex.x > 0.5) return tex2D(s0, tex);
...

Acba
4th November 2021, 23:01
Here's an example.
float4 main(float2 tex : TEXCOORD0) : COLOR
{
if (tex.x > 0.5) return tex2D(s0, tex);
...

It worked!
Now I finally have "left-side-only" shaders.
Thank you very much!

butterw2
20th May 2023, 16:57
## mpc-hc HideWindowedControls

Options > Advanced > HideWindowedControls
This Advanced option was added a while back to mpc-hc and helps modernize the windowed mode UI a lot. The toolbar is displayed only when the mouse hovers the bottom of the window similar to what happens by default in full screen mode. The result reduces the windows height and IMO looks much better.

The configuration for the following win10 window screenshot is:
normal preset + dark mode theme + hidden menubar
I'm using the following advanced options:
- DefaultToolbarSize=18.
- status bar display: codec/resolution + frame rate
the video resolution is 576x1024.

https://raw.githubusercontent.com/butterw/bShaders/078f2a1d7a4de0d339ed729c02348bbc52991140/assets/img/mp-hc_HideWindowedControls.jpg

The top menubar can be displayed if needed with the Alt key or the right-mouse click menu can be used instead.

EDIT: The Controls toolbar isn't typically very useful in mpc-hc, and can be disabled if you are familiar with the basic keyboard shortcuts.

butterw2
21st May 2023, 01:37
MPC Video Renderer 0.6.7.2013 (https://github.com/Aleksoid1978/VideoRenderer/releases/tag/0.6.7)

Changes:
Added "Request Super Resolution" option for Nvidia and Intel graphics adapters. Hardware and driver support required. The display of "SuperResolution*" in the statistics only means that the request was sent successfully.
Recommended version of MPC-BE 1.6.6 or later.

I've tried out a few 720p and lower videos with mpcvr dx11 (vp resize+superResolution to 1080p on intel uhd730 with latest drivers). I will need to do test further to confirm that it is actually working as expected.
The result seem OK (nothing magical) but are achieved with very low cpu/gpu usage.

I believe intel vsr should also be available in Chrome web browser, but I haven't tried this yet

butterw2
21st May 2023, 14:52
my config for mpc-be windowed mode:
- Minimal Preset (no window bar, hidden Menubar, hidden Toolbar)
- keep Flybar (displays when the mouse hovers at the top of the window and times out unless locked)
+ seekbar
- Show OSD + show seek time enabled, show filename disabled (can be toggled in Options>Player without restarting the player)
- HideWindowedMousePointer (time out)
- Window Size: after starting Playback, scale to video size: 100%.
- SnapToDesktopEdges.


https://raw.githubusercontent.com/butterw/bShaders/0dd9f80dda6ae601cc6be861039ce2a57b743cd5/assets/img/mpc-be_minimal_flybar_seekbar.jpg
The screenshot shows the default flybar, it's possible to change it by putting a custom flybar.svg file in the mpc-be folder.
Chapter markers can be displayed in the seekbar by toggling Options > Player > Interface > x use Chapter Markers.

When enabled the OSD display can show filename, playtime, clock, and feedback information such as Volume, Zoom. However no time-out is applied when the OSD keyboard shortcuts are used (it's ON until you toggle OFF, even restarting the player doesn't help!).

In fullscreen mode I would typically prefer the default Normal preset (the toolbar/seekbar autohide) with full OSD, but I don't think it is possible to configure two different custom setups for windowed and fullscreen mode.

SirMaster
23rd May 2023, 20:43
I've tried out a few 720p and lower videos with mpcvr dx11 (vp resize+superResolution to 1080p on intel uhd730 with latest drivers). I will need to do test further to confirm that it is actually working as expected.
The result seem OK (nothing magical) but are achieved with very low cpu/gpu usage.

I believe intel vsr should also be available in Chrome web browser, but I haven't tried this yet

Are you sure it's working?

When I use the super resolution on my desktop it takes almost all of my RTX 3080 and shoots up to 300W power usage.

butterw2
24th May 2023, 18:45
SuperResolution magic is not working for me. :D

with Intel Arc & Iris Xe Graphics WHQL graphics driver 31.0.101.4369 on Win10 22H2.

using mpc-be + mpcvr / intel dx11 vp for resizing.
The igpu (uhd730) is using 7W when upscaling 480p to 1080p (1% cpu, 10% gpu). Sharpness is similar to lanczos3 shader.

huhn
25th May 2023, 06:32
can you try this on the uhd730 and share me an upscaled image?

https://drive.google.com/file/d/1B0HoArJK4OXMvE9LhPqw1VQ0bU2qWUbM/view?usp=sharing

butterw2
25th May 2023, 09:42
Low bitrate (<1Mbps, ex: 500kbps) youtube streams

- mpc-be can open youtube urls (via copy-paste) and play the video efficiently.
- Youtube encoded 480p videos don't look good upscaled to 1080p on a monitor. They look OK at 100% zoom.
- Well encoded 720p can upscale decently to 1080p. For similar bitrates, 720p-av1 (if available) would be preferable over youtube 480p-avc.
- Hardware decoders: Whereas even very old computers have h264-dec, only recent generations of gpu/igpu have av1-dec. Still it should be possible to play 720p av1 in software on a PC. Otherwise vp9 hw-dec are more widely available (vp9 uses webm container). When the hw-dec is used, GPU is circled in the mpc-be Controls toolbar at the bottom of the screen.

mpc-be: Options > Playback > Online media services
with the built-in web page parser (you can also use a youtube-dl variant executable)
Preferred format: mp4-av1 720p (alternative options: mp4, webm, +60fps)

butterw2
25th May 2023, 10:22
can you try this on the uhd730 and share me an upscaled image?

https://drive.google.com/file/d/1B0HoArJK4OXMvE9LhPqw1VQ0bU2qWUbM/view?usp=sharing

upscaled to 1080p >> screenshot
https://files.videohelp.com/u/295418/mpc-vr_uhd730_dx11vp-upscale.png.zip
I can confirm the superresolution option doesn't change the output on this setup.

Do you have a 1080p picture of the test patterns for reference ?

huhn
25th May 2023, 10:36
there is no reference.

this image show that the scaler should be the good old lanczos 3 with maybe AR in very low quality (the banding).

here is mpcvr jinc2m https://abload.de/img/jinc2l9ezb.png
which is flawless no bands or discontinuities.

this just a pattern that roughly tells you the scaler and shows error in it. the band seen in your intel results could be pointless if you are only scaling x2.

butterw2
25th May 2023, 13:13
jinc2m generates a clean pattern on this test, but does tend to oversharpen with real video.

if anyone wants to see what the input test patterns looks like, here's the integer scaling (180x180 pixels) of the first test pattern:
https://raw.githubusercontent.com/butterw/bShaders/master/test_resize/pattern1_bw180x180.png

1080 version: https://github.com/butterw/bShaders/tree/master/test_resize

lvqcl
25th May 2023, 13:30
A Pixel Is Not A Little Square,
A Pixel Is Not A Little Square,
A Pixel Is Not A Little Square!
(http://alvyray.com/Memos/CG/Microsoft/6_pixel.pdf)

nevcairiel
25th May 2023, 13:55
The image is not meant to be perfectly upscaled, its meant to visualize properties of upscalers. Of course "integer scaling" (whoever named it that? Its point sampling or nearest neighbour scaling) will look just like a perfectly bigger version of it. But you get aliasing, tons of aliasing. Thats all the sharp corners. Normal images have no sharp corners.
You don't even know if thats what it was supposed to look like. Maybe it was once bigger and had smooth detail, but when downscaling the lack of resolution made it appear to be pixel-y.

You totally missed the point of this image and what its supposed to test. "integer scaling" is a pointless excercise with very little real-world use, at best only useful if you play old pixelart games.

What the test did show is that whatever upscaler was being used for your original images is terrible. It creates a lot of visible block artifacts around the elements. This may not be visible in normal video because the scaling factor is not as extreme, but its certainly not a great algorithm.

butterw2
25th May 2023, 15:21
Of course nearest neighbour/integer scaling doesn't perform well for general purpose video. Having the reference is useful to determine that there is a pixel shift of the motif.

The built-in scaler is not great, not terrible. Out of the box, it actually performs slightly better than lanczos3 on my random video test (480p low bitrate + compression artefacts to 1080p). Jinc2m looked very poor there. catrom lacked sharpness.

It's going to take some magic to make these videos look good upscaled to 1080p (2-3x upscale), getting a better source is easier.

huhn
25th May 2023, 16:52
lowering resolution is a terrible compression algorithm so it unlikely to find a scaler that will make a lower resolution video look constantly or at least for the majority better than higher resolution video.

Of course "integer scaling" (whoever named it that? Its point sampling or nearest neighbour scaling) will look just like a perfectly bigger version of it.

integer scaler and NN are not 100 % the same well it is only used for specific situation or how should i say it. it is NN with a integar multiply to scale only.

https://abload.de/img/integarscaleri7elz.png
pretty sure nvidia also uses that name.
it was ask for for about a decade to make pixel art game look normal on rare 1440p displays at the time.
pixelart games are usually 720p like FTL.

only pascal and newer can do it on nvidia don't ask why. (may have changed not that i care)
point and NN where not enough i guess...

butterw2
26th May 2023, 15:13
- Integer scaling allows to zoom in to the source pixels as they are (without upscaler effect).
At 200% upscale, the low resolution, bitrate constrained web video that was compressed to look ok at 100% shows it's artefacts. The upscaler has to mitigate this somehow. The most common artefact is noisy edges, from what I observed.

To view the available codec/bitrates on a url from a streaming site, you can use a youtube-dl variant from command-line:
> yt-dlp.exe -F url
When you go from a 480p to a 360p stream you are lowering resolution, but also lowering bitrate, so the upscaling problem becomes a lot harder.

From initial testing close-up on a 24" monitor, 720p to 1080p upscale (1.5x) with acceptable quality might be more feasible than 480p to 1080p.
but screen display size and viewing distance are key:
- upscaling 480p to 720p (1.5x upscale) on the small screen of a smarphone is probably OK.
- upscaling 480p to 1080p (2.25x upscale) on a 24" monitor might look OK if you are watching from a distance.
- 720p to 1440p monitor would be a 2x upscale.
- 720p to 2160p would be a 3x upscale.

Web video quality is typically poor to OK (this is NOT a bluray source). Bitrate would typically be in the range 1000-1500kbps for 720p and currently are typ. only available as h264 (with the exception of youtube).

What are your current recommandation for realtime upscaling of low bitrate video to 1080p on PC ?

butterw2
30th May 2023, 12:37
Low resolution web-videos and scaling (fullscreen, 2x, 1.5x, 0.75x), without superResolution

- Scaling low resolution to fullscreen to view on a monitor should probably only be considered if the source is reasonably good. In this case to upscale 720p to 1080p, you just need a sharp resizer or a sharpening shader. Adding noise/grain might help if the source lacks it.
- When the source has visible artifacts at 100% zoom, the options are to try to reduce the artifacts or to view downscaled.
- Some artifacts can be treated effectively at low cost, but there isn't much built-in to mpc-hc/be to do this. Mpc-hc does offer a 3x3 gaussian blur shader (light spatial smoothing).
- In mpc-hc and mpc-be, only 200% and 50% zoom can be easily and directly applied in windowed mode. But often the desirable scaling would be 150% or 75%...

butterw2
31st May 2023, 10:00
In mpc-hc and mpc-be, only 200% and 50% zoom can be easily and directly applied in windowed mode. But often the desirable scaling would be 150% or 75%...

To be more complete:
- You can go back to 100% zoom using View > Zoom > 100% or the corresponding hotkey.
- mpc-hc and mpc-be do allow to set a fixed window size or remember last window size. But random videos will have different resolutions so this isn't typically practical.
- mpc-hc has added a "zoom window +", "zoom window -" hotkey, which would allow to adjust window size manually (! the step is small though).
- in fullscreen mode, you could create a custom zoom factor with View>Pan&scan> Edit... preset, with the option to further adjust manually with numpad 9,1, 5 (PnS reset) hotkeys.

However Vlc does have the setting I was looking for (custom default windowed zoom):
Tools > Preferences > Show Settings: All (at the bottom) to access Advanced Settings.
Video > zoom Video: 150%. Restart the player.

In mpv:
> mpv --no-hidpi-window-scale --window-scale=1.5 "b:\Videos\day_480p.mp4"


- mpc-hc Changes from 1.9.1 to 1.9.2: Added a 25% zoom shortcut and menu entry
I don't know what the use case for a 25% zoom is, but I would suggest having a user customizable zoom would be more useful. The default value could remain 25%.

butterw2
1st June 2023, 15:51
To darken shadows only, I'm using the following formula (1 texture, 5 arithmetic):

#define Shadows 0.15
pixel.rgb = pixel.rgb -Shadows*(1-luma)**4

butterw2
2nd June 2023, 10:36
with mpc-hc, you need put your custom hlsl shaders in the .\shaders (for dx9) and .\shaders11 (for dx11). The shaders need to be have the same filename (ex: bShadows.hlsl) to be applied correctly when switching between dx9 and dx11 renderers.

It's easier to develop the shaders in dx9 Evr-CP, with the debug shader compiler output available.
You can then port the shader to dx11. For this, I was able to use BingChat (I specified that the language is similar to C and gave an input/output example from mpc-hc shaders).

toniash
5th June 2023, 07:51
Some mobile apps have great shaders for video adjustment. Corresponding shaders may not exist or be hard to find for video players, so I'm thinking of releasing a small updated pack of essential lightweight filters. The shaders would be available for hlsl evr-cp, hlsl dx11 and mpv hook.

example: 16-235 to 0-255.hlsl from mpc-hc (1 texture, 1 arithmetic) can be used to stretch the histogram. While it's not its initial purpose, I've found the shader to be useful to boost the contrast of some lackluster internet videos (when activated the haze lifts !).
not for potplayer?:devil:

butterw2
6th June 2023, 05:39
My understanding is that potplayer does support hlsl pixel shaders, but I don't know the specifics as I don't use this player.
Some players require the the shaders to have a .txt extension instead of .hlsl.
Video players often come with different shader bundles (ex: mpc-hc vs mpc-be) , some shaders will simply have been renamed. If he has the required folder permissions, the user can delete these shaders and copy whatever shaders he likes to the shader folder

butterw2
19th June 2023, 10:47
Video "Enhancements" by the graphics card driver.

The graphics card driver can process video being played back.
ex: Intel graphics command center > Video
This applies to directshow players such as mpc-hc, mpc-be but not vlc, mpv.

for uwp apps (incl. ms store apps like Movies & TV, wmp, windows media, etc.) there is an extra switch to enable/disable this feature.
Win10 > Apps and Features > Video Playback > x automatically process video to enhance it.
or > ms-settings:videoplayback


These adjustments settings (noise reduction, sharpness, skin tone, contrast) can be useful but they are vendor specific and not well documented. It's a manual, slider-based, permanent video adjustment hidden in a tab of the control panel app. You can set up custom profiles, but if you need specific adjustments for one video, you would need to remember to reset to the default profile after watching the video, which typ. isn't practical.

butterw2
22nd June 2023, 13:11
I've started uploading some simple shaders for my color Adjustment pixel shader pack (A-pack). It will be available for dx9, dx11 and mpv.hook: https://github.com/butterw/bShaders/tree/master/A-pack
The shaders typically only have one parameter and provide easy color adjustments, these can typically be useful when watching (web) videos.

ex: The traditional Brightness control (rgb shift) is poor. vs Lift doesn't affect the white point (1, 1) and vs Exposure doesn't affect the black point (0, 0).
EDIT: The only benefit would be that Brightness doesn't change contrast at all.

butterw2
25th June 2023, 15:42
Saturation Adjustment

Saturation refers to the intensity of color. Gray pixels have a saturation of 0, whereas pure color (ex: red) has a saturation of 1.
Sat = max(r, g, b) - min(r, g, b), normalized to [0, 1]

Saturation adjustments need to be small as they can quickly lead to an oversaturated or desaturated picture.

Vibrance attempts to solve this with a smart saturation approach (parameter Vibrance>0: saturate the low saturation areas, <0: desaturate the high saturation areas).

For video player shader based adjustments, 2 shader parameters values would cover most needs:
vibrance.35: get more vibrant colors
vibrance-15: reduce oversaturation

Skintones are quite sensitive to saturation (ex: orange or pasty grey skin) and creating a dedicated shader to correct this issue specifically might be useful.

butterw2
28th June 2023, 20:26
Comparing contrast enhancement shaders:

The simplest and fastest approach is to use rgb expansion:
- contrast 0.10
or
- contrastB_W (10_240 to 0_255)
this requires only a single arithmetic operation and the results are typically quite good. The drawback is potential clipping.

A more advanced approach would be to use a S-curve:
Increases contrast in the mid-tones by pushing shadows down and highlights up. This reduces contrast in shadows and highlights, but doesn't clip them.
ex: sweetfx.curves #2 in rgb, Strength: 0.125
(1 texture, 9 arithmetic), incl. 7 arithmetic required to calculate the S-curve.
https://raw.githubusercontent.com/butterw/bShaders/master/img/S-curve.png
! S-curves lose contrast and brightness in shadows, so dark scenes tend to be slightly worse with the s-curve.

Finally there are some fakeHDR type approaches:
Take a SDR input video and try to make it look like HDR. The result is still SDR though.
- sweetfx.fakeHDR (hlsl): (17 texture, 35 arithmetic)
- faux_hdr.glsl

Some conclusions:
- All the listed shaders will enhance a video lacking contrast. Typically more vibrant colors would also be desirable.
- faux_hdr.glsl probably gave the best results (depending on the input), however it isn't a lightweight shader.
- There isn't much need for tuning. The required contrast enhancements are typically small.
- Doing a comparison of multiple shaders (+parameter values) isn't simple, but can be achieved by setting up mpc-hc shader presets or by configuring mpv input.conf.

butterw2
16th July 2023, 08:34
Another candidate for lightweight too dark/too bright adjustment shader.

Photoshop Multiply/Screen Blend (brightness/contrast curves)
c0 = (1-Multiply)*c0 + Multiply*c0*c0
with c0: pixel.rgb in [0, 1.0]
(1 texture, 3 arithmetic)

parameter Multiply [-1, 1], 0: no effect
positive: (Multiply Blend) decreases brightness and increases contrast in highlights without clipping.
negative: (Screen Blend) increases brightness and constrast in shadows without clipping.
Apply when picture is too dark. ex: Outdoor night shots, ex: -0.3.

toniash
18th July 2023, 16:19
Another candidate for lightweight too dark/too bright adjustment shader.

Photoshop Multiply/Screen Blend (brightness/contrast curves)
c0 = (1-Multiply)*c0 + Multiply*c0*c0
with c0: pixel.rgb in [0, 1.0]
(1 texture, 3 arithmetic)

parameter Multiply [-1, 1], 0: no effect
positive: (Multiply Blend) decrease brightness and increase contrast in highlights without clipping.
negative: (Screen Blend) increases brightness and constrast in shadows without clipping. Ex: -0.3
Could you write a complete HLSL shader so I can use it in PotPlayer?

toniash
19th July 2023, 07:31
I'm releasing my complete color adjustment pixel shader pack when I get back home in a few days. It does include tooDark and tooBright hlsl shaders.

In the meantime you could try out one of the already available shaders and let me know if you have any issues with Potplayer.
https://github.com/butterw/bShaders/blob/master/A-pack/Shaders/brighten%2020.hlsl (dx9)
https://github.com/butterw/bShaders/blob/master/A-pack/Shaders11/brighten%2020.hlsl (dx11)
It works, no issues! (dx9) but I prefer curves

butterw2
20th July 2023, 18:51
tooDark

@toniash
https://github.com/butterw/bShaders/blob/2da9267860cda5c36b79e95905968a28213f91f6/A-pack/Shaders/tooDark.hlsl
[4-5]: plot for Multiply: -1 and -0.3 (red)

[10-11]: The alternative I was initially considering was a gamma correction style curve (applied in the default sRGB, 1 texture, 9 arithmetic):
pow(c0.rgb, 1.0 - B), with ex: B=0.15 (gamma_c=1/(1-B)=1.1765).

[6 hidden]: The linear equation Exposure c0.rgb *(1.0 + Exposure)
(1 texture, 1 arithmetic) is OK for small adjustments like 0.10, but it does clip inputs>1/(1+Exposure).
However in most cases the required adjustments are small and highlight clipping isn't always an issue with dark videos.
Contrast=1+Exposure is constant.

EDIT: Here's a link to an interactive Desmos calculator plot of the curves:
https://www.desmos.com/calculator/eibkoj8sgp

EDIT2: Whether a video is too dark does depend quite a lot on viewing conditions (ex: daytime vs perfect dark), so it's good to have good adjustment options available.

butterw2
26th July 2023, 11:41
Brightness testing Update.

I've done some more testing on Brightness Adjustments.
I use mpc-hc with shader presets set up for each shader+value, and I play test clips, switching the shader on/off and switching between presets. I do this during the day and at night (different lighting conditions).

There are 2 types of useful brightness adjustments:
a1) boosting a clip that could maybe be brighter.
a2) the clip is too dark.

I tested different ajustments curves:
- Legacy brightness adjustment: rgbShift(0.05)
- brightenD(0.06)
- exposure(0.08)
- tooDark(0.15), Multiply: -0.15
- Gamma Correction: bGamma(0.10), gamma_c =1.111
- tooDark(0.20)

Conclusions:
- the legacy brightness adjustment x+Brightness is never good.
The problem of raised black levels can be solved by adding a Shadows term, I call this new shader brightenD:
out = x + Brightness -Brightness*(1-x)^4
with x, out: pixel.rgb in [0, 1.0].
(1 texture, 5 arithmetic).
Contrast is increased in Shadows, but unchanged in the rest of the curve.

- exposure.08 (1 texture, 1 arithmetic)
This small exposure adjustment often works well in a1 case, because it increases both contrast and brightness. It has the lowest increase in brightness in shadows of all the listed approaches. The drawback of exposure is that it blows-up/clips the highlights. This is also true for the previous rgbShift and brightenD approaches.

tooDark doesn't have this problem. The increase in brightness is max at the midpoint. I typically prefer this to a Gamma Correction, which has high contrast near Black and max brightness increase before the midpoint, as this can lead to rather flat images. Also tooDark is significantly faster.
The last two approaches are the best for case a2, as parameter values can be pushed up if needed.

Edit2: There are also higher order curves which have max brightness beyond the midpoint. It's possible to select a curve that doesn't clip (contrast will decreases sharply in the Highlights though). These curves are intermediates between tooDark and exposure.08.

Note: The tooDark shader user parameter has been changed to a positive value as this is more logical. The default value for tooDark will be lowered to 0.24 as this is typically enough for a2 (higher values are possible). Maybe I'll also provide a 0.12 shader for a1 type ajustments without highlights blow-up.

Edit: tooDark.24 and brightenD.06 have the same brightness impact except in Highlights:
https://github.com/butterw/bShaders/blob/master/img/tooDark.24_vs_BrigtenD.06.png?raw=true

butterw2
6th August 2023, 00:11
#mpv: Custom On Screen Display (OSD) my mpv.conf file (https://github.com/butterw/bShaders/blob/master/mpv/portable_config/mpv.conf)
This post covers customization of the standard mpv OSD messages, for deeper customization scripts can use an overlay (https://forum.doom9.org/showthread.php?p=1995689#post1995689).

OSD (https://mpv.io/manual/stable/#osd) customization options / properties:
--keep-open=yes Keep the player window open after the end of file is reached. <no, yes, always> default: no
--window-scale The windowed mode video zoom level, default: 1.000
--hidpi-window-scale=no default: yes
--fullscreen (or --fs) start in fullscreen. default: no
--osd-on-seek=msg-bar <no, bar, msg, msg-bar>, default: bar
--osd-msg3="(${percent-pos}%) ${playback-time}" displayed by (P) show-progress and on seeks. displays: (54%) 00:32:20
default: "${playback-time} / ${duration}" : 00:45:10 / 01:30:00
--osd-duration=2000 #default: 1000 (ms)
--osd-margin-x=10 #default: 25 (in scaled pixels)
--osd-margin-y=10 #default: 22
--osd-color= 1.0/0.93/0.93/0.97 r/g/b/a [0, 1.0], or 0.95 gray level. default: white, "#FFFFFFFF"
--osd-back-color= "#e6202020" #argb, a background color makes (small) text much easier to read. default: transparent black.
--osd-font = "Segoe UI" (default: sans-serif >> Arial)
--osd-font-size =40 #default: 55.0
--osd-scale-by-window=no default: yes
--osd-shadow-offset=4 default: 0, you can use this to pad dark-background text (! osd-back-color must not be completely transparent).

osd-bar=yes
--osd-bar-align-y=1.0 (bottom osd-bar). default: 0 middle-bar
--osd-bar-w=100 full-width
--osd-bar-h=0.3 # if you need chapter markers, you could use something like: --osd-bar-h=1.0 --osd-bar-border-size=0.25
--osd-bar-border-size=0 default: 1.2 (mpv0.37-dev)

OSD Messages:
--osd-playing-msg, --term-playing-msg displayed when a new video is loaded, default: ""
--osd-playing-msg-duration (in ms) [0 to 3600000] default: 0 (=osd-duration)
--osd-level <0, 1, 2, 3>, default: 1.
--osd-msg1 default: "" default osd (osd-level=1)
! only one message at a time can be displayed on the default osd.
--osd-msg2 alternate osd (osd-level=2), default display: > 00:45:10
playing > symbol is: "${osd-sym-cc}"
--title The window title. default: "${?media-title:${media-title}}${!media-title:No file} - mpv"
typ. displays: my_video.mp4 - mpv see https://mpv.io/manual/stable/#property-expansion
--term-status-msg terminal status message, ex display: (Pause) AV 00:00:50 / 00:01:02 (80%)
--display-tags comma separated list of metadata tags that are displayed in the terminal, when a new file is loaded.
default: "Artist,Album,Album_Artist,Comment,Composer,Date,Description,Genre,Performer,Rating,Series,Title,Track,icy-title,service_name,Uploader,Channel_URL"
--osd-fractions default: no. times are displayed with milliseconds (hh:mm:ss.xxx)
--background (black bars color) ex:"#FFBBBBBB" default(#ARGB): "#FF000000"
${clock} 24h system time 18:52


# osd-msg display vs osd-level
osd display can be permanent (until changed or disabled) or limited by duration (uses osd-duration by default).
osd-msg1 : default osd (osd-level=1)
osd-msg2 : alternate osd (osd-level=2)
osd-msg3 : show-progress and seeking osd.
with osd-level=3 : osd-msg3 becomes the permanent osd.
osd-level=0 : no-osd on commands, show-text and scripts can still display to osd.
mpv offers plenty of options for customizing the OSD (rendered with libass) and it's possible to go further with user scripts (.lua or .js).

# how to correctly toggle a permanent osd with a keybinding (the osd stays visible until disabled, it will auto-update when needed, in this case when a new file is loaded):
--osd-msg2="${filename}\n${file-size}"
input.conf: O no-osd cycle-values osd-level 2 1

To achieve a similar result with just input.conf, you need to block the property expansion using the `raw` prefix.
input.conf: N raw no-osd cycle-values osd-msg1 ${filename:} ""


stats.conf
An example of OSD achievable with an mpv script is the built-in stats OSD pages (default keybinding: i/I, you can then change the page number: 0-4), page_2 is of particular interest as it shows the output chain (video-filters, scalers and active shader passes).
the script can be configured by portable_config\script-opts\stats.conf https://github.com/mpv-player/mpv/blob/master/DOCS/man/stats.rst or --script-opts
These script-opts options / script.conf file options are a nice feature of mpv, this feature can be added to any user script without too much trouble with mp.options.read_options.
#ex: you can change the temporary display duration in second (default: 4) as it might be a bit short.
duration=10
scroll_lines=5
#rebinding the hotkeys for the different pages with key_page_1, key_page_2, etc. can be useful for non-us keyboards.

butterw2
8th August 2023, 10:56
mpv script: avg-bitrate.js /mpv v0.36 user-data

https://raw.githubusercontent.com/butterw/bShaders/master/mpv/scr_mpv_avg-bitrate.jpg

Here's my mpv script that calculates and displays the average bitrate in kbps of the video being played (using the video file properties file-size and duration): https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/avg-bitrate.js
v0.20: A new property named user-data was added in mpv v0.36. It can be used by scripts to save their data (ex: the calculated avg-bitrate is saved to a custom property named user-scripts/avg-bitrate).
ex, display average bitrate on osd for 2 seconds when key a is pressed:
input.conf: a no-osd show-text "${user-data/avg-bitrate}" 2000

v0.11: v0.11 (https://github.com/butterw/bShaders/blob/e6827e3363310804d1a2ed03bd1cec5b7bb67aba/mpv/settings/scripts/avg-bitrate.js) might be a better starting point for writing very simple custom osd scripts, and it doesn't use user-data (req. mpv v0.36). The output can be printed to the terminal, and/or displayed in the OSD (automatically for every file loaded or (by default) on demand for 0.7seconds via a keybinding).
input.conf: a script-message avg-bitrate

butterw2
9th August 2023, 14:26
mpv --no-input-default-bindings

When it comes to keybindings mpv has some great features:
- a separate file for keybindings: portable_config\input.conf: this is a human readable/editable text file that lists the keybindings and comments (including #menu: context-menu entries).
- you can have multiple keybindings for the same command.
- each keybinding can be associated with (custom) commands and script functions.
- it is possible to view the active keybindings on screen (stats > page 4) or export them to the standard output, or test a pressed keyboard key for associated bindings.

Like a number of other video players mpv has far too many keybindings active by default. This isn't helpful, IMO it is better to learn/use just the hotkeys you need and associate them with your favoured keys.
If you use a non-US keyboard you'll likely need to change at least some keybindings.

In mpv, there are two ways of solving this problem:
1) override individual default keybindings:
input.conf: CTRL+c ignore #disables the built-in Ctrl+c quit hotkey.

2) OR more radical: disable all built-in hotkeys, including the default bindings defined in user scripts (with mp.add_key_binding) and use only the ones defined in your input.conf.
mpv.conf or mpv command-line option: --no-input-default-bindings
This is the approach I would recommend for more advanced users. You'll need to have a complete input.conf file ready for this. As a starting point, the file listing the default keybindings is available here: https://github.com/mpv-player/mpv/blob/master/etc/input.conf
# indicates a comment in .conf files. So everything after # on a line will be disregarded.

Finally, the --no-config startup option allows you to test mpv without loading mpv.conf or input.conf (default keybindings are used).

SirMaster
9th August 2023, 18:13
If I can make a request?

Can you make an mpv script that displays the APL of the current frame?

Some information about this:
https://projectiondream.com/en/movie-brightness-adl-contrast-measurements/

The Math?:
https://www.avsforum.com/threads/what-i-look-for-while-subjectively-evaluating-a-projector-adl-measurement-tool-added.3222010/page-2#post-61334794

And if you can support both 2.2 and 2.4 gamma for the math, that would be ideal.

If this is even possible, thanks for your consideration!

SirMaster
10th August 2023, 19:24
Thanks, I'm sure you are right that Avisynth is a better fit for this.

I will investigate and try to make this work when I get some time.

butterw2
10th August 2023, 22:25
The math is just the frame average of the luminance with pow(luma, gamma=2.2 or 2.4) applied. You could do this with avisynth and just overlay the result on the frame (or save to .csv file). I do plan to take a look at vo_gpu_next/libplacebo compute shaders for calculating per frame averages, but currently I don't think there would be any way to transfer the results back to mpv (for display as text).

butterw2
15th August 2023, 20:57
#More on mpv custom OSD scripts
Mpv has many features, some of them great, but is often criticised for lacking the level of polish you can expect from GUI players such as mpc-hc on Windows. There hasn't been much progress on this, the on-screen controller script osc.lua is still weak (flawed design, OK in fullscreen but too small in windowed mode, no real user configurable options) and generally not all program defaults are well thought out. One might ask whether it is possible to customize mpv to make it more like a minimal (no-gui) mpc. Maybe with some effort you could come close. I am not going to attempt this, as I have different use cases for mpc-hc/mpc-be and mpv, and I am also not claiming mpc is perfect. Still I think the results of this endeavour would be of interest to some users.

To add some conclusions to my previous posts (https://forum.doom9.org/showthread.php?p=1990436#post1990436) on the subject of custom OSD for mpv:
- Mpv has many built-in OSD options and properties the user can combine.
- But the formats/strings used to display each properties are hardcoded (ex: OSD of file-size, playback-time, etc.) and actually can't be changed by users at all.
- It is possible to override the default OSD through scripting. This typically only requires a couple lines of fairly simple code (but modifying an existing script is probably easier).
- Don't expect script performance to match optimized native compiled code, but lightweight scripts should run OK.
- Javascript has nice syntax, but probably worse performance than lua (if it matters). Not all language features are available, which can make string manipulation troublesome.
- User scripts are less convenient to use than properties as they can't be used in mpv.conf or in startup options. But the new mpv v0.36 user-data custom properties can be used to get around this (see my script below).
- With a stronger OSD, maybe the OSC can be dispensed with alltogether (--no-osc).

My custom OSD stats script for mpv v0.36: https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/bstat.js
ex, custom osd using new user-data properties (calculated by the script):
--osd-msg2 = "${osd-sym-cc} ${percent-pos}% of ${user-data/duration}\n${user-data/res} ${user-data/ar}\n${user-data/file-size}\n${user-data/avg-bitrate}-${audio-bitrate:}\n${video-format:}: ${video-bitrate:}"

show-time ms: display playback-time / duration to OSD (with optional duration in ms)
For durations less than an hour, the default mpv format 00:25:18 / 00:50:00 gets shortened to 25:18 / 50:00 (like in mpc-hc).

butterw2
17th August 2023, 21:59
# time display formats of modern video-players (PC, android, web)
formats used for on-screen-display of playtime / duration.

01:05:28 legacy format: used by many players (0)
when durations >1h, ex: movies.

01:05:28.250 ms precision format available as an option in some players (1)
(@25fps, 1 frame corresponds to 40ms)

08:04 / 51:10 short format, used in mpc-hc and many other players (but not mpc-be) (2)
when duration <1h, ex: TV series, podcasts, ...

00:42 | 01:18:44 Windows media player (3)
short format applied also to playtime

00:42 | 1:18:44 vlc (v3.0.18 PC): short+ format (4)
duration <10h, drops the leading zero on hours for duration and playtime
when playtime<1h, short format applied to playtime.

00:42 | -1:18:02 time-remaining display (replaces duration) (4b)

0:07 / 3:23 Shorter format (5)
when duration <10 minutes, ex: short videos, music, ...

0:42 / 1:18:44 shortest format, used by youtube, web-browsers (6)
35:04 / 1:18:44
1:05:28 / 1:18:44
All leading zeros are dropped for duration and for playtime >1 minute

08:26 / 85:23 minutes only format (7)
08:26 / 117:30 doesn't use hours, just minutes, ex: sport broadcast.
same as short format except for durations >1 hour.

# What does typical video-player time display look like ?

- Internet short clips or Audio file (music):
00:00:00 / 00:00:15 legacy time format 00:00:00 / 00:03:20
00:00 / 00:15 short format 00:00 / 03:20 makes the display significantly more readable when playing short clips.
0:00 / 0:15 shortest 0:00 / 3:20 >>btime.js

- Full length movie:
00:08:00 / 01:42:25 legacy time format
08:00 / 1:42:25 short+ format (vlc pc) >>btime.js
8:00 / 1:42:25 shortest format.

What works best comes down to the duration of the videos, the available screen space and user preferences. The time display format doesn't have to be user configurable, but legacy time format shouldn't be the only option. For PC players, versatile defaults such as mpc-hc or a shorter variant can be good replacements IMO.

EDIT: my lightweight btime.js (https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/btime.js) script for mpv uses a format similar to youtube (https://raw.githubusercontent.com/butterw/bShaders/master/mpv/settings/scripts/btime_osd-bar.jpg) but better suited for movies. The script can now (https://forum.doom9.org/showthread.php?p=1996141#post1996141) also be configured to display a different time formats (ex: format=mpc-hc).
There are essentially 3 considerations:
1) do you drop the leading zero for hours
2) do you drop the leading zero for minutes
3) do you apply the same format for playtime and duration. This avoids having to add extra time digits during playback.

For something quite different you can try my last seconds countdown OSD (https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/obs_countdown.js), ex: -10s. The link to the lua version is in the next post.

butterw2
20th August 2023, 19:20
# Using shaders (mpv glsl hook) and scripts on mpv-android

shaders and scripts work the same in mpv-android as in mpv.
The build I was using only had lua script support however (no .js).
So I converted my countdown script to lua (https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/countdown.lua) (with minimal modification the script could also be useful to pass time values to vo_gpu-next shaders for instance to launch transition effects).

My device isn't rooted. To launch shaders or scripts, you need to edit a user mpv.conf file and specify the corresponding paths. The file paths must be readable by mpv-android.
- Create a mpv folder in your android phone's internal storage and place your shaders and scripts in it.
- Using your file manager go into the properties of one of the shader files (ex: a Black&White shader such as bw.hk is useful for testing) and copy the file path.
ex, on my phone: '/storage/emulated/0/mpv/bw.hk'

- Open the mpv-android app:
Settings > Advanced > `edit mpv.conf`: paste the required paths
glsl-shaders=my_path/bw.hk
script=my_path/countdown.lua

This sets the black&white shader and countdown script permanently until disabled. If a correct path was speficied the video should now be shown in black &white.
# to disable the shader or script, you'll need to comment out the corresponding line.

It's also possible to edit input.conf and configure some double-tap gestures to perform custom actions such as toggling a shader.

Alexkral
11th September 2023, 15:15
# Comparison of user shader features in the main video players for Windows

To Everyone: Please point out any mistakes/changes, so I can update this guide as needed. The reason for this thread is that the available documentation is sparse and mostly buried in very old/long threads.
You don't need to be a C++ dev to customize or write pixel shaders.



I did some tests to see how different renderers handle the alpha channel. This can be useful because the alpha channel can be used to pass data between shaders in shader chains. I used dx9 shaders in MPC-HC, not sure if other things can change the result as well. The test consisted of simply setting the alpha channel to a value in a shader, and seeing the value received by the next shader in the chain.

EVR-CP:

- Always returns 1 on the alpha channel regardless of the value passed.

MPC-VR (Very creative as you'll see):

- With 8-bit textures, always returns 1 like EVR-CP.
- With 10-bit textures, it returns 1 if you pass 1 and 0 if you pass 0, but if for example you pass 0.5, it returns 0.33, or if you pass 0.75, it returns 0.66.
- With 16-bit textures it returns the same value passed.

madVR:

- Returns the same value passed.

BTW, is there any reason for you not to consider madVR when talking about renderers? It also allows you to run shaders, and is the only one with an option (removed in the latest betas) to store the results with 32-bit precision.

v0lt
11th September 2023, 18:31
- With 10-bit textures, it returns 1 if you pass 1 and 0 if you pass 0, but if for example you pass 0.5, it returns 0.33, or if you pass 0.75, it returns 0.66.
Only 2 bits are allocated to the alpha channel for this texture format (D3DFMT_A2R10G10B10 or DXGI_FORMAT_R10G10B10A2_UNORM). Therefore, only 4 values are possible: 0, 0.333, 0.667, 1.

huhn
11th September 2023, 21:06
[B]BTW, is there any reason for you not to consider madVR when talking about renderers? It also allows you to run shaders, and is the only one with an option (removed in the latest betas) to store the results with 32-bit precision.

because it didn't age wel- can't display UHD BD correctly. quite buggy without the beta version. and inefficient.

mpcVR just works i have a hard time breaking it and if i break something it's usually the GPU driver that i broke.

jedi93
12th October 2023, 21:34
Does anyone know how to get debanding for MPC-HC/MPC-BE ? The shaders from an old thread on this site don't seem to work anymore (atleast not on my setup)...

BetA13
16th October 2023, 02:56
Does anyone know how to get debanding for MPC-HC/MPC-BE ? The shaders from an old thread on this site don't seem to work anymore (atleast not on my setup)...

probably because you are trying to use a dx9 shader with a dx11 renderer.
find a deband shader that works with DX11 ;)

butterw2
19th October 2023, 15:45
Video renderer surface/texture format (MPC-vr)

If multiple shaders are chained, it is best to avoid the 8bit integer surface/texture format in the video renderer because of precision loss. Default mpc video renderer texture format is Auto 8/10bit Integer, this means that depending on whether the source is 8 or 10bit, the internal format used will be RGBA uint8 or uint10.

Test on mpc-be/mpc-vr dx11 with intel hd graphics: There is some gpu usage overhead with using 16bit floating point (fp16) vs 8bit integer (uint8) surface/texture format (uint10 performs similar to fp16). This would only really be an issue for older/low end machines but it should be noted that this overhead applies whether shaders are used or not.
EDIT: For shaders that pass information using the alpha channel, you need to use fp16.

butterw2
22nd October 2023, 11:44
Classic sharpen shaders (mods)

I plan to release modded versions of the classic sharpen shaders in the different shader formats (dx9 hlsl, dx11 hlsl, glsl.hook vo_gpu and libplacebo vo_gpu-next).
https://github.com/butterw/bShaders/tree/master/edge/sharpen

Use case:
- improve a slightly soft/blurry video at native resolution.
- or restore sharpness to upscaled video
Ex: x264/x265 compressed (web) video or bluray rip.
video resolution: 720p, 1080p
display: 1080p or 1440p screen/monitor, windowed (100% zoom) or fullscreen.

The sharpen pack will include:
- sharpen(Sharpen_Amount). The fastest kernel is Laplacian1(5 texture, 8 arithmetic). >> uploaded initial dx9 version.
- unsharp mask (Sharpen_Amount, Threshold) based on gaussian 3x3 blur sigma: 0.85
- luma_sharpen (Sharpen_Amount, Clamp) pattern 3: Laplacian1
- sharpen_complex(Sharpen_Amount, Sharpen_Edge, Edge_Threshold)
- edge_sharpen (Sharpen_Edge, Edge_Threshold)

Shaders will have easy to use parameters (ex: Sharpen strength). It will be possible to display the edge detect/details image (Show_Edge).
Hlsl versions of the shaders will not use hardware linear sampling as this feature is disabled in mpc-hc/be (mpc-hc/be does point sampling for non-integer pixel offsets).

butterw2
25th October 2023, 14:39
unsharp shader (Sharpen_Amount=0.8, Threshold=0.6, Show_Edge=-1)
(9 texture, 16 arithmetic), threshold: +4 ari

Sharpens using the classic unsharp mask method (available in photo editing application such as photoshop, photodemon, etc.).
Sharpening means increasing the contrast of details. In the unsharp mask method a low-pass filtered (blurred) image is substracted from the original image to obtain the high-frequency detail image.
This shader uses a 3x3 gaussian filter (sigma=0.85) to calculate the blurred image.
detail = original - blurred
sharpened = original + Sharpen_Amount*detail
Detail can have positive or negative values. This corresponds to the positive and negative overshoot on edges and causes the brightness of sharpened details to be increased or decreased.

- Sharpening shaders are typically used post-resize.
- Over-sharpening should be avoided as it will cause a halo on high constrast edges. Sharpening requires a reasonably clean source video (in particular if the source is upscaled on a large display) as it will reenforce existing artefacts such as aliasing, etc.
- A detail threshold value can be applied to only sharpen strong edges or to prevent sharpening of noise/artifacts.
- The Show_Edge parameter allows the display of the threshold mask and edges for analysis.

butterw2
29th October 2023, 17:07
Comparing edge detection results
The two sharpening methods (sharpen and unsharp mask) are based on obtaining a detail image: sharpened = original + Sharpen_Amount*detail

Comparing detail image (from sharpener) vs edge image (from edge detector, ex: Sobel):
- both can be thresholded.
- both are obtained from convolution kernels.
- sharpening kernel (ex: Laplacian) generates thin natural looking edges. Sharpener detects texture but also noise/artifacts.
- edge detector has thicker edges but also more reliable output vs noise. (https://raw.githubusercontent.com/butterw/bShaders/master/img/hsplit_scr_Edge_Detect_1080p.jpg)
- edge (from edge detector) is a positive grayscale value usually inferior to 1.0, whereas detail is positive or negative rgb.

To compare edges (A, B) obtained from different edge detector kernels (visually results seem similar):
It is first necessary to match scales as kernel results typically have different amplitudes: adjust scaling factor k to try to best match 10*(A-k*B)==0 and 10*abs(A-k*B)==0. Display of float4(A, k*B, 0, 1) would then be yellow (Red if something is detected on A but not on B, green for detection on B but not on A).

Compared kernels:
- Sobel 3x3 (8 texture, 20 arithmetic) with 2 gradients (horizontal and vertical)
- Prewitt 3x3 (8 texture, 28 arithmetic) with 4 gradients (incl. diagonal), amplitude: 1.025*Sobel
- Adaptive-sharpen_pass1 5x5 diamond (13 texture, 45 arithmetic), amplitude: 1.7*Sobel

Conclusions:
- detected edges are very similar, especially between Prewitt and Sobel.
- Sobel is fastest.
- Adaptive-sharpen sometimes detects (weak) edges that aren't picked up by Sobel.

butterw2
2nd November 2023, 02:12
Contrast adjustment via S-Curve

Contrast increase
Contrast(0.10) is an effective method to improve the viewing of hazy web-videos. But this isn't always applicable (blows-up the white/black ranges then clips them).
An S-curve (boosts midtone contrast ...at the cost of degraded contrast in highlights/shadows !) can avoid this problem if used with a suitably low blending parameter (ex: S in [0, 0.125]).

Symmetrical s-curves:
x: pixel rgb in [0, 1.0].
the max boost occurs at the midpoint (x=0.5).

- Sigmoid(0.05), out = 1.0 / ( 1.0 + exp(-14*x +7 )) ), (1 texture, 12 arithmetic) >> my sCurve shader (https://github.com/butterw/bShaders/tree/master/A-pack).
max contrast boost: S*2.5
contrast degradation at the black and white points: S.

- S2(0.125), out = 0.5 + x1 / (0.5 + abs(x1)) with x1 = x - 0.5, (1 texture, 9 arithmetic)
max contrast boost: S
contrast degradation at the black and white points: S/2.
Curve #2 in sweetfx.curves.

- S3(0.10), out = x*x*(3-2*x), (1 texture, 5 arithmetic).
max contrast boost: S/2.
contrast degradation at the black and white points: S.

S-curve vs contrast(0.10) comparison: https://raw.githubusercontent.com/butterw/bShaders/master/img/contrast_vs_sCurves.png
- Contrast(C), out = x*(1 + C) -0.5*C, (1 texture, 1 arithmetic)
- contrast boost= C.
! But when the curve clips, the contrast is zero (contrast.10 clips below x=0.04).

Conclusion: Sigmoid sCurve(0.05) and S2(0.125) are good alternatives to the contrast.10 or expand10_240 adjustment. Contrast is only increased in the midtones, but using a s-curve means the input is not clipped.

Contrast reduction
S-curves can also be used to reduce contrast. For negative values of the parameter S, midtone contrast is decreased, and near-Black (darks) and near-White (brights) contrast is increased.

Notes:
- It is not typically necessary to increase contrast for movies (though a low Strength s-curve adjustment could be beneficial in special cases, ex: faded colors in older films).
! Because s-curves (with S positive) degrade the contrast (and lower brightness) in shadows, they can have a detrimental effect in dark scenes.

butterw2
11th November 2023, 14:07
#Display on a 1440p monitor using mpv v0.37(gpu-next) with igpu (intel uhd730).

mpv has recently changed its default scalers in (https://forum.doom9.org/showthread.php?p=1936377#post1936377) and I've tested different sources on my 1440p monitor.
Win10> mpv --vo=gpu-next --scale=lanczos --cscale=catmull-rom --sigmoid-upscaling --dither-depth=auto

- low-res sources (low quality web videos) >> upscale 2x or 1.5x
Sources up to 480p will need scaling (the display is otherwise too small), ex: 2x upscale: --window-scale=2. The quality of the video limits how much you can upscale/sharpen.
igv\FSRCNNX_x2_16_0_4_1_distort.glsl sometimes works OK for 2x upscale with strong artefact removal. It runs for sources up to 360p on my igpu.
For 480p sources, I would probably limit the upscale to 1.5x and not apply any sharpener.

- Low quality web sources (720p, 1080p) >> watch at 1x or downscale 0.75x
Bad quality 1080p (upscaled) web videos with are quite common. Downscaling 0.75x is an option.
Use --correct-downscaling, dscale=hermite (bicubic with b=c=0) with --linear-downscaling.

- OK quality videos (720p, 1080p), ex: 1080p BDRip 2000kbps x265 >> upscale to 1440p.
Upscaling to fullscreen with lanczos or spline36 should work OK (scaling ratio: 2x, 1.33x). A little extra sharpening might be beneficial.

Current mpv spatial sharpeners/external upscalers (by igpu usage):
lumasharpen.glsl (luma) < AMD_CAS_lite_rgb.glsl < agyild/FSR.glsl (amd FSR v1.02 mod), upscale ratio: >1 to 2.0 < igv/SSimSuperRes.glsl (SSSR Scaler>1) < igv/Adaptive-sharpen.glsl (0.4)

I will be looking more at sharpeners (at 1 to 2x upscale) as they can improve perceived quality. This typically requires an OK quality source. Filmgrain shaders should also be considered.
For low quality videos, a little contrast boosting can often help, ex: sCurve(0.05).

butterw2
12th November 2023, 15:26
Resolution info available to shaders (there are major differences)

Image resolution (W, H) info available to user shaders with different renderer:
- EVR-CP pre-resize (dx9) shader: you can access video file resolution. Shader does not apply to padding with black bars.
- EVR-CP post-resize (dx9) shader: you can only access the fullscreen resolution not the video file resolution. Shader applies to black bars. >> Not great, could still work in fullscreen.
- MPC-VR (dx11) shader (post-resize only): you can only access windowed resolution (including black bars). Shader does not apply to black bars.
- Mpv shaders (vo=gpu-next)
(LUMA, MAIN: pre-resize rgb, SCALED, OUTPUT: post-resize rgb): you can access both video file resolution (input_size) and resized resolution (target_size, doesn't include black bars). Shader does not apply to black bars.

Trying to get a consistent sharpen strength across shaders (by adjusting the detection level):
Without adjustment:
1) Sharpening depends on the sharpening kernel used.
2) for a given (fixed size) kernel, the sharpen effect depends on the resolution of the image.
- at 100% zoom the source resolution, otherwise the scaled resolution.
The higher the resolution, the lower the sharpening effect for the same sharpen strength parameter.
3) because different renderers do not provide the same resolution information, it isn't possible to make this 100% work the same across renderers. Mpv does provides the full information pre-resize and post-resize.

EDIT: A pre-resize sharpen has a consistent effect°, whatever the display resolution. For a post-resize sharpen, the idea is to normalize the detection for a picture display size of 1280 pixels. If the picture is displayed at a higher resolution, we increase the detection. The following seems to work for an unsharp shader:
detail = detail * max(W, H)/1280. with W, H scaled picture dimensions in pixels.
° In the case of a pre-resize sharpen the effect will depend on the source resolution, so it may make sense to normalize the detection vs source resolution.

butterw2
18th November 2023, 19:34
Contrast Adaptive Sharpening dx9/dx11 hlsl shader (AMD FidelityFX CAS): https://gist.github.com/butterw/ceb89a68bc0aa3b0e317660fb4bacaa3
(9 texture, 47 arithmetic).

The algorithm adjusts the amount of sharpening per pixel to target an even level of sharpness across the image. Areas of the input image that are already sharp are sharpened less, while areas that lack detail are sharpened more. This allows for higher overall natural visual sharpness with fewer artifacts.

parameters:
- CAS: Contrast sharpening Amount. ex: 0.35 [.. to 2.66]. Negative values are possible for lighter sharpening.
- Show_Edge: integer [0 or 1] 0: sharpened image, 1: detail.

Note: doesn't generate a bright pixel at the border with the padded black bars in post-resize fullscreen mode.

stax76
21st November 2023, 09:58
I've updated awesome-mpv (https://github.com/stax76/awesome-mpv) today, syncing it with the user scripts list in the wiki. I noticed you added a script that is similar with an old script of mine, showing a simpler time format when seeking.

https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/btime.js

https://github.com/stax76/mpv-scripts/blob/main/misc.lua#L138
https://github.com/stax76/mpv-scripts/blob/main/misc.lua#L276

In the past I was also using the seek event, but this caused a problem with another popular mpv feature, users were dissatisfied, so I changed it to not use the seek event. I don't remember what the problem was, unfortunately, maybe changing chapters, I checked the issue tracker, but couldn't find it. I also had a JavaScript version, that was before I learned Lua.

butterw2
22nd November 2023, 12:17
I would probably never have coded btime.js without the inspiration from your original javascript code, so thanks for that.
I prefer the javascript syntax and haven't run into any performance issues with my scripts so far, but translating to lua isn't impossible. I use lua scripts on mpv-android (works on my years-old phone, but also on a weak android-tv device I have).

Using seek event you can display time each time there is a seek (screenshot (https://raw.githubusercontent.com/butterw/bShaders/master/mpv/settings/scripts/btime_osd-bar.jpg)). It should work perfectly work with core mpv, if not it's a bug (or a design flaw) IMO. Now that mpv v0.37 has been released (ex: https://github.com/shinchiro/mpv-winbuild-cmake/releases) I would encourage anyone to report any such issues at github.com/mpv-player/mpv.
Obviously when mixing (complex) user scripts there is always potential for conflict, so manually binding a time display function (to every seek command) can avoid such issues.
To avoid these issues, mpv should make one alternative time-display format available by default as ${playback-time/short}. The mpc-hc format (00:10:05 / 02:15:00, 03:05 / 55:00) would be good here.

stax76
25th November 2023, 15:44
I think I remember now what the problem was, something with the built-in OSC, maybe changing chapters with button controls in the OSC, things overlap then.

butterw2
28th November 2023, 19:13
# Filmgrain in shaders, and how to blend it.
https://github.com/butterw/bShaders/tree/master/FilmGrain_Noise

Filmgrain is a physical characteric of film media, digital camera sensors don't have grain, only noise.
Adding filmgrain can be beneficial for sources that have been heavily denoised or are completely devoid of noise/grain (ex: some generative AI outputs). A small amount of grain paradoxically increases perceived sharpness and quality. Adding too much just degrades the signal over noise ratio.

Grain shaders typically generate a dynamic luma noise pattern and blend it with the original image. Grain is calculated for every (x, y) pixel of the image using a pseudo-random hash function. This requires a number of arithmetic operations but no texture samples, so it can be handled quite easily by current gpus.
float grain = good_hash_function(tex.xy, seed); // random variable with a gaussian distribution.

The simplest way to blend the grain with the original image is by adding it:
out = c0.rgb + Strength*grain
with c0 and out pixel.rgb values in [0, 1.0].
grain, positive or negative grayscale value, ex: in [-0.125, 0.125].

The grain pattern can be displayed with: return 0.5+grain; // Show_Grain
Screenshots of the grain pattern can be analysed using the histogram feature of photo editors.
The grain pattern is dynamic, meaning it changes every frame. This is done by updating the seed of the pseudo-random hash function using a uniform variable provided by the video player ('mpc' or ''mpv''),
ex: the player 'clock' in seconds, the integer ''frame'' 'counter' or a ''random'' variable from a uniform distribution in [0, 1.0].

grain shaders:
1) per pixel pseudo-random grayscale noise (with approximate gaussian distribution).
2) additive blending method does not significantly alter the original brightness and contrast of the image.
3) the grain is applied uniformly to the image.
4) grain pattern is updated every frame.

Grain should only be added after any sharpening operations are performed (sharpening generated grain is undesirable).
When upscaling with no post-resize sharpening, grain can be added pre-resize. There are 2 benefits with regards to 1):
- any resizing (ex bicubic A=-0.60, scaling ratio=1.33x) smooths the shape of the distribution and results in a clean gaussian.
- the grain size is scaled. This may achieve a more pleasing result for scaling ratios up to 2x, as single pixels are fairly small at 1080p or higher.

With regards to 4) it can be beneficial to slow down the grain at higher framerates (30, 50 or 60fps video) vs 24 frames-per-second film. A shader using the frame counter as seed can limit the grain update to ex: fps/2 with seed = floor(0.5*counter);

We can change 3) by using a luma-based curve (ex: a parabola). The idea is to apply less grain to dark and bright areas vs the midtones.
To test this out, I used an online palette generator to generate a 9 color grayscale RGB gradient palette. The first color is black, the last white and middle color is midgray128. The palette image was converted to a x264 mp4 video with correct colors (and the desired duration and frame rate) using ffmpeg. https://github.com/butterw/bShaders/blob/73835ae8f3857d6713f10b7582c0e7e51d23a86d/test_LimitedRange/graycard9_1392x336p30-15s_0-32-64-96-128-159-191-223-255.mp4

Results with grain.hlsl shader (1 texture, 42 arithmetic), no resize:
grain.35 (strong grain). (top) C:1 uniform grain vs C0:C1:0.30 (https://raw.githubusercontent.com/butterw/bShaders/4bd779e4e81152c6c5f1b0ead0ff15141c61e09f/FilmGrain_Noise/grain.35_D1vs.30.png)

EDIT An alternative blend that avoids having too much grain on darks is:
c0.rgb = c0.rgb* (1 + 1.30*Strength*grain) = c0.rgb + c0.rgb*1.30*Strength*grain;
This is a simple linear shaping function (https://raw.githubusercontent.com/butterw/bShaders/45c093f0a721981e01ae6ae4b2961b41f87d9586/FilmGrain_Noise/grain-profile_parabola_linear_uniform.png) (y=ax+b with a=1.30 and b=0). It has less grain on darks and midtones vs parabola(C:0.25) but higher grain in highlights (the grain will be visible there).

butterw2
2nd December 2023, 21:45
# tunable parabolic shaping function, in/out: [0, 1.0]

The grain.hlsl/.glsl shader (previous post) can apply less grain to dark and bright areas vs midtones by multiplying grain with a shaping function based on luma. grain = gshape(luma)*grain;

The shaping function is a tunable parabola (https://raw.githubusercontent.com/butterw/bShaders/88173f2273f9de714c220dae2ebef1fb825e4140/FilmGrain_Noise/grain_densityCurve-vsLuma_D0-black_D1-red.png) centered at midgray, it has a zero-derivative at x=0.5. parabola(x:0.5)=1;,

tuning parameter C, ex: 0.30, typ in [0 to 1.0]
By default, the values in x:0 and x:1.0 are set by parameter C: Curve01. parabola(x:0)=parabola(x:1)=C
But its possible to use different values of C for x>0.5 and x<=0.5. ex: float C = (x>0.5) ? Curve1: Curve0;
for negative C, use: max(gshape(luma, C), 0)

float pow2(float x) { return x*x; }
float gshape(float x, float C) {
// tunable parabola(x, C) centered in x=0.5: C + (1-C)*(1 -(2*x-1)^2) = (C-1)*(2*x-1)^2 +1 = (C-1)*(2*(x-0.5))^2 +1
return lerp(1 -pow2(2*x -1), 1, C);
}

butterw2
7th December 2023, 17:18
# restart-mpv to recompile shaders and reload configuration

mpv-daily (v0.37.0-70-g562450f5) fixes --watch-later-options-append=glsl-shaders
This applies to input.conf: Q quit-watch-later
It also corrects the glsl-shaders property display, which now uses the platform file-list separator (";" on windows, ':' elsewhere) instead of "," previously. The separator is required when multiple shaders are used.
This does mean scripts using the glsl-shaders property may need to be updated.

Ex: here is a standalone update to my script restart-mpv.js. Use case: restart mpv to recompile shaders (and reload scripts, .conf files) after they have been modified.
v0.10 is backwards compatible: https://github.com/butterw/bShaders/commit/1c75f06ef7539d5cf1d9644cfde08d4b5206a8d7. I'll provide updated versions of my mpv shader/OSD scripts in the next release of A-pack.

With mpv v0.37-dev, restart-mpv can now be done directly from input.conf without any script required (tested on windows):
F5 run mpv.com --glsl-shaders=${glsl-shaders} --start=${playback-time} --pause=${pause} "${path}"; quit #restart-mpv

# Script Keybindings in mpv:
The scripts adds a Shift+F5 script-binding by default. I would recommend setting the keybinding explicitly in input.conf: this is where all your keybindings should be defined, not in scripts. The option --no-input-default-bindings disables regular script key bindings and the built-in defaults.
mp.add_key_binding("Shift+F5", "restart-mpv", restart_mpv); // input.conf: Shift+F5 script-binding restart-mpv
script-message or script-message-to (no default keybinding defined, string parameter support) can be used instead of script-binding.
//mp.register_script_message("restart-mpv", restart_mpv); // input.conf: Shift+F5 script-message restart-mpv
restart_mpv is the name of the function that gets called when the message is received
mp.add_key_binding(null can be good (no default keybinding defined), but you should use _ rather than - in the script name, ex: X script-binding my_script/restart-mpv. Also unlike script-message-to it doesn't support parameters.
With X script-message-to my_script restart-mpv, the message "restart-mpv" is only sent to my_script, this avoids the possibility of random collisions

butterw2
13th December 2023, 11:50
mpv-menu-plugin (https://github.com/tsl0922/mpv-menu-plugin): customizable native context menu for mpv on windows , requires mpv v0.37 or later.
https://github.com/tsl0922/mpv-menu-plugin/releases
previous v1.10 release: 100% C, some dynamic submenus available.
EDIT-2: The current version (v2.0-dev) delegates the dynamic menu updates to a lua script. Without script the menu will be purely static. The default script adds some new dynamic submenus (ex: #@tracks, #@playlist, #@profiles) and it is possible to create your own (by forking the code).

This recent C-plugin project (GPLv2 license) provides mpv with a customizable right-click menu with submenus and commands (the corresponding hotkeys are displayed).
Installation: unzip menu.zip. Put the plugin (the file menu.dll) into mpv's portable_config/scripts dir. Then edit (or create) your portable_config/input.conf file to show the menu. #menu: is used to indicate menu entries.
The following input.conf example binds a dynamic context-menu (navigate chapters, select audio channel and subtitles) to right-click:

# The default syntax is similar to mpv.net:
_ show-text hello #menu: mpv-plugin
Ctrl+a show-text hello #menu: Foo > bar #this here is a user comment. The following line is a separator.
_ ignore #menu: -
_ ignore #menu: Audio #@tracks/audio
_ ignore #menu: Subtitle #@tracks/sub
_ ignore #menu: Chapters #@chapters
j cycle sub #menu: Subtitle > Cycle/Next
v cycle sub-visibility #menu: Subtitle > / Visibility
f cycle fullscreen #menu: / fullscreen
_ ignore #menu: -
Ctrl+w quit #menu: X Quit
MBTN_RIGHT script-message-to menu show
Here is a screenshot demonstrating a small (static) context menu and a pause-indicator in the window titlebar (discussed in next post).
https://raw.githubusercontent.com/butterw/bShaders/ebbd4e35a424ef117e66904189f8e438fc912c2f/mpv/settings/scripts/mpv-menu_win10-light-1440p-hidpi125_pause-indicator.png

butterw2
19th December 2023, 17:40
# mpv: how to create and display a shaders-On indicator (°)

Knowing whether shaders are loaded can be useful. Here's what is currently possible in mpv (v0.37):
- The shader list is stored in the property glsl-shaders (a list of file-path strings).
- The simplest is just to display glsl-shaders ${glsl-shaders}, but this is often not practical because this property can be long and typically needs to be parsed for display.
- Using property-expansion (https://mpv.io/manual/stable/#property-expansion) and based on the content of glsl-shaders we can display a single character shaders-On indicator (°).
- This indicator can be used in various places: window title, OSD, terminal-status, etc. It is typically initialized in mpv.conf or via command-line, but these properties can also be changed via input.conf commands.
- Once set the display will automatically update when glsl-shaders changes.
- Unfortunately there are 2 possible values for an empty shader list which evaluate differently. Always (re-)initialize shaders to "", otherwise you need to check for 2 values here instead of just one (this also avoids the default osd display being (error) when toggling off the last shader).
- my shaders-On indicator: ${!glsl-shaders==:°} evaluates to "°" if glsl-shaders is not an empty string, otherwise "".

- Other indicators are of course possible, ex: a pause indicator, which I use in the mpv window title: ${?pause==yes:|| } this evaluate to "|| " if paused, otherwise "".
playlist indicator: ${!playlist-count==1:${!playlist-count==0: #${playlist-pos-1}/${playlist-count}}} evaluates to ", 1/5" if the playlist has a greater than one length, otherwise "".
Indicators can be combined and displayed via the following string properties (they support property-expansion):
title, term-status-msg
osd-msg1, etc.
osd-playing-msg, term-playing-msg (only displayed when a new video is loaded, default: "")

ex mpv.conf or command-line, --title="${!glsl-shaders==:°}${?pause==yes:|| }${?media-title:${media-title}}${!media-title:No file}${!playlist-count==1:${!playlist-count==0: #${playlist-pos-1}/${playlist-count}}}"

butterw2
19th December 2023, 23:22
mpv: shaders-On but shader not applied !

setting glsl-shaders in mpv does not guarantee that the shader will be applied. Here are the possible issues:
1) Fails to open shader file, likely because the file-path is wrong, ex: Cannot open file 'abba.glsl': No such file or directory.
This can happen when typing shader names at command-line or because the shader has been renamed. This type of error can be displayed on OSD with a script. (https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/error-osd.lua)
2) Shader compilation error (from vo, ex: [vo/gpu/d3d11]), likely because of a syntax error.
With vo=gpu the video output is blue (helpful for shader developers), but this is not the case with gpu-next. The compiler output printed in red in the terminal is quite long.
3) No errors, but shader not applied because there are no active shader HOOKs.
Mpv shaders can contain multiple HOOKs that are executed conditionally. For instance a LUMA hook will only run if the input is YUV. Prescalers are often only applied for some scaling ratios (specified in WHEN conditions expressed in reverse polish notation). The active shader passes can viewed on page 2 of the built-in stats display. The same information is available in the property vo-passes. The pass names are taken from the hook's DESC line and don't always reference the name of the shader.

Conclusions about troubleshooting shader issues:
- first check the shader is loaded in glsl-shaders.
- look at the terminal output for any errors (they are displayed in red).
- display stats page2 to check whether there are active shader passes. If not check the conditions under which the desired shader HOOK is supposed to be executed.
- If paused, toggling fullscreen forces a screen refresh.
- If all seems OK, make sure the user parameter values used by the shader are correct.
- If you've modified (and saved) the shader source code you need to restart mpv (https://forum.doom9.org/showthread.php?p=1994854#post1994854) to recompile the shader.

butterw2
21st December 2023, 16:21
Dynamic mpv-menu example in dark mode, the played video file has an audio track, but no subtitles or chapters:
https://raw.githubusercontent.com/butterw/bShaders/85c3e9f5812c456ecebb56062c00b5a861361177/mpv/settings/scripts/mpv-menu_dynamic_win10-dark.png

In the mpv/portable_config for A-pack, I will be using mpv-menu as a command launcher/hotkey memo for useful commands that may not be used frequently, but also as a way to use mpv with only the mouse when required.
The menu contains different types of commands. Here I used a prefix symbol to identify them: / indicates that the command toggles between 2 states, ex: fullscreen can be on or off. : indicates a permanent (until disabled) osd, ' indicates a limited duration osd. + or - increase or decrease value, = reset to default value (ex: 100 for volume). X indicates that the command quits mpv.

[EDIT] This is a standard windows menu, it supports standard hotkeys and can be navigated with the keyboard: Arrow keys can be used to navigate, Return/enter to execute command or exit menu. Alt/Esc closes an open menu. The first letter of commands/submenus can be used as accelerators, so use different starting letters for items of a same (sub)menu when possible.

Depending on your preference, you could include a fair number of commands in the menu using 2 levels of submenus, or you could just go with a minimalist launcher.

butterw2
26th December 2023, 14:00
mpv: Disable (--no-osc) or Hide the On screen Controller

By default, mpv overlays (and auto-hides) a seekbar+buttons at the bottom of the screen. This feature is called the On-Screen-Controller and is based on a built-in script called osc.lua (https://github.com/mpv-player/mpv/blob/master/player/lua/osc.lua). The OSC offers only limited configuration options (https://github.com/mpv-player/mpv/DOCS/man/osc.rst) through script-opts/osc.conf. The default OSC is bad, the result is maybe passable after tuning the config. If you are decidedly not impressed with the OSC, you can disable it completely with --no-osc (input.conf or command-line option). The drawback is you won't have a seekbar available unless you get a replacement script. It's not difficult to do a better design, the problem is that Osc.lua is 3000 lines and gets regular commits, so any replacement fork requires regular updates. I present my own custom seekbar in the next post (not osc-based).

The alternative is to change the OSC visibility (hiding it when it is not required).
This can be done via a hotkey, ex input.conf: DEL script-binding osc/visibility #menu: View > OSC # OSC visibility: auto, always, never

You can override default OSC visibility (priority: script defaults < portable_config\script-opts\osc.conf < mpv.conf < command-line)
--script-opts-add=osc-visibility=never # <always, auto, never> default: auto
--script-opts-add=osc-showwindowed=no #default: yes. no: the OSC is not displayed in windowed mode

butterw2
1st January 2024, 23:56
mpv --no-osc: custom seekbar using a (kick-ass) overlay. Intro: showing custom OSD text in mpv (https://forum.doom9.org/showthread.php?p=1990436#post1990436)

The mpv OSD is rendered with libass (also used for displaying subtitles). ASS_Tags can be used to render:
- text (font, color, position on screen).
- shapes (ex: the mpv logo) and of particular interest here rectangles (color, position).
For this, I would recommend to first create an overlay with mp.create_osd_overlay() in a script. I am doing this with basic (mpv uses mujs, ES 5.1) javascript.

Objective: I am trying to do a modern seekbar, colored bar with transparency similar to youtube.
UI elements associated with a hidable seekbar:
- seek time tooltip (for seeking with the mouse)
- playback-time / duration display.
- an optional status bar for information display, possibly with some command buttons.
I don't really need on screen buttons, as I typically use (keyboard /mouse) keybindings +right-click context menu. I do want to use a short time display format.

Mpv limitations:
- The built-in OSC... but we can disable it using --no-osc
- No built-in support for custom time formats.
- Mpv has a built-in progress bar feature called the osd-bar. It looks terrible by default, but it is fairly customizable. However, there are no options to change the fill color of the osd-bar (it uses the main osd color).
- The mpv text OSD default is (Font: sans-serif -> Arial), large size (=55), White color, thick black borders (size=3), transparent back-color. The OSD scales with window size, this only really works in fullscreen or with a large window. The big font causes some serious issues at small sizes and it doesn't work so well on light pictures either (the reason for the thick text borders).
Interestingly VLC uses a similar default and achieves a much nicer result using Freetype2 Font renderer (white text, small, black outline, shadow opacity 128). The time OSD display is shown at the top-right. It's readable (but a bit ugly) down to 50% zoom.

Overall it's easy to get a nice text display on a large dark background (just use a large white font). The difficult cases are:
1) white or grey pictures.
2) when you have to scale the display to a 360p (or less) window.
My preference for OSD text is to use a smaller font and not to scale the OSD with window size: Segoe UI (size=44), light font on dark background.
- To be able to keep small text readable (ex time-display) you probably need to use light text on dark background, ex: mpc-hc in dark mode has a nice hidable seekbar+status bar. This doesn't work with a modern transparent design though.
- When displaying text with a dark background in mpv, you will likely want some extra padding. This is true for regular OSD and overlay. Here are 2 ways to do it:
1) Add padding with a space char before and after. Use nbsp char (rather than regular space char, which only works with show-text and only before the text).
ex, input.conf: a show-text " Hello " #text padded with nbsp. Ass has a not very readable "\\h" tag.
2) With show-text, you can use --osd-shadow-offset=4
- Youtube does achieve acceptable results with gray time display text on a shaded background (this is the only case where they don't use a dark background for text). However I have not been able to achieve the same level of quality in mpv, maybe because of inferior font border rendering ?
- Youtube uses the google font Robota Medium (before that it used Arial). These fonts are good for a small time display (ex: size 16, bold). Specifically for time-readouts it is important that the font should have constant width digits (this is the case for Segoe UI, but not for ex: Segoe UI Semibold !).

my OSD text display and red seekbar:
https://raw.githubusercontent.com/butterw/bShaders/db4c939ba50de6fc883025b9070440110853e6c8/mpv/settings/scripts/seek-bar.jpg

EDIT: a simple javascript script showing overlay features: overlay0.js (https://github.com/butterw/bShaders/commit/ed400d9257405dd57ba2e787a9d9a2ae0c06c03f#diff-c87bf7d6cbe8d4410a7fa169c6602da13972a43e649a86c778838bd8a82f04d0), the release version will have a hideable seekbar and custom time display.
Note: The script observes changes in the percent-pos property, triggering updates to the overlay for each new frame. This is overkill for just displaying a progress bar / custom playtime on screen. Updates using a (ex: 1 second) periodic timer would be sufficient here.

stax76
2nd January 2024, 12:19
To be continued...

I find it interesting how other users use mpv, thanks for sharing.

butterw2
5th January 2024, 11:52
# Ass_Tags in mpv

The Ass_Tags format (https://aegisub.org/docs/3.2/ASS_Tags/) consists in a combination of \tag strings to display a text element or a shape. There are some quirks, so expect some trial and error:
- Each \tag needs to be escaped to "\\tag" for use in javascript strings.
- A simplified syntax seems to work fine ex: &AA rather than &HAA& in the doc.
- Color is specified as hexa &BBGGRR
- !!! alpha &OO is opacity not transparency: 00 is solid color and FF is transparent. 80 is mid-transparency.
\\c \\alpha : global color and alpha
\\1c \\1a : primary fill color, osd-color
\\3c \\3a : border color, osd-border-color
\\4c \\4a : shadow color, osd-shadow-color
- The background color itself cannot be modified in tags* (uses osd-back-color). You can specify global \\alpha or you can revert to the \\rDefault style which has transparent background.
- Font is changed with "\\fnSegoe UI\\fs18\\b1" (Segoe UI, size 18, bold). OSD style: osd-font, osd-font-size, osd-bold.
- Font size is the height of the characters in osd pixels. Unless you explicitly specify font size (\\fs18), the text will scale with the window.
- In addition to text, fonts are used to display icons on screen. Many useful characters/symbols are available in the windows standard fonts (if you can use a large fontsize), and there also dedicated iconic fonts available.
- You can use system installed fonts or fonts in portable_config/fonts.
- for text, you can specify just an anchor, osd-margins will be applied (--osd-margin-x, --osd-margin-y ). If you don't specify an anchor the default will be used, this isn't recommended as it will cover standard osd.
- You can specify precise position with \\pos(x,y), but you also need to consider the anchor point. It uses numpad numbering. The default \\an7 anchors the top right corner of the bounding box to position.
- The default (x,y) coordinate system is normalized to a display height of 720. The overlay will scale with the window size and the coordinates include any black bar padding.
- \\pos(0,0) is top-left of the OSD.
- I've chosen to switch to displayed osd pixels coordinates. It's simpler to use and the overlay doesn't scale with window size.
- For shapes you need to specify a \\p1 scale-factor, ! Do not specify it for text.
- Rectangles are filled. You can specify you don't want any border or shadow with \\bord0\\shad0.
- The overlay data consists in the concatenation with "\n" of all text and shape strings. The order in which you draw can have a visual impact.
- The overlay is always on top of the normal OSD (ex: show-text commands) when displayed. It can be hidden.
*It seems mpv messes with OSD parameter values for background fill. The shadow parameter can be used either to pad text background color or for actual font shadows depending on the alpha value of osd-back-color ? In mpv, text borders and shadows don't look so good, just set a non completely transparent alpha value to osd-back-color and avoid the nonsense.

stax76
8th January 2024, 06:29
Is learning and using Lua not an option? Most script authors prefer it.

Here is a short intro:

https://www.youtube.com/watch?v=jUuqBZwwkQw

butterw2
8th January 2024, 13:08
Good video, but no I don't think someone who wants to write a simple script for mpv needs to learn lua. Lua is the default in mpv, it's probably the better solution for advanced mpv scripts if you know it (and don't hate it), but both can work. Javascript is widely used and it's syntax is going to be easy for anyone who has ever done any c/java/python. Lua is also supposed to be faster, the mpv ES5 Javascript engine is old (meaning some useful functions are missing) and it's true that most available mpv scripts are in .lua.
Modifying existing scripts is the preferred approach if working code is already available. Typically you only need to write a few lines of new code, which can be done with a text editor with syntaxic coloring like notepad++. When debugging scripts you can just print your (number or string) variables to console or screen, but it doesnt work so well when you have to deal with objects (ex: lua table). A tool such as https://github.com/tsl0922/mpv-debug-plugin can be useful to visualize the content of mpv properties (including user-data properties).
A simple color progress-bar OSD overlay script is 100 lines of code, the final version with a hidable seekbar and custom time-format support isn't going to be huge, so the language used doesn't matter that much.

--
printd("x:", x), an enhanced print function for the purpose of debugging scripts: can print tables, differentiates string values from regular values.
- in js: function printd(pre, x) { print(pre, JSON.stringify(x)) }
- in lua: local utils = require('mp.utils')
local function printd(pre, x) print(pre, utils.to_string(x)) end

butterw2
14th January 2024, 16:36
mpv script: short time format OSD btime.js v0.40 (2024-01-19) (https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/btime.js).
Now configurable via portable_config/script-opts/btime.conf (https://github.com/butterw/bShaders/blob/master/mpv/portable_config/script-opts/btime.conf)
Install: Copy script to portable_config/scripts, portable_config/input.conf: F11 script-binding btime/show

playtime / duration for the different supported formats:
00:00:08 / 00:01:12 (mpv default)
00:08 / 01:12 (mpc-hc, symetrical)
0:08 / 1:12 (btime, youtube)
-1.04 / 1:12 (alt + btime)

00:06:04 / 01:27:09 (mpv default, mpc-hc)
0:06:04 / 1:27:09 (symetrical)
06:04 / 1:27:09 (btime)
6:04 / 1:27:09 (youtube)
-1:21:05 / 1:27:09 (alt + btime)

01:02:08 / 01:27:09 (mpv default, mpc-hc)
1:02:08 / 1:27:09 (btime, youtube, symetrical)
-25:01 / 1:27:09 (alt + btime)

Options:
The OSD time format can be customized by the user via the format option. by default, uses a short time format similar to youtube, but better suited for movies (format=btime).
- You can switch to mpc-hc or youtube format.
- alt option allows to switch to remaining-time display.
- displays via standard OSD either using a keybinding or on seek (with seek=yes).
- the duration of the display can be configured (ms option). The text readout message isn't updated on screen, so duration (ms=1500) shouldn't be set too long.
- the custom duration string is updated each time a new file is loaded. It could be made available to other script by saving it in the property user-data/duration.

btime.conf
# format=btime <youtube, btime, symetrical, mpc-hc, mpv> time format: playback-time / duration
# alt=no <yes, no> alternative format: - remaining-time / duration
# percent=no <yes, no> percent progress format: (percent-pos%) time-pos, OR with alt: -remaining-time (percent-pos%)
# seek=yes <yes, no> display on seek event
# ms=-1 <-1, value> duration of OSD display in milliseconds ex:1500, -1: standard OSD duration

Added in v0.40 percent=yes, a percent progress format with playback-time or remaining-time:
(40%) 2:25 (percent, btime)
(100%) 1:35:25
-25:15 (75%)
-1:01:25 (23%) (alt+btime, percent)

butterw2
16th January 2024, 18:15
mpv-menu-plugin: custom dynamic menus
menu_window_scale.lua (https://github.com/butterw/bShaders/blob/master/mpv/settings/scripts/menu_window_scale.lua): custom window-scale submenu, with checkmark for current value.
Edit: Using the new (dyn_menu v2.1) message interface, a script (lua or js) now has full control over menu items and dynamic submenus tagged with a predefined or user-created #@keyword in input.conf, without needing to fork dyn_menu.lua. You can dynamically change the title, the displayed hotkeys, the command, the checked state, and the disabled (grayed) state of menu items.

mpv-menu-plugin v2.1 (req mpv 0.37 on windows) has been released.
- static menus are simple and work fine.
- dyn_menu.lua provides a few useful dynamic submenus: #@tracks, #@chapters, #@playlist
#@audio-devices is also available if needed.
- dyn_menu.lua has a new message interface to allow user scripts to create custom dynamic submenus. Advantage of this approach: dyn_menu.lua doesn't need to be modified, allowing independent updates of user scripts and dyn_menu.lua.
- By default menu items are unchecked. The addition of a state-based checkmark for specific menu entries can improve menu readability significantly. However, this requires a dynamic update when the value changes.
#@property:check syntax, ex: #@mute:check is easy to use, but currently only works for a few (boolean) properties: mute, pause, fullscreen, border, ontop, deband, deinterlace, sub-visibility.

How custom dynamic menus work
at startup mpv loads scripts menu.dll and dyn_menu.lua > parses #:menu entries + associated keybindings in input.conf > creates user-data/menu/items (a nested table)
- the menu (user-data/menu/items) is displayed by win32 c-plugin (menu.dll)
- the default script dyn_menu.lua handles:
-- #@keyword dynamic menu updates
-- messaging to third party plugins (ex: recentmenu.lua) with data in json format.

Displayed keybindings vs actual keybindings
- There is no mechanism in mpv to change runtime input.conf keybinding: what you define in input.conf always applies.
- By default, the menu displays the keybindings associated to menu entries exactly as defined in input.conf. The menu doesn't check the keybindings work.
If you can launch a command from the menu, but not from the keybinding this would indicates some keybinding conflict, ex:
-- the key is not what you thought, ex: CTRL+O isn't the same as CTRL+o
-- you may have redefined the keybinding further down in input.conf.
-- or the key is getting stolen ex: by the OS (ex: you can't use printscreen on windows).
- It is possible to change the keybindings displayed in the menu. However what is displayed in the menu doesn't affect actual keybindings.
-- Why you might want to change what is displayed in the menu: some mpv keynames are a bit long or mpv uses local key names which are sometimes un-intuitive on non US-keyboard.

I created a custom dynamic submenu #@window-scale, this allows full control over the submenu and its entries. A checkmark for the current value is useful here.
Items created in dynamic submenus do not have associated hotkeys from input.conf. In input.conf, I do have hotkeys associated with the window-scale commands. But trying to retrieve them would not be simple, it is much simpler to display no hotkeys (https://github.com/butterw/bShaders/commit/2484df7cfcdedfa1be8d513ab603ed92e83d275f). I decided to display fake hotkeys (position is consistent with US keyboard keys, and more meaningful than the local key names).

https://raw.githubusercontent.com/butterw/bShaders/master/mpv/scr/mpv-menu-plugin_v2.1_btime.png

Notes:
- I've displayed my time readout in the screenshot (using the short format=btime from previous post).
- To dismiss the menu use Alt/Esc keys, or left-click on an empty command (ex: --- menu space in my screenshot).
- add _ ignore at the end of input.conf to avoid binding _.

butterw2
19th January 2024, 15:27
mpv (on win10/11): my Tips

mpv is a cross-plaform open-source, ffmpeg-based, command-line video player. By default, it uses a glsl shader-based renderer (and libplacebo with the option --vo=gpu-next). Mpv has extensive configuration options and generally good documentation. It can be scripted (using either lua or javascript) and supports c-plugins.

My tips for mpv newbies:
- create your mpv folder: with no spaces in path and with user write permissions.
- on windows, current mpv0.37-dev build (ex: Shinchiro x86_64 weekly (https://sourceforge.net/projects/mpv-player-windows/files/64bit/)) works well. Just download and unzip the build to mpv folder. You can update when you want using updater.bat.
-- Create mpv/portable_config for your .conf files and the portable_config/scripts subfolder.
- Get a copy of an existing config or create your own, no .conf files are provided by default.
- Start mpv from terminal in the mpv folder, you can use drag&drop. mpv pathto.myvideo.mp4
-- On windows the command prompt (cmd) will uses mpv.com, use a shortcut to mpv.exe if you don't want a terminal window (you can still use the console if needed).
- Startup options: user default startup options are configured in mpv.conf file. Command-line options have higher priority if specified.
- It is possible to define multiple configuration [profiles] in mpv.conf. Select the profiles to apply with the option --profile=
- For info on mpv options, check out the mpv.io/manual, some decent configuration guides are also available on the web but might not be 100% up-to-date.
- ! hardware decoder isn't enabled by default. I use --hwdec=d3d11va
- For old igpu: you likely need options from --profile=fast
- mpv isn't a GUI-based player and the On-Screen-Controler (built-in osc.lua) is probably the weakest feature. Fortunately it can be hidden, disabled (--no-osc) then replaced.
- For runtime commands you can use keybindings, it also possible to use the console (but the syntax isn't always simple). On windows, a custom context menu is available with context-menu-plugin (https://github.com/tsl0922/mpv-menu-plugin).
- Define all your hotkeys in portable_config/input.conf, disable default keybindings with --no-input-default-bindings
-- the format is: KEY command1; command2 #:menu for context-menu entries #comments
- mpv is easy to script with .lua or .js (javascript ES5.1).
- Keep only the scripts you need in portable_config/scripts as they are autoloaded by default. You can manually load scripts with --scripts=
- I keep shaders and manually loaded scripts in mpv/s subfolder. It's also possible to use portable_config/shaders, the path can use ~~ for portable_config.
glsl-shaders property is a path list (if you have multiple shaders the separator is ; on windows, : elsewhere). ex: ---glsl-shaders=s/bw.hk;s/x_10_240.glsl Vs =~~/shaders/bw.hk;~~/shaders/x10_240.glsl
- Scripts can support configuration via portable_config/script-opts, myScript.conf is the configuration file for myScript.lua, ! option syntax must be strictly respected. Script configuration options can also be specified in mpv.conf or via command-line.
- Use _ rather than - in script names.
- mpv-debug-plugin (https://github.com/tsl0922/mpv-debug-plugin) is a mpv GUI tool that can help you make sense of mpv commands, properties and options.
- if you have questions reddit r/mpv is a good place to ask.

butterw2
22nd January 2024, 20:21
mpv: seek menu

I'm using a static context-menu with some relative jumps/seeks (10, 30, 60, 300s), and like youtube some absolute percent seeks (10, 25, 50, 75, 90%). When the menu is displayed the first letter of menu entries acts as an accelerator, this allows to get more hotkeys without having to permanently define them. To block unwanted accelerators, you can add a space in front of the title. I also use input.conf: kp0 no-osd seek 0 absolute; set pause no #menu: Play > from start.
Some keys names in mpv aren't great (also, not very consistent), so there are a couple cases where I wanted key name substitutions in the menu, Ex: Ctrl+WHEEL_DOWN >> ctrl+WhDn. The length of the displayed menu titles and keybindings set the width of the context menu and some key combination are quite long, ex:Ctrl+Shift+KP_ENTER, another reason for changing displayed hotkeys would be to show multiple hotkeys for the same command on the same line.

https://raw.githubusercontent.com/butterw/bShaders/637eac08eb69ce74d8a3c1e557a500265e7efde3/mpv/scr/mpv-menu_jump_seek.png

One feature that is sometimes useful is the ability to define one or more seek-points by setting a time marker. A custom Markers menu with some user-data/markers properties should allow to do this (currently you could set ab-loop-a, or use revert-seek mark). The next release of context-menu-plugin will support copy/paste to clipboard, meaning a Go to Time feature becomes possible (at runtime: copy a timestamp to clipboard, then seek to it).

anta777
15th March 2024, 19:41
How to check the shader is loaded in glsl-shaders?

Find

CTRL+0 show-text "Shaders: ${glsl-shaders:}"