clsid2 / mpc-hc

Media Player Classic
GNU General Public License v3.0
10.97k stars 491 forks source link

Add a Gaussian Blur shader to the shader list #681

Closed JorgeR81 closed 3 years ago

JorgeR81 commented 3 years ago

Hi, 

I've noticed you don't have a blur shader in the MPC-HC's shader list. Other players, like Potplayer and VLC, have the ability to add blur to the picture, out of the box.

I use this feature a lot. I have many old SD quality video files, from DVD and VHS. They still look pretty good on my 27 inch CRT TV, but on a modern display, you can see all the encoding “imperfections”. I’ve found that, if I apply a small amount of Gaussian blur, I get a very decent image quality, even in a modern display. The encoding artifacts are gone, and I don’t really lose a lot of detail. If you apply the right amount of blur, the "detail" you lost is mostly encoding artifacts.

I actually prefer a simple Gaussian blur, instead of a "smart" blur, because it gives a more natural look, without distorting the image.

Potplayer and VLC let you fine tune the amount of blur with a slider. But they don't have presets. Sometimes I need to change the amount of Gaussian blur, depending on the resolution of the video, and the encoding quality. So I lose all the fine tuning I already did for other videos.

This is why your implementation could be even better! You could have 2 or 3 blur shaders in the list, variations of the same shader, with different settings, for different amounts of blur. That's all the basic user will ever need. And for the advanced user, you can have instructions/comments on the shader file on how change the settings, in order to create new custom presets.

I've found an example online: https://www.shadertoy.com/view/Xltfzj

But I don't know if it will work in MPC-HC. Or even if it would harm my computer. If this or other similar shader was included in the official MPC-HC releases, I would feel more comfortable using it.

Thanks

adipose commented 3 years ago

Try this one:

https://github.com/butterw/bShaders/blob/master/blurGauss.hlsl

It looks fine to me and was tested with mpc-hc, supposedly. There are two filters in mpc-hc that use a gaussian filter, but I think they use it as an unsharp mask (sharpens rather than blurs).

JorgeR81 commented 3 years ago

OK, thanks.

It seems you can control the blur strength, by modifying the integer in the “i<3” part, right? I will make some presents and see the ones that are more useful to me.

Another thing related to this, that could be interesting, is the ability to use a shortcuts keys to activate the shaders. Perhaps, you could have an option on the shader’s menu: “toggle with shortcut key” or something. Then, instead of automatically applying the shaders, they would be toggle off by default. And now, in the shortcut menu you will have one more line for all each shader you “drag and dropped” in the shader’s menu. This workflow, seems logical to me, but I guess you could add a tool tip on the shader’s menu, for the user to “select shader’s shortcut in the shortcut menu”.

And If toggling individual shaders is not practical to implement, you could just have a single, permanent, new line in the shortcut menu: “toggle all active shaders”. Just that would be very helpful. I have this in Potplayer, but not in VLC, and it makes a lot of difference! You can instantly apply the effect, and you don’t have a big menu in front of the picture, when you want so see how the picture changes when you apply it.

(But, if this is possible, I guess it should be a different issue for that.)

clsid2 commented 3 years ago

An "enabled" entry could be added in the menu above the preset list. With a hotkey to toggle it on/off. Anything else is too complex.

JorgeR81 commented 3 years ago

So, do you mean something like my second suggestion? Yes, that would be perfectly fine! (As I was writing my first idea I realized just how over complicated it was, so I came up with the second suggestion.)

JorgeR81 commented 3 years ago

Could we assign the key we want for this? Or would it be “hard coded”? If “hard coded”, when the hotkey option is enabled it would override my other shortcut for that key, right?

clsid2 commented 3 years ago

If it gets implemented then hotkey can be changed (options>player>keys).

JorgeR81 commented 3 years ago

Great! Thanks.

butterw commented 3 years ago

blurGauss.hlsl (X+Y passes) isn't ajustable, but you can achieve a stronger effect by using it multiple times in your preset.

EDIT: these are the coefficients to use for a weaker blur (i<2):

//blur5 with hw linear sampling (3 texture, 6 arithmetic)
#define Offsets float2(0.0, 4/3.) 
#define K float2(0.29411764705882354, 0.35294117647058826)

For a fast blur (with ajustable parameter k), 3*(X+Y passes) of boxblur are commonly used for gaussian approximation: https://github.com/butterw/bShaders/blob/master/blurMean.hlsl

A weaker blur (single-pass 3x3 gaussian kernel) would also not be difficult to implement in mpc.

adipose commented 3 years ago

https://github.com/clsid2/mpc-hc/issues/502 is a duplicate of the enable/disable feature. We can probably close this one.

adipose commented 3 years ago

Also, if you want to add a shader to mpc-hc, I have no objection if @clsid2 is ok with it. However, make sure you implement both a dx9 and dx11 version as mpc-hc now supports both and has all shaders in both formats.

clsid2 commented 3 years ago

Yes, adding a good blur shader would be totally fine. But it needs to be a single shader. Something that requires multiple shaders or passes is not really user friendly.

butterw commented 3 years ago

Single pass blur in a pixel shader has poor speed (and it gets worse the larger the kernel) because of the number of texel fetches required. 3x3 kernel 2D gaussian convolution is trivial to write, but actually blurs very little. The only possible use is as a smoothing filter and even then 5x5 might be preferable.

Using multipass shaders in mpc is easy if preconfigured presets are offered by default, ex: 1=Blur Gaussian (Light) 2=Blur Gaussian PreResize1=.\blurGauss.hlsl;.\blurGauss_Y.hlsl PreResize2=.\blurGauss.hlsl;.\blurGauss_Y.hlsl;.\blurGauss.hlsl;.\blurGauss_Y.hlsl;.\blurGauss.hlsl;.\blurGauss_Y.hlsl

adipose commented 3 years ago

It's true a shader is not a good way to do a gaussian blur in one pass. Presets may be a decent solution.

Personally I would prefer it if the gaussian could be combined with other shaders without having to append to a preset list. One idea is to support a folder or zip of shaders and add them as a group.

butterw commented 3 years ago

You can load the blur preset and just add in your other shaders. It's possible to save a new preset or overwrite an existing one, but it is not required.

Default presets make it understandable for new users that multiple passes are required. Adding two passes (with meaningful names) isn't a big deal really.

adipose commented 3 years ago

I can see some advantages to the way you describe. But on the other hand, using presets to add an effect is counter to how all the other shaders work. And while understanding the multiple passes may be nice, we could easily achieve that with a description or note.

Default presets aren't implemented, I don't think. It's probably the easiest way to achieve the goal, but it doesn't follow the traditional ui pattern users are familiar with.

Another way is to add a new button(s) to append/insert a preset/group instead of a shader.

I was thinking a clean solution is a zip containing

  1. Extra shaders needed if any
  2. Shader list for multiple passes

Actually just a text file with a multiple shader list could be enough but I kind of wanted to hide the "useless" shaders that are only for the multipass effect.

butterw commented 3 years ago

By default preset, I really just meant populating an initial preset.

The easiest way to group multiple shaders would be to do it on filename (a multiple shader list works also). ex: If filename ends with "_pass1" 1) auto-handle subsequent passes when loaded/removed. 2) Hide _passN in the shader list.
A zip file would be troublesome for editing parameter values.

https://github.com/butterw/bShaders/blob/master/img/mpc-hc_Select_Shaders_Menu.png?raw=true Unrelated there is room for at least one button in the Select Shaders interface. From my use, I would say a sideways arrow to transfer shaders from Active pre-resize list to Active post-resize would actually be quite handy.

adipose commented 3 years ago

It might be more functional to just do pre/postsize as a checkbox. This way, mpc-vr would not need any explanation for lack of support. We could just gray out the checkbox in that instance.

adipose commented 3 years ago

I understood what you meant about an initial preset. But it's not currently implemented. Of course we could hard code some values referring to the shaders included with mpc-hc and populate the default settings, but it's not very elegant.

Your idea about naming with _pass1 isn't bad.

butterw commented 3 years ago

for a single pass gaussian smoothing filter mpc/shaders/sharpen complex.hlsl has a 3x3 implementation: return blurred; // add this line just after blurred is calculated.

adipose commented 3 years ago

Yes, I mentioned earlier the gaussian blur was being used as an unsharp mask. Maybe it's good enough.

https://github.com/clsid2/mpc-hc/pull/745

How about this. Since this blur is a single shader, it can be used as many passes as you want. If you want to blur more, simply add it to your list more times. This is the simplest solution and seems to work ok for me.

butterw commented 3 years ago

Gaussian 3x3 is the only thing that makes sense as a single pass shader. Strength can be increased with multiple passes, but it's more of a smoothing filter than a blur.

Performance (9 texture, 15 arithmetic) compares unfavorably vs 2-pass blurGauss hw.9x9 (10texture, 16 arithmetic). Using a hardware linear sampling implementation (hw.3x3) allows better perf (4 texture, 7 arithmetic), but support isn't 100% (on my PC, falls back to Nearest Neighbor sampling in dx9). In dx11, it should be possible to use the ps5.0 gather4 instruction.

JorgeR81 commented 3 years ago

Hi, As a user, I wouldn't mind to just add the shader multiple times to the list, to increase the amount of blur. I guess that if this method is used, the "weaker" the effect the better, because it gives more control over the amount of blur.  

Do you have any idea on how many times would it be necessary do add this shader to achieve about same effect as the default values on ffmpeg's gblur filter (steps=1, sigma=0.5) ? https://ffmpeg.org/ffmpeg-filters.html#gblur

And what about sigma=1 ? The "sweet spot" for me is usually between these values depending on the video resolution and the encoding quality. I never needed something above sigma=1.3.

butterw commented 3 years ago

A single pass of gaussian3x3 pre-resize should put you in the same ballpark (If you are upscaling, using it post-resize weakens the effect). ffplay "input.mp4" -vf gblur=1.0

JorgeR81 commented 3 years ago

OK, I see. I mainly use it on old SD files (height = 384, 432 or 480), but upscaled to an FHD display (height = 1080). VLC seems to apply the gblur filter "pre-resize" because the amount of blur appears more or less the same, whether the video is in the original resolution or upscaled to the display's size.  

I guess that with MPC's capability to apply the shader multiple times, pre-resize and post-resize should give playroom to get the right amount of blur. 

adipose commented 3 years ago

FYI, MPC-VR doesn't support pre-size shaders, so that's one potential pitfall. I created a test build that supports multi-pass shaders, and I included those from @butterw in the dx9 (dx11 shaders still need doing). Rather than complicate it further, I have just pass1 and pass2, and if you want repeated (double) passes, you can just include it more times.

This achieves the goal of a "single" shader in the interface, so the user doesn't have to understand the multi-pass nature.

https://mega.nz/file/lcwlTYDQ#vnpi1X3aJEzHH3CqZZe8EOr_UXQuB8hNwvp_Jrc0O4M

butterw commented 3 years ago

Could you test https://github.com/butterw/bShaders/blob/master/blur/bSmooth.hlsl ? It includes the hw linear sampling optimization (Mode 1).

With the initial parameters you will get a fully black screen if hw linear sampling isn't supported (that's what I get with intel i3-4150, HD Graphics 4400 (driver version: 20.19.15.4531)), if it is supported you can then comment out the debug-output.

JorgeR81 commented 3 years ago

OK, so I tested with the type of files and display I described above.  Also, I have an nvidia gtx 1070 on my desktop (with the original drivers)     Gausian Blur_pass1 (dx9) A single "Gausian blur" shader in pre resize is about what I need most of the times. This is very handy for a quick set up. I can have a similar effect with about 3 x "Gausian Blur" post resize.  But with this shader the edges of the images seem to "shift" horizontaly a little bit. 

Gaussian Blur 3x3 (dx9)   I can have a similar amount of blur with 2 x  "Gaussian Blur 3x3" pre-resize, and the edges don't shift.  I can also see a similar amount of blur with about 7 x  "Gaussian Blur 3x3" post resize, (and the image edges don't shift either). These small steps are a good way to control the amount of blur. I think this is the method I would use.

Gaussian Blur 3x3 (dx11)  I get a black image when I try to use it. But I have the same effect when I try to use the dx11 versions of other shaders like "Sharpen complex 2".

List size A minor usability problem is that after adding it more than 7 times you can lose track, visually, of how many you used, without scrolling the list. But I don't think anyone one is going to need more than that, (unless they actually want a blurry picture effect).

bSmooth.hlsl I copied bSmooth.hlsl to the "dx9" folder, in the "shaders" folder. But I get a black image when I try to use it.

Select shader menu shortcut I see you have a shortcut for toggle debug shaders. But I can't find one to toggle the select shaders menu.

Enable shader shortcuts I don't have a problem with 2 enable hotkeys pre and post resize. It could be useful to apply 2 different effects separately.  If you change it to a single hotkey for both, it could be nice to still have 2 hotkeys as an option.

Shader preset shortcuts I see that you have hotkeys shortcuts for the previous and next shader preset.  How do these work exactly? Could this be somehow set up to increase and decrease blur.   It could add a new "Gaussian Blur 3x3"shader, post reside with each preset or something like that. I could use shift+mouse wheel to change the intensity of the effect, without opening the panel!

(Portable programs)   Newbie side question. This is more of a general question for portable programs. Since this is a portable version, if I add it to the right click menu ("open with ..."), will it disappear after I delete the program and windows can't find the exe file no more.  Or will I have to perform some registry hack.

butterw commented 3 years ago

dx11 Shaders are only for dx11 renderers (ex: MPC-VR in dx11 mode).

(Portable programs) The portable version does no registry hacks (hopefully !). You can select the option for mpc.ini file in the same folder instead of the registry, and it works exactly the same as an install. The trick is to always keep the same portable folder name (ex: b:\MPC-HC) and copy the new files in it.

The select shader menu is the Options menu "O" >> playback >> Shaders

Previous/next shader shortcut: You could cycle between 2 blur strengths. It isn't very useful beyond 2 or 3 presets though. The shader presets menu is available with right-click to select your preset.

Enable shader shortcuts IMO, it should be possible to define a single shortcut that triggers both, but no reason not to keep the current mpc-be pre/post commands as defaults.

List size Save a Preset if you need multiple instances (ex: 5) of the same shader. You can still tweak if needed.

JorgeR81 commented 3 years ago

Shader presets are awesome!!!

I've just made 7 presets. Each one adds a new "Gaussian Blur 3x3" shader to the post resize list. Now I can fine tune the amount of blur with the mouse wheel. I think "Gaussian Blur 3x3" is the way to go. It allows a nice transition between levels of blur.

JorgeR81 commented 3 years ago

Yea, I get that if you have presets for different types of shaders it wouldn't work, with the mouse wheel.

But if you just want to change the strength of a single type of shader it works like a charm.

mpc

butterw commented 3 years ago

As your numbers demonstrate, Blur should really be done pre-upscaling. Strong blur are commonly achieved by first downscaling to quarter frame before blurring. You may want to look at the type of scaler you are using. It probably doesn't make sense to use a sharp upscaler (try a soft cubic or bilinear).

Though you will not get a black screen like in bSmooth, Gausian Blur [sic] also use hw linear sampling, which doesn't seem to be working for some reason. @adipose: can you confirm whether bSmooth/hw linear sampling is working for you ? The glsl version works fine in mpv.

JorgeR81 commented 3 years ago

I'm using the defaults on this mpc version. I will look in to the scaler issue.

But just to clarify, a shader with a weaker effect is a good thing for me, because it allows me to fine tune the amount of blur.
I usually end up using about the same settings, because most of the SD files I have are about the same resolution and encoding quality. But the capability to fine tune is essential in this use case. Too much blur and you lose detail, too little blur, and you can still see encoding artifacts.

And, of course, with very high quality SD files (large files), I don't need a blur filter at all.

JorgeR81 commented 3 years ago

Also, I guess I'm more used to a "softer" (more blurry) image than most people now a days. I never had an LCD tv (never liked the image quality). I prefer a softer CRT image, but with better blacks and better motion. I went straight from CRT to OLED. And I still use the CRT in the bedroom. And the OLED tv is one of the first models (is 55 inch FHD not 4K). But it looks stunning with FHD content.

I also have a 27 inch "VA" panel on my Samsung PC monitor, witch is supposed to give better blacks levels than an IPS panel. Colors are a bit too saturated on these panels, but you can fix it on the nvidia gpu settings. This is this still an FHD VA panel. FHD content looks great. Never felt the need to upgrade to 4K.

JorgeR81 commented 3 years ago

Mouse Ctrl, Alt, Shift modifiers

I don't know if this is an issue specific to this development version, because I haven't tried the version 1.9.8 (stable) yet. The new mouse modifiers I've set up had an odd behavior. I didn't get it at first, but I think I understand now.

When you set up a new windowed mouse modifier it does not work at first. It just works after you set up the fullscreen mouse modifier, for the same command.

But then, the fs modifier is also in control of the windowed mouse actions. Eg.: even if you set a different mouse modifier for windowed mode, mpc will still use the fs one, in both modes.

(note: a simple fs mouse action (wheel up and wheel down) with no modifiers, also has the same control over the windowed set up. Eg.: you can set up mouse wheel + Ctrl for windowed mode, but only the wheel will work on both modes).

The only control the windowed modifiers gives you, is the ability to completely disable the windowed actions, by deleting the windowed modifier for that command.

(I just tested with mouse wheel + modifiers, mostly in "PnS Inc Width" and "PnS Dec Width" commands).

adipose commented 3 years ago

I just noticed I only enabled the multi-pass for the pre-size shaders. So if you had a problem with that, it could be why.

adipose commented 3 years ago

As your numbers demonstrate, Blur should really be done pre-upscaling. Strong blur are commonly achieved by first downscaling to quarter frame before blurring. You may want to look at the type of scaler you are using. It probably doesn't make sense to use a sharp upscaler (try a soft cubic or bilinear).

Though you will not get a black screen like in bSmooth, Gausian Blur [sic] also use hw linear sampling, which doesn't seem to be working for some reason. @adipose: can you confirm whether bSmooth/hw linear sampling is working for you ? The glsl version works fine in mpv.

It did not work for me. I have Ryzen 2400G.

adipose commented 3 years ago

https://mega.nz/file/NEgWESSB#AjV6IRXv4jijEj07i4Pk2qpNnC2R6rn59irHn7Uy9jE

Another test build. This one should support pre/post and also other renderers (previously only mpc-vr and madvr).

If you are seeing "pass1" in the shaders you don't have a supported build and it won't work properly.

butterw commented 3 years ago

I'm hoping hw linear sampling #748 can be made to work in mpc-hc as it allows much better performance.

I'll will update 2-pass blurGauss.hlsl so that it uses the full implementation of the separable 7x7 Gaussian kernel by default (with sigma=1.5, but it will be possible to manually switch to a different sigma).

JorgeR81 commented 3 years ago

tested vs the older version

Gaussian Blur (pre-resize)  It gives a more intense blur, and with no "edge shift". It looks good to me. This is a good amount of blur for me. I don't think I will need a more intense blur. I don't think anyone is going to need more blur than this, for this usage scenario (I'm using SD files). In some cases it might be too much.

Gaussian Blur (post-resize) I need 5 applications to get about the same amount (slightly less) of blur as above. (I tested frame by frame). (6 applications is more blurry than an single Gaussian Blur pre-resize)   This could be a good thing, because it's a good way to control the blur level.

Gaussian Blur 3x3 (pre-resize)  I need 3 applications to get about the same amount (slightly less) of blur than a single Gaussian Blur pre-resize. (4 applications is more blurry than a single Gaussian Blur pre-resize)

Gaussian Blur 3x3 (post-resize) This has very little effect, with a low number of applications. But it can still be helpful to fine tune the effect of the previous blurring methods.  Eg., if you want a level of blur in between 1 and 2 Gaussian Blur 3x3 (pre-resize):  You can use a single application pre-reside and fine tune with a couple of applications post-resize.  This seems a lot of work for the user, but you only have to do it once, if you save it as preset.

Black bars  If your aspect ratio demands blacks bars, I noticed that a large amount of post-resize blur, makes them blurry. But I would only use post-reside blur in small amounts, if I needed to fine tune, adding just a little more blur, so it's no problem.

Intensity levels I really think you should keep both shaders, to allow the user to fine tune the intensity of the blur effect. The application pre and post-reside, helps with this, but it's not enough.  Don't forget that other players let you insert or select numeric values, with a slider.  I don't think such a level of precision is really necessary. But you need at least these 2 shaders, with these 2 different intensities. 

(other issues related to hotkeys) I have the menu bar hidden in my set up. But when I press the "Alt" key the menu bar appears, and "file" is highlighted.  This interferes with my mouse modifier short cuts. (I use Alt + mouse wheel to seek fame by frame).

( mouse modifiers ) With this new version I still have the same problems I describe in the previous post. Eg.: after deleting full screen mouse modifiers for frame steep, the windowed mode modifiers for this commands also stopped working. 

adipose commented 3 years ago

Thanks for the testing. Alt showing the menu is intentional and likely won't be changed. It's how most applications show hidden menus, as alt is the key that shows the accelerators.

Please enter another bug for the mouse modifier issue.

JorgeR81 commented 3 years ago

Comparison to ffmpeg gblur (in mpv) These shaders look good to me, already. But if you want to improve them further, it might be a good idea to compare them with ffmpeg's gblur filter. https://ffmpeg.org/ffmpeg-filters.html#gblur

Color saturation These 2 shaders give slightly more saturated (pink) skin tones in my tests. It looks very similar to ffmpeg's smartblur (in mpv) https://ffmpeg.org/ffmpeg-filters.html#smartblur-1 ( I don't use "smartblur" in mpv, because I don't really notice much difference from "gblur", and I generally prefer less saturated colors. But this is also fine. Potplayer also uses "smartblur", with the same effect, and it never bothered me. )

Blur intensity vs object size These 2 shaders seem to "over blur" isolated objects like tree branches against the blue sky. Eg. a single application of Gaussian Blur pre resize seems similar to gblur sigma=1.5, steps=1. But this is when you look at a face in the first plane (with about a third of the height of the display). When you look at the tip of a palm tree against the blue sky in the distance, it's much more blurred. ( I think you should take look in to this one. I din't check if "smartblur" also does this, but this is the opposite of what it's supposed to do, right?... )

butterw commented 3 years ago

blurred Black bars The default renderer EVR-CP applies shaders to black bars in fullscreen post-resize. This is not the case for MPC-VR renderer or mpv however.

Current 2-pass Gaussian Blur.hlsl isn't working as expected in mpc-hc. The next version should be more accurate.

My perf optimized Gaussian blur shaders are also available and working with mpv. The benefit vs ffmpeg is they use gpu instead of cpu. https://github.com/butterw/bShaders/blob/master/blur/blurGauss.hook.glsl https://github.com/butterw/bShaders/blob/master/blur/gSmooth.hook.glsl

VLC Spatial Blur uses a slider (buried in the settings menu !) + you don't know the value of sigma. It's a single-threaded cpu implementation (bad perf, not at all usable on a low-end system).

JorgeR81 commented 3 years ago

OK thanks. Later on you could perhaps add to your main page, a brief explanation, or a link, on how to use shaders in mpv (for the newbies). I know how to apply and control ffmpeg filters with a lua script, but I have no idea how to use a shader. ( perhaps a lua scrip with the command "glsl-shaders-append=file.glsl" in a function binned to a hotkey?... I would need to create a "glsl-shaders" folder in the "scripts-opts" folder? ... ... and how to toggle off or remove the shader? ... Is there a glsl-shaders-toggle command or something, similar to vf-toggle? ...)

butterw commented 3 years ago

I've uploaded the math correct sigma=1.5 gblur7, 2x(7textures, 11 arithmetic). https://github.com/butterw/bShaders/blob/master/blur/blurGauss_pass1.hlsl and _pass2.hlsl

At first glance, the difference with the previous version of gaussian blur (2-pass hw.gBlur9, 5 texture, 8 arithmetic) doesn't seem very significant (I was upscaling 720p to 1080p). It still available in the dx9 version as Mode 3.

@JorgeR81 see this thread for mpv configuration: https://forum.doom9.org/showthread.php?p=1929051#post1929051

adipose commented 3 years ago

I merged in those updated shaders.

JorgeR81 commented 3 years ago

By the way, about the Alt key. The menu bar only shows after you release the Alt key, (after the frame step is already set with the mouse wheel movement). And I discovered that if you press the Ctrl key while releasing the Alt key, the menu does not show up. Sounds complicated, but this movement it gets in "muscle memory" pretty fast, so there's no problem with this.