Log in

View Full Version : YAP (Yet Another Player) v0.9.5


Pages : 1 [2] 3 4 5

Orf
16th November 2014, 14:40
madshi, on the second thought, may be your efforts for making API is not needed at all. Correct me if I'm wrong, but are all rescaling algorithms madVR uses for now, including NNEDI3 a pieces of shader code ? And if I manage the way to apply shaders to YAP images, you can simply give me the permission to use your shader code. Is it a better way for us to go or I'm missing something here ?

madshi
16th November 2014, 20:26
NNEDI3 uses OpenCL. The other algorithms use D3D9 HLSL, but they require some lookup tables/textures to be filled, so just using the HLSL code won't help, you'd also have to use the code which fills those lookup tables/textures etc. And to be honest, I'm not sure if I want to make my source code available. E.g. you might be tempted to use the same algorithms for EVR. I'd rather make an API available. But I currently don't have the time. Maybe you could use the madVR screenshot functionality to do image resampling, once I've extended it a bit. I'm planning to let the user choose whether he wants screenshots to be taken in the original video resolution or scaled etc. And there's already an official API (supported by madVR) which lets the media player fetch the current image from the video renderer. You could use that API. The only problem right now is that it's always the unscaled video atm. But I plan to change that "soon", as described above.

Orf
17th November 2014, 06:45
madshi, thanks for the explanations and honesty. I respect honesty, especially when it compared to false promises. Well, API will only be useful, if it will work without madVR instance. Also API doesn't solve my intensions as you've said 'tempted to use the same algorithms for EVR' problem. Existing API is not useful too, cause it requires DS graph and copies image from GPU memory back to system memory which is the huge overhead, because resizing needed not only on image load stage

madshi
17th November 2014, 08:37
Oh, so you want the final image to stay in GPU RAM? I thought you wanted it in CPU RAM. Well, I guess that rules out the screenshot idea, too bad. But yes, a DS graph would be necessary in any case. I have to admit that my source code currently isn't in the best shape. There is a lot of code in the DS event routines atm. I plan to cleanup my code after I've reached v1.0 in madVR. If my code were cleaner, it would probably be easier for me to offer you a rendering API without DS. But with the current state of my source code it would be hard to achieve without a DS framework.

generalmx
17th November 2014, 08:54
Hmm, would this work for NNEDI3 still-image support, if AVISynth support is added: http://avisynth.nl/index.php/Nnedi3ocl#Filters

I also found one Japanese Manga Viewer called "MangaMeeya" which supports AVISynth plugins for most of its features (google something like "comic+viewer+avisynth" and it's the only one that comes up), going to try and give it a shot myself (if interested, try tails's lasted translated version where he says he fixed Avisynth support).

Orf
17th November 2014, 11:10
madshi, yes, maybe I was not clear enough before, function that takes texture, needed dimensions and scale algorithm as input and returns the same or new scaled texture...

Orf
18th November 2014, 06:50
madshi:
I've decide that I need own shader options editor in YAP anyway. I have some questions about IMadVRExternalPixelShaders:
1) Is there any specific reason it didn't accept compiled shaders (only the source) ?
2) What is the best point during graph building to initially set the shaders ?
3) Can it handle clearing and re-adding a ps chain when graph is running or paused ?
Also, I'm planning a DB structure to store shader-related data and I'm trying to make it universal (to use with madVR at first and use it for may own needs later), wanna take part in discussion of it?

madshi
18th November 2014, 10:58
1) Is there any specific reason it didn't accept compiled shaders (only the source) ?
Hmmmm... Good question. IIRC, when I implemented that interface, MPC-HC was the only media player with custom shader support, so I implemented an interface which was easy to integrate for the MPC-HC devs. When I rewrite/extend the shader support in a future version (not too far away, I hope), I'll most probably also support compiled shaders.

2) What is the best point during graph building to initially set the shaders ?
3) Can it handle clearing and re-adding a ps chain when graph is running or paused ?
From the top of my head you can change the shaders at any time you want. Doing so results in madVR having to eventually clear the rendering queue and re-render frames, but that's not a problem, really. It might just cause a minor stutter in the moment when you change the shaders. An ideal time to set the shaders should be after building the graph and connecting the pins, but before starting/pausing the graph.

Also, I'm planning a DB structure to store shader-related data and I'm trying to make it universal (to use with madVR at first and use it for may own needs later), wanna take part in discussion of it?
I'm not sure I understand what you mean. Can you elaborate?

Orf
18th November 2014, 12:25
I've meant I can show you schema of shader-related DB tables I'm currently thinking over. It also can give you a picture on how the future shader interface will look like in YAP. Can you revise it and suggest if I'm missing something important maybe ?

leeperry
13th December 2014, 01:58
I do understand now, it is a lot of work for you too, so it was just another wish, that will never comes true, sadly...
OK thanks for the reply, so basically ACDSee-like features(previous/next/random/shrink to fit/1:1 scaling) with NNEDI3 and Jinc3 aren't gonna happen in YAP? :o

I also found one Japanese Manga Viewer called "MangaMeeya" which supports AVISynth plugins for most of its features (google something like "comic+viewer+avisynth" and it's the only one that comes up), going to try and give it a shot myself.
Oh your google-fu skills are impressive :cool:

It keeps crashing for me and can it do NNEDI3 luma doubling + Jinc upscaling? If so, could you create a thread and share your settings by any chance please?

It's a real bummer that picture viewers are still stuck in the 90's.

Orf
13th December 2014, 09:23
OK thanks for the reply, so basically ACDSee-like features(previous/next/random/shrink to fit/1:1 scaling) with NNEDI3 and Jinc3 aren't gonna happen in YAP? :o

No, what you've quoted means that madVR in its current state can't be used to accomplish this. But I think this idea of yours is nice, I like it much and I want to implement it anyway. So, I've already started to add pixel shader support on my own. When it will be finished, it will enable you to apply any combination of hlsl sources to images, madVR and to EVR CP in the future.

Also I've come to an understanding that compute shaders is better fit for this purpose then pixels shaders. Can anyone say, am I right that NNEDI3 is only currently available here @doom9 as pixel shader hlsl sources ?

@madshi
I can't reproduce the F11-F12 bug you've reported by your description. Maybe you have some more to report ? Is it always happen to you ?

Shiandow
13th December 2014, 16:15
Also I've come to an understanding that compute shaders is better fit for this purpose then pixels shaders. Can anyone say, am I right that NNEDI3 is only currently available here @doom9 as pixel shader hlsl sources ?

As far as I know it's available as Avisynth (.avsi) or OpenCL (.cl) files. MadVR uses DirectCompute but I'm not sure if madshi ever made that code public.

Edit: I was mistaken. It seems that MadVR also uses OpenCL. And I think part of the code actually comes with MadVR (in the folder 'legal stuff').

nevcairiel
13th December 2014, 16:19
NNEDI3 is done in OpenCL in madVR as well. Only the dithering shaders are DirectCompute, afaik.

Shiandow
13th December 2014, 16:24
Oh, I think you're right, the changelog mentions that NNEDI3 needs OpenCL.

madshi
13th December 2014, 16:29
I've tried converting NNEDI3 to DirectCompute, but it performed *much* slower than with OpenCL, unlike error diffusion which was actually slightly faster with DirectCompute. So nevcairiel ist right, NNEDI3 is done in OpenCL, error diffusion in DirectCompute.

@Orf, unfortunately I don't have any time atm. But I know that it was 100% reproducable for me, when I reported the problem.

Orf
13th December 2014, 19:36
Shiandow, nevcairiel, madshi,
thanks guys firstly for your comments, they are really helpful finding my way in the dark. But at second thought, and may be I'm missing something here, but why all of your starts talking in one voice about OpenCL vs DirectCompute, when I was initially asked about pixels shaders vs direct compute shaders ?

madshi
14th December 2014, 10:56
at second thought, and may be I'm missing something here, but why all of your starts talking in one voice about OpenCL vs DirectCompute, when I was initially asked about pixels shaders vs direct compute shaders ?
Because you were asking about NNEDI3 GPU implementations, and you were asking about DirectCompute. So we tried to explain to you that for NNEDI3, you'd better be using OpenCL because it's dramatically faster.

Orf
15th December 2014, 06:39
madshi, I agree, I do not ask a question in a correct way may be. Will try to correct myself now. As far as I understood beside using DirectCompute/OpenCL APIs there's third way to do it by simply drawing a quad via Direct3D and applyng pixel shader to it. Did you test is that method any faster then OpenCL ?

nevcairiel
15th December 2014, 08:09
As far as I understood beside using DirectCompute/OpenCL APIs there's third way to do it by simply drawing a quad via Direct3D and applyng pixel shader to it. Did you test is that method any faster then OpenCL ?

Pixel Shaders are much more limited, and something as complex as NNEDI3 is unlikely to be possible with pixel shaders alone.

madshi
15th December 2014, 08:15
madshi, I agree, I do not ask a question in a correct way may be. Will try to correct myself now. As far as I understood beside using DirectCompute/OpenCL APIs there's third way to do it by simply drawing a quad via Direct3D and applyng pixel shader to it. Did you test is that method any faster then OpenCL ?
I actually did try to do NNEDI3 via PS3.0 pixel shaders, and from what I remember, it was slower by a factor of around 1000x, compared to OpenCL.

The reason why pixel shaders are so much slower for OpenCL is that pixel shaders apply math to every destination pixel separetely. OpenCL and DirectCompute are more flexible, you can configure them to render multiple destination pixels with one kernel pass. Doing that allows to cleverly cache things and to share some calculations for multiple pixels etc. Especially for NNEDI3 that's very important to get things up to speed.

Orf
16th December 2014, 05:32
nevcairiel, madshi, thanks
I do understand OpenCL/DirectCompute is more powerfull, that was why I initially asked.
But this NEDI/NNEDI is really confusing me. To summarize what I've learned from your:
- NNEDI3 is the most heavy algorithm, but it gives the best result in the end
- NEDI implemented here for example (http://forum.doom9.org/showthread.php?t=170727) is less heavy, so PS use is acceptable
- madVR internally should have at least two image processing conveyers. #1 is PS conveyer, #2 is OpenCL conveyer. Also it possible have DirectCompute conveyer as #3
- IMadVRExternalPixelShaders supports only #1 (?)
- To make general and flexible image processing support all three conveyers have to be implemented
- Which one of the three is better is kind of an open question. Also picking and implementing only one of them will require rewriting of hlsl/cl code (thing I very unlikely can do myself)

I'm I still missing something ?

madshi
16th December 2014, 09:28
But this NEDI/NNEDI is really confusing me. To summarize what I've learned from your:
- NNEDI3 is the most heavy algorithm, but it gives the best result in the end
- NEDI implemented here for example (http://forum.doom9.org/showthread.php?t=170727) is less heavy, so PS use is acceptable
- madVR internally should have at least two image processing conveyers. #1 is PS conveyer, #2 is OpenCL conveyer. Also it possible have DirectCompute conveyer as #3
- IMadVRExternalPixelShaders supports only #1 (?)
- To make general and flexible image processing support all three conveyers have to be implemented
- Which one of the three is better is kind of an open question. Also picking and implementing only one of them will require rewriting of hlsl/cl code (thing I very unlikely can do myself)
Seems all correct to me.

Although the names suggest otherwise, NNEDI3 and NEDI are *totally* different algorithms, which have almost nothing in common (except for doing an exact 2x upscale). IMO NNEDI3 has better image quality, but it's also quite a bit slower than NEDI. And yes, NEDI works fine with simple PS3.0 pixel shaders, while NNEDI3 requires OpenCL to run at a decent speed.

FYI, Shiandow has written a super-res post-processing algorithm (using simple pixel shaders, once again) which improves NEDI quality even further, bringing it even nearer to NNEDI3 quality. This super-res algorithm is currently available for NEDI, only, I think, but it could in theory also be used to improve other 2x upscale algorithms, e.g. NNEDI3, or even Bicubic/Lanczos. I'm not sure if this super-res algorithm would improve NNEDI3 quality, too, we haven't tried yet, I think. But it might. I'm hoping that the super-res algorithm will sooner or later be a separate filter, running after any other 2x upscaling algorithm.

Shiandow
16th December 2014, 12:24
FYI, Shiandow has written a super-res post-processing algorithm (using simple pixel shaders, once again) which improves NEDI quality even further, bringing it even nearer to NNEDI3 quality. This super-res algorithm is currently available for NEDI, only, I think, but it could in theory also be used to improve other 2x upscale algorithms, e.g. NNEDI3, or even Bicubic/Lanczos. I'm not sure if this super-res algorithm would improve NNEDI3 quality, too, we haven't tried yet, I think. But it might. I'm hoping that the super-res algorithm will sooner or later be a separate filter, running after any other 2x upscaling algorithm.

SuperRes works for arbitrary scaling factors, and arbitrary algorithms. It's not hard to combine with other scaling algorithms, it basically just needs a 'before' and 'after' image. So far I'm having a bit of trouble with larger scaling factors, since it's hard to add detail back into the image without introducing aliasing, but I still have some ideas I could try and MPDN's render scripts make it quite easy to try things out so hopefully I'll be able to improve that soon.

madshi
16th December 2014, 12:40
Ok, sounds good!

Gravitator
16th December 2014, 14:45
Still barely understand, who are we and what do they want from me.
p/s pls remove this torrent shot of yours from my thread


This is just a proposal for expansion/improvement of your product. The problem is in the understanding of the translation. It would be good to contact you via e-mail (Vkontakte).

Orf
17th December 2014, 06:13
madshi,
can you please share your the PS and DirectCompute versions of nnedi3? It will be nice example for me to estimate the differences in code base and test performance maybe. Quick looked through Shiandow SuperRes realization, I'm right guessing that separate PS hlsl's theoretically can be combined in one DirectCompute hlsl or one OpenCL cl ?

Shiandow,
as far as I understand SuperRes requires only that separate hlsl been applied in correct order to work. So what benefits MPDN's render scripts gives to your comparing to MPC-HC way of configuring shaders ?

Gravitator,
I do not use any of social networks. But you can use the PM I guess.

Shiandow
17th December 2014, 12:07
Shiandow,
as far as I understand SuperRes requires only that separate hlsl been applied in correct order to work. So what benefits MPDN's render scripts gives to your comparing to MPC-HC way of configuring shaders ?

A few weeks ago madshi asked a similar question, you may want read my reply here (http://forum.doom9.org/showthread.php?p=1701264#post1701264). But the gist of it is that SuperRes needs to compare the current image to the original image, so you need to be able to store the original somewhere. If it wasn't for some very creative use of the alpha channel, I wouldn't have been able to do SuperRes with just shaders, at all.

Orf
19th December 2014, 10:03
Shiandow,
sorry for delay, have to check some things before answer. That's because we're implementing the same thing. Does it simply means you need another sampler with source image on any stage of processing ? Because from what I've found here (http://forum.doom9.org/showthread.php?p=1699589#post1699589) it looks more complex. Like you need samplers with the result of all previous stages or something more maybe.

Shiandow
19th December 2014, 10:34
There's only one step where I'd need another sampler with the source image, but more importantly that is still not quite enough to implement SuperRes. To implement SuperRes it's more or less necessary to be able to create new samplers and be able to send multiple samplers to one shader. It's technically possible to do SuperRes for one of the channels by storing things in the alpha channel, but that's not ideal.

The way this is achieved in MPDN is by building a chain of so called 'filters' which keeps track of allocating textures and sending the right textures to the right shaders. It might seem that you can use results from all previous stages, but under the hood it will try to allocate as few textures as possible, it also won't calculate results that aren't used and since recently it can even optimize away unnecessary conversions (so if you have X -> ConvertToYUV -> ConvertToRGB -> Y, it will simply do X -> Y).

Orf
19th December 2014, 11:02
In other words, some logics need to be programmed anyway. I'm currently trying' to understand if texture creating is possible inside compute shader hlsl. Can't find any useful information so far. May be madshi will shed some light on this matter.

madshi
19th December 2014, 11:21
Creation of textures etc is something you need to do in CPU code. AFAIK, kernels (doesn't matter if it's pixel shaders, DirectCompute, CUDA or OpenCL) can't create textures, they can just use them.

Orf
20th December 2014, 09:35
madshi, and what about this one (http://forum.doom9.org/showthread.php?p=1703000#post1703000) ?

madshi
20th December 2014, 09:43
can you please share your the PS and DirectCompute versions of nnedi3?
The DirectCompute kernel is shipping with madVR. The PS version for upscaling in X direction is here:

"sampler SourceSampler : register(s0);\n"
"sampler WeightSampler : register(s2);\n"
"float4 floatConsts1 : register(c0);\n"
"#define pixSizeX (floatConsts1[0])\n"
"#define pixSizeY (floatConsts1[1])\n"
"static float1 SumWeights1[nns] = (float1[nns]) packedSumWeights1Array;\n"
"static float1 SumWeights2[nns] = (float1[nns]) packedSumWeights2Array;\n"
"static float4x4 rgbToHd = {+0.2126000000000000, +0.7152000000000000, +0.0722000000000000, 0,\n"
" -0.1145721060573400, -0.3854278939426600, +0.5000000000000000, 0,\n"
" +0.5000000000000000, -0.4541529083058166, -0.0458470916941834, 0, 0, 0, 0, 0};\n"
"\n"
"float4 main(float2 Tex : TEXCOORD0) : COLOR0\n"
"{\n"
" float input[32];\n"
" float mstd0, mstd1, mstd2;\n"
" {\n"
" float sum = 0;\n"
" float sumsq = 0;\n"
" int index = 0;\n"
" float xpos = Tex.x - 1.0 * pixSizeX;\n"
" for (int ix = 0; ix < 4; ix++)\n"
" {\n"
" float ypos = Tex.y - 3.0 * pixSizeY;\n"
" for (int iy = 0; iy < 8; iy++)\n"
" {\n"
" float4 sample = tex2Dlod(SourceSampler, float4(xpos, ypos, 0, 0));\n"
" sample = (sample - 16.0f / 255.0f) / (219.0f / 255.0f);\n" // d3d9Float8 16-235 -> 0-255
" sample = mul(rgbToHd, sample) * 255.0;\n"
" ypos += pixSizeY;\n"
" input[index++] = sample[0];\n"
" sum += sample[0];\n"
" sumsq += sample[0] * sample[0];\n"
" }\n"
" xpos += pixSizeX;\n"
" }\n"
" mstd0 = sum / 32.0;\n"
" mstd1 = sumsq / 32.0 - mstd0 * mstd0;\n"
" mstd1 = (mstd1 <= 1.19209290e-07) ? 0.0 : sqrt(mstd1);\n"
" mstd2 = (mstd1 > 0) ? (1.0 / mstd1) : 0.0;\n"
" }\n"
" float vsum = 0;\n"
" float wsum = 0;\n"
" {\n"
" float ypos = 0.5 / nns;\n"
" for (int i1 = 0; i1 < nns; i1++)\n"
" {\n"
" float xpos = 0.5 / 16.0;\n"
" float sum1 = 0;\n"
" float sum2 = 0;\n"
" int index = 0;\n"
" for (int i2 = 0; i2 < 16; i2++)\n"
" {\n"
" float4 weights = tex1Dlod(WeightSampler, float4(xpos, ypos, 0, 0));\n"
" xpos += 1.0 / 16.0;\n"
" float sample = input[index++];\n"
" sum1 += sample * weights[0];\n"
" sum2 += sample * weights[1];\n"
" sample = input[index++];\n"
" sum1 += sample * weights[2];\n"
" sum2 += sample * weights[3];\n"
" }\n"
" ypos += 1.0 / nns;\n"
" float temp1 = sum1 * mstd2 + SumWeights1[i1];\n"
" float temp2 = sum2 * mstd2 + SumWeights2[i1];\n"
" temp1 = exp(clamp(temp1, -80.0, +80.0));\n"
" vsum += temp1 * (temp2 / (1.0 + abs(temp2)));\n"
" wsum += temp1;\n"
" }\n"
" }\n"
" float result = (mstd0 + ((wsum > 1e-10) ? (((5.0 * vsum) / wsum) * mstd1) : 0.0)) / 255.0;\n"
" return result * (219.0f / 255.0f) + 16.0f / 255.0f;\n" // d3d9Float8 0-255 -> 16-235
"}";
This kernel needs the NNEDI3 weight "database" uploaded to the "WeightSampler" texture and the "SumWeights1/2" constants in the right order, though, and I don't have that information easy to share, unfortunately.

Orf
22nd December 2014, 06:52
madshi,
thanks, will look into it

Shiandow,
have thought a bit about it, so if I made support for simple script, that will look like in the example below, will it allow you to replace RenderScript part without changing your hlsl's ?

For example we have a shader pack of 5 hlsl scripts (Shader1.hlsl, Shader2.hlsl, Shader3.hlsl, Shader4.hlsl, Shader5.hlsl),
the default script generated would be one pass:
Shader1(Source)->Shader2(Shader1)->Shader3(Shader2)->Shader4(Shader3)->Shader5(Shader4);
but you can change it to something like this:
Shader1(Source)->Shader2(Shader1)->Shader3(Shader2); // first pass
Shader4(Source); // second pass
Shader5(Source, Shader3, Shader4); // third pass

Shiandow
22nd December 2014, 11:27
Shiandow,
have thought a bit about it, so if I made support for simple script, that will look like in the example below, will it allow you to replace RenderScript part without changing your hlsl's ?

For example we have a shader pack of 5 hlsl scripts (Shader1.hlsl, Shader2.hlsl, Shader3.hlsl, Shader4.hlsl, Shader5.hlsl),
the default script generated would be one pass:
Shader1(Source)->Shader2(Shader1)->Shader3(Shader2)->Shader4(Shader3)->Shader5(Shader4);
but you can change it to something like this:
Shader1(Source)->Shader2(Shader1)->Shader3(Shader2); // first pass
Shader4(Source); // second pass
Shader5(Source, Shader3, Shader4); // third pass

Well, I'd need to be able to choose the sizes of the output of a shader. And for SuperRes I'm also using MPDN's internal scaling algorithms, but if you can use shaders and change their output size then it shouldn't be too hard to recreate those scaling algorithms.

Orf
22nd December 2014, 13:00
I see, something like Shader2(Shader1); ResizeOutput(2, 1); Shader3(Shader2);
where ResizeOutput(2, 1) will results in OutputImage.Width = 2 * InputImage.Width ?

Shiandow
22nd December 2014, 13:15
That notation is a bit ambiguous, does it resize the output of Shader2 or does it render Shader2 onto a larger texture? The latter is more important to have, but the former can also be convenient.

v0lt
22nd December 2014, 19:23
I ran from the archive YAP.exe and it without asking anything added context menu for folders. :mad:

Orf
23rd December 2014, 04:48
That notation is a bit ambiguous, does it resize the output of Shader2 or does it render Shader2 onto a larger texture? The latter is more important to have, but the former can also be convenient.
Yes, that was just first that comes to mind. I've meant that Shader3(Shader2) will be rendered at twice wider texture

v0lt,
uncheck "Explorer context menu entry" option and YAP will remove it. But if you only plan move executable to some other place, don't worry YAP will update path automatically

Orf
23rd December 2014, 04:48
That notation is a bit ambiguous, does it resize the output of Shader2 or does it render Shader2 onto a larger texture? The latter is more important to have, but the former can also be convenient.
Yes, that was just first that comes to mind. I've meant that Shader3(Shader2) will be rendered at twice wider texture

v0lt,
uncheck "Explorer context menu entry" option and YAP will remove it. But if you only plan move executable to some other place, don't worry YAP will update path automatically

madshi
23rd December 2014, 09:51
I'd need to be able to choose the sizes of the output of a shader. And for SuperRes I'm also using MPDN's internal scaling algorithms, but if you can use shaders and change their output size then it shouldn't be too hard to recreate those scaling algorithms.
JFMI: What do you need to scale for? I thought SuperRes would look at the original/unscaled image and at the final/scaled image and then post-process the scaled image, based on analyzing both images? Do you need to manually scale another time to make SuperRes work?

Shiandow
23rd December 2014, 13:38
JFMI: What do you need to scale for? I thought SuperRes would look at the original/unscaled image and at the final/scaled image and then post-process the scaled image, based on analyzing both images? Do you need to manually scale another time to make SuperRes work?

The basic idea behind SuperRes is to try to invert a downscaling algorithm, to do this it tries to minimize the difference between the original image and a downscaled version of the final image. If A and B are the the original and upscaled image and D is a downscaling operator, then you can minimize the "||A - D B||^2" (which measures the difference between the A and a downscaled version of B) by changing the amount pixel values of B by something like:

- D^t (A - D B)

Where D^t is the transpose of the downscaling operator, which (surprisingly) is the corresponding upscaling operator. For instance if D performs bicubic downscaling then D^t performs bicubic upscaling. This means that you can calculate this part by downscaling 'B', subtracting this from A and then upscaling this again. You could technically do this in only one go, but that is several orders of magnitude slower.

This method does effectively invert the downscaling operation, but is ill behaved. It will create lots of ringing and aliasing. To avoid that it is necessary to do some post-processing to remove those, but of course this may cause the image to deviate from the original again, so you have to correct that again. Anyway that goes back and forth a few times and (hopefully) converges onto a final image. In practice 2 times seems to be enough to get reasonable results.

madshi
24th December 2014, 11:49
Ok, so let me try to sum that up:

1) SuperRes needs access to the original image A and the upscaled image B.
2) SuperRes downscales B internally to the resolution of A.
3) SuperRes calculates the difference between A and B.
4) SuperRes upscaled the difference to the resolution of B.
5) SuperRes applies the upscaled difference to B.

Is that correct? I suppose the algorithms for steps 2) and 4) should be "identical" (e.g. both Bicubic AR)? Should they also be identical to the original upscaling algorithm used to upscale A to B? Or is that not necessary?

Shiandow
24th December 2014, 12:05
Ok, so let me try to sum that up:

1) SuperRes needs access to the original image A and the upscaled image B.
2) SuperRes downscales B internally to the resolution of A.
3) SuperRes calculates the difference between A and B.
4) SuperRes upscaled the difference to the resolution of B.
5) SuperRes applies the upscaled difference to B.

Is that correct? I suppose the algorithms for steps 2) and 4) should be "identical" (e.g. both Bicubic AR)? Should they also be identical to the original upscaling algorithm used to upscale A to B? Or is that not necessary?

Yeah, that's more or less correct. Although in the last step you should also do some post-processing (SuperRes currently does anti-aliasing, anti-ringing and some sharpening).

Anyway, according to the mathematics step 2) and 4) should have "identical" scaling algorithms, but in practice using a better algorithm for step 4) has far more benefit than using a better algorithm for 2). My current favorite combination is to use bilinear for downscaling and Gaussian for upscaling (low aliasing and ringing). In theory you can use whatever algorithm you want for the initial scaling of A to B, but it's generally better to use one without too much aliasing, NEDI is almost ideal in that regard.

madshi
24th December 2014, 12:15
Ok, thanks.

Anima123
24th December 2014, 23:38
Shiandow, NEDI doubles the resolution on both directions, does SuperRes with NEDI enabled need to do last step scaling in order to get the targeted rectangle, while the SuperRes without NEDI does not?

foxyshadis
25th December 2014, 02:18
Anima123, it looks like it hands off to the player/renderer/next in chain to make any final adjustments, like plain NEDI. Without NEDI it'll go direct to the output resolution (unless you have a weird chain and force something else), so no further resize should be done.

Shiandow, something I'm curious about with SuperRes: Once the algorithm is pretty locked in, will converting it to OpenCL make a big difference? Also, would you eventually be willing to make an AviSynth or VapourSynth filter out of it? (NEDI-based upsizing is definitely better than NNEDI for some things.) If not, at least having the code available makes it possible for others. It just keeps getting better, I really like how well it works!

Also, if you guys don't mind, I think it's best to split this discussion out of the YAP thread.

Shiandow
25th December 2014, 11:03
Shiandow, something I'm curious about with SuperRes: Once the algorithm is pretty locked in, will converting it to OpenCL make a big difference? Also, would you eventually be willing to make an AviSynth or VapourSynth filter out of it? (NEDI-based upsizing is definitely better than NNEDI for some things.) If not, at least having the code available makes it possible for others. It just keeps getting better, I really like how well it works!

Also, if you guys don't mind, I think it's best to split this discussion out of the YAP thread.

I don't think converting to OpenCL will make much difference. One of the main advantages of NEDI and SuperRes is that a pixel only depends on the pixels that immediately surround it, so it's pretty easy to do all the work with shaders. So far I'm not not planning to make an AviSynth or VapourSynth out of it. I had a quick look and it think would take me a lot of time to figure out how to use those shaders in either of them.

Anyway, this discussion is deviating quite a bit from the original topic so I agree that it would probably be better to move it to it's own thread.

Orf
26th December 2014, 04:41
Shiandow, to be completely sure

For SuperRes:
NEDI-pre -> <Upscale>-I -> <Upscale>-II -> SuperRes-pre -> SuperRes -> [SuperRes-inf -> SuperRes] -> NEDI-pst
Upscale means 2x upscale in both directions ? Where did final scaling should happen and what algorithm is used (better to use) for it ? And how did MPC-HC knew that it should reallocate and resize output texture on steps 2 and 3 ?

And can you please draw the same scheme for MPDN NEDI ?

Shiandow
26th December 2014, 14:36
Shiandow, to be completely sure

For SuperRes:
NEDI-pre -> <Upscale>-I -> <Upscale>-II -> SuperRes-pre -> SuperRes -> [SuperRes-inf -> SuperRes] -> NEDI-pst
Upscale means 2x upscale in both directions ? Where did final scaling should happen and what algorithm is used (better to use) for it ? And how did MPC-HC knew that it should reallocate and resize output texture on steps 2 and 3 ?

And can you please draw the same scheme for MPDN NEDI ?

That version of SuperRes is more of a proof of concept, it worked well enough but MPDN's version is nicer. In that version I got around the problem of allocating a new texture by abuseing the alpha channel, I think either "Nedi-pre" or "Upscale-I" stores the original image in the alpha channel and "SuperRes-pre" / "SuperRes-inf" downscale the image and store the difference with the original in the alpha channel. I only did this for the luma channel since the others didn't fit. The more complete MPDN diagram is something like:


/---------------------------------------\
| |
v |
Initial Guess ---> Downscale ---> Diff ---> SuperRes
^ ^
| |
Original --------------------------+-----------/

For clarity I've left out the various colour conversions. Basically I do downscaling in linear light and everything else in L*a*b.

For the NEDI shaders the diagram is something like:


NEDI-pre -> NEDI-I -> NEDI-II -> NEDI-pst


but in MPDN I could allocate new textures and did it as follows (the part in parentheses is the size of the resulting image).

Input (w,h)--->NEDI-Hinterleave (2w,h)--->NEDI-Vinterleave(2w,2h)
| ^ | ^
V | V |
NEDI-I (w,h)--------/ NEDI-II (2w,h)--------/

The NEDI-XInterleave shaders reshuffle the pixels of its two inputs resulting in an image that is either scaled 2x horizontally or 2x vertically. Doing it this way avoids some unnecessary calculations.