View Full Version : Deathray - OpenCL GPU accelerated spatial/temporal non-local means de-noising


Jawed
17th January 2011, 23:07
I've created Deathray, an Avisynth plug-in filter for spatial/temporal non-local means de-noising. It uses OpenCL for GPU acceleration.

The project lives on GitHub now: Deathray on GitHub (https://github.com/JawedAshraf/Deathray)

To download the DLL only:

On the Deathray project page click on "Deathray.dll" in the list of files. On the new page, press the "Raw" button and you will be offered the option of saving the file.

To download the entire source code, including the compiled DLL:

On the Deathray project page click on the Download ZIP button at the bottom of the right-hand column.

Version History


1.04 - Marks use of OpenCL 1.1 features, that have been deprecated in 1.2, as preferred. This keeps AMD SDK from complaining.

1.03 - Fixed black pixels bug with low values of hY and z=true (also affected chroma with low values of hUV)
Fixed bug with allocation of a spurious buffer

1.02 - Added new l, c, z and b options
Temporal filtering now re-weights target pixel based upon all sampled frames

1.01 - Removed logging to stderr (was only present in NVidia debug version);
Includes post-filtering correction first introduced in NVidia debug version;
Updated to use AMD APP SDK;
Updated to VS2012 Express Edition;
Updated DLL so that it is not dependent upon visual C runtime - see post 70;

1.00 - Initial version


Post 90 contains a version of Deathray which ignores the Intel OpenCL platform. This is a quick and dirty fix for people who have the Intel graphics driver installed and find that it is stopping Deathray from working on their graphics card.

I've quoted here the Deathray readme.txt:

Deathray
========

An Avisynth plug-in filter for spatial/temporal non-local means de-noising.

Created by Jawed Ashraf - Deathray@cupidity.f9.co.uk


Installation
============

Copy the Deathray.dll to the "plugins" sub-folder of your installation of
Avisynth.


De-installation
===============

Delete the Deathray.dll from the "plugins" sub-folder of your installation of
Avisynth.


Compatibility
=============

The following software configurations are known to work:

- Avisynth 2.5.8 and 2.6 MT (SEt's)
- AMD Stream SDK 2.3 and AMD APP SDK 2.8.1
- AMD Catalyst 10.12 and 13.8 beta 2
- Windows Vista 64-bit and Windows 8 64-bit

- NVidia software is known to work but drivers unknown

The following hardware configurations are known to work:

- ATI HD 5870
- AMD HD 7770
- AMD HD 7970
- Various NVidia, models unknown

Known non-working hardware:

- ATI cards in the 4000 series or earlier
- ATI cards in the 5400 series

Video:

- Deathray is compatible solely with 8-bit planar formatted video. It has
been tested with YV12 format.


Usage
=====

Deathray separates the video into its 3 component planes and processes each
of them independently. This means some parameters come in two flavours: luma
and chroma.

Filtering can be adjusted with the following parameters, with the default
value for each in brackets:

hY (1.0) - strength of de-noising in the luma plane.

Cannot be negative.

If set to 0 Deathray will not process the luma plane.

hUV (1.0) - strength of de-noising in the chroma planes.

Cannot be negative.

If set to 0 Deathray will not process the chroma planes.

tY (0) - temporal radius for the luma plane.

Limited to the range 0 to 64.

When set to 0 spatial filtering is performed on the
luma plane. When set to 1 filtering uses the prior,
current and next frames for the non-local sampling
and weighting process. Higher values will increase
the range of prior and next frames that are included.

tUV (0) - temporal radius for the chroma planes.

Limited to the range 0 to 64.

When set to 0 spatial filtering is performed on the
chroma planes. When set to 1 filtering uses the prior,
current and next frames for the non-local sampling
and weighting process. Higher values will increase
the range of prior and next frames that are included.

s (1.0) - sigma used to generate the gaussian weights.

Limited to values of at least 0.1.

The kernel implemented by Deathray uses 7x7-pixel
windows centred upon the pixel being filtered.

For a 2-dimensional gaussian kernel sigma should be
approximately 1/3 of the radius of the kernel, or less,
to retain its gaussian nature.

Since a 7x7 window has a radius of 3, values of sigma
greater than 1.0 will tend to bias the kernel towards
a box-weighting. i.e. all pixels in the window will
tend towards being equally weighted. This will tend to
reduce the selectivity of the weighting process and
result in relatively stronger spatial blurring.

x (1) - factor to expand sampling.

Limited to values in the range 1 to 14.

By default Deathray spatially samples 49 windows
centred upon the pixel being filtered, in a 7x7
arrangement. x increases the sampling range in
multiples of the kernel radius.

Since the kernel radius is 3, setting x to 2 produces
a sampling area of 13x13, i.e. 169 windows centred
upon the target pixel. Yet higher values of x such as
3 or 4 will result in 19x19 or 25x25 sample windows.

Deathray uses 32x32 tiles to accelerate its processing.
Each tile is equipped with a border of 8 pixels around
all four edges, with pixels copied from neighbouring
tiles, or mirrored from within the tile if the tile
edge corresponds with a frame edge. This apron of 8
extra pixels ensures that the default sampling of
49 windows is correct, allowing pixels near the edge of
the tile to employ 49 sample windows that all have
valid pixels.

When x is set to 2 or more, sampling will "bump" into
the edges defined by the 48x48 region. With strong
values of the de-noising parameters this will create
artefacts in the filtered image. These artefacts are
visible as a grid of vertical and horizontal lines
corresponding with the 32x32 arrangement of the tiles.

l (false) - linear processing of luma plane.

true or false.

This option allows processing in linear space instead
of the default gamma space.

c (true) - correction after filtering.

true or false.

This option applies a correction after filtering
to limit the amount of filtering per pixel.

When set to false the naked NLM algorithm is used.

z (false) - target pixel tends towards zero-weighted.

true or false.

Reduces the weight of the pixel being filtered to
a minimum. This results in more even filtering across
the tonal range from shadows to highlights.

The standard NLM algorithm gives the pixel being filtered
the maximum weight of all. A refinment of the algorithm
is to give the pixel being filtered the maximum weight
derived from all the other pixels that were inspected.

This maximum of other pixels' weights is used when z is
set to false.

When set to true, the minimum of other pixels' weights is
used instead.

b (false) - balanced weighting.

true or false.

Attempts to balance weighting of pixels based upon their
luma value.

This parameter is not applied to chroma planes.


Avisynth MT
===========

Deathray is not thread safe. This means that only a single instance of
Deathray can be used per Avisynth script. By extension this means that
it is not compatible with any of the multi-threading modes of the
Multi Threaded variant of Avisynth.

Use:

SetMTMode(5)

before a call to Deathray in the Avisynth script, if multi-threading
is active in other parts of the script.


Multiple Scripts Using Deathray
===============================

The graphics driver is thread safe. This means it is possible to have
an arbitrary number of Avisynth scripts calling Deathray running on a
system.

e.g. 2 scripts could be encoding, another could be running in a media player
and another could be previewing individual frames in AvsP or VirtualDub.

Eventually video memory will probably run out, even though it's virtualised.


System Responsiveness
=====================

Currently graphics drivers are unable to confer user-responsiveness
guarantees on OpenCL applications that utilise GPUs. This means if you
are using Deathray on a frame size of 16 million pixels, there will be some
juddering in Windows every ~0.7 seconds (1.5 frames per second on HD 5870)
accompanied by difficulty in typing, etc.


Deathray is BSD licensed

Zep
18th January 2011, 23:19
awesome. will test this weekend for sure. :P

pokazene_maslo
19th January 2011, 02:29
Is this filter motion compensated?

pirej
19th January 2011, 02:42
Nice one, ill give it a try.
Is ati HD5750 compatible ? I have ati stream installed/enabled.


edit: I gues it's compatible, i loaded the default settings, and it works...(just for previewing the filtered video.. cpu load is only 20%, GPU 50% load), now i have to try to tweak the settings and see the effect.
Thanks Jawed

Jawed
19th January 2011, 11:33
Is this filter motion compensated?
Not explicitly.

The general algorithm searches the entire image for blocks (what are usually called "windows") that look like the block around the target pixel. It uses the similarity of each sampled block as the weighting of the centre pixel of each sampled block.

The filtered pixel is then the weighted sum of all the centre pixels of every block in the original image.

In Deathray the search is restricted to 49 windows around the target pixel. This means if motion is "low", i.e. less than 3 pixels in any direction, motion compensation "arises".

Deathray has an option, x, to increase the sampling area.

Intrinsically NLM is a spatial filtering technique based on self-similarity in real world images plus it is geared towards noise rather than artefacts such as JPEG/DCT blocks or interlacing artefacts. See this paper for a summary:

http://hal.archives-ouvertes.fr/docs/00/27/11/47/PDF/ijcvrevised.pdf

One of the problems with NLM (generally as well as in Deathray) is that it isn't doing time-series pixel averaging (what you might do with a series of photographs of a static scene) - the spatial aspect tends to dominate, even with a temporal radius of 5 or even 7.

Ironically, after the grand claims made in the paper linked above, hybrid time-series techniques have been experimented with by some of the same people:

ftp://ftp.math.ucla.edu/pub/camreport/cam09-62.pdf

In this paper you will see reference to something called BM3D, which as far as I can tell is the academics' name for MVTools' MVDegrain (or MVTools2's MDegrain).

The principle of the hybrid approach is to use BM3D where "registration" is achieved (i.e. motion compensation meets a threshold of suitability) and to use NLM where registration fails.

I normally use FizzKiller, which is a variation of MDegrain using a calmed clip for analysis:

http://forum.doom9.org/showthread.php?t=133977

but I'm looking for something faster, so I decided to implement temporal NLM.

I should update the FizzKiller script I posted in that thread (post 23) as I tweaked it a bit. Overall, FizzKiller is awesome.

Jawed
19th January 2011, 11:42
Nice one, ill give it a try.
Is ati HD5750 compatible ? I have ati stream installed/enabled.


edit: I gues it's compatible, i loaded the default settings, and it works...(just for previewing the filtered video.. cpu load is only 20%, GPU 50% load), now i have to try to tweak the settings and see the effect.
Thanks Jawed
Nice, thanks. Glad to hear it works somewhere else!

I'm working on linear correction, a post-filtering step, to improve detail retention. This improves the result while allowing stronger de-noising, so I will post an updated version of Deathray soon.

I recommend temporal rather than spatial - use 2 or 3 for the radius. I prefer low sigma, i.e. <=1. h varies with material.

With sigma set to ~0.7 you are effectively using a 5x5 kernel - the outer ring of 24 pixels in each 7x7-pixel window is effectively weighted "0" (all 24 of these pixels have a total weighting of 4%). The search area is still 7x7 (i.e. 49 windows), but the smaller kernel is "sharper".

I may implement a native 5x5 variant of Deathray to make it go faster, since I think temporal is more useful than spatial.

I also need to understand how to make arguments for a plug-in optional (this is my first plug-in). Argument handling is very clumsy. Any help on that would be appreciated.

Gavino
19th January 2011, 12:28
I also need to understand how to make arguments for a plug-in optional
Simply add the argument name in square brackets in the call to env->AddFunction, and supply a default value when you extract the value using AsInt etc.

For an example, see http://avisynth.org/mediawiki/Filter_SDK/Simple_sample_1.3a.

Jawed
19th January 2011, 12:45
Thanks, this is how I setup Deathray:

env->AddFunction("deathray", "c[hY]f[hUV]f[tY]i[tUV]i[s]f[x]i", CreateDeathray, 0);

Then I have:

AVSValue __cdecl CreateDeathray(AVSValue args, void *user_data, IScriptEnvironment *env) {

double h_Y = args[1].AsFloat(1.);
if (h_Y < 0.) h_Y = 0.;

double h_UV = args[2].AsFloat(1.);
if (h_UV < 0.) h_UV = 0.;

int temporal_radius_Y = args[3].AsInt(0);
if (temporal_radius_Y < 0) temporal_radius_Y = 0;
if (temporal_radius_Y > 64) temporal_radius_Y = 64;

int temporal_radius_UV = args[4].AsInt(0);
if (temporal_radius_UV < 0) temporal_radius_UV = 0;
if (temporal_radius_UV > 64) temporal_radius_UV = 64;

double sigma = args[5].AsFloat(1.);
if (sigma < 0.1) sigma = 0.1;

int sample_expand = args[6].AsInt(1);
if (sample_expand <= 0) sample_expand = 1;
if (sample_expand > 14) sample_expand = 14;

return new deathray(args[0].AsClip(),
h_Y,
h_UV,
temporal_radius_Y,
temporal_radius_UV,
sigma,
sample_expand,
env);
}

If I do this:

deathray(hY=2)

it works fine. If, instead, I try this:

deathray(hy=2,1)

It fails. But now I think about it, I think that's not valid Avisynth function call syntax - you can't mix named and un-named paramters. Sigh, addled by C++...

Didée
19th January 2011, 12:59
The principle of the hybrid approach is to use BM3D where "registration" is achieved (i.e. motion compensation meets a threshold of suitability) and to use NLM where registration fails.
To the experienced Avisynth users around here, this is kind of boring, isn't it? :rolleyes:

There's a bunch of scripts that do exactly this kind of "hybrid" filtering ... several by *mp4guy, one or two by me ...
Here (http://forum.doom9.org/showthread.php?p=1087049#post1087049) is one with a short explanation of the principle, 3 years old. And I definetly know my first mentioning of that problem/solution has been years before that already.

Jawed
19th January 2011, 13:28
To the experienced Avisynth users around here, this is kind of boring, isn't it? :rolleyes:
:D Of course. I didn't suggest it was novel, did I?

There's a bunch of scripts that do exactly this kind of "hybrid" filtering ... several by *mp4guy, one or two by me ...
Here (http://forum.doom9.org/showthread.php?p=1087049#post1087049) is one with a short explanation of the principle, 3 years old. And I definetly know my first mentioning of that problem/solution has been years before that already.
Yes, I made FizzKiller based on the calm-clip idea.

Has anyone built a hybrid of NLM and MDegrain?

I've been thinking about trying Deathray to generate the calm clip for FizzKiller...

ChaosKing
19th January 2011, 17:45
I get an error: "Error in OpenCl status=1 frame 0"
My graphics card is a Nvidia 260GTX.
Win7 x64

Jawed
19th January 2011, 18:46
That seems to be a compilation error. Or it could be that the code is too complex (which behaves like a compilation error).

I presume you have OpenCL working on your system?

As you can probably tell I don't have any NVidia cards to test with so it's something I can only do remotely with others' help.

If you or others are prepared to "mess about", I can try to diagnose the issue with tailored versions of the DLL (which might not do any filtering, but would verify basic capability).

I'm also planning on a change in architecture (which should improve performance), which has the side-effect of reducing complexity, making the code more likely to work on NVidia. But that's a few days away at least.

I'd be interested in results with NVidia 400 or 500 series as the code's complexity is theoretically less of a problem there.

(The complexity issue is to do with registers. The code uses an extremely high register allocation on ATI, and likely similar on NVidia. NVidia prefers lower register allocations, but 400/500 series should be fine. My planned changes include a reduction in register allocation.)

Did you try Deathray with all default values? i.e. use:

Deathray()

It may also be worth trying

Deathray(hUV=0)

but I'm doubtful that will work if the default version doesn't work.

If you'd like to try some diagnosis, try this version of Deathray:

www.cupidity.f9.co.uk/DeathrayNV110119001.zip

Delete the Deathray DLL that is installed in your plugins folder and put this version of Deathray in there. This version of Deathray merely passes through the frame, with default settings. (It will do something else, not sure what, if you turn on temporal filtering.) Make sure to test with no parameters, please.

I've also increased the detail on the error status message. That might provide some insight.

ChaosKing
19th January 2011, 19:49
Yep, OpenCL is working on my system. The NLMeansCL (http://forum.doom9.org/showthread.php?t=158925) filter works on my system for example ^^

hUV=0 makes no difference

your Debug version of Deathray gives me: "Error in OpenCL status=11 frame=0 and OpenCl status= -30"

Hope this values can help you :)

Jawed
19th January 2011, 21:04
Thanks. That means it is having trouble finding devices. Which is definitely not what I was expecting.

Do you have the AMD OpenCL installed on your computer, in addition to NVidia OpenCL? I'm wondering if it finds the AMD OpenCL first, but there's no GPUs. So then fails. But the status you're getting doesn't seem to correspond with that, there's a different error for that situation.

The OpenCL error is more mysterious, "invalid value"...

If you'd like to help some more, this will tell me which OpenCL call is failing:

www.cupidity.f9.co.uk/DeathrayNV110119002.zip

EDIT: corrected, should be fine now

Didée
19th January 2011, 21:48
With this one, it is

"Error reading source frame 0: Avisynth read error: Deathray: Error in OpenCL status=11 frame 0 and OpenCL status=-30"

Jawed
19th January 2011, 22:08
Thanks, that's really peculiar. It's asking for the number of devices and seemingly responding that asking for the number of devices is invalid.

This is going to be tedious.

OK this test version doesn't ask for the device count (eventually Deathray will support multiple cards :p ), it assumes there's 1 device:

www.cupidity.f9.co.uk/DeathrayNV110119003.zip

Fingers-crossed.

Didée
19th January 2011, 23:19
Different message now:

"Error reading source frame 0: Avisynth read error: Single-frame initialisation failed, status=1"


However, note I'm not running the latest NV driver for my GT240, it's one or two revisions behind.
Reports from people running the most recent drivers could be more interesting.
Or, perhaps the GT240 is simply "too small" ?

ChaosKing
19th January 2011, 23:56
I get exactly the same messages as Didée, both new versions tested.
And no, there is no trace of an AMD driver on my system ^^"

Maybe this information can help?
===================================================
GPU Caps Viewer v1.9.5
http://www.ozone3d.net/gpu_caps_viewer/
===================================================


===================================[ System / CPU ]
- CPU Name: Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
- CPU Core Speed: 2833 MHz
- CPU Num Cores: 4
- Family: 6 - Model: 7 - Stepping: 10
- Physical Memory Size: 4095 MB
- Operating System: Windows 7 64-bit build 7600 [No Service Pack]
- DirectX Version: 10.0
- PhysX Version: 9100514


===================================[ Graphics Adapter / GPU ]
- SLI: disabled
- GPUs: 1
- Logical GPUs: 1
- OpenGL Renderer: GeForce GTX 260/PCI/SSE2
- Drivers Renderer: NVIDIA GeForce GTX 260
- DB Renderer: NVIDIA GeForce GTX 260
- Device Description: NVIDIA GeForce GTX 260
- Adapter String: GeForce GTX 260
- Vendor: NVIDIA Corporation
- Vendor ID: 0x10DE
- Device ID: 0x05E2
- Sub device ID: 0x1109
- Sub vendor ID: 0x19DA
- Drivers Version: 8.17.12.6099 (10-16-2010) - nvoglv64
- GPU Codename: GT200
- GPU Unified Shader Processors: 192
- GPU Vertex Shader Processors: 0
- GPU Pixel Shader Processors: 0
- SM / SIMD: 24
- TPC: 8
- TPD (Watts): 182
- Video Memory Size: 896 MB
- Video Memory Type: GDDR3
- Clocks level #0: Core: 300MHz - Memory: 100MHz - Shader: 600MHz
- Clocks level #1: Core: 400MHz - Memory: 300MHz - Shader: 800MHz
- Clocks level #2: Core: 576MHz - Memory: 999MHz - Shader: 1242MHz
- BIOS String: 62.0.61.0.0
- Current Display Mode: 1280x1024 @ 60 Hz - 32 bpp


===================================[ OpenGL GPU Capabilities ]
- OpenGL Version: 3.3.0
- GLSL (OpenGL Shading Language) Version: 3.30 NVIDIA via Cg compiler
- ARB Texture Units: 4
- Vertex Shader Texture Units: 32
- Pixel Shader Texture Units: 32
- Geometry Shader Texture Units: 32
- Max Texture Size: 8192x8192
- Max Anisotropic Filtering Value: X16.0
- Max Point Sprite Size: 63.4
- Max Dynamic Lights: 8
- Max Viewport Size: 8192x8192
- Max Vertex Uniform Components: 4096
- Max Fragment Uniform Components: 2048
- Max Geometry Uniform Components: 2048
- Max Varying Float: 60
- Max Vertex Bindable Uniforms: 12
- Max Fragment Bindable Uniforms: 12
- Max Geometry Bindable Uniforms: 12
- Frame Buffer Objects (FBO) Support:[yes]
- Multiple Render Targets / Max draw buffers: 8
- Pixel Buffer Objects (PBO) Support:[yes]
- S3TC Texture Compression Support:[yes]
- ATI 3Dc Texture Compression Support:[no]
- Texture Rectangle Support:[yes]
- Floating Point Textures Support:[yes]
- MSAA: 2X
- MSAA: 4X
- MSAA: 8X
- MSAA: 16X
- OpenGL Extensions: 221 extensions (GL=199 and WGL=22)
<li>GL_ARB_blend_func_extended</li>
<li>GL_ARB_color_buffer_float</li>
<li>GL_ARB_compatibility</li>
<li>GL_ARB_copy_buffer</li>
<li>GL_ARB_debug_output</li>
<li>GL_ARB_depth_buffer_float</li>
<li>GL_ARB_depth_clamp</li>
<li>GL_ARB_depth_texture</li>
<li>GL_ARB_draw_buffers</li>
<li>GL_ARB_draw_elements_base_vertex</li>
<li>GL_ARB_draw_instanced</li>
<li>GL_ARB_ES2_compatibility</li>
<li>GL_ARB_explicit_attrib_location</li>
<li>GL_ARB_fragment_coord_conventions</li>
<li>GL_ARB_fragment_program</li>
<li>GL_ARB_fragment_program_shadow</li>
<li>GL_ARB_fragment_shader</li>
<li>GL_ARB_framebuffer_object</li>
<li>GL_ARB_framebuffer_sRGB</li>
<li>GL_ARB_geometry_shader4</li>
<li>GL_ARB_get_program_binary</li>
<li>GL_ARB_half_float_pixel</li>
<li>GL_ARB_half_float_vertex</li>
<li>GL_ARB_imaging</li>
<li>GL_ARB_instanced_arrays</li>
<li>GL_ARB_map_buffer_range</li>
<li>GL_ARB_multisample</li>
<li>GL_ARB_multitexture</li>
<li>GL_ARB_occlusion_query</li>
<li>GL_ARB_occlusion_query2</li>
<li>GL_ARB_pixel_buffer_object</li>
<li>GL_ARB_point_parameters</li>
<li>GL_ARB_point_sprite</li>
<li>GL_ARB_provoking_vertex</li>
<li>GL_ARB_robustness</li>
<li>GL_ARB_sampler_objects</li>
<li>GL_ARB_seamless_cube_map</li>
<li>GL_ARB_separate_shader_objects</li>
<li>GL_ARB_shader_bit_encoding</li>
<li>GL_ARB_shader_objects</li>
<li>GL_ARB_shading_language_100</li>
<li>GL_ARB_shadow</li>
<li>GL_ARB_sync</li>
<li>GL_ARB_texture_border_clamp</li>
<li>GL_ARB_texture_buffer_object</li>
<li>GL_ARB_texture_compression</li>
<li>GL_ARB_texture_compression_rgtc</li>
<li>GL_ARB_texture_cube_map</li>
<li>GL_ARB_texture_env_add</li>
<li>GL_ARB_texture_env_combine</li>
<li>GL_ARB_texture_env_crossbar</li>
<li>GL_ARB_texture_env_dot3</li>
<li>GL_ARB_texture_float</li>
<li>GL_ARB_texture_mirrored_repeat</li>
<li>GL_ARB_texture_multisample</li>
<li>GL_ARB_texture_non_power_of_two</li>
<li>GL_ARB_texture_rectangle</li>
<li>GL_ARB_texture_rg</li>
<li>GL_ARB_texture_rgb10_a2ui</li>
<li>GL_ARB_texture_swizzle</li>
<li>GL_ARB_timer_query</li>
<li>GL_ARB_transform_feedback2</li>
<li>GL_ARB_transpose_matrix</li>
<li>GL_ARB_uniform_buffer_object</li>
<li>GL_ARB_vertex_array_bgra</li>
<li>GL_ARB_vertex_array_object</li>
<li>GL_ARB_vertex_buffer_object</li>
<li>GL_ARB_vertex_program</li>
<li>GL_ARB_vertex_shader</li>
<li>GL_ARB_vertex_type_2_10_10_10_rev</li>
<li>GL_ARB_viewport_array</li>
<li>GL_ARB_window_pos</li>
<li>GL_ATI_draw_buffers</li>
<li>GL_ATI_texture_float</li>
<li>GL_ATI_texture_mirror_once</li>
<li>GL_S3_s3tc</li>
<li>GL_EXT_texture_env_add</li>
<li>GL_EXT_abgr</li>
<li>GL_EXT_bgra</li>
<li>GL_EXT_bindable_uniform</li>
<li>GL_EXT_blend_color</li>
<li>GL_EXT_blend_equation_separate</li>
<li>GL_EXT_blend_func_separate</li>
<li>GL_EXT_blend_minmax</li>
<li>GL_EXT_blend_subtract</li>
<li>GL_EXT_compiled_vertex_array</li>
<li>GL_EXT_Cg_shader</li>
<li>GL_EXT_depth_bounds_test</li>
<li>GL_EXT_direct_state_access</li>
<li>GL_EXT_draw_buffers2</li>
<li>GL_EXT_draw_instanced</li>
<li>GL_EXT_draw_range_elements</li>
<li>GL_EXT_fog_coord</li>
<li>GL_EXT_framebuffer_blit</li>
<li>GL_EXT_framebuffer_multisample</li>
<li>GL_EXTX_framebuffer_mixed_formats</li>
<li>GL_EXT_framebuffer_object</li>
<li>GL_EXT_framebuffer_sRGB</li>
<li>GL_EXT_geometry_shader4</li>
<li>GL_EXT_gpu_program_parameters</li>
<li>GL_EXT_gpu_shader4</li>
<li>GL_EXT_multi_draw_arrays</li>
<li>GL_EXT_packed_depth_stencil</li>
<li>GL_EXT_packed_float</li>
<li>GL_EXT_packed_pixels</li>
<li>GL_EXT_pixel_buffer_object</li>
<li>GL_EXT_point_parameters</li>
<li>GL_EXT_provoking_vertex</li>
<li>GL_EXT_rescale_normal</li>
<li>GL_EXT_secondary_color</li>
<li>GL_EXT_separate_shader_objects</li>
<li>GL_EXT_separate_specular_color</li>
<li>GL_EXT_shadow_funcs</li>
<li>GL_EXT_stencil_two_side</li>
<li>GL_EXT_stencil_wrap</li>
<li>GL_EXT_texture3D</li>
<li>GL_EXT_texture_array</li>
<li>GL_EXT_texture_buffer_object</li>
<li>GL_EXT_texture_compression_latc</li>
<li>GL_EXT_texture_compression_rgtc</li>
<li>GL_EXT_texture_compression_s3tc</li>
<li>GL_EXT_texture_cube_map</li>
<li>GL_EXT_texture_edge_clamp</li>
<li>GL_EXT_texture_env_combine</li>
<li>GL_EXT_texture_env_dot3</li>
<li>GL_EXT_texture_filter_anisotropic</li>
<li>GL_EXT_texture_integer</li>
<li>GL_EXT_texture_lod</li>
<li>GL_EXT_texture_lod_bias</li>
<li>GL_EXT_texture_mirror_clamp</li>
<li>GL_EXT_texture_object</li>
<li>GL_EXT_texture_shared_exponent</li>
<li>GL_EXT_texture_sRGB</li>
<li>GL_EXT_texture_swizzle</li>
<li>GL_EXT_timer_query</li>
<li>GL_EXT_transform_feedback2</li>
<li>GL_EXT_vertex_array</li>
<li>GL_EXT_vertex_array_bgra</li>
<li>GL_IBM_rasterpos_clip</li>
<li>GL_IBM_texture_mirrored_repeat</li>
<li>GL_KTX_buffer_region</li>
<li>GL_NV_blend_square</li>
<li>GL_NV_conditional_render</li>
<li>GL_NV_copy_depth_to_color</li>
<li>GL_NV_copy_image</li>
<li>GL_NV_depth_buffer_float</li>
<li>GL_NV_depth_clamp</li>
<li>GL_NV_explicit_multisample</li>
<li>GL_NV_fence</li>
<li>GL_NV_float_buffer</li>
<li>GL_NV_fog_distance</li>
<li>GL_NV_fragment_program</li>
<li>GL_NV_fragment_program_option</li>
<li>GL_NV_fragment_program2</li>
<li>GL_NV_framebuffer_multisample_coverage</li>
<li>GL_NV_geometry_shader4</li>
<li>GL_NV_gpu_program4</li>
<li>GL_NV_half_float</li>
<li>GL_NV_light_max_exponent</li>
<li>GL_NV_multisample_coverage</li>
<li>GL_NV_multisample_filter_hint</li>
<li>GL_NV_occlusion_query</li>
<li>GL_NV_packed_depth_stencil</li>
<li>GL_NV_parameter_buffer_object</li>
<li>GL_NV_parameter_buffer_object2</li>
<li>GL_NV_pixel_data_range</li>
<li>GL_NV_point_sprite</li>
<li>GL_NV_primitive_restart</li>
<li>GL_NV_register_combiners</li>
<li>GL_NV_register_combiners2</li>
<li>GL_NV_shader_buffer_load</li>
<li>GL_NV_texgen_reflection</li>
<li>GL_NV_texture_barrier</li>
<li>GL_NV_texture_compression_vtc</li>
<li>GL_NV_texture_env_combine4</li>
<li>GL_NV_texture_expand_normal</li>
<li>GL_NV_texture_multisample</li>
<li>GL_NV_texture_rectangle</li>
<li>GL_NV_texture_shader</li>
<li>GL_NV_texture_shader2</li>
<li>GL_NV_texture_shader3</li>
<li>GL_NV_transform_feedback</li>
<li>GL_NV_transform_feedback2</li>
<li>GL_NV_vertex_array_range</li>
<li>GL_NV_vertex_array_range2</li>
<li>GL_NV_vertex_buffer_unified_memory</li>
<li>GL_NV_vertex_program</li>
<li>GL_NV_vertex_program1_1</li>
<li>GL_NV_vertex_program2</li>
<li>GL_NV_vertex_program2_option</li>
<li>GL_NV_vertex_program3</li>
<li>GL_NVX_conditional_render</li>
<li>GL_NVX_gpu_memory_info</li>
<li>GL_SGIS_generate_mipmap</li>
<li>GL_SGIS_texture_lod</li>
<li>GL_SGIX_depth_texture</li>
<li>GL_SGIX_shadow</li>
<li>GL_SUN_slice_accum</li>
<li>GL_WIN_swap_hint</li>
<li>WGL_EXT_swap_control</li>
<li>WGL_ARB_buffer_region</li>
<li>WGL_ARB_create_context</li>
<li>WGL_ARB_create_context_profile</li>
<li>WGL_ARB_create_context_robustness</li>
<li>WGL_ARB_extensions_string</li>
<li>WGL_ARB_make_current_read</li>
<li>WGL_ARB_multisample</li>
<li>WGL_ARB_pbuffer</li>
<li>WGL_ARB_pixel_format</li>
<li>WGL_ARB_pixel_format_float</li>
<li>WGL_ARB_render_texture</li>
<li>WGL_ATI_pixel_format_float</li>
<li>WGL_EXT_create_context_es2_profile</li>
<li>WGL_EXT_extensions_string</li>
<li>WGL_EXT_framebuffer_sRGB</li>
<li>WGL_EXT_pixel_format_packed_float</li>
<li>WGL_NVX_DX_interop</li>
<li>WGL_NV_float_buffer</li>
<li>WGL_NV_multisample_coverage</li>
<li>WGL_NV_render_depth_texture</li>
<li>WGL_NV_render_texture_rectangle</li>


===================================[ NVIDIA CUDA Capabilities ]
- CUDA Device 0
- Device name: GeForce GTX 260
- Compute Capability: 1.3
- Total Memory: 877 MB
- Shader Clock Rate: 1242 MHz
- Multiprocessors: 24
- Warp Size: 32
- Max Threads Per Block: 512
- Threads Per Block: 512 x 512 x 64
- Grid Size: 65535 x 65535 x 1
- Registers Per Block: 16384
- Texture Alignment: 256 byte
- Total Constant Memory: 64 Kb


===================================[ OpenCL Capabilities ]
- Num OpenCL platforms: 1
- Name: NVIDIA CUDA
- Version: OpenCL 1.0 CUDA 3.2.1
- Profile: FULL_PROFILE
- Vendor: NVIDIA Corporation
- Num devices: 1

- CL_DEVICE_NAME: GeForce GTX 260
- CL_DEVICE_VENDOR: NVIDIA Corporation
- CL_DRIVER_VERSION: 260.99
- CL_DEVICE_PROFILE: FULL_PROFILE
- CL_DEVICE_VERSION: OpenCL 1.0 CUDA
- CL_DEVICE_TYPE: GPU
- CL_DEVICE_VENDOR_ID: 0x10DE
- CL_DEVICE_MAX_COMPUTE_UNITS: 24
- CL_DEVICE_MAX_CLOCK_FREQUENCY: 1242MHz
- CL_NV_DEVICE_COMPUTE_CAPABILITY_MAJOR: 1
- CL_NV_DEVICE_COMPUTE_CAPABILITY_MINOR: 3
- CL_NV_DEVICE_REGISTERS_PER_BLOCK: 16384
- CL_NV_DEVICE_WARP_SIZE: 32
- CL_NV_DEVICE_GPU_OVERLAP: 1
- CL_NV_DEVICE_KERNEL_EXEC_TIMEOUT: 1
- CL_NV_DEVICE_INTEGRATED_MEMORY: 0
- CL_DEVICE_ADDRESS_BITS: 32
- CL_DEVICE_MAX_MEM_ALLOC_SIZE: 224608KB
- CL_DEVICE_GLOBAL_MEM_SIZE: 877MB
- CL_DEVICE_MAX_PARAMETER_SIZE: 4352
- CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: 0 Bytes
- CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: 0KB
- CL_DEVICE_ERROR_CORRECTION_SUPPORT: NO
- CL_DEVICE_LOCAL_MEM_TYPE: Local (scratchpad)
- CL_DEVICE_LOCAL_MEM_SIZE: 16KB
- CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: 64KB
- CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: 3
- CL_DEVICE_MAX_WORK_ITEM_SIZES: [512 ; 512 ; 64]
- CL_DEVICE_MAX_WORK_GROUP_SIZE: 512
- CL_EXEC_NATIVE_KERNEL: 4751356
- CL_DEVICE_IMAGE_SUPPORT: YES
- CL_DEVICE_MAX_READ_IMAGE_ARGS: 128
- CL_DEVICE_MAX_WRITE_IMAGE_ARGS: 8
- CL_DEVICE_IMAGE2D_MAX_WIDTH: 4096
- CL_DEVICE_IMAGE2D_MAX_HEIGHT: 32768
- CL_DEVICE_IMAGE3D_MAX_WIDTH: 2048
- CL_DEVICE_IMAGE3D_MAX_HEIGHT: 2048
- CL_DEVICE_IMAGE3D_MAX_DEPTH: 16
- CL_DEVICE_MAX_SAMPLERS: 16
- CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: 1
- CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: 1
- CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: 1
- CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: 1
- CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: 1
- CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: 1
- CL_DEVICE_EXTENSIONS: 16
- Extensions:
- cl_khr_byte_addressable_store
- cl_khr_icd
- cl_khr_gl_sharing
- cl_nv_d3d9_sharing
- cl_nv_d3d10_sharing
- cl_khr_d3d10_sharing
- cl_nv_d3d11_sharing
- cl_nv_compiler_options
- cl_nv_device_attribute_query
- cl_nv_pragma_unroll
-
- cl_khr_global_int32_base_atomics
- cl_khr_global_int32_extended_atomics
- cl_khr_local_int32_base_atomics
- cl_khr_local_int32_extended_atomics
- cl_khr_fp64


===================================[ Misc. ]


===================================[ Related Graphics Drivers ]
- http://www.geeks3d.com/?page_id=752
- http://downloads.guru3d.com/download.php?id=10
- http://www.tweakguides.com/NVFORCE_1.html
- http://www.nvidia.com/object/winxp-2k_archive.html
- http://www.geeks3d.com/?p=65


===================================[ Related Graphics Cards Reviews ]
- http://www.geeks3d.com/?tag=geforce-gtx-260
- http://www.google.us/search?q=NVIDIA+GeForce+GTX+260+review

TheProfileth
19th January 2011, 23:57
Will give this a look see in a bit.
Edit:
I tried the normal version and the 3 fixed versions in avspmod
I got this for the normal
Traceback (most recent call last):
File "AvsP.pyo", line 5813, in OnMenuVideoRefresh
File "AvsP.pyo", line 8950, in ShowVideoFrame
File "AvsP.pyo", line 9492, in PaintAVIFrame
File "pyavs.pyo", line 322, in DrawFrame
File "pyavs.pyo", line 306, in _GetFrame
File "avisynth.pyo", line 309, in GetPitch
ValueError: NULL pointer access

I got this for the first fixed
Traceback (most recent call last):
File "AvsP.pyo", line 5813, in OnMenuVideoRefresh
File "AvsP.pyo", line 8950, in ShowVideoFrame
File "AvsP.pyo", line 9492, in PaintAVIFrame
File "pyavs.pyo", line 322, in DrawFrame
File "pyavs.pyo", line 306, in _GetFrame
File "avisynth.pyo", line 309, in GetPitch
ValueError: NULL pointer access

and this for the second and third
Traceback (most recent call last):
File "AvsP.pyo", line 6281, in OnButtonTextKillFocus
File "AvsP.pyo", line 8950, in ShowVideoFrame
File "AvsP.pyo", line 9492, in PaintAVIFrame
File "pyavs.pyo", line 322, in DrawFrame
File "pyavs.pyo", line 306, in _GetFrame
File "avisynth.pyo", line 309, in GetPitch
ValueError: NULL pointer access
Traceback (most recent call last):
File "AvsP.pyo", line 7147, in OnPaintVideoWindow
File "AvsP.pyo", line 9492, in PaintAVIFrame
File "pyavs.pyo", line 322, in DrawFrame
File "pyavs.pyo", line 306, in _GetFrame
File "avisynth.pyo", line 309, in GetPitch
ValueError: NULL pointer access

Really want to test this filter out, so I will hope you fix it soon
also I am able to get nlmeanscl to run fine on my computer, I have a GTX 260 and a AMD Phenom quad core

Jawed
20th January 2011, 00:38
Thanks Didée and ChaosKing. That means it's found the GPU and is now trying to create memory allocations and/or preparing the GPU code (kind of compilation).

From another forum (someone else's application) I've learnt there are (or at least, were) problems with NVidia's support for my use of a feature, which complicates things.

This is my last update for tonight:

www.cupidity.f9.co.uk/DeathrayNV110119004.zip

Yet more detail in error tracking. Though I'm pessimistic overall due to the problem I mentioned above.

Jawed
20th January 2011, 00:46
Really want to test this filter out, so I will hope you fix it soon
also I am able to get nlmeanscl to run fine on my computer, I have a GTX 260 and a AMD Phenom quad core
Thanks for your report.

I don't know why but AvsP has that trouble when Deathray throws an error message. Playing the script in MPC is fine, reporting the messages that the others have posted.

In my experience, sometimes that message is true, there really was a null pointer access. I just can't tell.

In SingleFrameInit Deathray has tried to create two buffers on the GPU, input and output, for each of the 3 planes - so 6 in total. It does this once when Deathray is loaded and re-uses them for each frame.

Jawed
20th January 2011, 01:43
Oh, I've just noticed from ChaosKing's capabilities dump that GTX260 is OpenCL 1.0.

I will have to research the differences between 1.0 and 1.1 to see if I've done something 1.1 that's causing problems for 1.0 cards. The obvious thing, the size of local memory, shouldn't be an issue. I'm allocating ~11KB of local memory out of the 16KB available on OpenCL 1.0 devices.

I'm doubtful this is the source of the problem, but...

Jawed
20th January 2011, 01:58
ARGH

I've just discovered that if the DLL is named Deathray.DLL it's OK, but if the DLL is named like the debug versions I provided earlier, it fails.

SIGH. I forgot that Deathray asks Windows for a handle to "Deathray.dll" as part of compilation. So this has wasted quite a bit of time. Sorry.

Versions 3 or 4 may actually work if the NV110119003/4 suffix is deleted. That's what I get for testing before renaming the file for distribution.

TheProfileth
20th January 2011, 02:19
ooh let me try :D
Edit:
damn, renaming it did not work by renaming them :(

Jawed
20th January 2011, 13:42
If someone can report the error status numbers from the 4th debug DLL I uploaded, that would be cool, thanks.

ChaosKing
20th January 2011, 15:37
debug v4: Single-Frame initialisation failed, status=6 and OpenCL status= -48
I also updated to the newest Nvidia driver, but it changed nothing.

Jawed
20th January 2011, 16:27
That error happens to correspond with the DLL filename being wrong, although of course it could be the real error.

Please make sure that the DLL is called deathray.dll and that there is only one deathray DLL in the plugins folder.

If that doesn't solve the problem, then I need to make an even simpler piece of code to test the OpenCL compilation.

ChaosKing
20th January 2011, 19:01
I tested both filenames (also deleted other deathray* dlls), same error :/

Jawed
20th January 2011, 19:29
Thanks very much for your patience.

OK, this version of Deathray will produce a file called Deathray.log. This file appears in the same folder as your Avisynth script.

This file contains the output from the OpenCL compiler, if an error occurs during compilation. If no error occurs, the file will have 0 bytes as its file size.

www.cupidity.f9.co.uk/DeathrayNV110120001.zip

If Deathray.log contains some text it would be useful if you can post the text here. Thanks.

ChaosKing
20th January 2011, 20:58
Here's my Debug Log:
<program source>:300:22: error: no matching function for call to 'max'
int2 sample_start = max(target - sample_radius, 3);
^~~
<built-in>:3696:26: note: candidate function
ulong16 __OVERLOADABLE__ max(ulong16, ulong16);
^
<built-in>:3695:25: note: candidate function
ulong8 __OVERLOADABLE__ max(ulong8, ulong8);
^
<built-in>:3694:25: note: candidate function
ulong4 __OVERLOADABLE__ max(ulong4, ulong4);
^
<built-in>:3690:25: note: candidate function
ulong2 __OVERLOADABLE__ max(ulong2, ulong2);
^
<built-in>:3689:25: note: candidate function
long16 __OVERLOADABLE__ max(long16, long16);
^
<built-in>:3688:24: note: candidate function
long8 __OVERLOADABLE__ max(long8, long8);
^
<built-in>:3687:24: note: candidate function
long4 __OVERLOADABLE__ max(long4, long4);
^
<built-in>:3683:24: note: candidate function
long2 __OVERLOADABLE__ max(long2, long2);
^
<built-in>:3682:25: note: candidate function
uint16 __OVERLOADABLE__ max(uint16, uint16);
^
<built-in>:3681:24: note: candidate function
uint8 __OVERLOADABLE__ max(uint8, uint8);
^
<built-in>:3680:24: note: candidate function
uint4 __OVERLOADABLE__ max(uint4, uint4);
^
<built-in>:3676:24: note: candidate function
uint2 __OVERLOADABLE__ max(uint2, uint2);
^
<built-in>:3675:24: note: candidate function
int16 __OVERLOADABLE__ max(int16, int16);
^
<built-in>:3674:23: note: candidate function
int8 __OVERLOADABLE__ max(int8, int8);
^
<built-in>:3673:23: note: candidate function
int4 __OVERLOADABLE__ max(int4, int4);
^
<built-in>:3669:23: note: candidate function
int2 __OVERLOADABLE__ max(int2, int2);
^
<built-in>:3668:27: note: candidate function
ushort16 __OVERLOADABLE__ max(ushort16, ushort16);
^
<built-in>:3667:26: note: candidate function
ushort8 __OVERLOADABLE__ max(ushort8, ushort8);
^
<built-in>:3666:26: note: candidate function
ushort4 __OVERLOADABLE__ max(ushort4, ushort4);
^
<built-in>:3662:26: note: candidate function
ushort2 __OVERLOADABLE__ max(ushort2, ushort2);
^
<built-in>:3661:26: note: candidate function
short16 __OVERLOADABLE__ max(short16, short16);
^
<built-in>:3660:25: note: candidate function
short8 __OVERLOADABLE__ max(short8, short8);
^
<built-in>:3659:25: note: candidate function
short4 __OVERLOADABLE__ max(short4, short4);
^
<built-in>:3655:25: note: candidate function
short2 __OVERLOADABLE__ max(short2, short2);
^
<built-in>:3654:26: note: candidate function
uchar16 __OVERLOADABLE__ max(uchar16, uchar16);
^
<built-in>:3653:25: note: candidate function
uchar8 __OVERLOADABLE__ max(uchar8, uchar8);
^
<built-in>:3652:25: note: candidate function
uchar4 __OVERLOADABLE__ max(uchar4, uchar4);
^
<built-in>:3648:25: note: candidate function
uchar2 __OVERLOADABLE__ max(uchar2, uchar2);
^
<built-in>:3647:25: note: candidate function
char16 __OVERLOADABLE__ max(char16, char16);
^
<built-in>:3646:24: note: candidate function
char8 __OVERLOADABLE__ max(char8, char8);
^
<built-in>:3645:24: note: candidate function
char4 __OVERLOADABLE__ max(char4, char4);
^
<built-in>:3641:24: note: candidate function
char2 __OVERLOADABLE__ max(char2, char2);
^
<built-in>:3640:27: note: candidate function
double16 __OVERLOADABLE__ max(double16, double16);
^
<built-in>:3639:26: note: candidate function
double8 __OVERLOADABLE__ max(double8, double8);
^
<built-in>:3638:26: note: candidate function
double4 __OVERLOADABLE__ max(double4, double4);
^
<built-in>:3634:26: note: candidate function
double2 __OVERLOADABLE__ max(double2, double2);
^
<built-in>:3633:26: note: candidate function
float16 __OVERLOADABLE__ max(float16, float16);
^
<built-in>:3632:25: note: candidate function
float8 __OVERLOADABLE__ max(float8, float8);
^
<built-in>:3631:25: note: candidate function
float4 __OVERLOADABLE__ max(float4, float4);
^
<built-in>:3627:25: note: candidate function
float2 __OVERLOADABLE__ max(float2, float2);
^
<built-in>:3474:27: note: candidate function
double16 __OVERLOADABLE__ max(double16 x, double y) ;
^
<built-in>:3473:27: note: candidate function
double8 __OVERLOADABLE__ max(double8 x, double y) ;
^
<built-in>:3472:27: note: candidate function
double4 __OVERLOADABLE__ max(double4 x, double y) ;
^
<built-in>:3468:27: note: candidate function
double2 __OVERLOADABLE__ max(double2 x, double y) ;
^
<built-in>:3458:26: note: candidate function
float16 __OVERLOADABLE__ max(float16 x, float y) ;
^
<built-in>:3457:26: note: candidate function
float8 __OVERLOADABLE__ max(float8 x, float y) ;
^
<built-in>:3456:26: note: candidate function
float4 __OVERLOADABLE__ max(float4 x, float y) ;
^
<built-in>:3452:26: note: candidate function
float2 __OVERLOADABLE__ max(float2 x, float y) ;
^
<built-in>:3449:24: note: candidate function
ulong __OVERLOADABLE__ max(ulong, ulong);
^
<built-in>:3448:23: note: candidate function
long __OVERLOADABLE__ max(long, long);
^
<built-in>:3447:23: note: candidate function
uint __OVERLOADABLE__ max(uint, uint);
^
<built-in>:3446:22: note: candidate function
int __OVERLOADABLE__ max(int, int);
^
<built-in>:3445:25: note: candidate function
ushort __OVERLOADABLE__ max(ushort, ushort);
^
<built-in>:3444:24: note: candidate function
short __OVERLOADABLE__ max(short, short);
^
<built-in>:3443:24: note: candidate function
uchar __OVERLOADABLE__ max(uchar, uchar);
^
<built-in>:3442:23: note: candidate function
char __OVERLOADABLE__ max(char, char);
^
<built-in>:3441:25: note: candidate function
double __OVERLOADABLE__ max(double, double);
^
<built-in>:3440:24: note: candidate function
float __OVERLOADABLE__ max(float, float);
^

Jawed
20th January 2011, 22:12
Ooh, that should be a simple fix. Fingers crossed it's the last thing.

First, try this:

www.cupidity.f9.co.uk/DeathrayNV110120002.zip

This contains a fix for the bug above. I think it's my fault, I think the AMD compiler is mistakenly accepting that line as valid.

If that works, then try this:

www.cupidity.f9.co.uk/DeathrayNV110120003.zip

It will actually filter the video instead of doing nothing to it. It will do spatial or temporal, so all the options are available. It also produces the log file, so let's hope that it's empty.

The filtering is different from version 1.00. This is an experimental linear correction. I don't think the math is correct though, so I'm still working on it. Despite that I prefer it to version 1.00...

TheProfileth
20th January 2011, 22:15
Will test now
Edit:
Woohoo it works!
time to take a look at this thing
Edit2:
Works pretty well, and retains decent details,
http://screenshotcomparison.com/comparison/21410
http://screenshotcomparison.com/comparison/21411
my only issue is that if something is surrounded by black, the area it sort of gets washed into it
the color sort of gets sucked out of those areas too
I wonder if there is a way to give things that border black areas more weight

Jawed
20th January 2011, 22:27
Yay. Thanks guys. Hope it works for you all.

I'll produce a proper version 1.01 tomorrow, probably.

ChaosKing
20th January 2011, 22:36
Yeah it works! :D
I get 28~ fps on my gtx260
I will play with the filter tomorrow.

Didée
20th January 2011, 22:39
Aaahh, waitaminute ...

With 110120003:

Avisynth read error:
"Single-frame initialisation failed, status=6 and OpenCL status=-48"

log:
:310: error: incompatible type initializing 'int', expected 'float4'
float4 euclidean_distance = 0;
^
:396: error: incompatible type initializing 'int', expected 'float4'
float4 average = 0;
^
:397: error: incompatible type initializing 'int', expected 'float4'
float4 weight = 0;
^

Jawed
20th January 2011, 22:53
Sigh, I'm normally over-zealous with zeroes.

Try this:

www.cupidity.f9.co.uk/DeathrayNV110120004.zip

Jawed
20th January 2011, 22:59
my only issue is that if something is surrounded by black, the area it sort of gets washed into it
the color sort of gets sucked out of those areas too
I wonder if there is a way to give things that border black areas more weight
Try more temporal, 2 or 3. Also don't be afraid to lower s (sigma) and increase h at the same time.

It's a bit tricky. Version 1.00 is a lot harder to use and inferior. As I say, I'm still working on the linear correction.

Didée
20th January 2011, 23:06
Hooray, that 110120004 finally works for me, too.

Jawed
20th January 2011, 23:14
Great.

Just need to get my brain around the variance of a single sample and get the linear correction working. Then ponder whether I want to attempt a first or second order regression correction. Gulp.

aNToK
21st January 2011, 08:52
Hi, read in the literature that this doesn't work with AMD 4xxx series, but wasn't clear whether that was the regular Radeon 4xxx series or the HD 4xxx series. Did you mean the HD ones as well?

Jawed
21st January 2011, 10:13
Yes, HD 4000 series. It doesn't support a workgroup size of 256. There's a way round this so there's a decent chance I'll make an additional path specifically for that series, when I do other changes I'm planning.

aNToK
21st January 2011, 12:12
I'll get around to upgrading the card one of these days but since I don't game much, haven't had the need.

Thanks for the reply and the possible future support.

bus_labi
21st January 2011, 22:24
Have a collection of DV home videos - quite a lot of it shot in low light conditions thus noisy. Over last few days extensively tested FFT3Dfilter with various setting to improve the videos.

Found about Deathray and was eager to test it, because had read promising things about NLM denoising.

For testing i wrote simple script that loops 100+ frames thru filter at different settings and outputs filtered video + video with original minus filtered image (contrast enlarged). This gives very good visual of what filter is doing without much pixel peeking. If filter removes only white noise, then only white noise appears in differential image. If there is some structure visible then either that area is not denoised or denoised more or some structure degradation is happening. I am testing only luma channel for now.

Win7 64bit, ATI Radeon HD57xx 1Gb RAM latest versions of Catalyst and Stream SDK installed yesterday. Today experimented with Deathray for an hour or so and not a single crash/problem.

Some observations (based on my noisy dark video sampe).

In low temporal settings - ty = 1,2 there are substantial areas which are not denoised at all. Going up to tY=5 improves, but there are still areas which are less denoised. FFT3DFilter is better in this respect, as there is much less structure in the noise removed. I tested deathray up to ty=5, hy=2 and s = 1.
I could not see difference between hy 1.5 and 2. Will go up from there later.
Deathray was removing about same amount of noise as FFT3Dfilter, but much differently - FFT removed noise was mostly high contrast pixels, where Deathray removed less contrasted pixels and left high contrast noise.
As result FFT3Dfilter produced smoother picture. Higher contrast gives effect of seemingly more detail in deathray'ed picture, but it is less pleasing to look at because of high contrast noise.
Neither of filters at reasonable settings take away any structure.
I noticed that FFT3 tends to denoise more areas which Deathray tends to avoid and tested FFT3 on deathrayed video. This produced most pleasing result as FFT3 removed high contrast pixels. Both filters seem somehow to complement each other. As of now i would not use Deathray alone because of the high contrast noise. On neither of filters i used extreme settings as i prefer some grain to complete smootheness.

I upload some screenshots, but static images do not really give a good impression - moving image is much better and informative. Here is simple script i use for testing.


fr = 100 # number of frames to be looped
sigma_start = 0.5 # start value for sigma range
sigma_incr = 0.1 # sigma increment
sigma_finish = 1.0 # end value for sigma range
hY_start = 2.0 # denoise strength luma
hY_finish = 2.0 # denoise strength luma
tY = 5 # temporal radius luma

c = DirectShowSource ("2001 03 229.avi", audio=false).viewfields.crop(0,0,-0,-288).trim (0,fr).grayscale.converttoyv12
gray = BlankClip(c, length=fr, color = $808080)
cf = BlankClip(c, 0)
co = BlankClip(c, length=0)
co = Stackvertical (co,co)

GScript ("""
while (hY_start <= hY_finish)
{
ssigma = sigma_start
while (ssigma <= sigma_finish)
{
if (FrameCount(cf) > 0) {NOP} else {cr = gray}
cf = deathray (c, hy = hY_start, huv = 0.0, ty = tY, s =ssigma)
cd = subtract (c, cf)
Stackvertical ( \
cf.Subtitle("sigma = " + String(ssigma) + "\n hY = " + String(hY_start)+ "\n tY = " + String(tY), align=6, lsp=0), \
cd.histogram(mode="luma").Subtitle("Difference original - filtered", align=9, lsp=0))
co = co + last
ssigma = ssigma + sigma_incr
}
hY_start = HY_start + 1 }
""")
return (co)

Jawed
22nd January 2011, 12:28
For testing i wrote simple script that loops 100+ frames thru filter at different settings and outputs filtered video + video with original minus filtered image (contrast enlarged).
Your automated parameters technique is nice.

This gives very good visual of what filter is doing without much pixel peeking. If filter removes only white noise, then only white noise appears in differential image. If there is some structure visible then either that area is not denoised or denoised more or some structure degradation is happening. I am testing only luma channel for now.
I've been doing something very similar, testing with the histogram("luma") technique or with a simple levels call to magnify the subtraction.

Though I've been doing it by hand, single stepping through clips and tweaking parameters. My reference filter, for what it's worth, is FizzKiller.

Have you evaluated motion-compensated MDegrain (from MVTools 2)? It's slow, but extremely good.

Obviously I also make encodes and watch them, too.

Win7 64bit, ATI Radeon HD57xx 1Gb RAM latest versions of Catalyst and Stream SDK installed yesterday. Today experimented with Deathray for an hour or so and not a single crash/problem.
There is a way to crash Deathray. I'm surprised your script hasn't caused it to crash, to be honest. I don't understand the reason for the crash and I can't reliably reproduce it. But repeatedly hand-tweaking Deathray parameters and single-frame stepping tends to crash it after a while, sometimes.

Some observations (based on my noisy dark video sampe).

In low temporal settings - ty = 1,2 there are substantial areas which are not denoised at all. Going up to tY=5 improves, but there are still areas which are less denoised. FFT3DFilter is better in this respect, as there is much less structure in the noise removed. I tested deathray up to ty=5, hy=2 and s = 1.
I find the "naked" NLM, which is what version 1.00 is, inadequate. This is the original algorithm, first described by Buades, Coll and Morel - with the caveat that the sampling region is limited, instead of being the entire image. (It turns out there's very little to be gained by sampling the entire image). Actually this algorithm is tweaked with a re-weighting for the target pixel that they described later.

It's too weak at settings that are required not to destroy fine detail.

The most recent "NVidia Debug" version contains a crude averaging with the original image. This is considerably better, but the averaging I'm using is not the averaging that is described here:

http://hal.archives-ouvertes.fr/docs/00/27/11/43/PDF/double_revised.pdf

I'm currently getting my head round that.

The NVidia Debug version (110120004) is preferable to 1.00.

I could not see difference between hy 1.5 and 2. Will go up from there later.
Ultimately, one has to balance the 3 key parameters, h, sigma and temporal-radius.

The sample-radius factor, x, is also useful, but has to be used with care (turn h up to 1000 and set x=3 to see what I'm talking about). A planned change to the filter incidentally makes x safer, though truthfully with sane values of h and s, x=2 or 3 is quite safe (and slow...).

I think temporal 5 is too strong.

I hope the regression correction I'm working on is worth it. It should require re-evaluation of settings...

Deathray was removing about same amount of noise as FFT3Dfilter, but much differently - FFT removed noise was mostly high contrast pixels, where Deathray removed less contrasted pixels and left high contrast noise.
As result FFT3Dfilter produced smoother picture. Higher contrast gives effect of seemingly more detail in deathray'ed picture, but it is less pleasing to look at because of high contrast noise.
Neither of filters at reasonable settings take away any structure.
I noticed that FFT3 tends to denoise more areas which Deathray tends to avoid and tested FFT3 on deathrayed video. This produced most pleasing result as FFT3 removed high contrast pixels. Both filters seem somehow to complement each other. As of now i would not use Deathray alone because of the high contrast noise. On neither of filters i used extreme settings as i prefer some grain to complete smootheness.
Make sure you try MVTools 2 techniques. You can also try motion-compensated FFT3DFilter and of course there's FFT3DGPU, which can also be motion-compensated.

Generally I would say don't rush and use lots of test clips.

---

A little sidenote on one aspect of the NVidia "problems". The problem with the max() function turns out to be a difference between OpenCL 1.0 and OpenCL 1.1.

jclampy
14th December 2011, 00:02
Hi, Would really like to try this filter out but the links are dead.

ChaosKing
14th December 2011, 00:09
Hi, Would really like to try this filter out but the links are dead

DL-Link (http://chaosking.de/wp-content/uploads/avsfilters/Denoisers/Spatio-Temporal_Denoisers/Deathray___(1.00_-_2011-01-17)_gpu.7z)

jclampy
14th December 2011, 00:40
Thankyou very much ChaosKing. ;)

Jawed
14th December 2011, 00:55
Does it work? I just made a long post that got lost :(

Jawed
14th December 2011, 01:02
Rather than try to recreate the post I just lost, I'll just briefly link this, which is DeathrayNV110120004.zip:

http://www.mediafire.com/?yyiaqbqp77h236p

This is just the DLL. It is a slightly different algorithm (which I think is better) and it solves the original problem with failure on NVidia.

This version of the DLL always creates a deathray.log file. If there are problems this file should help me help you.

I have a caveat: when I wrote this OpenCL code AMD's and NVidia's compilers were a little bit loose. I think they are stricter now and there's a chance this will not compile with recent drivers.

I didn't fix this issue due to a general lack of interest, so this may be more of an experiment than you wanted. Fingers-crossed!

EDIT: oh yeah, my website is down because my host took it down for going over the 250MB daily limit :(

xiulet
17th November 2012, 02:45
any news about this plugin? :O

thanks

Jawed
17th November 2012, 10:46
No news, dead due to lack of interest (mostly my lack of interest, it seems).

My lack of interest is due to the fact that I prefer the results from MDegrain.

My website is available. There are 3 files:

Deathray_1_00.zip - see post 1
Deathray_1_00_DLL.zip - see post 1
DeathrayNV110120004.zip - see post 36

Please note that the source code I've provided in post number 1 does not match the source code for post 36.

Please read the entire thread to learn how best to use this.

For the best quality I recommend DeathrayNV110120004.zip. This contains a tweaked algorithm (hence the improved quality) as well as a fix to ensure it works on NVidia. This DLL works with AMD, too. The downside with this version is that it creates a deathray.log file in the same folder as the Avisynth script.

I have no idea whether Deathray works with recent AMD or NVidia drivers. In theory the newest drivers will reject my code because they are more strict.

Obviously, anyone is welcome to play with the code.

xiulet
17th November 2012, 13:09
No news, dead due to lack of interest (mostly my lack of interest, it seems).

My lack of interest is due to the fact that I prefer the results from MDegrain.

My website is available. There are 3 files:

Deathray_1_00.zip - see post 1
Deathray_1_00_DLL.zip - see post 1
DeathrayNV110120004.zip - see post 36

Please note that the source code I've provided in post number 1 does not match the source code for post 36.

Please read the entire thread to learn how best to use this.

For the best quality I recommend DeathrayNV110120004.zip. This contains a tweaked algorithm (hence the improved quality) as well as a fix to ensure it works on NVidia. This DLL works with AMD, too. The downside with this version is that it creates a deathray.log file in the same folder as the Avisynth script.

I have no idea whether Deathray works with recent AMD or NVidia drivers. In theory the newest drivers will reject my code because they are more strict.

Obviously, anyone is welcome to play with the code.

ok thanks you for the info my friend :)

you mean MVTools+MDegrain...¿?

Keiyakusha
17th November 2012, 18:42
My lack of interest is due to the fact that I prefer the results from MDegrain.

So how about porting Mdegrain to gpu then? Porting motion search proved to be possible and if i'm not mistaken its opensource (since mvtools is opensource). But they had different purpose and ported only mflowfps(and renderer part of that is closed source). However they claim their motion search is better than original, which I so far can't see, unfortunately. So maybe it requires some tweaks.

Jawed
17th November 2012, 19:10
So how about porting Mdegrain to gpu then?
One of those things I just didn't get round to, and now behind other things.

I logged on to this forum today for the first time in quite a while and discovered VapourSynth.

Previous time I logged in, I discovered people are doing 10-bit encodes.

I'm out of touch.

Porting motion search proved to be possible and if i'm not mistaken its opensource (since mvtools is opensource). But they had different purpose and ported only mflowfps(and renderer part of that is closed source). However they claim their motion search is better than original, which I so far can't see, unfortunately. So maybe it requires some tweaks.
Even just downloading the code and setting up a development project is more effort than I want to get involved in, right now. Sorry.

Jawed
16th July 2013, 21:34
I've just realised I could make a git version of this:

Deathray on github.com (https://github.com/JawedAshraf/Deathray)

This is v1.00 without any of the bug fixes or improvements that I created during the debugging work done for NVidia users.

It's also for an ancient SDK.

It will definitely require work to get it working with latest drivers and/or SDKs.

---

And for those of you who understand Git branches, the branch called FindFixes is my attempt to identify the code that makes the DeathrayNV110120004 version.

lansing
24th August 2013, 05:30
i have a question.

I just brought a new nvidia graphic for encoding purposes, and when I did test on both deathray and nlmeanscl with avsmeter, the default nlmeanscl setting gave me 252fps with 70% gpu loaded, while deathray in default setting gave me 47fps and over 90% gpu loaded. It makes me wonder what's the difference between the two to have a huge different in speed like this?

Jawed
24th August 2013, 10:53
i have a question.

I just brought a new nvidia graphic for encoding purposes, and when I did test on both deathray and nlmeanscl with avsmeter, the default nlmeanscl setting gave me 252fps with 70% gpu loaded, while deathray in default setting gave me 47fps and over 90% gpu loaded.

Wow, it still works? I was expecting newer drivers to stop it working.

It makes me wonder what's the difference between the two to have a huge different in speed like this?
Looking at my notes, I see for 1920x798 video I had about 32fps on HD5870. This is "compute-limited", i.e. memory accesses have no impact on performance. For standard definition I had 122fps theoretical, but memory accesses meant that this was only about 25fps in practice, so I needed to watch 5 videos in parallel (in Media Player Classic) to get 100% GPU usage.

Alternatively a temporal radius of 2 would produce 100% GPU usage (tY=2, tUV=2) on standard definition clips.

Because I coded for AMD, it uses on-chip memory in a way that's potentially "unfriendly" towards NVidia. In other words I took advantage of the very large register capacity on AMD and I wouldn't be surprised if NVidia cards ran out of registers. The newest NVidia cards (Kepler) have much better register capacity, so in theory even if this was a problem a few years ago, it shouldn't be a problem for the latest NVidia cards.

Due to lack of interest, no performance comparisons were made between AMD and Nvidia, so I don't know if this is really true or not.

I don't know the size of the window in nlmeanscl. Deathray uses a 7x7 size, and the larger it is the more effort involved.

Also I don't know the search area in nlmeanscl. Deathray does not search the entire frame to get other 7x7 windows, it only searches near the pixel being filtered (it looks at 48 other 7x7 windows). Again, searching more of the frame is more effort. In fact searching the entire frame is counter-productive, it is better to search a limited area near the pixel being filtered.

I don't think there's much point in the nlmeans algorithm. It is only mildly useful when used with temporal settings and pretty much a waste of time without temporal settings. I prefer MDegrain, which is why I don't use Deathray.

Do you like the results of either Deathray or nlmeanscl?

Do you prefer it when you use temporal settings?

Have you used MDegrain?

lansing
24th August 2013, 16:07
mdegrain didn't fit my taste in which it manipulated the image too much. It's going to be either a hit or miss. On moving scene, sometime it gives a good result, and sometime it smooths out the original shape.

I'd did some test with this sample, i uploaded here:
sample (http://www.mediafire.com/download/nk5tbg5fo5stkcf/anime_low_light_thin_line_sample.264)

Both deathray and nlmeanscl pretty much gave the same result, except in some low light area with thin lines, deathray at default desaturated the color by a little.

This sample also gives the reason why i don't use mdegrain, notice the panning scene from 2-6 second, there're some spider webs across the screen. When i used smdegrain, it pretty much wiped out half of them. While deathray and nlmeanscl still preserved them.

well on the temporal side, smdegrain did a better job at calming the grains.

Jawed
24th August 2013, 21:56
I trimmed off the first frame, which is broken:

http://www.mediafire.com/download/0wn3l95nmiynrpf/anime_low_light_thin_line_sample_JA.mp4

I have to say I'm horrified that apparently recent anime can be such a disaster zone.

Jawed
28th August 2013, 20:21
Updated the first post with information on version 1.01. Please note that www.cupidity.f9.co.uk is not being maintained with source or DLL. All mirrors in this thread should be considered defunct.

lansing
4th September 2013, 00:44
Jawed, I replaced the 1.01 version and there's an error message saying that there's no such function.

Jawed
4th September 2013, 19:41
Make sure you are not running an encode or previewing an avisynth script in an editor such as AvsP at the time you delete the old Deathray.dll. After you've deleted the DLL refresh the explorer window to make sure that the Deathray.dll has really gone.

Then download the 1.01 DLL from the github page and copy to the Avisynth plugins folder.

I've just done those exact steps here and it works fine.

You might like to try a re-boot of your PC.

I can't think of anything else that could be causing your problem. Maybe someone else can report their experience?

lansing
4th September 2013, 21:52
i'm using the avisynth mt version in here (http://forum.doom9.org/showthread.php?t=148782)

version 1.00 works fine

Jawed
4th September 2013, 22:28
That's the version of avisynth I'm using :confused:

I have the avisynth DLL in two places on my system:

SysWOW64 - used by AvsP
MeGUI\tools\avs - used by MeGUI

---

When you say 1.0 works do you mean the NVidia NV110120004 version?

lansing
5th September 2013, 08:38
i don't know, the date of that deathray dll is 1/17/2011.

When i use the old one, avspmod recognized it, but when i replaced it with the new one, it said "there's no function name deathray"

Jawed
5th September 2013, 21:43
A friend helped me debug this and discovered that he is missing msvcp110.dll. And then msvcr110.dll.

In Virtualdub this is clearly shown as a sequence of two error messages. The first says that msvc*110.dll is missing. The second message says that Deathray is not a function.

AvsPmod on his system says "Deathray is not a function".

Sorry about that. I think I can recompile with an older runtime (90), but that will be a couple of hours at the earliest. I'm not 100% sure of that though.

Now I wonder if I can eliminate the runtime?

Morte66
5th September 2013, 22:09
A friend helped me debug this and discovered that he is missing msvcp110.dll. And then msvcr110.dll.

Those two DLLs are bundled with Lord Mulder's Simple x264 launcher, by the way. At least, that's where I found them.

Jawed
5th September 2013, 22:36
Please try:

Non-runtime DLL (https://github.com/JawedAshraf/Deathray/tree/v1_1_no_runtime)

and tell me if it works.

lansing
6th September 2013, 01:06
yes the new one is working now

Jawed
8th September 2013, 12:45
I have made version 1.1 compile to a non-runtime-required DLL. I have updated github (master and 1_1 branches) with the new DLL and I have removed the test branch 1_1_no_runtime.

Jawed
16th September 2013, 22:30
This new release is primarily aimed at de-noising more evenly across the tonal range.

Two new parameters, z and b control this.

z is more important and I would recommend it is set to true. It works best with temporal mode (tY > 0 and tUV > 0).

l is probably a waste of time, but feel free to play (it increases de-noising in shadows and reduces de-noising in highlights).

c defaults to true, which reproduces the behaviour of 1.01. I recommend using false when z and/or b are set to true.

A good set of parameters to start your experiments with:

hy=1,huv=0,tY=2,tuv=0,s=0.7,x=3,l=false,c=false,z=true,b=true

It's a bit slow though.

lansing
1st October 2013, 22:00
i played around with the new parameter, and the z parameter is giving me issues.

For my anime source, when i set z=true and hy less than 2, all the small white dots in the video were filled with black. When i set hy >= 2, everything is back to normal.

Jawed
1st October 2013, 22:14
Hi there, can you try the 1.3 branch that I have just released?

I discovered what I think is the same problem (though I had to use hY < 0.5 with z=true).

Are you happy to switch to the v1_3 branch on Github and download the DLL?

lansing
1st October 2013, 23:39
yes it's fixed, thanks.

I've also uploaded a sample video here for testing. It's an anime scene of flashing light with very heavy grain on top. So far I have no success with any denoiser except temporaldegrain.

http://www.mediafire.com/download/616tj9u8rd6av6t/flashing.mkv


EDIT: which one is the parameter to control the temporal strength, it seems like that the temporal denoise is doing very little effect to my source.

Jawed
2nd October 2013, 22:51
yes it's fixed, thanks.I'm glad to hear that works.

EDIT: which one is the parameter to control the temporal strength, it seems like that the temporal denoise is doing very little effect to my source.
The tY and tUV parameters control the count of frames. If you set tY to 3 then you get 3 frames before the current frame, 3 frames after it + the current frame. So that's 7 frames.

You can control colour temporal with tUV.

The hY setting works together with tY and hUV works with tUV.

As for your flashing clip, I doubt I can help much. The near-black nastiness is pretty horrible.

You might have more chance of help if you make a thread about it, rather than posting in this thread. Most people ignore this sub-forum. Presumably there are people on Doom9 who have some expertise in cleaning up this kind of noise on anime.

You might want to turn on L (linear), which will make denoising much stronger near black - this sounds contradictory to setting z=true and b=true - but I think the combination can work.

Try s = 0.7. And try x=2 or x=3. Try tY=1 or 2.

I don't think you have much choice but to spend a long time experimenting.

I'm still experimenting with new code for Deathray, so perhaps I'll have something more useful.

Jawed
9th December 2013, 19:40
lansing, I would like your opinion on these encodes of the videos you uploaded a while ago:

https://dl.dropboxusercontent.com/u/81074020/Vicious%20Deathray%20Alpha.zip

Encoding them is very slow, about 0.4fps, but I think it's worth it :)

lansing
9th December 2013, 21:43
they look pretty nice to me, the grain pattern after the denoise were distributed evenly. in comparison to before where there're grain of different sizes here and there.

Selur
9th January 2016, 09:23
Any one got a working binary?
Using the one from: https://github.com/JawedAshraf/Deathray/commit/17a6f0ba4499c411a31ea0bc3bfbb97fc7ed154d
and
LoadCPlugin("G:\Hybrid\avisynthPlugins\ffms2.dll")
LoadPlugin("G:\Hybrid\avisynthPlugins\Deathray.dll")
# loading source: F:\TestClips&Co\test.avi
FFVideoSource("F:\TESTCL~1\test.avi",cachefile="H:\Temp\avi_0197468a3716844ade54f3f30f60eeda_491.ffindex",fpsnum=25)
# denoising
Deathray()
return last
Ii just get:
Error reading source frame 0: Avisynth read error: Deathray: Copy Y to Device status = 7 and OpenCL status = -36'
in Virtual Dub. Am I missing something? (I'm on Windows 10 and an NVIDIA Geforce GTX 980 Ti)

Cu Selur

Jawed
9th January 2016, 10:54
-36 is Invalid command queue, an OpenCL error.

7 is FILTER_COPYING_TO_PLANE_FAILED

I don't know what your test clip looks like, but please make sure that the video frame size is at least 8x8 in size.

NVidia support for OpenCL has not been very good. You may have to try a variety of drivers to get one that works. I think NVidia has been making changes to OpenCL support in its drivers recently, in theory to make it better.

Alternatively, well there's a bug in my code. This binary works on my current AMD system with up-to-date drivers. But sometimes the way AMD and NVidia compile code can show that there are subtle errors in C++ or OpenCL code. Which would be my fault :confused:

Move to a later frame and try a preview again.

Also, instead of trying to preview the video in Virtual Dub, encode a short clip. Use TRIM(1000,2000) to make a 1001 frame clip on a line just before the return last. Then send the script to your encoder.

Also try the parameter:

colorspace="YV12"

in FFVideoSource. I actually use FFmpegSource2, so I'm not sure if that parameter works for FFVideoSource. The video you supply to Deathray must be in a planar format, such as YV12.

Selur
9th January 2016, 11:27
Trim, doesn't help, encoding (with x264/x264/vpxenc) doesn't work (that is why I switched to Virtual Dub to check if something is wrong ;)).
Input is a avi with 640x352 (Xvid, Yv12). -> Video format should be planar Yv12. (you can get the test.avi from my google drive (https://drive.google.com/folderview?id=0B_WxUS1XGCPASUZibG5XZkRfeTg&usp=sharing), but the problem happens with any clip I throw at Deathray,... tested multiple SD, HD and 4k sources to make sure it's not an resolution issue)
Adding 'ConvertToYv12' before Deathray() and/or adding 'colorspace="YV12" ' to the FFVideoSource call doesn't help either.
-> Some OpenCL incompatibility is probably the best guess.
Will try older drivers later (currently using latest version: 361.43)

Cu Selur

Groucho2004
9th January 2016, 12:28
This works for me:
colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio()
Deathray()


WinXPSP3
GTX750
Drivers: 350.12
OpenCL DLL: Khronos OpenCL ICD 1.2.11.0 (supplied with the driver)

Jawed
9th January 2016, 15:27
I've thought of another reason why this might not work with NVidia: Deathray requires OpenCL 1.1 including features that were marked for deletion in a future version.

NVidia's latest driver may have removed some or all of those 1.1 features that were marked for deletion (deprecated).

If that's true, then I would need to compile a newer version without those 1.1 features :(

Selur
9th January 2016, 16:06
"This works for me" -> doesn't work here, gives me the same error as any other source.

including features that were marked for deletion in a future version.
.. using depreciated option is always a bad idea ;)

Jawed
9th January 2016, 16:54
The deprecation occurred when OpenCL 1.2 was announced. After I'd written this software.

If both the driver and ICD versions reported by Groucho2004 fail to work on your 980Ti, then I'm afraid to say it prolly isn't deprecation that's caused the problem.

But it's impossible for me to rule that out, since NVidia might have decided to write software for Maxwell version 2 GPUs that deprecates 1.1, but Maxwell version 1 GPUs are using some other software.

If I fix deprecation it'll be when I have evidence of that being the case. And the fix will probably be in Deathray2 (not officially published but for those of you that can make Deathray work, google is your friend).

Selur
9th January 2016, 17:04
How can I check the ICD version that is installed with NVIDIA drivers, or should I install something from https://www.khronos.org/registry/cl/ manually?

Jawed
9th January 2016, 17:16
I'm afraid I don't know if it's safe for you to try to install another ICD. Hopefully Groucho2004 will be able to show you how to check your system configuration.

Or perhaps someone else who owns a GTX9xx card will be able to help, if their system works.

A couple more thoughts: do you have multiple GPUs in your computer? Do you have an Intel OpenCL driver installed?

Selur
9th January 2016, 17:31
Got an i7 4770k which comes with an HD 4600 and I didn't install any special OpenCL drivers,...
Installing latest drivers: https://downloadcenter.intel.com/download/25489/Intel-Graphics-Driver-for-Windows-10-15-40-4th-Gen- didn't help with Deathray.

Groucho2004
9th January 2016, 18:03
How can I check the ICD version that is installed with NVIDIA drivers
"%windir%\system32\opencl.dll" (or "%windir%\syswow64\opencl.dll") right-click on "Properties" -> "Version".

FYI - I had to manually copy the OpenCL.dll that comes with the driver to the system directory. It was the only way to get KNLMeansCL working. I don't know why the driver installer didn't overwrite the old version.

Jawed
9th January 2016, 18:21
Got an i7 4770k which comes with an HD 4600 and I didn't install any special OpenCL drivers,...
Installing latest drivers: https://downloadcenter.intel.com/download/25489/Intel-Graphics-Driver-for-Windows-10-15-40-4th-Gen- didn't help with Deathray.
This Intel driver, or the driver that this replaced, might be causing a problem.

I don't know if it is possible or safe to de-install the Intel driver. If the OpenCL component of the Intel driver is installed then it seems very likely that it is interfering (or that Deathray won't work it). Perhaps it's possible to install the Intel driver but not the OpenCL component?

Deathray asks the computer for the first GPU it can find, but only from the first OpenCL platform. The computer you are using almost certainly has both the Intel and NVidia OpenCL platforms available.

Is there a reason you have the Intel graphics driver installed?

(My CPU is AMD, so I only have a single OpenCL platform on my computer.)

Jawed
9th January 2016, 19:59
I have made a new test build of Deathray DLL:

https://github.com/JawedAshraf/Deathray/tree/Platform-Exclude-Intel

Try to download the new DLL and see what happens.

It looks at the vendor of the OpenCL platform. If it sees the word "Intel" in there, it skips past that platform.

The code is written so that it will crash if there are no platforms without the word "Intel" inside. Hopefully the NVidia platform will be found, and it won't crash, and Deathray will work :)

Selur
9th January 2016, 20:10
Nice! That seems to work!

Cu Selur

Jawed
9th January 2016, 20:35
Well, that's awesome. Glad to hear it worked.

Selur
10th January 2016, 08:44
May be adding and option to set a preference which platform to use (Intel,AMD, NVIDIA) might be a nice thing.

Jawed
10th January 2016, 10:42
It's already in my to-do list for Deathray2.

kalehrl
10th January 2016, 13:49
How does it compare to knlmeanscl?
I suppose they are quite similar.

Khanattila
11th January 2016, 17:49
How does it compare to knlmeanscl?
I suppose they are quite similar.


In fact I never checked, but I think there are differences.

mastrboy
18th January 2016, 20:03
Where can I find binary releases? The release page on github is empty: https://github.com/JawedAshraf/Deathray/releases

Reel.Deel
18th January 2016, 20:33
Where can I find binary releases? The release page on github is empty: https://github.com/JawedAshraf/Deathray/releases

Look for Deathray.dll in the list here: https://github.com/JawedAshraf/Deathray

mastrboy
18th January 2016, 20:49
Thank you, an oversight on my part being to used to github users using the release page.

Magik Mark
27th July 2016, 02:34
Do you have a 64bit version?

Jawed
27th July 2016, 17:34
I could make a 64-bit version, but I don't know what you could use it for, since Deathray only works with Avisynth and that's 32-bit only. Isn't it?

How would you use a 64-bit version?

captaiŋadamo
27th July 2016, 17:53
Avisynth+ has had 64-bit builds for a while now.

Jawed
27th July 2016, 18:40
Does Deathray work with Avisynth+ ?

Groucho2004
27th July 2016, 18:55
Does Deathray work with Avisynth+ ?Sure, no problem.

captaiŋadamo
27th July 2016, 20:20
Does Deathray work with Avisynth+ ?

Wouldn't see why not. One of the main selling points is plugin compatibility.

Magik Mark
28th July 2016, 01:01
I guess there's only one way to find out

Is it possible to have a template similar to light, medium, and strong as a starting point?


Sent from my iPhone using Tapatalk

Jawed
28th July 2016, 19:32
I believe that I would have to create a new version of Deathray to be able to support 64-bit Avisynth+, because I would be linking against Avisynth+'s 64-bit lib. Instead of Avisynth's 32-bit lib.

These are two completely different pieces of software.

I have no idea how much work that involves.

Jawed
28th July 2016, 21:30
I guess there's only one way to find out

Is it possible to have a template similar to light, medium, and strong as a starting point?
Start here:

deathray(hy=0.3, huv=0.3, ty=0, tuv=0, s=1, x=1, l=false, c=false, z=true, b=true) # light

If you don't have colour noise, set huv=0.

Set hy as low as 0.1 or as high as you like. Similar for huv.

Set ty to 3 or 5 if you want to try temporal denoising (lots of frames). Set tuv similarly if you have colour noise:

deathray(hy=0.5, huv=0.5, ty=3, tuv=3, s=1, x=1, l=false, c=false, z=true, b=true) # medium

Try x=2 (don't use higher) for another way to increase strength:

deathray(hy=1, huv=1, ty=5, tuv=5, s=1, x=2, l=false, c=false, z=true, b=true) # heavy

I don't think there's any reason to go beyond 5 for ty and tuv.

I prefer MDegrain3.

By far my favourite is Deathray2 making a calm clip for MDegrain3 with a very light post-denoise by Deathray. That combination is on a whole other level.

ultim
28th July 2016, 22:32
I believe that I would have to create a new version of Deathray to be able to support 64-bit Avisynth+, because I would be linking against Avisynth+'s 64-bit lib. Instead of Avisynth's 32-bit lib.

These are two completely different pieces of software.

I have no idea how much work that involves.

The headers are the same for both x32 and x64, and a plugin never needs to link with the Avisynth .lib at all. So the extra effort is as small as just compiling with the x64 toolchain (doing an extra build) without any code changes, assuming that your own code is x64-compatible.

Jawed
28th July 2016, 22:59
The headers are the same for both x32 and x64, and a plugin never needs to link with the Avisynth .lib at all. So the extra effort is as small as just compiling with the x64 toolchain (doing an extra build) without any code changes, assuming that your own code is x64-compatible.
Thanks, you're right I had a look and the external libs include OpenCL and AMD APP, but not Avisynth.

I will have a quick play...

Jawed
28th July 2016, 23:49
My avisynth.h has the following line 347:

void* operator new(unsigned size);

And when I try to compile for 64-bit I get the error message:

error C2821: first formal parameter to 'operator new' must be 'size_t'

So, I've changed it to:

void* operator new(size_t size);

Which compiles. I have no idea if that's broken it :eek: (I'm assuming that the 64-bit avisynth uses the same fix...)

Now, anyone who'd like to experiment, go here:

https://github.com/JawedAshraf/Deathray/tree/x64-experimental

and right-click the Deathray.dll file and save the target file.

So if you're feeling brave, see what happens when you use this experimental 64-bit release. I don't know how to test it...

(I have written other non-Avisynth 64-bit DLLs that work fine (using OpenCL), so I'm pretty hopeful about this.)

Groucho2004
28th July 2016, 23:55
You should use the latest AVS+ header from here (https://github.com/AviSynth/AviSynthPlus/tree/MT/avs_core/include).

Jawed
29th July 2016, 00:06
OK, tomorrow night, nearly my bedtime.

Magik Mark
29th July 2016, 04:54
Thanks for the preset. It makes our testing a lot easier. By the way,. How will you classify video grain? Luminance noise? Will the light setting be able to take care of this?


Sent from my iPhone using Tapatalk

Jawed
29th July 2016, 09:37
Thanks for the preset. It makes our testing a lot easier. By the way,. How will you classify video grain? Luminance noise? Will the light setting be able to take care of this?
I made an error in the heavy preset:

deathray(hy=1, huv=3, ty=5, tuv=5, s=1, x=2, l=false, c=false, z=true, b=true) # heavy

huv should be set to 1. I've corrected that.

There is no classification of video grain or luminance noise.

I'm afraid these "presets" are literally just starting points.

Also, bear in mind that apart from a very light preset and as a pre-processor, I don't use Deathray. I certainly wouldn't use it as the sole de-noiser. Except for a quick and dirty de-noise.

Jawed
29th July 2016, 23:11
You should use the latest AVS+ header from here (https://github.com/AviSynth/AviSynthPlus/tree/MT/avs_core/include).
Thanks.

As I expected, there was quite a bit more effort involved than simply using the new header. The commits show the gory detail.

So, I've updated the DLL. See post 111 for instructions on getting this DLL. I haven't tested it.

Have fun!

Groucho2004
29th July 2016, 23:37
As I expected, there was quite a bit more effort involved than simply using the new header. The commits show the gory detail
Looking at the commits, it's pretty much the usual things required for updating AVS2.5 filters to the AVS2.6 interface.

Thanks for the update, I'll give it a whirl soon.

spiralout
21st January 2023, 20:46
Anybody get the 64bit Deathray working?

Jawed
7th March 2025, 16:16
Recently, I fixed a memory leak issue with Deathray2 and then earlier today, Jamaika started to submit some pull requests for it.

It's been years since I've been on here. And it was, until a few weeks ago, years since I wrote/used an Avisynth script or even did any video encoding. So, I'm out of touch. Apparently I didn't make an official Deathray2 thread.

So, for the time being I'm going to make this the Deathray2 thread.

You can download it here:

https://github.com/JawedAshraf/Deathray2/blob/master/Deathray2.dll

which is from:

https://github.com/JawedAshraf/Deathray2

This is the readme:


Deathray2
=========

An Avisynth plug-in filter for spatial/temporal non-local means de-noising.

Created by Jawed Ashraf - Deathray@cupidity.f9.co.uk


Installation
============

Copy the Deathray2.dll to the "plugins" sub-folder of your installation of
Avisynth.


De-installation
===============

Delete the Deathray2.dll from the "plugins" sub-folder of your installation of
Avisynth.


Compatibility
=============

The following software configurations are known to work:

- Avisynth 2.5.8 and 2.6 MT (SEt's)

The following hardware configurations are known to work:

- AMD HD 7770
- AMD HD 7970

Known non-working hardware:

- ATI cards in the 4000 series or earlier
- ATI cards in the 5400 series

Video:

- Deathray2 is compatible solely with 8-bit planar formatted video. It has
been tested with YV12 format.


Usage
=====

Deathray2 separates the video into its 3 component planes and processes each
of them independently. This means some parameters come in two flavours: luma
and chroma.

Filtering can be adjusted with the following parameters, with the default
value for each in brackets:

hY (1.0) - strength of de-noising in the luma plane.

Cannot be negative.

If set to 0 Deathray2 will not process the luma plane.

hUV (1.0) - strength of de-noising in the chroma planes.

Cannot be negative.

If set to 0 Deathray2 will not process the chroma planes.

tY (0) - temporal radius for the luma plane.

Limited to the range 0 to 64.

When set to 0 spatial filtering is performed on the
luma plane. When set to 1 filtering uses the prior,
current and next frames for the non-local sampling
and weighting process. Higher values will increase
the range of prior and next frames that are included.

tUV (0) - temporal radius for the chroma planes.

Limited to the range 0 to 64.

When set to 0 spatial filtering is performed on the
chroma planes. When set to 1 filtering uses the prior,
current and next frames for the non-local sampling
and weighting process. Higher values will increase
the range of prior and next frames that are included.

s (1.0) - sigma used to generate the gaussian weights.

Limited to values of at least 0.1.

The kernel implemented by Deathray2 uses 7x7-pixel
windows centred upon the pixel being filtered.

For a 2-dimensional gaussian kernel sigma should be
approximately 1/3 of the radius of the kernel, or less,
to retain its gaussian nature.

Since a 7x7 window has a radius of 3, values of sigma
greater than 1.0 will tend to bias the kernel towards
a box-weighting. i.e. all pixels in the window will
tend towards being equally weighted. This will tend to
reduce the selectivity of the weighting process and
result in relatively stronger spatial blurring.

x (1) - factor to expand sampling.

Limited to values in the range 1 to 4.

By default Deathray2 spatially samples 49 windows
centred upon the pixel being filtered, in a 7x7
arrangement. x increases the sampling range in
multiples of the kernel radius.

Since the kernel radius is 3, setting x to 2 produces
a sampling area of 13x13, i.e. 169 windows centred
upon the target pixel. Yet higher values of x such as
3 or 4 will result in 19x19 or 25x25 sample windows.

l (false) - redundant option to be removed

c (true) - redundant option to be removed

z (false) - redundant option to be removed

b (false) - option non-functional

a (8) - alpha sample set size.

limited to values in the range 8 to 128, with values
rounded down to the nearest multiple of 8.

Deathray2 sorts the samples in order to exclude the
worst samples. This improves detail retention while
enabling strong filtering.


Avisynth MT
===========

Deathray2 is not thread safe. This means that only a single instance of
Deathray2 can be used per Avisynth script. By extension this means that
it is not compatible with any of the multi-threading modes of the
Multi Threaded variant of Avisynth.

Use:

SetMTMode(5)

before a call to Deathray2 in the Avisynth script, if multi-threading
is active in other parts of the script.


Multiple Scripts Using Deathray2
================================

The graphics driver is thread safe. This means it is possible to have
an arbitrary number of Avisynth scripts calling Deathray2 running on a
system.

e.g. 2 scripts could be encoding, another could be running in a media player
and another could be previewing individual frames in AvsP or VirtualDub.

Eventually video memory will probably run out, even though it's virtualised.

Usage warnings:


It does not denoise the area just inside the four borders of the frame.
It is not a drop-in replacement for Deathray as the arguments it supports are different.
It only works with 32-bit Avisynth on Windows.


The reason I didn't officially release it, years ago, was that it wasn't finished. It was excellent for my own use, but needed some tidying. And laziness prevailed.

I'm publishing officially now merely because there may be some interest and because I fixed that memory leak, which was a foolish mistake by me.

Jawed
7th March 2025, 17:25
I wrote Deathray2 inspired by a concept in photography software called DxO for image denoising, in which a threshold is used to reject non-local sample weights, when performing non-local means denoising.

Deathray2 sorts the weights that are produced during non-local analysis and then uses the "best" of those weights for the final denoising. The count of weights is specified with the parameter "a".

Surprisingly this works fairly well. In theory the weights, themselves, should produce this "sorted by quality" characteristic, but in practice non-local means denoising tends to be blurry spatially and blotchy temporally. Sorting the weights makes it less ugly, though you can still produce a blurry mess if you really want.

I don't use Deathray or Deathray2 for video denoising, because it's not that good - I don't care how fast it is. Instead I use Deathray2 to create a calm clip, which I then feed in to MDegrain, part of MVTools.

Jawed
7th March 2025, 17:28
SadisticCalm is the function I have created that uses Deathray2 to produce a calm clip. Notice that it creates an "apron" which solves the problem with denoising near the four borders of the frame.


function SadisticCalm(clip source, float "hY", float "hUV", int "tY", int "tUV", int "x", int "a")
{ # Creates a calm clip using Deathray2, to be consumed by MVTools for denoising

hY = Default(hY, 1000) # Deathray2 luma strength
hUV = Default(hUV, 1000) # Deathray2 chroma strength
tY = Default(tY, 0) # Deathray2 luma temporal radius
tUV = Default(tUV, 0) # Deathray2 chroma temporal radius
x = Default(x, 1) # Deathray2 sample expand factor
a = Default(a, 40) # Deathray2 alpha sample count

SetMTMode(2)

corners = source.FlipHorizontal().FlipVertical()
edges = source.FlipVertical()
sides = source.FlipHorizontal()
apron = StackVertical(StackHorizontal(corners, edges, corners), StackHorizontal(sides, source, sides), StackHorizontal(corners, edges, corners))
apron = apron.crop(source.width - 16, source.height - 16, source.width + 32, source.height + 32, true)
SetMTMode(5)
calm = apron.deathray2(hy=hY, huv=hUV, ty=tY, tuv=tUV, s=1, x=x, a=a) # Deathray2 will eventually get its own apron capability
SetMTMode(2)
calm.crop(16,16,-16,-16,true) # remove apron
}

I use SeT's multi-threading Avisynth, hence the SetMTMode commands.

I use this function for the actual denoising, based upon the calm clip produced by SadisticCalm:


function MDegrainNCalm(clip source, clip calm, int temporal, int "blksize", int "overlap", int "sharp", int "thSAD", int "thSCD1", bool "RefineMotion")
{ # Motion compensated denoiser for progressive source clip
# Uses MVTools2

blksize = default(blksize,16) # blksize value (4, 8 or 16)
overlap = default(overlap,blksize/2) # overlap value (0 to half blksize)
sharp = default(sharp,2) # 0=bilinear softest, 1=bicubic, 2=Wiener sharpest
thSAD = default(thSAD,300) # higher risks motion ghosting and swimming, lower risks blotchy denoising
thSCD1 = default(thSCD1, thSad>300 ? 3*thSAD/4 : 300) # Scene change detection. Defaults to thSAD*3/4 when more than 300 because bad blocks on scene change affect more frames, becoming easier to see
RefineMotion = default(RefineMotion,true) # true means MRecalculate will be used to improve motion vectors

halfblksize = blksize/2 # MRecalculate works with half block size
halfoverlap = overlap/2 # Halve the overlap to suit the halved block size
halfthSAD = thSAD/2 # MRecalculate uses a more strict thSAD, which defaults to 150 (half of function's default of 300)

dct=5

source = source.assumeframebased() # MSuper pel=2 is faster with this

calm_super = calm.MSuper(pel=2, hpad=blksize, vpad=blksize, sharp=sharp)
source_super = source.MSuper(pel=2, hpad=blksize, vpad=blksize, sharp=sharp,levels=1)
recalculate = calm.MSuper(pel=2, hpad=blksize, vpad=blksize, sharp=sharp,levels=1)

all_vectors = MAnalyse (calm_super, multi=true, blksize=blksize, overlap=overlap, delta=temporal, dct=dct)
all_vectors = RefineMotion ? MRecalculate(recalculate, all_vectors, tr=temporal, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD) : all_vectors

MDegrainN(source, source_super, all_vectors, temporal, thSAD=thSAD, thSCD1=thSCD1)
}

That's using Ferenc's amazing MVTools2 MDegrainN, which makes me very happy.

Jawed
7th March 2025, 17:58
So this is an example of how I might use Deathray2:


setmemorymax(2048)
setmtmode(5,16) # I have 16 cores, 32 threads on my CPU

FFVideoSource("something", colorspace="YV12")
original=last

calm=SadisticCalm()

SetMTMode(2)

original.MDegrainNCalm(calm, 5, thsad=175)


The results are generally spectacular.

In reality I run multiple scripts one after the other, passing a lossless-encoded video into each successive script. This is my solution to the limited memory of 32-bit Avisynth :) So I encode first with SadisticCalm on its own in a script and then feed the output video into a script that solely runs MDegrainNCalm to do the denoising.

There are three parameters to play with:

Deathray2 strength, using "hY" and "hUV": 1 to 5 is safe; 10-1000 is strong; 10000 to 100000 is getting fairly blurry.
Deathray2 alpha set size "a", 8 or 16 is quite limited, 40 is the strongest I recommend for spatial Deathray2.
MDegrainN thSAD from 50 to 300. More than 300 indicates that you should be setting hY and/or hUV to higher values or increasing alpha set size up to a=40.

I don't see any real value in temporal denoising with Deathray2 when using it to make a calm clip, it's just slow. If you're going to try it, then start with tY=5 and tUV=5. Alpha set size "a" can be set to values in the range 48 to 128 to see good results.

When Deathray2 is used for spatial denoising the difference between a=40 and a=48 is shocking. 48 really spoils the quality (when combined with MVTools denoising) and I recommend against it.

The parameter "x" should be left at 1. I've never found value in raising it.

[I posted a few times in succession because of the very long lines of code in the previous post]