Log in

View Full Version : CTools


Pages : 1 2 3 [4]

Ceppo
2nd April 2022, 18:51
I posted CQTGMC in the first post. I will add parameters and stuff under request since it already does what I care about. :)

Ceppo
3rd April 2022, 17:13
Progressive Frame (https://i.ibb.co/rm70cWt/source.png)
QTGMC (https://i.ibb.co/nzkPnc3/QTGMC.png)
CQTGMC (https://i.ibb.co/4g1bMfC/CQTGMC.png)

Here are some screenshots to see the difference, as you can see CQTGMC does a better job than QTGMC, but it is slower. The intent is to use CQTGMC with CPostProcessing to reduce its usage to leftover combed so you don't need years to encode a movie. If you want a faster solution then you should stick to QTGMC, in the future, I might try some faster settings to see if it still does it better at the same speed.

ChaosKing
3rd April 2022, 18:23
As long it is not "feisty2 slow" (0.01 fps) I prefer quality over speed.
Result looks great, no artifacts + no oversharpened look like in the qtgmc version, very nice!

Ceppo
3rd April 2022, 18:30
To me it runs at 6 fps while QTGMC is 20fps, so I need to fix this speed gap. :)

guest
8th April 2022, 07:28
Can you show me a frame in the source that the chroma repair can handle and CFieldDeBlend can't?


bob = qtgmc(EdiMode="BWDIF+EEDI3",Sharpness=0, Refinemotion=true, n16=true, TV_range=true, tr2=2)
CTelecine(dclip=Blur(1.58,0))
CFieldDeBlend() #CFieldDeBlend works only after fieldmatching
CPostProcessing(dclip=vsMSharpen().blur(1.58,0).RemoveGrain(),edeint2=bob) #This dClip gives me more false positive than default


Also, default CPostProcessing is meant to detect every mouth, so is very sensitive. You might want to change blksize/blkthr to get less of them, but some mouth might escape the check.

BTW, I think is good to use as fewer filters as possible, instead of vsMSharpen you might want to try CSharpen so that the script doesn't have much external dependency. As it is now you need:
1- QTGMC
2- vsMSharpen
3- Removegrain
4- BWDIF
5- EEDI3
6- CTools
Aside Removegrain/QTGMC, I don't think that the others are in everyone folders (I had to download them).

Also, I'm working on CTGMC, still alpha, when I'm done studing QTGMC we can try with that.

Hi Ceppo,

I'm trying to get ### DEINTERLACER #### CQTGMC by Ceppo to run with RipBot...

Not having much luck, are these ALL the dependencies it needs ??

I keep getting errors in CQTGMC.avs

kedautinh12
8th April 2022, 07:42
Read from here and add vinverse.dll
https://forum.doom9.org/showthread.php?p=1966996#post1966996

guest
8th April 2022, 07:51
Read from here and add vinverse.dll
https://forum.doom9.org/showthread.php?p=1966996#post1966996

Thanks again, ked, you're the best :)

I was trying with this :-

LoadPlugin("%AVISYNTHPLUGINS%\BWDIF\BWDIF.dll")
LoadPlugin("%AVISYNTHPLUGINS%\CTools\CTools.dll")
LoadPlugin("%AVISYNTHPLUGINS%\EEDI3\EEDI3.dll")
LoadPlugin("%AVISYNTHPLUGINS%\mvtools\mvtools2.dll")
LoadPlugin("%AVISYNTHPLUGINS%\nnedi3\nnedi3.dll")
LoadPlugin("%AVISYNTHPLUGINS%\RemoveGrain\RemoveGrain64.dll")
Import("%AVISYNTHPLUGINS%\scripts\extras\QTGMC.avs")
Import("%AVISYNTHPLUGINS%\scripts\extras\CQTGMC.avs")
video=CQTGMC(video, Sharpness=0.25, thSAD1=192, thSAD2=320, thSAD3=128, thSAD4=320)

kedautinh12
8th April 2022, 09:33
You can use rgtools replace removegrain64

Ceppo
8th April 2022, 12:32
You need:
rgTools.dll
masktools2.dll
mvtools2.dll
nnedi3.dll
To run CQTGMC(), if you don't tell me what kind of error you are getting, I can't help :p

guest
9th April 2022, 02:01
You need:
rgTools.dll
masktools2.dll
mvtools2.dll
nnedi3.dll
To run CQTGMC(), if you don't tell me what kind of error you are getting, I can't help :p

Thanks Ceppo,

I was using these :-

https://forum.doom9.org/showthread.php?p=1966665#post1966665

As it was the only "list" of dependencies I could find, and that's now also why I was getting errors.

If I get some errors now, I will let you know.

UPDATE:-

I got it to work :)

#Custom
LoadPlugin("%AVISYNTHPLUGINS%\CTools\CTools.dll")
LoadPlugin("%AVISYNTHPLUGINS%\masktools\masktools2.dll")
LoadPlugin("%AVISYNTHPLUGINS%\mvtools\mvtools2.dll")
LoadPlugin("%AVISYNTHPLUGINS%\nnedi3\nnedi3.dll")
LoadPlugin("%AVISYNTHPLUGINS%\RgTools\RgTools.dll")
Import("%AVISYNTHPLUGINS%\scripts\extras\CQTGMC.avs")
Import("%AVISYNTHPLUGINS%\scripts\extras\QTGMC.avs")
video=CQTGMC(video, Sharpness=0.25, thSAD1=192, thSAD2=320, thSAD3=128, thSAD4=320)

Cheers

Ceppo
9th April 2022, 12:26
BTW, you don't need CTools and QTGMC to run CQTGMC :)

real.finder
12th April 2022, 18:21
there are many hybrid DVDs that got film (24 fps) and video (30 fps) content by different proportions

tivtc got d2v parameter for this case, but we are in avs+ age that got frame properties, more info https://github.com/pinterf/TIVTC/issues/18

so maybe CTools should use frame properties for these cases to not do an unnecessary matches or other unnecessary process if the frame is in film (24 fps) section or even video (30 fps) progressive

and in the future even VFR can be done with frame properties and that mean one pass and no log file at all! https://forum.doom9.org/showthread.php?p=1960041&highlight=vfr#post1960041 and https://forum.doom9.org/showthread.php?p=1960175&highlight=vfr#post1960175

Ceppo
13th April 2022, 11:34
Thanks for your support.


so maybe CTools should use frame properties for these cases to not do an unnecessary matches or other unnecessary process if the frame is in film (24 fps) section or even video (30 fps) progressive

Is the d2v file that tells you if the cycle is 24fps or 30fps? I use DGDECNV, since is the only "safe" way for h264 interlaced in my experience, does it supports that too?

In any case, frame proprieties have many disadvantages compared to a txt file. Once you did the analysis pass CTelecine and CDecimate become free, since they only call the frame and nothing more. By doing this you can decimate a CQTGMC/QTGMC output using CTelecine metrics with CDecimate, if I use frame properties I can't do that.

I don't know how frame properties work but if you need to call the frame to get them, you will need to call 5 frames every 4 frames, while CDecimate is currently free since it does everything at the startup. Also, with frame properties, I can't do the default startup error, which is the whole point of the filter.

However, I could use frame properties to skip calculation in the field matching, and get more correct results, if mpeg2source automatically adds them to the source when it loads the d2v file. And I also need sample plugin to see how this stuff is done :)

real.finder
13th April 2022, 13:37
Is the d2v file that tells you if the cycle is 24fps or 30fps?
I think so, if it soft telecine indeed, I don't know if DGDECNV file is the same but I think soft telecine can be found only in mpeg2 dvd

frame proprieties have many disadvantages compared to a txt file. Once you did the analysis pass CTelecine and CDecimate become free, since they only call the frame and nothing more. By doing this you can decimate a CQTGMC/QTGMC output using CTelecine metrics with CDecimate, if I use frame properties I can't do that.

yes, but in case someone hate doing analysis pass :) so it won't hurt if we got both

about others, I think you can PM/email pinterf for help

ChaosKing
13th April 2022, 13:43
However, I could use frame properties to skip calculation in the field matching, and get more correct results, if mpeg2source automatically adds them to the source when it loads the d2v file. And I also need sample plugin to see how this stuff is done :)
I would look at some repos by Asd-g.

https://github.com/Asd-g/MPEG2DecPlus/commit/30508c32477cad7e0dade724b3faa6d36911b0e5
https://github.com/Asd-g/AviSynthPlus-PropToClip/blob/main/src/PropToClip.cpp

Ceppo
13th April 2022, 14:09
Ok, I will do it. It's in my TODO list. But now I have to study that DSP book, so I know better what I'm doing :)

Ceppo
18th April 2022, 12:11
I update CQTGMC and I left also the prev version. It should be faster and more accurate. If someone can test them is appreciated.

Ceppo
26th April 2022, 13:55
Nobody was around at work and I did this, no field matching mouth problem:


D2VSource("VTS_01_1.d2v")
src = last
nnedi3(-2)
src_nnd = last
DoubleWeave(src).SelectOdd()
nxt = last
nnedi3(-2)
nxt_nnd = last
prv = nxt.DuplicateFrame(0)

src_nnd
src_A = mt_average(last,Trim(1,0),u=3,v=3)
src_B = mt_average(last,DuplicateFrame(0),u=3,v=3)
ScriptClip("""
src_P = YDifferenceFromPrevious()
src_N = Trim(1,0).YDifferenceFromPrevious()
src_N < src_P ? src_A : src_B
""")
src_C = mt_average(SelectEven(),SelectOdd(),u=3,v=3)
src_match = mt_lutxy(src_C,SelectEven(),"x y - abs",u=3,v=3)

nxt_nnd
nxt_A = mt_average(last,Trim(1,0),u=3,v=3)
nxt_B = mt_average(last,DuplicateFrame(0),u=3,v=3)
ScriptClip("""
nxt_P = YDifferenceFromPrevious()
nxt_N = Trim(1,0).YDifferenceFromPrevious()
nxt_N < nxt_P ? nxt_A : nxt_B
""")
nxt_C = mt_average(SelectEven(),SelectOdd(),u=3,v=3)
nxt_match = mt_lutxy(nxt_C,SelectEven(),"x y - abs",u=3,v=3)
prv_match = mt_lutxy(nxt_C.DuplicateFrame(0),SelectEven().DuplicateFrame(0),"x y - abs",u=3,v=3)

src
ScriptClip("""
CLuma = AverageLuma(src_match)
NLuma = AverageLuma(nxt_match)
PLuma = AverageLuma(prv_match)
NLuma < CLuma ? nxt.subtitle("nxt") : PLuma < CLuma ? prv.subtitle("prv") : src.subtitle("src")
""")

real.finder
26th April 2022, 18:12
Nobody was around at work and I did this, no field matching mouth problem:

even if it not a big problem with dClip, but will test and see, thanks

real.finder
19th May 2022, 14:22
Nobody was around at work and I did this, no field matching mouth problem:


D2VSource("VTS_01_1.d2v")
src = last
nnedi3(-2)
src_nnd = last
DoubleWeave(src).SelectOdd()
nxt = last
nnedi3(-2)
nxt_nnd = last
prv = nxt.DuplicateFrame(0)

src_nnd
src_A = mt_average(last,Trim(1,0),u=3,v=3)
src_B = mt_average(last,DuplicateFrame(0),u=3,v=3)
ScriptClip("""
src_P = YDifferenceFromPrevious()
src_N = Trim(1,0).YDifferenceFromPrevious()
src_N < src_P ? src_A : src_B
""")
src_C = mt_average(SelectEven(),SelectOdd(),u=3,v=3)
src_match = mt_lutxy(src_C,SelectEven(),"x y - abs",u=3,v=3)

nxt_nnd
nxt_A = mt_average(last,Trim(1,0),u=3,v=3)
nxt_B = mt_average(last,DuplicateFrame(0),u=3,v=3)
ScriptClip("""
nxt_P = YDifferenceFromPrevious()
nxt_N = Trim(1,0).YDifferenceFromPrevious()
nxt_N < nxt_P ? nxt_A : nxt_B
""")
nxt_C = mt_average(SelectEven(),SelectOdd(),u=3,v=3)
nxt_match = mt_lutxy(nxt_C,SelectEven(),"x y - abs",u=3,v=3)
prv_match = mt_lutxy(nxt_C.DuplicateFrame(0),SelectEven().DuplicateFrame(0),"x y - abs",u=3,v=3)

src
ScriptClip("""
CLuma = AverageLuma(src_match)
NLuma = AverageLuma(nxt_match)
PLuma = AverageLuma(prv_match)
NLuma < CLuma ? nxt.subtitle("nxt") : PLuma < CLuma ? prv.subtitle("prv") : src.subtitle("src")
""")


I did test with your sample https://www.mediafire.com/file/at0mup1flbkuutb/Pokimooon.m2v/file
https://i.postimg.cc/NjHtwrMk/New-File-19-001588.png (https://postimages.org/)

LigH
20th May 2022, 07:09
Hey Ash ... why so serious?!

Orikson
4th January 2023, 00:34
Just wanted to tell you that I just found your CQTGMC-Plugin and was surprised that is should be even better that QTGMC :thanks: I will test it with some old familiy videos (MiniDV for now, Video8 later) and am looking for the absolute best quality, no matter how slow it will be :p

anton_foy
12th January 2023, 19:59
This filter is a degrain that blends stationary parts of the picture.
It takes the chroma difference into account to reduce blending by using a block based approch.

So the non stationary(static?) parts will be motion/moving parts and left untouched by cdegrain?
Then I have a request, to have an option to spatial smooth the untouched parts, or better yet if possible option to use an external clip to feed to filter the untouched parts. Example: CDegrain(3,5,32,4,dClip=src.fft3dfilter(),sClip=src.blur(0.7))

Where the 'sClip' is for filtering the untouched parts.
Great stuff, really hope to see your plugin for HBD soon!

Selur
14th January 2023, 08:34
I don't use VapourSynth, BUT when I'm done with HBD and optimizations I might do it, but not sure.
Is there still hope for a Vapoursynth port?

Cu
Selur

kedautinh12
14th January 2023, 09:11
Is there still hope for a Vapoursynth port?

Cu
Selur

When PyTorch's Vapoursynth filters can port to avisynth. Maybe in "one dream" :D

Selur
14th January 2023, 13:53
btw. I get a small speedup to cqtgmc when adding an 'opencl' option, which when enabled would use nnedi3cl (https://github.com/Asd-g/AviSynthPlus-NNEDI3CL) instead of nneedi3.
# Added opencl parameter which, when enabled, will use NNEDI3CL instead of NNEDI3
function CQTGMC(clip input, float "Sharpness", int "thSAD1", int "thSAD2", int "thSAD3", int "thSAD4", bool "opencl")
{
thSAD1 = default(thSAD1, 192)
thSAD2 = default(thSAD2, 320)
thSAD3 = default(thSAD3, 128)
thSAD4 = default(thSAD4, 320)
Sharpness = default(Sharpness, 0.25)
opencl = default(opencl, false)

padded = StackHorizontal(input,input.FlipHorizontal()).Crop(0,0,input.width()+input.width()%64,0)
padded = StackVertical(padded,padded.FlipVertical()).Crop(0,0,0,input.height()+input.height()%64)
bobbed = opencl ? padded.NNEDI3CL(field=-2) : padded.nnedi3(field=-2)
padded
TDeint(mode=1,sharp=false,tryWeave=true,edeint=bobbed)
RemoveGrain(12).GaussResize(width(),height(),0,0,width()+0.0001,height()+0.0001,p=2).Merge(last,0.25)
srchClip = last
super = MSuper()
bvec = MAnalyse(super,isb=true,blksize=64,overlap=32)
fvec = MAnalyse(super,isb=false,blksize=64,overlap=32)
Comp1 = MCompensate(super,bvec,thSAD=thSAD2)
Comp2 = MCompensate(super,fvec,thSAD=thSAD2)
Interleave(Comp1,last,Comp2)
super = MSuper()
bvec = MAnalyse(super,isb=true,blksize=64,overlap=32)
fvec = MAnalyse(super,isb=false,blksize=64,overlap=32)
Inter = MFlowInter(super,bvec,fvec,blend=false)
global CQTGMC_A = Inter.SelectEvery(3,0)
global CQTGMC_B = Inter.SelectEvery(3,1)
srchClip
ScriptClip("""
P = YDifferenceFromPrevious()
N = Trim(1,0).YDifferenceFromPrevious()
N < P ? CQTGMC_A : CQTGMC_B
""")
super = MSuper()
bVec1 = MAnalyse(super,isb=true,overlap=4,delta=1)
fVec1 = MAnalyse(super,isb=false,overlap=4,delta=1)
bobbed
super = MSuper(levels=1)
bComp1 = MCompensate(super,bVec1,thSAD=thSAD3)
fComp1 = MCompensate(super,fVec1,thSAD=thSAD3)
Interleave(\
SeparateFields(bobbed).SelectEvery(4,0),\
SeparateFields(fComp1).SelectEvery(4,1),\
SeparateFields(bComp1).SelectEvery(4,2),\
SeparateFields(bobbed).SelectEvery(4,3))
Weave()
super = MSuper(levels=1)
bComp1 = MCompensate(super, bVec1,thSAD=thSAD4)
fComp1 = MCompensate(super, fVec1,thSAD=thSAD4)
tMax = mt_logic(fComp1,"max",U=3,V=3).mt_logic(bComp1,"max",U=3,V=3)
tMin = mt_logic(fComp1,"min",U=3,V=3).mt_logic(bComp1,"min",U=3,V=3)
MDegrain1(super,bVec1,fVec1,thSAD=thSAD1)
sharpen = mt_adddiff(mt_makediff(Removegrain(20),u=3,v=3),u=3,v=3)
mt_clamp(sharpen,tMax,tMin,Sharpness,Sharpness,3,3,3)
super = MSuper(levels=1)
MDegrain1(super,bVec1,fVec1,thSAD=thSAD1)
Crop(0,0,-(input.width()%64),-(input.height()%64))
return last
}

Reel.Deel
14th January 2023, 18:16
Is there still hope for a Vapoursynth port?


Sadly I don't think Ceppo is coming back; I believe he was discouraged after an argument on GitHub.

anton_foy
14th January 2023, 18:50
Sadly I don't think Ceppo is coming back; I believe he was discouraged after an argument on GitHub.

Very sad. I made a request to Asd-g today:

https://github.com/Asd-g/AviSynthPlus-Scripts/issues/15

Selur
14th January 2023, 20:09
Always sad to see when a developer leaves, but thanks for the info.

Cu
Selur

kedautinh12
15th January 2023, 01:31
Sadly I don't think Ceppo is coming back; I believe he was discouraged after an argument on GitHub.

Can you share me link about it??

anton_foy
17th January 2023, 15:01
Not sure this is the right place to ask but since Ceppo is out of doom9 (at least since 10 months ago) I think forking his plugin would be in ok. Also I have not yet recieved a reply from Asd-g if he/she wants to modify/fork CTools.

The question is about the source code and how to modify it for HBD. I also see that it has no specific code for avx, avx2, avx512 etc. but as I am not even familiar with C++ or programming I leave that for now.

Here is my no-knowledge attempt to modify CDegrain.

type.h-file:

//type.h
#ifndef AVS_TYPES_H
#define AVS_TYPES_H

// Define all types necessary for interfacing with avisynth.dll
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
#include <cstddef>
#include <cstdarg>
#else
#include <stddef.h>
#include <stdarg.h>
#endif

// Raster types used by VirtualDub & Avisynth
typedef uint32_t Pixel32;
typedef uint16_t Pixel16;
//?
typedef Pixel16 Y_PLANE;
typedef Pixel16 U_PLANE;
typedef Pixel16 V_PLANE;
//?
typedef uint14_t Pixel14;
typedef Pixel14 Y_PLANE;
typedef Pixel14 U_PLANE;
typedef Pixel14 V_PLANE;
//
typedef uint12_t Pixel12;
typedef Pixel12 Y_PLANE;
typedef Pixel12 U_PLANE;
typedef Pixel12 V_PLANE;
//
typedef uint10_t Pixel10;
typedef Pixel10 Y_PLANE;
typedef Pixel10 U_PLANE;
typedef Pixel10 V_PLANE;
//
typedef uint8_t BYTE;
typedef uint10_t BYTE;
typedef uint12_t BYTE;
typedef uint14_t BYTE;
typedef uint16_t BYTE;

// Audio Sample information
typedef float SFLOAT;

#endif //AVS_TYPES_H


CDegrain.h-file:

#pragma once
#include <cmath>
#include <windows.h>
#include "avisynth.h"

class CDegrain : public GenericVideoFilter
{
int radius;
int nt;
int thr;
int blksize;
PClip dClip;

public:
CDegrain(PClip _child, int _radius, int _nt, int _thr, int _blksize, PClip _dClip, IScriptEnvironment* env);
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
};

void CDegrain_Y(PVideoFrame(&src)[15], PVideoFrame(&den)[15], PVideoFrame& dst, int nt, int thr, int radius, int blksize);
void CDegrain_YUV420(PVideoFrame(&src)[15], PVideoFrame(&den)[15], PVideoFrame& dst, int nt, int thr, int radius, int blksize);
void CDegrain_YUV422(PVideoFrame(&src)[15], PVideoFrame(&den)[15], PVideoFrame& dst, int nt, int thr, int radius, int blksize);
void CDegrain_YUV444(PVideoFrame(&src)[15], PVideoFrame(&den)[15], PVideoFrame& dst, int nt, int thr, int radius, int blksize);


End of part 1.

anton_foy
17th January 2023, 15:03
CDegrain.cpp:

#include "CDegrain.h"

CDegrain::CDegrain(PClip _child, int _radius, int _nt, int _thr, int _blksize, PClip _dClip, IScriptEnvironment* env) : GenericVideoFilter(_child), radius(_radius), nt(_nt), thr(_thr), blksize(_blksize), dClip(_dClip)
{
if (!vi.IsY() && !vi.IsYUV420() && !vi.IsYUV422() && !vi.IsYUV444())
{
env->ThrowError("CDegrain: supported colorspaces are Y, YUV420, YUV422, YUV444!");
}
else if ((vi.IsYUV420() || vi.IsYUV422()) && blksize < 2)
{
env->ThrowError("CDegrain: YUV420/YUV422 min. blksize is 2!");
}
else if (radius < 0 || radius > 7)
{
env->ThrowError("CDegrain: radius values must be in the [1, 7] range!");
}
}

PVideoFrame __stdcall CDegrain::GetFrame(int n, IScriptEnvironment* env) {

int i;
PVideoFrame dst = env->NewVideoFrame(vi);

PVideoFrame src[15];

for (i = 0; i < radius; i += 1)
{
src[i] = child->GetFrame(max(n - radius + i, 0), env);
}

src[radius] = child->GetFrame(n, env);

for (i = 0; i < radius; i += 1)
{
src[i + radius + 1] = child->GetFrame(min(n + i + 1, vi.num_frames - 1), env);
}

PVideoFrame den[15];

if (!dClip)
{
vi.IsY() ? CDegrain_Y(src, src, dst, nt, thr, radius, blksize) : NULL;
vi.IsYUV420() ? CDegrain_YUV420(src, src, dst, nt, thr, radius, blksize) : NULL;
vi.IsYUV422() ? CDegrain_YUV422(src, src, dst, nt, thr, radius, blksize) : NULL;
vi.IsYUV444() ? CDegrain_YUV444(src, src, dst, nt, thr, radius, blksize) : NULL;
}
else
{
for (i = 0; i < radius; i += 1)
{
den[i] = dClip->GetFrame(max(n - radius + i, 0), env);
}

den[radius] = dClip->GetFrame(n, env);

for (i = 0; i < radius; i += 1)
{
den[i + radius + 1] = dClip->GetFrame(min(n + i + 1, vi.num_frames - 1), env);
}

vi.IsY() ? CDegrain_Y(src, den, dst, nt, thr, radius, blksize) : NULL;
vi.IsYUV420() ? CDegrain_YUV420(src, den, dst, nt, thr, radius, blksize) : NULL;
vi.IsYUV422() ? CDegrain_YUV422(src, den, dst, nt, thr, radius, blksize) : NULL;
vi.IsYUV444() ? CDegrain_YUV444(src, den, dst, nt, thr, radius, blksize) : NULL;
}

return dst;
}

void CDegrain_Y(PVideoFrame(&src)[15], PVideoFrame(&den)[15], PVideoFrame& dst, int nt, int thr, int radius, int blksize)
{
int i;
unsigned char* dstp;
dstp = dst->GetWritePtr(PLANAR_Y);

const unsigned char* srcp[15];
const unsigned char* denp[15];
for (i = 0; i < 15; i += 1)
{
srcp[min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_Y);
denp[min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_Y);
}

int dst_pitch;
dst_pitch = dst->GetPitch(PLANAR_Y);

int src_pitch[15];
int den_pitch[15];
for (i = 0; i < 15; i += 1)
{
src_pitch[min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_Y);
den_pitch[min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_Y);
}

int height = dst->GetHeight(PLANAR_Y);
int row_size = dst->GetRowSize(PLANAR_Y);

int64_t BSY = 0;
int64_t BSX = 0;
BSY += min(1, height % blksize);
BSY += height / blksize;
BSX += min(1, row_size % blksize);
BSX += row_size / blksize;
auto SUM = new int[BSY * BSX][15];
memset(SUM, 0, BSY * BSX * 15 * sizeof(int));

int BX, BY;
int pixel_sum[2];
int x, y, a, b, temp;

//DIFFERENCE
for (y = 0; y < height; y += 1)
{
BY = y / blksize;
BY += y % blksize ? 1 : 0;
for (x = 0; x < row_size; x += 1)
{
BX = x / blksize;
BX += x % blksize ? 1 : 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
temp = abs(denp[i][x] - denp[radius][x]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
}
}
for (i = 0; i < radius * 2 + 1; i += 1)
{
denp[i] += den_pitch[i];
}
}

//BLENDING
for (y = 0; y < height; y += 1)
{
BY = y / blksize;
BY += y % blksize ? 1 : 0;
for (x = 0; x < row_size; x += 1)
{
BX = x / blksize;
BX += x % blksize ? 1 : 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] = 0;
pixel_sum[1] = 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] += SUM[BY * BSY + BX][i] <= thr ? 1 : 0;
pixel_sum[1] += SUM[BY * BSY + BX][i] <= thr ? srcp[i][x] : 0;
}
dstp[x] = int(pixel_sum[1] / static_cast<float>(pixel_sum[0]) + 0.5f);
}
}
dstp += dst_pitch;
for (i = 0; i < radius * 2 + 1; i += 1)
{
srcp[i] += src_pitch[i];
}
}
}

void CDegrain_YUV420(PVideoFrame(&src)[15], PVideoFrame(&den)[15], PVideoFrame& dst, int nt, int thr, int radius, int blksize)
{
int i;
unsigned char* dstp[3];
dstp[0] = dst->GetWritePtr(PLANAR_Y);
dstp[1] = dst->GetWritePtr(PLANAR_U);
dstp[2] = dst->GetWritePtr(PLANAR_V);

const unsigned char* srcp[3][15];
const unsigned char* denp[3][15];
for (i = 0; i < 15; i += 1)
{
srcp[0][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_Y);
denp[0][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_Y);
srcp[1][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_U);
denp[1][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_U);
srcp[2][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_V);
denp[2][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_V);
}

int dst_pitch[3];
dst_pitch[0] = dst->GetPitch(PLANAR_Y);
dst_pitch[1] = dst->GetPitch(PLANAR_U);
dst_pitch[2] = dst->GetPitch(PLANAR_V);

int src_pitch[3][15];
int den_pitch[3][15];
for (i = 0; i < 15; i += 1)
{
src_pitch[0][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_Y);
den_pitch[0][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_Y);
src_pitch[1][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_U);
den_pitch[1][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_U);
src_pitch[2][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_V);
den_pitch[2][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_V);
}

int height = dst->GetHeight(PLANAR_Y);
int row_size = dst->GetRowSize(PLANAR_Y);

int64_t BSY = 0;
int64_t BSX = 0;
BSY += min(1, height % blksize);
BSY += height / blksize;
BSX += min(1, row_size % blksize);
BSX += row_size / blksize;
auto SUM = new int[BSY * BSX][15];
memset(SUM, 0, BSY * BSX * 15 * sizeof(int));

int BX, BY;
int pixel_sum[3];
int x, y, a, b, temp;

//DIFFERENCE
for (y = 0; y < height; y += 1)
{
BY = y / blksize;
BY += y % blksize ? 1 : 0;
for (x = 0; x < row_size; x += 1)
{
BX = x / blksize;
BX += x % blksize ? 1 : 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
temp = abs(denp[0][i][x] - denp[0][radius][x]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
}
if (!(y % 2) && !(x % 2))
{
for (i = 0; i < radius * 2 + 1; i += 1)
{
temp = abs(denp[1][i][x / 2] - denp[1][radius][x / 2]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
temp = abs(denp[2][i][x / 2] - denp[2][radius][x / 2]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
}
}
}
for (i = 0; i < radius * 2 + 1; i += 1)
{
denp[0][i] += den_pitch[0][i];
}
if (!(y % 2))
{
for (i = 0; i < radius * 2 + 1; i += 1)
{
denp[1][i] += den_pitch[1][i];
denp[2][i] += den_pitch[2][i];
}
}
}

//BLENDING
for (y = 0; y < height; y += 1)
{
BY = y / blksize;
BY += y % blksize ? 1 : 0;
for (x = 0; x < row_size; x += 1)
{
BX = x / blksize;
BX += x % blksize ? 1 : 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] = 0;
pixel_sum[1] = 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] += SUM[BY * BSY + BX][i] <= thr ? 1 : 0;
pixel_sum[1] += SUM[BY * BSY + BX][i] <= thr ? srcp[0][i][x] : 0;
}
dstp[0][x] = int(pixel_sum[1] / static_cast<float>(pixel_sum[0]) + 0.5f);

// Continues in next post.

anton_foy
17th January 2023, 15:04
if (!(y % 2) && !(x % 2))
{
pixel_sum[0] = 0;
pixel_sum[1] = 0;
pixel_sum[2] = 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] += SUM[BY * BSY + BX][i] <= thr ? 1 : 0;
pixel_sum[1] += SUM[BY * BSY + BX][i] <= thr ? srcp[1][i][x / 2] : 0;
pixel_sum[2] += SUM[BY * BSY + BX][i] <= thr ? srcp[2][i][x / 2] : 0;
}
dstp[1][x / 2] = int(pixel_sum[1] / static_cast<float>(pixel_sum[0]) + 0.5f);
dstp[2][x / 2] = int(pixel_sum[2] / static_cast<float>(pixel_sum[0]) + 0.5f);
}
}
}
dstp[0] += dst_pitch[0];
for (i = 0; i < radius * 2 + 1; i += 1)
{
srcp[0][i] += src_pitch[0][i];
}
if (!(y % 2))
{
dstp[1] += dst_pitch[1];
dstp[2] += dst_pitch[2];
for (i = 0; i < radius * 2 + 1; i += 1)
{
srcp[1][i] += src_pitch[1][i];
srcp[2][i] += src_pitch[2][i];
}
}
}
}

void CDegrain_YUV422(PVideoFrame(&src)[15], PVideoFrame(&den)[15], PVideoFrame& dst, int nt, int thr, int radius, int blksize)
{
int i;
unsigned char* dstp[3];
dstp[0] = dst->GetWritePtr(PLANAR_Y);
dstp[1] = dst->GetWritePtr(PLANAR_U);
dstp[2] = dst->GetWritePtr(PLANAR_V);

const unsigned char* srcp[3][15];
const unsigned char* denp[3][15];
for (i = 0; i < 15; i += 1)
{
srcp[0][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_Y);
denp[0][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_Y);
srcp[1][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_U);
denp[1][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_U);
srcp[2][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_V);
denp[2][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_V);
}

int dst_pitch[3];
dst_pitch[0] = dst->GetPitch(PLANAR_Y);
dst_pitch[1] = dst->GetPitch(PLANAR_U);
dst_pitch[2] = dst->GetPitch(PLANAR_V);

int src_pitch[3][15];
int den_pitch[3][15];
for (i = 0; i < 15; i += 1)
{
src_pitch[0][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_Y);
den_pitch[0][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_Y);
src_pitch[1][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_U);
den_pitch[1][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_U);
src_pitch[2][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_V);
den_pitch[2][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_V);
}

int height = dst->GetHeight(PLANAR_Y);
int row_size = dst->GetRowSize(PLANAR_Y);

int64_t BSY = 0;
int64_t BSX = 0;
BSY += min(1, height % blksize);
BSY += height / blksize;
BSX += min(1, row_size % blksize);
BSX += row_size / blksize;
auto SUM = new int[BSY * BSX][15];
memset(SUM, 0, BSY * BSX * 15 * sizeof(int));

int BX, BY;
int pixel_sum[3];
int x, y, a, b, temp;

//DIFFERENCE
for (y = 0; y < height; y += 1)
{
BY = y / blksize;
BY += y % blksize ? 1 : 0;
for (x = 0; x < row_size; x += 1)
{
BX = x / blksize;
BX += x % blksize ? 1 : 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
temp = abs(denp[0][i][x] - denp[0][radius][x]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
}
if (!(x % 2))
{
for (i = 0; i < radius * 2 + 1; i += 1)
{
temp = abs(denp[1][i][x / 2] - denp[1][radius][x / 2]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
temp = abs(denp[2][i][x / 2] - denp[2][radius][x / 2]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
}
}
}
for (i = 0; i < radius * 2 + 1; i += 1)
{
denp[0][i] += den_pitch[0][i];
denp[1][i] += den_pitch[1][i];
denp[2][i] += den_pitch[2][i];
}
}

//BLENDING
for (y = 0; y < height; y += 1)
{
BY = y / blksize;
BY += y % blksize ? 1 : 0;
for (x = 0; x < row_size; x += 1)
{
BX = x / blksize;
BX += x % blksize ? 1 : 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] = 0;
pixel_sum[1] = 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] += SUM[BY * BSY + BX][i] <= thr ? 1 : 0;
pixel_sum[1] += SUM[BY * BSY + BX][i] <= thr ? srcp[0][i][x] : 0;
}
dstp[0][x] = int(pixel_sum[1] / static_cast<float>(pixel_sum[0]) + 0.5f);

if (!(x % 2))
{
pixel_sum[0] = 0;
pixel_sum[1] = 0;
pixel_sum[2] = 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] += SUM[BY * BSY + BX][i] <= thr ? 1 : 0;
pixel_sum[1] += SUM[BY * BSY + BX][i] <= thr ? srcp[1][i][x / 2] : 0;
pixel_sum[2] += SUM[BY * BSY + BX][i] <= thr ? srcp[2][i][x / 2] : 0;
}
dstp[1][x / 2] = int(pixel_sum[1] / static_cast<float>(pixel_sum[0]) + 0.5f);
dstp[2][x / 2] = int(pixel_sum[2] / static_cast<float>(pixel_sum[0]) + 0.5f);
}
}
}
dstp[0] += dst_pitch[0];
dstp[1] += dst_pitch[1];
dstp[2] += dst_pitch[2];
for (i = 0; i < radius * 2 + 1; i += 1)
{
srcp[0][i] += src_pitch[0][i];
srcp[1][i] += src_pitch[1][i];
srcp[2][i] += src_pitch[2][i];
}
}
}

void CDegrain_YUV444(PVideoFrame(&src)[15], PVideoFrame(&den)[15], PVideoFrame& dst, int nt, int thr, int radius, int blksize)
{
int i;
unsigned char* dstp[3];
dstp[0] = dst->GetWritePtr(PLANAR_Y);
dstp[1] = dst->GetWritePtr(PLANAR_U);
dstp[2] = dst->GetWritePtr(PLANAR_V);

const unsigned char* srcp[3][15];
const unsigned char* denp[3][15];
for (i = 0; i < 15; i += 1)
{
srcp[0][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_Y);
denp[0][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_Y);
srcp[1][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_U);
denp[1][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_U);
srcp[2][min(i, radius * 2)] = src[min(i, radius * 2)]->GetReadPtr(PLANAR_V);
denp[2][min(i, radius * 2)] = den[min(i, radius * 2)]->GetReadPtr(PLANAR_V);
}

int dst_pitch[3];
dst_pitch[0] = dst->GetPitch(PLANAR_Y);
dst_pitch[1] = dst->GetPitch(PLANAR_U);
dst_pitch[2] = dst->GetPitch(PLANAR_V);

int src_pitch[3][15];
int den_pitch[3][15];
for (i = 0; i < 15; i += 1)
{
src_pitch[0][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_Y);
den_pitch[0][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_Y);
src_pitch[1][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_U);
den_pitch[1][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_U);
src_pitch[2][min(i, radius * 2)] = src[min(i, radius * 2)]->GetPitch(PLANAR_V);
den_pitch[2][min(i, radius * 2)] = den[min(i, radius * 2)]->GetPitch(PLANAR_V);
}

int height = dst->GetHeight(PLANAR_Y);
int row_size = dst->GetRowSize(PLANAR_Y);

int64_t BSY = 0;
int64_t BSX = 0;
BSY += min(1, height % blksize);
BSY += height / blksize;
BSX += min(1, row_size % blksize);
BSX += row_size / blksize;
auto SUM = new int[BSY * BSX][15];
memset(SUM, 0, BSY * BSX * 15 * sizeof(int));

int BX, BY;
int pixel_sum[4];
int x, y, a, b, temp;

//DIFFERENCE
for (y = 0; y < height; y += 1)
{
BY = y / blksize;
BY += y % blksize ? 1 : 0;
for (x = 0; x < row_size; x += 1)
{
BX = x / blksize;
BX += x % blksize ? 1 : 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
temp = abs(denp[0][i][x] - denp[0][radius][x]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
temp = abs(denp[1][i][x] - denp[1][radius][x]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
temp = abs(denp[2][i][x] - denp[2][radius][x]);
SUM[BY * BSY + BX][i] += temp > nt ? 255 : temp;
}
}
for (i = 0; i < radius * 2 + 1; i += 1)
{
denp[0][i] += den_pitch[0][i];
denp[1][i] += den_pitch[1][i];
denp[2][i] += den_pitch[2][i];
}
}

//BLENDING
for (y = 0; y < height; y += 1)
{
BY = y / blksize;
BY += y % blksize ? 1 : 0;
for (x = 0; x < row_size; x += 1)
{
BX = x / blksize;
BX += x % blksize ? 1 : 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] = 0;
pixel_sum[1] = 0;
pixel_sum[2] = 0;
pixel_sum[3] = 0;
for (i = 0; i < radius * 2 + 1; i += 1)
{
pixel_sum[0] += SUM[BY * BSY + BX][i] <= thr ? 1 : 0;
pixel_sum[1] += SUM[BY * BSY + BX][i] <= thr ? srcp[0][i][x] : 0;
pixel_sum[2] += SUM[BY * BSY + BX][i] <= thr ? srcp[1][i][x] : 0;
pixel_sum[3] += SUM[BY * BSY + BX][i] <= thr ? srcp[2][i][x] : 0;
}
dstp[0][x] = int(pixel_sum[1] / static_cast<float>(pixel_sum[0]) + 0.5f);
dstp[1][x] = int(pixel_sum[2] / static_cast<float>(pixel_sum[0]) + 0.5f);
dstp[2][x] = int(pixel_sum[3] / static_cast<float>(pixel_sum[0]) + 0.5f);
}
}
dstp[0] += dst_pitch[0];
dstp[1] += dst_pitch[1];
dstp[2] += dst_pitch[2];
for (i = 0; i < radius * 2 + 1; i += 1)
{
srcp[0][i] += src_pitch[0][i];
srcp[1][i] += src_pitch[1][i];
srcp[2][i] += src_pitch[2][i];
}
}
}


Someone who knows better could tell me where the BitsPerComponent should be? Or if this code is structured in another manner.

StainlessS
17th January 2023, 20:26
I once asked Pinterf if there was a good example for coding for AVS+ colorspace stuff, [I cant find the posts, but], see here reply suggested Average plugin :-
https://github.com/pinterf/Average/releases/tag/0.95

anton_foy
18th January 2023, 00:35
I once asked Pinterf if there was a good example for coding for AVS+ colorspace stuff, [I cant find the posts, but], see here reply suggested Average plugin :-
https://github.com/pinterf/Average/releases/tag/0.95

Thanks for the link! Way over my head atm but hopefully Im getting the hang of things later on.
Harassing the ChatGPT bot to spit out CUDA optimizations of CTools and hbd support. One can only dream I guess.

Edit: here I paste what the bot did. Gibberish or usable?

Cdegrain_cuda.cpp:
https://pastebin.com/cCsNN3Uh

Cdegrain.h (cuda):
https://pastebin.com/HDy5wS10

AvisynthpluginInit_cuda.cpp:
https://pastebin.com/VRAQhgri

types_cuda.h:
https://pastebin.com/SCnCWY3N

minmax_cuda.h:
https://pastebin.com/0MTCE2pB

cpuid_cuda.h:
https://pastebin.com/Ndu6wSJu

Alignment_cuda.h:
https://pastebin.com/xdh1hNM2

Ctemporalsoften_cuda.cpp:
https://pastebin.com/d4bBPxD2

Ceppo
18th January 2023, 22:47
I got the notification for this CDegrain stuff, glad someone found uselful my work and wants to improve it. BTW, it was not for the argument on github iyeah I was pissed, I admit it) that i leaved but because I'm tring to get a degree in philosophy in 1 year and I'm giving 3 exams for month, I also left my job, so I can't let myself get obsessed by my encoding obsession otherwise or I want be able to reach my goal. I won't answer to any replay to protect myself from the ipnoting power of avisynth.

Reel.Deel
18th January 2023, 22:56
@Ceppo

Glad that I was wrong that you won't return :) ... It just sounded that way from your last words on there, and then you went missing. But good to hear that all is fine with you!

anton_foy
19th January 2023, 00:38
I got the notification for this CDegrain stuff, glad someone found uselful my work and wants to improve it. BTW, it was not for the argument on github iyeah I was pissed, I admit it) that i leaved but because I'm tring to get a degree in philosophy in 1 year and I'm giving 3 exams for month, I also left my job, so I can't let myself get obsessed by my encoding obsession otherwise or I want be able to reach my goal. I won't answer to any replay to protect myself from the ipnoting power of avisynth.

Good to hear from you, sorry about the job but good luck with your goals!

Thanks for letting me/us improve your code.

Ceppo
23rd January 2023, 20:23
I have a good news, to get a degree I need to do only 2 exams and write the thesis. So if someone mods CSharpen or a simple plugin like that I can rewrite CTools for HBD (when I want to relax to not think about philosophy) but is not something that I will do in a few days. Also, I have no knowlodge of optimization and stuff, and unless someone makes me an easy tutorial to get started, someone else will have to do the optimization.

Hope that helps.

anton_foy
23rd January 2023, 22:30
I have a good news, to get a degree I need to do only 2 exams and write the thesis. So if someone mods CSharpen or a simple plugin like that I can rewrite CTools for HBD (when I want to relax to not think about philosophy) but is not something that I will do in a few days. Also, I have no knowlodge of optimization and stuff, and unless someone makes me an easy tutorial to get started, someone else will have to do the optimization.

Hope that helps.

Yay Ceppo awesome news! I wish I could help but I know nothing about programming. But I don't think just making it HBD should be so hard. If I understand correctly (which I probably don't) then what I modded in the helper headers and cpp-files for hbd is enough?
From old avisynth to avs+ I was thinking the change is
yv12 becomes YUV420, YV16 - YUV422, yv24 - YUV444, Y8 - Y. Then call bitspercomponent and probably use bitLshift when need of scaling 0-256.
Someone who really knows this please correct me.

Ceppo
23rd January 2023, 22:35
I'm not a programmer, I need working examples to make experiments and learn that way to get the hang of it. Sadly, I have a humanistic CV, so I lack a lot of information about programming. :eek:

AND ON STACKOVERFLOW NOBODY CARES ABOUT AVISYNTH; WHYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

of course I'm drunk :)

Ceppo
24th January 2023, 17:17
I have only 1 exam this month, so I'm making experiments since I'm rusty. Can someone help me figure out why this plugins makes AVSPMOD crash? It's probabily something stupid, but I can't figure it out.


#pragma once
#include <avisynth.h>

class CReadVideoFrame
{
public:
PVideoFrame frame;
const unsigned char* pixel[3];
int pitch[3];
int height[3];
int row_size[3];

CReadVideoFrame(PVideoFrame src)
{
this->frame = src;
this->pixel[0] = this->frame->GetReadPtr(PLANAR_Y);
this->pixel[1] = this->frame->GetReadPtr(PLANAR_U);
this->pixel[2] = this->frame->GetReadPtr(PLANAR_V);
this->pitch[0] = this->frame->GetPitch(PLANAR_Y);
this->pitch[1] = this->frame->GetPitch(PLANAR_U);
this->pitch[2] = this->frame->GetPitch(PLANAR_V);
this->height[0] = this->frame->GetHeight(PLANAR_Y);
this->height[1] = this->frame->GetHeight(PLANAR_U);
this->height[2] = this->frame->GetHeight(PLANAR_V);
this->row_size[0] = this->frame->GetRowSize(PLANAR_Y);
this->row_size[1] = this->frame->GetRowSize(PLANAR_U);
this->row_size[2] = this->frame->GetRowSize(PLANAR_V);
};
};

class CWriteVideoFrame
{
public:
PVideoFrame frame;
unsigned char* pixel[3];
int pitch[3];

CWriteVideoFrame(PVideoFrame dst)
{
this->frame = dst;
this->pixel[0] = this->frame->GetWritePtr(PLANAR_Y);
this->pixel[1] = this->frame->GetWritePtr(PLANAR_U);
this->pixel[2] = this->frame->GetWritePtr(PLANAR_V);
this->pitch[0] = this->frame->GetPitch(PLANAR_Y);
this->pitch[1] = this->frame->GetPitch(PLANAR_U);
this->pitch[2] = this->frame->GetPitch(PLANAR_V);
};
};

class SimpleCopy : public GenericVideoFilter
{
public:
SimpleCopy(PClip _child, IScriptEnvironment* env) : GenericVideoFilter(_child)
{ }
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env)
{
CReadVideoFrame src(child->GetFrame(n, env));
CWriteVideoFrame dst(env->NewVideoFrame(vi));

for (int p = 0; p < 3; p++)
{
for (int y = 0; y < src.height[p]; y++)
{
for (int x = 0; x < src.row_size[p]; x++)
{
dst.pixel[p][x] = src.pixel[p][x];
}
dst.pixel[p] += dst.pitch[p];
src.pixel[p] += src.pitch[p];
}

}
return dst.frame;
}
};

AVSValue __cdecl Create_SimpleCopy(AVSValue args, void* user_data, IScriptEnvironment* env)
{
return new SimpleCopy(args[0].AsClip(), env);
}

const AVS_Linkage* AVS_linkage = 0;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment * env, const AVS_Linkage* const vectors)
{
AVS_linkage = vectors;
env->AddFunction("SimpleCopy", "c", Create_SimpleCopy, 0);

return "SimpleCopy";
}

PoeBear
7th March 2023, 05:40
even if it not a big problem with dClip, but will test and see, thanks

Can I ask what the fix is with dClip to solve the field matching problem?

I'm enjoying CQTGMC on my live-action DVDs, but it seems to affect nearly every Fox Animation DVD I have, though they are notorious for being poorly encoded (Simpsons, Family Guy, etc)

real.finder
15th July 2023, 05:03
Can I ask what the fix is with dClip to solve the field matching problem?

I'm enjoying CQTGMC on my live-action DVDs, but it seems to affect nearly every Fox Animation DVD I have, though they are notorious for being poorly encoded (Simpsons, Family Guy, etc)

you can search in this Thread and see

anyway, if Ceppo still care, I came across a source with a stubborn scene that has mouth problem, so I used animeivtc (https://raw.githubusercontent.com/realfinder/AVS-Stuff/master/avs%202.5%20and%20up/AnimeIVTC.avsi) but even the default autoAssufthr1 was not enough so I did use "autoAssuf=true, autoAssufthr1=0.3"

so Ceppo may like port the method to CTelecine https://github.com/realfinder/AVS-Stuff/blob/8db8a29a8cf70b9f1ff42087101add3a70985933/avs%202.5%20and%20up/AnimeIVTC.avsi#L290-L307 as mode=7 or as new parameter

real.finder
14th October 2023, 15:53
after more tests seems http://avisynth.nl/index.php/IT is the best for field matching mouth problem

also seems Ceppo delete his account in github and also the project go with it so here the archive like for it https://web.archive.org/web/20230118221708/https://github.com/CeppoTools/CTools

kedautinh12
15th October 2023, 02:34
@real.finder did you test new ideas from Ceppo???
https://forum.doom9.org/showthread.php?t=185104

real.finder
15th October 2023, 03:43
@real.finder did you test new ideas from Ceppo???
https://forum.doom9.org/showthread.php?t=185104

didn't note it, I am busy with other things these days so I kinda not check doom9 as before

anyway it seems interesting, but still I hope for a plugin update not only for better Field Matching but also for better VFR and frame properties support Plus HBD