View Full Version : New filter: Fix Telecined Fades


feisty2
29th December 2016, 20:31
binary(windows x64, requires msvcr 2017):https://github.com/IFeelBloated/Fix-Telecined-Fades/releases/tag/r5
git repo:https://github.com/IFeelBloated/Fix-Telecined-Fades/blob/master/Source.cpp

the filter gives a mathematically perfect solution to such(fades were done AFTER telecine which made a picture perfect IVTC pretty much impossible) (http://forum.doom9.org/showthread.php?p=1584763#post1584763) problem, and it's now time to kiss "vinverse" goodbye cuz "vinverse" is old and low quality.
unlike vinverse which works as a dumb blurring + contra-sharpening combo and very harmful to artifacts-free frames, this filter works by matching the brightness of top and bottom fields with statistical methods, and also harmless to healthy frames.


core.ftf.FixFades(clip, mode=0, threshold=0.002, color=[0.0, 0.0, 0.0], opt=True)

clip: clip to be processed

mode: could be 0(default), 1, or 2
0: adjust the brightness of both fields to match the average brightness of 2 fields.
1: darken the brighter field to match the brightness of the darker field
2: brighten the darker field to match the brightness of the brighter field

threshold: threshold for the average difference per pixel, on a scale of 0.0 - 1.0, but could go beyond 1.0, the frame will remain untouched if the average difference between 2 fields goes below this value

color: base color of the fade, default is [0.0, 0.0, 0.0](black)

opt: call the fastest possible functions if opt=True, else call the C++ functions.

INPUT CLIP MUST BE 32BITS FLOATING POINT FORMAT!!!
apply this filter AFTER field matching!!!

feisty2
29th December 2016, 21:03
comparison against vinverse
input

import vapoursynth as vs
core = vs.get_core()
clp = core.lsmas.LWLibavSource("rule6")
clp = core.vivtc.VFM(clp,0)
clp.set_output()

http://i.imgur.com/IvBQNka.png
vinverse

import vapoursynth as vs
core = vs.get_core()
clp = core.lsmas.LWLibavSource("rule6")
clp = core.vivtc.VFM(clp,0)

clp = core.vinverse.Vinverse(clp)

clp.set_output()

http://i.imgur.com/3nZsXj5.png
FTF

import vapoursynth as vs
core = vs.get_core()
clp = core.lsmas.LWLibavSource("rule6")
clp = core.vivtc.VFM(clp,0)
clp = core.fmtc.bitdepth(clp,bits=32,fulls=False,fulld=True)

clp = core.ftf.FixFades(clp)

clp.set_output()


http://i.imgur.com/lPcvPBp.png

feisty2
29th December 2016, 21:16
and vinverse failed miserably at the top-right part of the image, there's clear aliasing around edges, and ftf produced a picture perfect reconstruction.

Mystery Keeper
29th December 2016, 22:22
Does it do combing detection? Can you do better combing detection than TDM?

feisty2
30th December 2016, 05:36
Does it do combing detection? Can you do better combing detection than TDM?

No combing detection, it pretty much won't affect the normal frames so no masking required. Technically every pixel will be processed but only the problem frames will be affected.

ShogoXT
30th December 2016, 07:35
Does this work in general on IVTC scene transitions? Since using Vapoursynth (through Staxrip) ive been having such a problem with duplicate frames and scthresh with VFM and Vdecimate (no blending???), that ive been forced to stay with mode=0, but scene changes look awful. Ive also been having trouble with dealing with rainbows and dotcrawl in motion, but I guess thats another problem as all the solutions are temporal only.

EDIT: Also scrolling scenes stink...

feisty2
30th December 2016, 10:42
Does this work in general on IVTC scene transitions? Since using Vapoursynth (through Staxrip) ive been having such a problem with duplicate frames and scthresh with VFM and Vdecimate (no blending???), that ive been forced to stay with mode=0, but scene changes look awful. Ive also been having trouble with dealing with rainbows and dotcrawl in motion, but I guess thats another problem as all the solutions are temporal only.

EDIT: Also scrolling scenes stink...

not sure what you meant by "IVTC scene transitions", it works on any "simple" telecined fades(fade from/to pure color, eg. black), and it won't work on telecined cross-fades(2 or more scenes blending into each other), shit like that is simply beyond repair.

WolframRhodium
30th December 2016, 16:33
Great algorithm. The result is fantastic.

Question:
Will the results be even better if the algorithm acting on local rather than global?

feisty2
30th December 2016, 19:48
r2:
fixed a stupid memory leak
new parameter "threshold"
new parameter "color"

feisty2
30th December 2016, 19:49
Question:
Will the results be even better if the algorithm acting on local rather than global?

done, use the "threshold" parameter

feisty2
30th December 2016, 20:06
another demonstration for something other than fading into blackness
input

import vapoursynth as vs
core = vs.get_core()
clp = core.lsmas.LWLibavSource("rule6")
clp = core.vivtc.VFM(clp,0)
clp = core.fmtc.bitdepth(clp,bits=32,fulls=False,fulld=True)
clp = core.std.Expr(clp, ["1.0 x -", "x"]) #invert Y so it would be literally fading into whiteness
clp.set_output()

http://i.imgur.com/Shra82y.png
FTF

import vapoursynth as vs
core = vs.get_core()
clp = core.lsmas.LWLibavSource("rule6")
clp = core.vivtc.VFM(clp,0)
clp = core.fmtc.bitdepth(clp,bits=32,fulls=False,fulld=True)
clp = core.std.Expr(clp, ["1.0 x -", "x"]) #invert Y so it would be literally fading into whiteness

clp = core.ftf.FixFades(clp, color=[1.0, 0.0, 0.0])

clp.set_output()

http://i.imgur.com/xQMEHes.png

jackoneill
30th December 2016, 21:22
and it won't work on telecined cross-fades(2 or more scenes blending into each other), shit like that is simply beyond repair.

No, no, fades like that can still be saved. By which I mean that you can obtain a 24 fps fade with smooth motion even if field matching is impossible in the fade. The solution involves QTGMC, so the detail preservation isn't awesome, but it's still good, considering the situation.

Steps:
1. Invoke source filter to obtain the untouched 30 fps clip.
2. Extract the fade using Trim.
3. Pass to QTGMC to obtain a 60 fps clip.
4. Stare at the output of QTGMC really carefully. It's been a few months since I did this, so I forget exactly what you're looking for.
5. Extract 4 frames out of a cycle of 10 using SelectEvery.
Tada!

ShogoXT
30th December 2016, 22:44
No, no, fades like that can still be saved. By which I mean that you can obtain a 24 fps fade with smooth motion even if field matching is impossible in the fade. The solution involves QTGMC, so the detail preservation isn't awesome, but it's still good, considering the situation.

Steps:
1. Invoke source filter to obtain the untouched 30 fps clip.
2. Extract the fade using Trim.
3. Pass to QTGMC to obtain a 60 fps clip.
4. Stare at the output of QTGMC really carefully. It's been a few months since I did this, so I forget exactly what you're looking for.
5. Extract 4 frames out of a cycle of 10 using SelectEvery.
Tada!

I was under the impression that if the source is 2:3 telecined that it HAD to be ivtc and not QTGMC. QTGMC is very nice but I thought it was for interlace 121212 only. Vinverse has helped me a little, does the color conversation and fixfade cost much speed?

fAy01
30th December 2016, 23:08
No, no, fades like that can still be saved. By which I mean that you can obtain a 24 fps fade with smooth motion even if field matching is impossible in the fade. The solution involves QTGMC, so the detail preservation isn't awesome, but it's still good, considering the situation.

Steps:
1. Invoke source filter to obtain the untouched 30 fps clip.
2. Extract the fade using Trim.
3. Pass to QTGMC to obtain a 60 fps clip.
4. Stare at the output of QTGMC really carefully. It's been a few months since I did this, so I forget exactly what you're looking for.
5. Extract 4 frames out of a cycle of 10 using SelectEvery.
Tada!

Is there a possibility to write a script/plugin that deinterlaces and matches correctly at the same time without using QTGMC?

Mystery Keeper
30th December 2016, 23:47
I was under the impression that if the source is 2:3 telecined that it HAD to be ivtc and not QTGMC. QTGMC is very nice but I thought it was for interlace 121212 only. Vinverse has helped me a little, does the color conversation and fixfade cost much speed?After IVTC you can still find a lot of combed frames of various origins.

WolframRhodium
31st December 2016, 01:43
done, use the "threshold" parameter

I mean maybe the calculation of TopFieldSum/BottomFieldSum can be done in a small neighborhood, for example, 16x16 block?

There seems to be some residual fades after filtering, and I think the reason is the calculation is done in global, currently.

feisty2
31st December 2016, 08:16
I mean maybe the calculation of TopFieldSum/BottomFieldSum can be done in a small neighborhood, for example, 16x16 block?

There seems to be some residual fades after filtering, and I think the reason is the calculation is done in global, currently.

the statistical info(TopFieldSum/BottomFieldSum) should be no-local according to the weak law of large numbers (https://en.wikipedia.org/wiki/Law_of_large_numbers#Weak_law).
if you got residual combing still even with threshold=0, it's then most likely your video suffers from something other than telecined fades and this filter won't help

feisty2
31st December 2016, 08:23
No, no, fades like that can still be saved. By which I mean that you can obtain a 24 fps fade with smooth motion even if field matching is impossible in the fade. The solution involves QTGMC, so the detail preservation isn't awesome, but it's still good, considering the situation.

Steps:
1. Invoke source filter to obtain the untouched 30 fps clip.
2. Extract the fade using Trim.
3. Pass to QTGMC to obtain a 60 fps clip.
4. Stare at the output of QTGMC really carefully. It's been a few months since I did this, so I forget exactly what you're looking for.
5. Extract 4 frames out of a cycle of 10 using SelectEvery.
Tada!

my definition of "repair" is, to perfectly restore the frame without deinterlacing.

WolframRhodium
31st December 2016, 09:14
the statistical info(TopFieldSum/BottomFieldSum) should be no-local according to the weak law of large numbers (https://en.wikipedia.org/wiki/Law_of_large_numbers#Weak_law).
if you got residual combing still even with threshold=0, it's then most likely your video suffers from something other than telecined fades and this filter won't help

Thank you for your reply. I misunderstood the function of this filter before and now I understand it better. :thanks:

feisty2
15th January 2017, 11:01
r3:
AVX and FMA3 optimizations, will probably crash if your CPU is a predecessor of the Haswell microarchitecture (just use r2 in that case)

feisty2
15th January 2017, 11:07
guess I can actually optimize my floating point MVTools now with AVX and FMA, but I don't really want to...

Mystery Keeper
15th January 2017, 11:13
guess I can actually optimize my floating point MVTools now with AVX and FMA, but I don't really want to...Pretty please with a cherry on the top?

Myrsloik
15th January 2017, 11:34
r3:
AVX and FMA3 optimizations, will probably crash if your CPU is a predecessor of the Haswell microarchitecture (just use r2 in that case)

How much faster is it?

feisty2
15th January 2017, 13:14
How much faster is it?

r2 runs at 476.65fps at 1920x1080
r3 runs at 489.65fps at 1920x1080

makes no sense!!!
shouldn't AVX and FMA be at least 8x faster than x87???

I think there's probably something wrong with my compiler (VS2017), can you please compile the source code with your compiler and do a test as well?

to switch avx/fma back to c++

Line 225: FixFadesPrepare_AVX(); -> FixFadesPrepare();

Line 231: FixFadesMode0_AVX_FMA(); -> FixFadesMode0();

Line 234: FixFadesMode1_AVX_FMA(); -> FixFadesMode1();

Line 237: FixFadesMode2_AVX_FMA(); -> FixFadesMode2();

feisty2
15th January 2017, 13:16
Pretty please with a cherry on the top?

someday, I'll add that to my to-do list...

cork_OS
15th January 2017, 15:59
shouldn't AVX and FMA be at least 8x faster than x87???
1. It's limited by FPU IPC (real number and width of add/mult/etc. units).
2. Why x87? Are you using 80 bits of precision?

Myrsloik
15th January 2017, 16:08
r2 runs at 476.65fps at 1920x1080
r3 runs at 489.65fps at 1920x1080

makes no sense!!!
shouldn't AVX and FMA be at least 8x faster than x87???

I think there's probably something wrong with my compiler (VS2017), can you please compile the source code with your compiler and do a test as well?

to switch avx/fma back to c++

Line 225: FixFadesPrepare_AVX(); -> FixFadesPrepare();

Line 231: FixFadesMode0_AVX_FMA(); -> FixFadesMode0();

Line 234: FixFadesMode1_AVX_FMA(); -> FixFadesMode1();

Line 237: FixFadesMode2_AVX_FMA(); -> FixFadesMode2();

YOU ARE NOT USING X87!!! You compiled it as x64 code and the ABI (more or less) requires it to use sse2 instructions to implement it. Obviously at least the scalar float versions. It's even possible that it managed to auto vectorize like half of this code since most of it is just mindless read and sum. Look at the generated code instead of asking us about what you, YOURSELF, told the compiler to do.

Your assumption still wouldn't be true about x87 vs avx. For simple algorithms you run into memory bw limitations long before you see the glory of sse (avx is even more rare to matter). Modern cpus are just too good.

feisty2
15th January 2017, 16:53
YOU ARE NOT USING X87!!! You compiled it as x64 code and the ABI (more or less) requires it to use sse2 instructions to implement it. Obviously at least the scalar float versions. It's even possible that it managed to auto vectorize like half of this code since most of it is just mindless read and sum. Look at the generated code instead of asking us about what you, YOURSELF, told the compiler to do.
the "Look at the generated code" part is a bit too hard to me tho... Staring at thousands lines of generated assembly is far beyond my programming skill since I'm not a professionally trained programmer...

Your assumption still wouldn't be true about x87 vs avx. For simple algorithms you run into memory bw limitations long before you see the glory of sse (avx is even more rare to matter). Modern cpus are just too good.
which means it's pretty much pointless to manually optimize simple plugins?

Myrsloik
15th January 2017, 16:58
the "Look at the generated code" part is a bit too hard to me tho... Staring at thousands lines of generated assembly is far beyond my programming skill since I'm not a professionally trained programmer...

which means it's pretty much pointless to manually optimize simple plugins?

It's not thousands of lines. The interesting part is about 50 instructions at most. How to do shit properly: set a breakpoint in one of your inner loops, when it's hit simply open the (debug\window\disassembly) window. Look at like 10 instructions and see what it picked. Repeat for all critical loops. Done.

And yes, you're wasting perfectly good internet space by trying to optimize such simple things. Oh, and if you can't read simple disassembled stuff you shouldn't be writing optimizations like these in the first place.

MonoS
18th January 2017, 23:57
Ohi feisty, if you want some help with your optimization task fell free to ask to me directly (send me a PM and we can chose a more direct mean of communication)

As Myrsloik said probably your code was just being autovectorized directly by the compiler, on gcc for example if you compile with -O3 and -march=native it will try to vectorize using the best instruction set you have available. Probably vc do the same.

First things first, i'll base all my statement using the intel reference you can find here https://software.intel.com/sites/landingpage/IntrinsicsGuide/ , agner sheet would be better but is not as easy to use, also i'll use the official intel optimization guide http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html.

There are some things you could write better just looking at ProcessLine_AVX_FMA.
First you should avoid all those store, without an assembly listing it's a bit difficult to know, but probably they are using most of the load/store port making it more difficult for the processor to load data (the load port are shared with the store ones), also you are clogging the frontend with useless istruction to decode.
Division are NO when dealing with any kind of core, on haswell they are 21 cycles of latency (and you can issues another one after 13 cycles), you can turn it in a multiplication making the reciprocal of the value, multiplication are WAAAAAY cheaper than division (5 cycles latency, 0.5 througput) and even more you can predivide YMMField and YMMReference and make a single call to fmad.
I'd also suggest to remove the _mm256_set_ps at the start and replace with a _mm256_set1_ps.

If assembly listing are for you hard to reason about, i'll try AICA (always from intel) https://software.intel.com/en-us/articles/intel-architecture-code-analyzer , this software will give you a better understanding where your code is failing, it helped me a lot understand where i was doing things wrong with my optimization in mvtools.

There are other places where you could write better SIMD code, but for now i'll stop :) .

I strongly disagree with myrsloik as this being a waste of time, i find SIMD optimization to be very fun to program with and simple code teach the basics of SIMD programming, and yes, sometimes computer generated assembly is better than handmade one, but people improve over time.

For a tutorial from an "expert", i MUST suggest you to watch some of the first episode of handmade hero in which @cmuratori explayn how to SIMD optimize math heavy code, you can find the playlist here https://www.youtube.com/playlist?list=PLEMXAbCVnmY5qGQB96s7Vysr1nJcX_BW_ what episode from 112 to 121 (337 is a bonus becose i'm pretty behind the series).

With this i go to sleep after have recovered ALL THIS TEXT from ram cause my browser froze just before me finish this message, i hope to have been of some help.

feisty2
27th January 2017, 16:16
r4 runs at 626.89 fps at 1920x1080, 150.24 fps faster than the compiler generated code (no idea if optimized or not)
@MonoS
you were right that _mm256_div_ps was the bottleneck there, I removed it and got a noticeable performance boost, thx.

anyone could show me how to do that "opt" parameter thing? like call the avx function if it's supported by the CPU, and call the C++ function if not.. and please tell me I don't have to write asm for it

TheFluff
27th January 2017, 18:51
You need to write asm to identify the CPU, but it's trivial. Just steal from the VS source tree:

cpu.asm (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/asm/x86/cpu.asm)
cpufeatures.c (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/cpufeatures.c)
cpufeatures.h (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/cpufeatures.h)

Myrsloik
27th January 2017, 18:53
You need to write asm to identify the CPU. From the VS source tree:

cpu.asm (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/asm/x86/cpu.asm)
cpufeatures.c (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/cpufeatures.c)
cpufeatures.h (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/cpufeatures.h)

Just copy those files into your own project. Done.

feisty2
28th January 2017, 18:54
r5:
new parameter "opt"
opt: call the fastest possible functions if opt=True, else call the C++ functions.

Just copy those files into your own project. Done.

You need to write asm to identify the CPU, but it's trivial. Just steal from the VS source tree:

cpu.asm (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/asm/x86/cpu.asm)
cpufeatures.c (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/cpufeatures.c)
cpufeatures.h (https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/cpufeatures.h)

Tried to use them but got stuck at "cpu.asm", apparently it requires nasm or yasm and these 2 are real pain in the ass, I wasted hours trying to make them work on VS2017 and all I got was millions of errors popping out relentlessly...

I even thought about translating "cpu.asm" to masm, and obviously I would have to translate "x86inc.asm" along with it, and that's a big NO.

so I merged those 3 into one file, "cpufeatures.hpp (https://github.com/IFeelBloated/Fix-Telecined-Fades/blob/master/cpufeatures.hpp)", and wrote my own version of CPUFeatures, with absolutely no trace of (literal) asm.

these 2 functions:

vs_cpu_cpuid()
vs_cpu_xgetbv()

have been integrated into the compiler,

Visual Studio 2017:
vs_cpu_cpuid() -> __cpuid()
GCC:
vs_cpu_cpuid() -> __get_cpuid()

vs_cpu_xgetbv() -> _xgetbv() //defined in immintrin.h


so I think there's no need to write literal asm for them.
and I canceled the "getCPUFeatures()" function, it could be simply integrated into the constructor since I'm using a C++ header.

so instead of

CPUFeatures CPU;
getCPUFeatures(&CPU);
if (CPU.fma3)
xxx

it's now cleaner like

auto CPU = CPUFeatures();
if (CPU.fma3)
xxx

Are_
29th January 2017, 02:02
Right now it looks like it's not compiling anymore with GCC.

feisty2
29th January 2017, 07:35
Right now it looks like it's not compiling anymore with GCC.

to make it work with GCC

cpufeatures.hpp:
line 1: #include <intrin.h> -> #include <cpuid.h>
line 6: return static_cast<int32_t>(val); -> return static_cast<uint32_t>(val);
line 28: __cpuid(Registers, 1); -> __get_cpuid(1, &eax, &ebx, &ecx, &edx);
line 43:__cpuid(Registers, 7); -> __get_cpuid(7, &eax, &ebx, &ecx, &edx);

feisty2
29th January 2017, 07:58
Right now it looks like it's not compiling anymore with GCC.

or just use this version of cpufeatures.hpp (https://github.com/IFeelBloated/Fix-Telecined-Fades/blob/master/cpufeatures_gnu.hpp)

MonoS
29th January 2017, 13:03
Glad to be of help :)

sl1pkn07
29th January 2017, 15:03
or just use this version of cpufeatures.hpp (https://github.com/IFeelBloated/Fix-Telecined-Fades/blob/master/cpufeatures_gnu.hpp)

nope

https://sl1pkn07.wtf/paste/view/b0cc57fb

feisty2
29th January 2017, 16:37
nope

https://sl1pkn07.wtf/paste/view/b0cc57fb

working now?

I'm sure I fixed everything except the "xgetbv" part, that function has been integrated into immintrin.h in Visual Studio 2017 but apparently not in GCC...
You'll have to compile cpu.asm yourself with yasm or nasm and I can't help you with that... I wouldn't have written my own Visual Studio version of CPUFeatures if I could handle them..

sl1pkn07
29th January 2017, 16:40
nope
https://sl1pkn07.wtf/paste/view/b2ac319f

let me time to test with yasm, idk how manage it

feisty2
29th January 2017, 16:56
that's weird...
please modify the source code manually and report back..
line 139:
replace

_mm256_store_ps(reinterpret_cast<float *>(&YMMField), _mm256_add_ps(reinterpret_cast<const __m256 &>(srcp[y][x]), YMMField));

with

_mm256_store_ps(reinterpret_cast<float *>(&YMMField), _mm256_add_ps(*reinterpret_cast<const __m256 *>(&srcp[y][x]), YMMField));

sl1pkn07
29th January 2017, 17:08
https://sl1pkn07.wtf/paste/view/883d7e05

feisty2
29th January 2017, 18:28
https://sl1pkn07.wtf/paste/view/883d7e05

I googled that error and apparently the source code was not what caused it.

there's something wrong with your compiling settings
That's the usual message for intrinsics that you haven't told the compiler the target supports.
see: http://stackoverflow.com/questions/35772562/inlining-failed-in-call-to-always-inline-m128i-mm-cvtepu8-epi32-m128i-t

damn, now I get how nice that Visual Studio compiler is (from the user's point of view), I never had any sort of shit like this with Visual Studio...

sl1pkn07
29th January 2017, 18:31
maybe is because my processor don't have AVX/FMA3 (Xeon x5650)

feisty2
29th January 2017, 18:36
maybe is because my processor dont have AVX/AVX2? (Xeon x5650)

you could try with "-march=haswell" and see if it does the trick

sl1pkn07
29th January 2017, 18:37
my processor is westmere/ep (+/- nehalem)

with -msse4.1

https://sl1pkn07.wtf/paste/view/9516661b

EDIT: with -march=haswell build ok. but i think is incompatible with my processor

feisty2
29th January 2017, 18:45
my processor is westmere/ep (+/- nehalem)

with -msse4.1

https://sl1pkn07.wtf/paste/view/9516661b

EDIT: with -march=haswell build ok. but i think is incompatible with my processor

doesn't matter, it will call the C++ functions automatically if the AVX functions fail.

sl1pkn07
29th January 2017, 18:46
is not better use "if detect, compile it" instead of force compiling?

feisty2
29th January 2017, 18:53
is not better use "if detect, compile it" instead of force compiling?

unfortunately, I don't know how to "if detect, compile it"...
is the forcibly-compiled binary running ok on your computer since there's the C++ function backup?

sl1pkn07
29th January 2017, 18:59
unfortunately, I don't know how to "if detect, compile it"...


something like:


#ifdef VAPOURSYNTH_H
static void VS_CC VapourSynthPluginViInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core,
const VSAPI *vsapi) {

NLMVapoursynth *d = (NLMVapoursynth*) * instanceData;
vsapi->setVideoInfo(d->vi, 1, node);
}
#endif //__VAPOURSYNTH_H__


(taken from knlmeans code)

but with CPU capabilities

EDIT: better example
EDIT: that is called conditionals? (sorry, im not coder, idk what is a real name of this)

feisty2
29th January 2017, 19:21
something like:


#ifdef VAPOURSYNTH_H
static void VS_CC VapourSynthPluginViInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core,
const VSAPI *vsapi) {

NLMVapoursynth *d = (NLMVapoursynth*) * instanceData;
vsapi->setVideoInfo(d->vi, 1, node);
}
#endif //__VAPOURSYNTH_H__


(taked from knlmeans code)

but with CPU capabilities

EDIT: better example
EDIT: that is called conditionals? (sorry, im not coder, idk what is a real name of this)

The past tense of "take" is "took", perfect tense "taken" :p
Anyways, it's called conditional compilation and I know how to do it theoretically but still can't do it, because it involves whole lot of compiler-specific macros that are not part of the C++ standard...

And since your compilation worked, I assume you figured out how to get yasm to work?
And does the compiled binary run correctly? (Checking if the "opt" parameter actually works)

sl1pkn07
29th January 2017, 19:48
about yasm

something like this?


diff --git a/Source.cpp b/Source.cpp
index 5409d6e..3dbd174 100644
--- a/Source.cpp
+++ b/Source.cpp
@@ -1,12 +1,13 @@
-#include "VapourSynth.h"
-#include "VSHelper.h"
-#include "cpufeatures.hpp"
+#include <VapourSynth.h>
+#include <VSHelper.h>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <immintrin.h>
#include <malloc.h>

+extern "C++" int CPUFeatures();
+
struct FixFadesData final {
const VSAPI *vsapi = nullptr;
VSNodeRef *node = nullptr;


(you can avoid the first change)

but i get https://sl1pkn07.wtf/paste/view/f32ca689

(takEN (XD) from https://github.com/vapoursynth/vapoursynth/blob/f65402b242b1eac05de1e485306ea1466d54541e/src/core/x86utils.h (with this help http://wiki.osdev.org/C%2B%2B_to_ASM_linkage_in_GCC)

about of test, give me time

feisty2
29th January 2017, 19:54
Include "cpufeatures_gnu.hpp" and remove that "extern "C++" int CPUFeatures();" thing

sl1pkn07
29th January 2017, 20:00
em, is the same as i tried before (only work with -march=haswell)(?)

or you mean convert the cpu.asm to object with yasm* and include it in the linker step?

*

yasm -f elf -m ${_m} -DARCH_X86_64=${_darch} -o cpu.o cpu.asm


can you share a clip/video sample? or how doing it with blankclip()

JoeyMonco
29th January 2017, 23:31
Anyways, it's called conditional compilation and I know how to do it theoretically but still can't do it, because it involves whole lot of compiler-specific macros that are not part of the C++ standard...

But compiler-specific cpuid functions are part of standard? Since when?

Myrsloik
30th January 2017, 00:02
Now you see why asm is kinda your friend.

There's a pile of pitfalls here you missed. And some you found.

1. You compile the whole file with avx2/whatever instrction set you selected. That means avx2 instructions may be emitted for you plain C++ code too. Solve it by placing the avx2 code in a separate file and use different compiler settings.

2. You can't put sse and avx intrinsics in the same file either. For example subps can get turned into vsubps to reduce register copies. So then the sse path needs avx too...

3. Cpuid is horrible in intrinsics, that's why I use asm. Lrn2yasm. Or write code that requires gcc or clang where convenient intrinsics are available. Clang is even available as a simple dropin for visual studio nowadays.

Mystery Keeper
30th January 2017, 05:19
Why do conditional compilation at all when you can compile function for every instruction set and use CPU information to select the proper function in runtime?

feisty2
30th January 2017, 05:40
or you mean convert the cpu.asm to object with yasm* and include it in the linker step?
yeah


can you share a clip/video sample? or how doing it with blankclip()
blankclip is okay, long as it's not crashing.

But compiler-specific cpuid functions are part of standard? Since when?
no they are not, but I can google this individual function and learn to use it, I can't however google thousands of compiler-specific macros and memorize them all.

JoeyMonco
30th January 2017, 05:59
yeah


blankclip is okay, long as it's not crashing.


no they are not, but I can google this individual function and learn to use it, I can't however google thousands of compiler-specific macros and memorize them all.

Thousands? Uhh no. There is __GNUC__ and __clang__ and _MSC_VER_.

http://stackoverflow.com/questions/28166565/detect-gcc-as-opposed-to-msvc-clang-with-macro

That was the first link in googling "how to detect gcc vs msvc"

feisty2
30th January 2017, 06:04
Now you see why asm is kinda your friend.

There's a pile of pitfalls here you missed. And some you found.

1. You compile the whole file with avx2/whatever instrction set you selected. That means avx2 instructions may be emitted for you plain C++ code too. Solve it by placing the avx2 code in a separate file and use different compiler settings.

2. You can't put sse and avx intrinsics in the same file either. For example subps can get turned into vsubps to reduce register copies. So then the sse path needs avx too...

3. Cpuid is horrible in intrinsics, that's why I use asm. Lrn2yasm. Or write code that requires gcc or clang where convenient intrinsics are available. Clang is even available as a simple dropin for visual studio nowadays.

1. got it
2. got it
3. the thing is I can't set it up... yasm doesn't seem to have an installer like clang that gets everything done automatically, also the manual setting-up documentation on the yasm website is obsolete, the visual studio folders it mentioned don't even exist anymore! I could switch to clang but that won't solve the xgetbv problem cuz it's not defined in clang's immintrin.h... and back to square one, I have to set up yasm first which is impossible.:(

sl1pkn07
30th January 2017, 07:39
yeah


blankclip is okay, long as it's not crashing.


Ok, but how? Xd

feisty2
30th January 2017, 12:37
Ok, but how? Xd

I separated the source code into 2 files.
just compile "Source.cpp" with "-march=native" and "Source_AVX_FMA.cpp" with "-march=haswell" and it should work, you don't have to edit the source code this time, I added the conditional compilation macros and it would pick "cpufeatures_gnu.hpp" automatically if you're on GCC

test script

import vapoursynth as vs
core = vs.get_core()
clp = core.std.BlankClip(width=1920, height=1080, format=vs.GRAYS, length=20000)
clp = core.ftf.FixFades(clp)
clp.set_output()

sl1pkn07
30th January 2017, 14:00
http://stackoverflow.com/questions/6121792/how-to-check-if-a-cpu-supports-the-sse3-instruction-set

if help you

feisty2
30th January 2017, 14:09
http://stackoverflow.com/questions/6121792/how-to-check-if-a-cpu-supports-the-sse3-instruction-set

if help you

I know how to do that SIMD extension detecting at runtime and it's already there in the source code, I don't need any help

I'm asking if it's working cuz I'm not sure about that..

sl1pkn07
30th January 2017, 14:58
Failed to evaluate the script:
Python exception: No attribute with the name ftf exists. Did you mistype a plugin namespace?
Traceback (most recent call last):
File "src/cython/vapoursynth.pyx", line 1712, in vapoursynth.vpy_evaluateScript (src/cython/vapoursynth.c:34991)
File "/home/sl1pkn07/aplicaciones/vapoursynth-test/fixtelecided-test.vpy", line 4, in
clp = core.ftf.FixFades(clp)
File "src/cython/vapoursynth.pyx", line 1306, in vapoursynth.Core.__getattr__ (src/cython/vapoursynth.c:28067)
AttributeError: No attribute with the name ftf exists. Did you mistype a plugin namespace?



all:
g++ -c -std=c++14 -fPIC -march=native -O2 -pipe -fstack-protector-strong -D_FORTIFY_SOURCE=2 -I. -I/usr/include/vapoursynth -o fixtelecinedfades.o Source.cpp
yasm -f elf -m amd64 -DARCH_X86_64=1 -o cpu.o cpu.asm
g++ -shared -fPIC -Wl,-O1,--sort-common,--as-needed,-z,relro -o libvsfixtelecinedfades.so fixtelecinedfades.o cpu.o

feisty2
2nd February 2017, 18:50
Failed to evaluate the script:
Python exception: No attribute with the name ftf exists. Did you mistype a plugin namespace?
Traceback (most recent call last):
File "src/cython/vapoursynth.pyx", line 1712, in vapoursynth.vpy_evaluateScript (src/cython/vapoursynth.c:34991)
File "/home/sl1pkn07/aplicaciones/vapoursynth-test/fixtelecided-test.vpy", line 4, in
clp = core.ftf.FixFades(clp)
File "src/cython/vapoursynth.pyx", line 1306, in vapoursynth.Core.__getattr__ (src/cython/vapoursynth.c:28067)
AttributeError: No attribute with the name ftf exists. Did you mistype a plugin namespace?



all:
g++ -c -std=c++14 -fPIC -march=native -O2 -pipe -fstack-protector-strong -D_FORTIFY_SOURCE=2 -I. -I/usr/include/vapoursynth -o fixtelecinedfades.o Source.cpp
yasm -f elf -m amd64 -DARCH_X86_64=1 -o cpu.o cpu.asm
g++ -shared -fPIC -Wl,-O1,--sort-common,--as-needed,-z,relro -o libvsfixtelecinedfades.so fixtelecinedfades.o cpu.o


then I think I won't be able to help you with that... sorry
I'm really just not familiar with all that gnu stuff and

1. there's the runtime simd extension detection so the unsupported forcibly-compiled functions won't matter cuz they will never get called.
2. you compiled "Source.cpp" which contains functions that will actually get called with "-march=native", so there should be no unsupported instructions in those functions.

so logically I can't see why your binary failed to work, maybe you should ask others that are more familiar with the whole gnu world..

feisty2
3rd February 2017, 05:26
anyways, if you really wanna use this plugin,
manually comment out:
line3
line123
line124
line156 - line161
in "Source.cpp",
line10 - line14 in "Shared.hpp"
and compile it and it should work..

jackoneill
6th February 2017, 21:57
Python exception: No attribute with the name _____ exists. Did you mistype a plugin namespace?

If you get this error and you know you have the plugin, try to load it manually to find out what's wrong with it:

core.std.LoadPlugin("/your/plugin/here.so")

sl1pkn07
6th February 2017, 21:58
@jackoneill the steps for build the plugin whit yasm is correct?

edit:


Failed to evaluate the script:
Python exception: Failed to load /usr/lib/vapoursynth/libvsfixtelecinedfades.so. Error given: /usr/lib/vapoursynth/libvsfixtelecinedfades.so: undefined symbol: _Z24fixfadesGetFrame_AVX_FMAiiPPvS0_P14VSFrameContextP6VSCorePK5VSAPI
Traceback (most recent call last):
File "src/cython/vapoursynth.pyx", line 1712, in vapoursynth.vpy_evaluateScript (src/cython/vapoursynth.c:34991)
File "/home/sl1pkn07/aplicaciones/vapoursynth-plugin-fixtelecinedfades-git/fixtelecined-test.vpy", line 3, in
clp = core.std.BlankClip(width=1920, height=1080, format=vs.GRAYS, length=20000)
File "src/cython/vapoursynth.pyx", line 1604, in vapoursynth.Function.__call__ (src/cython/vapoursynth.c:33131)
vapoursynth.Error: Failed to load /usr/lib/vapoursynth/libvsfixtelecinedfades.so. Error given: /usr/lib/vapoursynth/libvsfixtelecinedfades.so: undefined symbol: _Z24fixfadesGetFrame_AVX_FMAiiPPvS0_P14VSFrameContextP6VSCorePK5VSAPI

jackoneill
6th February 2017, 22:41
Gah, you made me look at the code.

You forgot to compile Source_AVX_FMA.cpp.

sl1pkn07
6th February 2017, 22:45
but that is not only for AVX CPU compilant?

Source.cpp -> older CPU
Source_AVX_FMA.cpp -> newer CPU

because Source_AVX_FMA.cpp needs build with -march=haswell, amd my cpu is not capable (don't have AVX or FMA3)

jackoneill
6th February 2017, 23:24
but that is not only for AVX CPU compilant?

Source.cpp -> older CPU
Source_AVX_FMA.cpp -> newer CPU

because Source_AVX_FMA.cpp needs build with -march=haswell, amd my cpu is not capable (don't have AVX or FMA3)

If the author did everything right, the code from that file will only be used if the CPU has FMA3. You still have to compile it.

sl1pkn07
7th February 2017, 09:25
ok. done

feisty2
7th February 2017, 09:36
ok. done

is it working now?

sl1pkn07
7th February 2017, 09:38
i think yes, but i need make more test

if all is ok, then i think you can merge the Source{,_AVX_FMA}.cpp again

sorry :S

feisty2
7th February 2017, 09:53
i think yes, but i need make more test

if all is ok, then i think you can merge the Source{,_AVX_FMA}.cpp again

sorry :S

no, I can't(shouldn't).
if I do merge Source.cpp and Source_AVX_FMA.cpp into one file, you'll have to compile that file with -march=haswell, and the compiler will probably generate unsupported instructions for the C++ functions..

feisty2
7th February 2017, 10:19
i think yes, but i need make more test

if all is ok, then i think you can merge the Source{,_AVX_FMA}.cpp again

sorry :S

I think you should make a PR on GitHub so I can merge those GNU compiling files into the repo

sl1pkn07
7th February 2017, 10:25
Then need making more refraction in Source.cpp, because as @jackoneill said,build Source.cpp with march=native and build Source_AVX_FMA3.cpp with march=haswell and merge both in the library, the plugin now load without problem. build

feisty2
7th February 2017, 10:33
Then need making more refraction in Source.cpp, because build It with march=native and build source_avx_fma3.cpp with march=haswell and merge both in the library the plugin now load without problem. Like @jackoneill said

what do you mean by "more refraction in Source.cpp"?

sl1pkn07
7th February 2017, 11:29
because if only build Source.cpp

https://forum.doom9.org/showpost.php?p=1796109&postcount=70

and if build both source.cpp and Source_AVX_FMA3.cpp the plugin is loaded and seems work

feisty2
7th February 2017, 11:33
of course you should compile both files, what's the problem here?

sl1pkn07
7th February 2017, 11:45
again. this make conflicts if the processor don't support AVX/FMA3?

feisty2
7th February 2017, 11:55
again. this make conflicts if the processor don't support AVX/FMA3?

ahh, I wish I could speak Spanish so it would be less painful for us to communicate..

like I said a million times before, you MUST compile Source_AVX_FMA.cpp (even if AVX and FMA are not supported by your CPU, forcibly compile it with -march=haswell if that's the case)
and it won't matter because the AVX/FMA functions will be rejected at RUNTIME if they are not supported by your CPU.

sl1pkn07
7th February 2017, 12:58
then all fine

Jindadil007
8th February 2017, 05:11
Really Good Filter...Got very good results...Thanks Feisty2

KingLir
22nd February 2017, 13:24
Trying to build this on macOS and getting the following error. Any ideas ?

meson-log seems ok, here is a copy. (https://mega.nz/#!B84Wja4Z!4jysdgIqJfmuh68cZRo9jSqYDFRaJlTUXZlQ9XF3ekQ)

[1/4] Compiling cpp object 'avxfma@sta/Source_AVX_FMA.cpp.o'
FAILED: avxfma@sta/Source_AVX_FMA.cpp.o
c++ '-Iavxfma@sta' '-I.' '-I..' '-I/usr/local/Cellar/vapoursynth/36/include/vapoursynth' '-I/usr/local/Cellar/zimg/2.4/include' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-std=c++14' '-O3' '-mavx' '-mfma' '-MMD' '-MQ' 'avxfma@sta/Source_AVX_FMA.cpp.o' '-MF' 'avxfma@sta/Source_AVX_FMA.cpp.o.d' -o 'avxfma@sta/Source_AVX_FMA.cpp.o' -c ../Source_AVX_FMA.cpp
In file included from ../Source_AVX_FMA.cpp:1:
../Shared.hpp:8:10: fatal error: 'malloc.h' file not found
#include <malloc.h>
^
1 error generated.
[2/4] Compiling cpp object 'fixtelecinedfades@sha/Source.cpp.o'
FAILED: fixtelecinedfades@sha/Source.cpp.o
c++ '-Ifixtelecinedfades@sha' '-I.' '-I..' '-I/usr/local/Cellar/vapoursynth/36/include/vapoursynth' '-I/usr/local/Cellar/zimg/2.4/include' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-std=c++14' '-O3' '-MMD' '-MQ' 'fixtelecinedfades@sha/Source.cpp.o' '-MF' 'fixtelecinedfades@sha/Source.cpp.o.d' -o 'fixtelecinedfades@sha/Source.cpp.o' -c ../Source.cpp
In file included from ../Source.cpp:1:
../Shared.hpp:8:10: fatal error: 'malloc.h' file not found
#include <malloc.h>
^
1 error generated.
ninja: build stopped: subcommand failed.

feisty2
22nd February 2017, 13:54
Trying to build this on macOS and getting the following error. Any ideas ?

meson-log seems ok, here is a copy. (https://mega.nz/#!B84Wja4Z!4jysdgIqJfmuh68cZRo9jSqYDFRaJlTUXZlQ9XF3ekQ)

[1/4] Compiling cpp object 'avxfma@sta/Source_AVX_FMA.cpp.o'
FAILED: avxfma@sta/Source_AVX_FMA.cpp.o
c++ '-Iavxfma@sta' '-I.' '-I..' '-I/usr/local/Cellar/vapoursynth/36/include/vapoursynth' '-I/usr/local/Cellar/zimg/2.4/include' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-std=c++14' '-O3' '-mavx' '-mfma' '-MMD' '-MQ' 'avxfma@sta/Source_AVX_FMA.cpp.o' '-MF' 'avxfma@sta/Source_AVX_FMA.cpp.o.d' -o 'avxfma@sta/Source_AVX_FMA.cpp.o' -c ../Source_AVX_FMA.cpp
In file included from ../Source_AVX_FMA.cpp:1:
../Shared.hpp:8:10: fatal error: 'malloc.h' file not found
#include <malloc.h>
^
1 error generated.
[2/4] Compiling cpp object 'fixtelecinedfades@sha/Source.cpp.o'
FAILED: fixtelecinedfades@sha/Source.cpp.o
c++ '-Ifixtelecinedfades@sha' '-I.' '-I..' '-I/usr/local/Cellar/vapoursynth/36/include/vapoursynth' '-I/usr/local/Cellar/zimg/2.4/include' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-std=c++14' '-O3' '-MMD' '-MQ' 'fixtelecinedfades@sha/Source.cpp.o' '-MF' 'fixtelecinedfades@sha/Source.cpp.o.d' -o 'fixtelecinedfades@sha/Source.cpp.o' -c ../Source.cpp
In file included from ../Source.cpp:1:
../Shared.hpp:8:10: fatal error: 'malloc.h' file not found
#include <malloc.h>
^
1 error generated.
ninja: build stopped: subcommand failed.

the error basically tells you that a header file "malloc.h" is missing
"malloc.h" should be provided by the compiler and it's also where the dynamic stack memory allocation function "alloca()" (unlike C99 and later versions of C, variable length array in stack frame (std::vector is a heap array, which means it's much slower than alloca()) is not allowed in C++, which leaves alloca() the only option to do such thing) should be defined..

"malloc.h" should be available in Visual Studio and GCC, maybe you should try one of these 2 compilers

jackoneill
22nd February 2017, 14:03
the error basically tells you that a header file "malloc.h" is missing
"malloc.h" should be provided by the compiler and it's also where the dynamic stack memory allocation function "alloca()" (unlike C99 and later versions of C, variable length array in stack frame (std::vector is a heap array, which means it's much slower than alloca()) is not allowed in C++, which leaves alloca() the only option to do such thing) should be defined..

"malloc.h" should be available in Visual Studio and GCC, maybe you should try one of these 2 compilers

You wouldn't need the nonstandard alloca function if you would use the plane pointers directly.

Try to include alloca.h instead of malloc.h.

KingLir
22nd February 2017, 14:24
"malloc.h" should be available in Visual Studio and GCC, maybe you should try one of these 2 compilers

The instructions says to use meson build system - so that what I used. Anyway, it's not straightforward to just build it with Visual Studio on macOS :)

I did what jackoneill suggested and changed the line in Shared.hpp to alloca.h instead of malloc.h.

It now build successfully with just one warning:

../Source.cpp:165:23: warning: 'VapourSynthPluginInit' has C-linkage specified, but returns user-defined type 'auto' which is incompatible with C [-Wreturn-type-c-linkage]
VS_EXTERNAL_API(auto) VapourSynthPluginInit(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin) {
^
1 warning generated.

Is this warning OK ? And are there any forseen impact (performance and etc) in using alloca instead of malloc ?

feisty2
22nd February 2017, 14:29
You wouldn't need the nonstandard alloca function if you would use the plane pointers directly.

but alloca freed me from the misery of pointer arithmetic which is dangerous and error-prone and a very ugly style of programming imho, it also restored the image back to its physical representation (2D instead of 1D in RAM), so "alloca" is definitely a big YEEESSSS to me


Try to include alloca.h instead of malloc.h.

got it.

feisty2
22nd February 2017, 14:39
The instruction says to use meson build system - so that what I used. Anyway, it's not straightforward to just build it with Visual Studio on macOS :)

I did what jackoneill suggested an changed the line in Shared.hpp to alloca.h instead of malloc.h.

It now build successfully with just one warning:

../Source.cpp:165:23: warning: 'VapourSynthPluginInit' has C-linkage specified, but returns user-defined type 'auto' which is incompatible with C [-Wreturn-type-c-linkage]
VS_EXTERNAL_API(auto) VapourSynthPluginInit(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin *plugin) {
^
1 warning generated.

Is this warning OK ?

it's okay, just ignore the warning.


And are there any forseen impact (performance and etc) in using alloca instead of malloc ?

alloca() could be translated into simply 1 assembly instruction if inlined (ignoring the 16 byte alignment of rsp)

sub rsp, size

and "malloc()" is much more complicated than "alloca()" at the assembly level, so alloca() is WAY faster than malloc(), at least ~1000 times faster from my previous tests.

KingLir
22nd February 2017, 14:47
Thank you guys! You should go and do a commit with the change.

A newbie question, what does it means " vapoursynth.Error: FixFades: input clip must be single precision fp, with constant dimensions. " ?
I am using a DVD (mpeg2) source. What conversation should I do ?

feisty2
22nd February 2017, 14:50
core.fmtc.bitdepth(xxx, bits=32, fulls=False, fulld=True)

KingLir
22nd February 2017, 15:11
core.fmtc.bitdepth(xxx, bits=32, fulls=False, fulld=True)

Thanks. I am getting only "pipe:: Invalid data found when processing input" for the following script:

clip = core.ffms2.Source(source.mkv)
clip = core.fmtc.bitdepth(clip=clip, bits=32, fulls=False, fulld=True)
clip = core.ftf.FixFades(clip=clip, mode=0, threshold=0.002, color=[0.0, 0.0, 0.0], opt=True)
clip.set_output()

feisty2
22nd February 2017, 15:17
your script is correct, maybe your output program does not support 32bits precision videos (I mean even the crappy 10bits gets to be so called "high bitdepth")

jackoneill
22nd February 2017, 15:19
but alloca freed me from the misery of pointer arithmetic which is dangerous and error-prone and a very ugly style of programming imho, it also restored the image back to its physical representation (2D instead of 1D in RAM), so "alloca" is definitely a big YEEESSSS to me


got it.

srcp[i] = reinterpret_cast<const float *>(vsapi->getReadPtr(src, plane)) + i * src_stride;
dstp[i] = reinterpret_cast<float *>(vsapi->getWritePtr(dst, plane)) + i * dst_stride;

That's pointer arithmetic right there.

feisty2
22nd February 2017, 15:36
srcp[i] = reinterpret_cast<const float *>(vsapi->getReadPtr(src, plane)) + i * src_stride;
dstp[i] = reinterpret_cast<float *>(vsapi->getWritePtr(dst, plane)) + i * dst_stride;

That's pointer arithmetic right there.

I think pointer arithmetic like this is kind of safe at least, basically because it's a one-time thing, initialize once with pointer arithmetic and no more afterwards.

and if there's no alloca() doing the dirty work before you get the actual thing started, you will have to later write a lot of crap like

srcp += src_stride;
dstp += dst_stride;

everytime you dereference the pointers within a loop...

and say you're out of your mind for a sec and forget to write that crap in the loop, what's about to happen is:
BOOM! crash!

and when that happens, it's again, extremely hard to find where the program went wrong.

and "alloca()" freed you from all these troubles

KingLir
22nd February 2017, 17:45
your script is correct, maybe your output program does not support 32bits precision videos (I mean even the crappy 10bits gets to be so called "high bitdepth")

Oh, I am using ffmpeg. Should I look for a special build of ffmpeg that support 32bits precision ? Do you know where I can find it ?

jackoneill
22nd February 2017, 20:33
Oh, I am using ffmpeg. Should I look for a special build of ffmpeg that support 32bits precision ? Do you know where I can find it ?

ffmpeg doesn't like floating point formats. You'll have to convert back to some integer format before output.

Or nag feisty2 to add support for integer clips, because there's no reason not to.

KingLir
22nd February 2017, 20:55
You'll have to convert back to some integer format before output.


Can you give me the line for the vs script ?


Or nag feisty2 to add support for integer clips, because there's no reason not to.

feisty2 - you are officially naged :)

feisty2
25th February 2017, 15:01
feisty2 - you are officially naged :)

I don't think that would be a good idea simply because integer formats are evil..

with floating point formats (half, single or double if supported someday), black is always [0.0, 0.0, 0.0]
with integer formats, black could either be
full range YUV: [0, 1 << (bits - 1), 1 << (bits - 1)]
or
tv range YUV: [16 << (bits - 8), 1 << (bits - 1), 1 << (bits - 1)]
or
RGB: [0, 0, 0]
which is already super confusing to newbies and the base color might not be black... and that's gonna get even more complicated...

I'd say just convert whatever you have to floating point format and save all that crap, floating point formats are much more beautiful than integer stuff from the mathematical point of view.

KingLir
26th February 2017, 00:14
I'd say just convert whatever you have to floating point format and save all that crap, floating point formats are much more beautiful than integer stuff from the mathematical point of view.

I see, thanks. What line should I use in vs script ?

ChaosKing
23rd December 2017, 16:49
Maybe I found a bug:

a2 = core.ftf.FixFades(a2, mode=0, threshold=0.0002, color=[0.56, 0.39, 0.22], opt=True)

I found this broken frame https://imgur.com/a/hCXq7

I know the threshold is lower (I was experimenting). But it does not happen with pure white/black color values + same thresh.