Log in

View Full Version : AviSynth+ thread Vol.2


Pages : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [18] 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

StainlessS
16th February 2021, 15:05
Tanks for your consideration P, "dont do dat" seems to be the way to go.

EDIT: Get my jab tomorrow. :)

EDIT: I think is unlimited parameters in Avs+, not sure bout 2.6 std.
I believe that at one time it may have been limited to 64. [think was maybe qyot27 idea to make unlimited].

stax76
18th February 2021, 16:06
Wiki page on AviSynth Unicode support on Windows 10 1903:

https://github.com/staxrip/staxrip/wiki/AviSynth-Unicode-support-on-Windows-10-1903

DTL
19th February 2021, 05:11
Can this approach - http://downloads.bbc.co.uk/rd/pubs/reports/1987-22.pdf be added to http://avisynth.nl/index.php/Limiter core filter ?

pinterf
22nd February 2021, 10:04
I've run through it, probably yes, but in my age a quick overview is not enough for deep understanding of the possible implementation steps. I'll return to the topic later.

DTL
23rd February 2021, 10:15
It looks some very hard long strategic question on core and plugin development:

Because of current execution hardware architecture moving to large number of processing cores with small per-core L1d cache and slow main memory access can be the new scan formats be added like blocks scan instead of full-frame line scans ?

Currently for algorithms for vertical data accessing it is require to read memory with large strides and it even 1 full line of 8K frame in float32 eats all 32 kB L1d cache.

The size of scan blocks is a new question. It looks must be < L1d cache size like 32..48 kB maximum and the ratio of V/H may be from 1:1 to may be natural for 4/3..16/9 frame.

The scan re-formatting may be made inside each plugin to and back but it will slow performance. May be also some plans in this direction exist ?

pinterf
23rd February 2021, 11:06
Given the large number of plugins and the extra complexity it introduces I think it will never happen. Filters are complex enough even without this feature. How many OpenCL or CUDA filters do we know? Only a few of them exist. Actually CUDA support** seems to be working with Avisynth+ core (do not search it in the official releases :) ) supporting native CUDA filter chain.

Like https://github.com/pinterf/AviSynthCUDAFilters . It includes
https://github.com/pinterf/NNEDI3/tree/cuda
https://github.com/pinterf/masktools/tree/cuda
I have forked them from Nekopanda's github pages and updated them to work with actual Avisynth 3.7. CUDA version build now is supported from CMake as well
https://github.com/AviSynth/AviSynthPlus/commit/891d100825c8fa5f0252d3198ba6d10e0817eef6
Other useful info:
https://github.com/pinterf/AviSynthCUDAFilters/blob/master/documentation/build_help.txt
and
http://avisynth.nl/index.php/SetFilterMTMode
(onCPU and onCUDA section)

**CUDA support = the interfaces and the framework exists. Implemented filters are in those above mentioned external plugins.

DTL
23rd February 2021, 12:23
How many OpenCL or CUDA filters do we know? Only a few of them exist. Actually CUDA support** seems to be working with Avisynth+ core (do not search it in the official releases :) ) supporting native CUDA filter chain.


So CUDA for GPU already uses some sort of small blocks scan mode instead of full line scanning also because of problems with 2D access with too large strides ?

I see current 'multi-frames' MultiThreading processing in Avisynth also limited by memory speed on many cores CPUs.

As for plugins it may be evolutional shifting to block scan formats if new formats will be added and plugin (and core) filters designers will move in time to support new scan formats.

Unfortunately no good news from hardware production industry on significant bus width increase and memory performance increase. Also sill even no progress of local on-chip cache being 'all-L1' but still divided to small L1 and larger L2/L3 with even low speed.

I think the reason of production Xeons with >10 cores for 'supercomputing' is only with software capable of process mostly data in register file or L1 cache.

Kogarou
2nd March 2021, 18:23
Given the large number of plugins and the extra complexity it introduces I think it will never happen. Filters are complex enough even without this feature. How many OpenCL or CUDA filters do we know? Only a few of them exist. Actually CUDA support** seems to be working with Avisynth+ core (do not search it in the official releases :) ) supporting native CUDA filter chain.

Like https://github.com/pinterf/AviSynthCUDAFilters . It includes
https://github.com/pinterf/NNEDI3/tree/cuda
https://github.com/pinterf/masktools/tree/cuda
I have forked them from Nekopanda's github pages and updated them to work with actual Avisynth 3.7. CUDA version build now is supported from CMake as well
https://github.com/AviSynth/AviSynthPlus/commit/891d100825c8fa5f0252d3198ba6d10e0817eef6
Other useful info:
https://github.com/pinterf/AviSynthCUDAFilters/blob/master/documentation/build_help.txt
and
http://avisynth.nl/index.php/SetFilterMTMode
(onCPU and onCUDA section)

**CUDA support = the interfaces and the framework exists. Implemented filters are in those above mentioned external plugins.

Woah you actually did it, the absolute madman. I wasn't expecting you to go this far to merge the fork into the mainline AVS+ in such a short amount of time.
I will happily try a CUDA-enabled build whenever pre-release builds are made public.
Thank you pinterf.

tormento
6th March 2021, 13:24
ok, so I will mention what not has HBD yet
Could you please update it? I think that it would be useful as sticky post.

real.finder
6th March 2021, 13:52
Could you please update it? I think that it would be useful as sticky post.

here https://forum.doom9.org/showthread.php?p=1937480#post1937480

DTL
6th March 2021, 20:39
Either I doing something wrong or some degradation happens:


BlankClip(1000,100,100,"RGB24",25,color=$00101010)

BilinearResize(target_width=width, target_height=height, src_left=0.5, src_top=0.3, src_width=width, src_height=height)


Looks like all built-in resizers start to fail with target_width and target_height params directly typed. Resizers from jpsdr pack works OK.
Documentation still lists these params - http://avisynth.nl/index.php/Resize and supplied with 3.7.0 release too.

Error message: Script error: Invalid arguments to function 'BilinearResize'. If delete 'target_width' and 'target_height' params names it works.

This: BilinearResize(width, height, src_left=0.5, src_top=0.3, src_width=width, src_height=height) works.

Tested with latest 3.7.0 release and also on some previous like 3.6.2.

pinterf
6th March 2021, 21:01
They are non-optional, unnamed parameters. They have names in the description just to have a clue what they really are for.

DTL
6th March 2021, 21:29
May be change error message to describe to user what to do to got resizer to work finally ? Or accept these params with names as we have in jpsdr's versions of resizers ?

Current error message is completely mysterious about what going wrong.

StainlessS
6th March 2021, 22:23
May be change error message to describe to user what to do to got resizer to work finally ? Or accept these params with names as we have in jpsdr's versions of resizers ?

Current error message is completely mysterious about what going wrong.

You're pretty much asking for NEARLY EVERY existing builtin filter to be updated [and if extended to non builtins, then an awful lot more].
Also ALL docs would likely need update, or at least compulsory arg names checked against implemented compulsory arg names. [for eg error messages]

Perhaps it aint gonna happen any time soon.

They are non-optional, unnamed parameters. They have names in the description just to have a clue what they really are for.

And also gives hint about which arguments you are describing in any documentaion.
[easier than "un-named arg 1, un-named arg 2" etc]

Also, If giving compulsory args optional names, then each filter would need additional code to detect where compulsory args were omitted,
and throw error - for each and every compulsory arg. As it is, Avisynth itself throws an error if compulsory arguments are not supplied, with the
"Script error: Invalid arguments to function ..." thing.

Where "Invalid arguments to function " error is given, it aint that much bother to check your supplied arguments against
a function prototype, whether it be style

BilinearResize(clip clip, int target_width, int target_height [,float src_left, float src_top, float src_width, float src_height ] )

or

BilinearResize(clip clip, int target_width, int target_height ,float "src_left", float "src_top", float "src_width", float "src_height" )

Where RED are compulsory and BLUE are optional, and in above clip args are compulsory but can use Special Last clip.
[ (Compulsory or Special Last) clip has no defined way of specifying it as such in function/filter prototype].

EDIT: I guess could use something like [where clip in "clip=Last" is not in double quotes and so not optional, but default to Last if not supplied]

BilinearResize(clip clip=Last, int target_width, int target_height ,float "src_left" = 0.0, ... )

DTL
7th March 2021, 00:43
" Avisynth itself throws an error if compulsory arguments are not supplied, with the
"Script error: Invalid arguments to function ..." thing."

In the syntax BilinearResize(target_width=width, target_height=height) compulsory arguments do supplied. But this syntax looks like not compatible with built-in Avisynth+ filters. But works for external filters. May be external jpsdr's plugin was designed much time after the beginning of Avisynth, so it uses newer API (or extended) that allow to have names for compulsory arguments too ? Or it is just 'special processing' of arguments list in jpsdr's plugins so it works ? I think plugin uses common API for function calls so it may work equally - either both works or both not works.

I stil not read all documentation on Avisynth+ but may be in some page about function calling and parameters naming there is a restriction to use names for compulsory arguments ?

The provided with current install engine for version 3.7.0 documentation at docs\English\avisynthdoc\syntax\syntax_ref.html only says:
"AviSynth functions can take named arguments. The named arguments can be specified in any order, and the filter will choose default values for any that you leave off."

So it is still undocumented feature that only optional function arguments for built-in functions can be provided in 'named' form ? Or it will raise error about Invalid arguments. And for other (external) functions it depends on exact arguments processing code in the plugin.

Also typically if function actually do not have named argument (or user make error in argument name) it is usually throwed error: Script error: <function name> does not have named argument "__"

So if BilinearResize actually do not have named argument 'targed_width' it is expected to have more pointed to error source message like: Script error: BilinearResize does not have named argument "target_width"

StainlessS
7th March 2021, 01:04
jpsdr's plugin must use this stuff

Also, If giving compulsory args optional names, then each filter would need additional code to detect where compulsory args were omitted,
and throw error, for each and every compulsory arg. As it is, Avisynth itself throws an error if compulsory arguments are not supplied, with the
"Script error: Invalid arguments to function ..." thing.

So, external to the plugin (ie as far as Avisynth is concerned) they are optional, but internal to the plugin, they are detected if missing
and then throws error, and as the plugin knows [well the author knows] the now optional names, so can throw error using those optional names
(although and because, they are actually compulsory).

You can do that for a one-off plugin, so long as author knows he is fully responsible for all errror processing, and avisynth
argument error checking will do pretty much nothing [although it will still check syntax].

I doubt if any special case will be given to any resizers just because jpsdr's did it with a few of his.
EDIT: Additionally, if in future any app [eg AvsPMod] was wanting to scan function prototype
exported/extracted from CPP/C plugin, then jpsdr's plugs compulsory args would be wrongly ascribed as being optional
and perhaps displayed to user as if so.

EDIT:

BlankClip
#Return test(2,3) # 6, OK
#Return test(arg2=2,arg3=3) # 6, OK
#Return test(arg2=2) # 6, OK, arg3 defaults
#Return test(2) # 6, OK, arg3 defaults
#Return test(3) # 9, arg2=3, arg3 = defaults 3, if given arg was intended to be for arg3, then result is wrong.
Return test(arg3=3) # ERR, arg2 not specified, & no default (ie internal compulsory)
# Error either:-
# "Evaluate: operands of '*' must be numeric"
# or
# "Test: arg2 Undefined", if the Assert() is uncommented.
return last

Function Test(clip c, int "arg2", int "arg3") { # Externally, both arg2 and arg3 are specified optional (surrounded by double quotes).
# arg2 is compulsory although externally specified as optional. So looking at prototype, you have NO IDEA AT ALL that arg2 is actually compulsory.
# Bucket loads of new and exciting bugs to experience and fix.
arg3 = default(arg3 , 3) # arg3 is optional both internal (has default) and external.

# Function author must detect missing arg2, Otherwise ::: "Evaluate: operands of '*' must be numeric"
# Assert(arg2.defined,"Test: arg2 Undefined") # Is internal compulsory. ::: UnComment to fix where gives error if missing.

x = arg2 * arg3 # arg2 no default value, is undefined if not supplied.
return c.Subtitle(String(x),size=48)
}


EDIT:
So if BilinearResize actually do not have named argument 'targed_width' it is expected to have more pointed to error source message like: Script error: BilinearResize does not have named argument "target_width"

OK, I accept that as a good observation, and could be (dare I say "easily") implemented within avisyhth
main code for both internal and external plugs :)

I stil not read all documentation on Avisynth+ but may be in some page about function calling and parameters naming there is a restriction to use names for compulsory arguments ?
So far as I know (maybe it changed recently), compulsory args never have a name in CPP/C spec [just a type]
eg "ci" for clip, int, both un-named.
Optional as in "cib[floatarg]f", where Function (clip, int, bool "boolarg", float "floatarg") sort of in script speak.
Un-named optional arg as in ""ci[]b" where bool arg is un-named optional.
As far as new arrays and such are concerned, I got no idea at all how that works.

From an old RT_stats script that extracts function prototypes from C style specifiers.
The script will only extract a single specifier string where there are multiple alternate specifiers strings, multiples are not exposed for extraction.
There should be 2 versions of Abs() below, ie Abs "f" and Abs "i". The script actually extracts 2 identical copies of Avs "f", I removed one by hand.

AviSynth+_3.5.2_(r3218,_neo,_i386)_ORDERED_Function_List

There follows a list of all function names together with CPP style argument specifiers that inform
Avisynth the argument types and optional names. Optional arguments have square brackets surrounding
their name as in [name] and are followed by a type specifier character that gives the type.
Unnamed arguments are not optional. eg "cc[arg1]b[arg2]i" would be two compulsory unnamed clip args,
followed by optional 'arg1' of type bool and optional 'arg2' of type int.

# Argument type specifier strings.
c - Video Clip
i - Integer number
f - Float number
s - String
b - boolean
. - Any type (dot)
# Array Specifiers
i* - Integer Array, zero or more
i+ - Integer Array, one or more
.* - Any type Array, zero or more
.+ - Any type Array, one or more
# Etc


abs "f"
acos "f"
AddAlphaPlane "c[mask]."
AddAutoloadDir "s[toFront]b"
AddBorders "ciiiii[color_yuv]i"
AlignedSplice "cci"
Amplify "cf+"
AmplifydB "cf+"
Animate "ciis.*"
Apply "s.*"
ApplyRange "ciis.*"
Array ".*"
ArrayGet "a.+"
ArraySize "a"
asin "f"
Assert "s"
AssumeBFF "c"
AssumeFieldBased "c"
AssumeFPS "cc[sync_audio]b"
AssumeFrameBased "c"
AssumeSampleRate "ci"
AssumeScaledFPS "c[multiplier]i[divisor]i[sync_audio]b"
AssumeTFF "c"
atan "f"
atan2 "ff"
audiobits "c"
audiochannels "c"
AudioDub "cc"
AudioDubEx "cc"
audioduration "c"
audiolengthf "c"
audiolengthhi "c[]i"
audiolengthlo "c[]i"
audiolengths "c"
audiorate "c"
AudioTrim "cf[end]f"
AutoloadPlugins ""
AverageB "c[offset]i"
AverageChromaU "c[offset]i"
AverageChromaV "c[offset]i"
AverageG "c[offset]i"
AverageLuma "c[offset]i"
AverageR "c[offset]i"
AVIFileSource "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b"
AVISource "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b"
BDifference "cc"
BDifferenceFromPrevious "c"
BDifferenceToNext "c[offset]i"
[COLOR="Red"]BicubicResize "cii[b]f[c]f[src_left]f[src_top]f[src_width]f[src_height]f"
BilinearResize "cii[src_left]f[src_top]f[src_width]f[src_height]f"

# ...


EDIT: In above extraction, [B]ArrayGet "a.+", the 'a' is new array specifier.
Looks something like, an array of any type of 1 or more elements, or maybe its an array of arrays or something,
as ".+" = any type Array, one or more.
EDIT: "a.+" Probably an array of arrays where each of the 2nd dim arrays has one or more elements of any type,
no idea what to call it, dont think "sparse array".
I still got no real idea, but wondering if "a.+" should be "a.*" where 2nd dim arrays could be 0 or more elements,
v3.7.0 (r3382) still uses ArrayGet "a.+".
EDIT: Or maybe I got it back-to-front and ".+" specifies 1st dimension of 1 or more. [no spec minimum els for 2nd dim].

EDIT: Nah, musta been half asleep, "a" is maybe single variable holding array, and ".+" one of more variables of any type", maybe.


EDIT: Also note un-named optional, audiolengthhi "c[]i"

wonkey_monkey
10th March 2021, 23:43
AVSValue's AsFloat(...) returns a double, but if you try and pass a double as the default value the compiler warns that there'll be a conversion to float. If it returns a double, shouldn't it accept a double as a default value?

pinterf
11th March 2021, 07:40
AVSValue's AsFloat(...) returns a double, but if you try and pass a double as the default value the compiler warns that there'll be a conversion to float. If it returns a double, shouldn't it accept a double as a default value?
There is an AsFloatf version of AsFloat that should be used to avoid warnings. This function exists for this very reason.
EDIT: maybe I explained the opposite: to avoid return value warning. You can use AsDblDef, but since there is no double in AVSValue there is no point of doing that.

Side note: internally there is no double type in Avisynth. Double and 64 bit integer types are impossible to implement. Reason: AVSValue defined in avisynth.h has its maximum value size dependent of the size of pointer - pointer type is 4 bytes on a 32 bit system - so only a 32 bit float can be held there, no 64 bit double. 64 bit systems would easily support them - of course this needs an interface update - I had plans for that but there are always more important stuffs in the development queue. With the extinction of 32 bit Avisynth versions nobody will care if interface would change.

pinterf
11th March 2021, 08:14
EDIT: In above extraction, ArrayGet "a.+", the 'a' is new array specifier.
Looks something like, an array of any type of 1 or more elements, or maybe its an array of arrays or something,
as ".+" = any type Array, one or more.
EDIT: "a.+" Probably an array of arrays where each of the 2nd dim arrays has one or more elements of any type,
no idea what to call it, dont think "sparse array".
I still got no real idea, but wondering if "a.+" should be "a.*" where 2nd dim arrays could be 0 or more elements,
v3.7.0 (r3382) still uses ArrayGet "a.+".
EDIT: Or maybe I got it back-to-front and ".+" specifies 1st dimension of 1 or more. [no spec minimum els for 2nd dim].

EDIT: Nah, musta been half asleep, "a" is maybe single variable holding array, and ".+" one of more variables of any type", maybe.


EDIT: Also note un-named optional, audiolengthhi "c[]i"
The new array specifier "a" expects a real array at its parameter position. Such arrays can be more-than 1D, and their elements are not restricted to have the same type.

In classic Avisynth arrays were always used behind the scenes (.+ one or more anything, .* zero or more anything). Script parser logic was grouping the comma delimited parameters into the given array variable. Only 1D arrays were supported, and array elements must have of the same type.
This kind of array element collection logic thus needs to know where the array elements are ended. This is easy for array of specific types. Comma separated list has an end where the value type gets changed. E.g. Avisynth parser can easily read and populate a string list into array when it has a specific end.
For this function signature:
[paramname_s]s*[anotherparam]i
the script parameters given
"Item1", "Item2", "Item3", 123
Parser will stop collecting string array when it encounters a non-string type.
paramname_s: array[3] : ("Item1", "Item2", "Item3")
anotherparam: integer : 123

What about the ".*" type? These mean array of zero-or-more any-type.
Avisynth can only detect the end of such arrays in a comma delimited list when a named parameter is explicitely given (thanks for StainlessS for the explanation).
Unnamed parameters cannot follow a ".*" array.

Edit: with Stain"EagleEye"LessS' corrections

StainlessS
11th March 2021, 12:41
Thanks P, it all seems very complicookered :)

EDIT: Removed some stuff.
I'll leave below in-situ as it maybe helps show practical usage example of
Explicitly given named param to terminate data list ('.*' or '.+' , zero/one or more, of any type).

Some of my plugs use eg "Append=True/False" following a pseudo array of zero/one or more items of any type,
user must explicitly use optional name to terminate pseudo data array early eg

".*", Any type, zero or more, if wanting to supply Append=true, then must explicitly use "Append=true" after final data arg, even if zero data args.

env->AddFunction("RT_WriteFile", "ss.*[Append]b",RT_WriteFile, 0);


Script doc style prototype (and doc), compulsory arg names FileName and format are only for docs, they cannot have names supplied.
Unnamed dat1 to datn, also cannot have names supplied, are only for docs.

RT_WriteFile(String FileName, string format, dat1, ... , datn, bool "Append"=False)

Writes a formatted string to FileName file. The unnamed 'format' string and optional unnamed 'dat' args are used to construct the
text string that is written, uses C/CPP printf() style formatting.
Format: compulsory string controlling format and describing the datn type args that are expected.
datn: Variable number of data args of any type (excluding clip).
Append, Default False, optional and MUST be supplied with name (eg Append=True) as we do not know where optional data args end,
Appends to file if already exists, else opens new FileName.

NOTE, Above, dat1 ... datn, are described as optional because of the zero or more spec [although they have no optional names].

Example script usage

RT_WriteFile(".\Fred.log", "%d] %s", current_frame, "Hello Sexy", Append=True) # Two Data Args are required as specified in format string(Int, String)
RT_WriteFile(".\Fred.log", "Some Text", Append=True) # Zero Data args in Pseudo Array (Format string has no '%' data insertion markers)


NOTE, above format string %d and %s describes only the C printf() style expected data args and is only to do with file output formatting,
it is not part of or related to the ".*" spec, we used only because its the easiest and only example that we thought of.

Dont think above has ever been documented anywhere, is result of testing to see what happens, ie 'suck-it-and-see' tactics.

EDIT: https://dictionary.cambridge.org/dictionary/english/suck-it-and-see
suck it and see
UK informal

to try something to find out if it will be successful:
I'm not sure whether this paint is the right colour for the bedroom - we'll just have to suck it and see.
If you've got a bag of identical looking (but multiple flavour) chocolates, you may implement a Suck It And See policy.

pinterf
11th March 2021, 14:41
Thank you SssS. You know the language so much better than me. Fixed the lines but I'm sure I put other stupid declarations there.

real.finder
13th March 2021, 14:58
is https://publishwith.me/ep/pad/view/ro.rDkwcdWn4k9/latest locked?
edit: I think I know why, I note there were some CCP writing spam text
I was trying to add
SetFilterMTMode("IT", MT_SERIALIZED)

anyway, here my MtModes.avsi https://pastebin.com/tmw7J2mj

uptodate one here https://github.com/realfinder/UniversalPluginsFolders/blob/master/plugins64%2B/MtModes.avsi

mp3dom
15th March 2021, 00:22
I have a question about ImageSource from AVS+.
Is it supposed to support 16bpc image input natively? Because I have a 16bpc PNG images sequence that by default is opened as RGB32 (with or without Devil library). If I force the pixel_type to RGB48 I get 16bpc but the difference (with subtract command) from this image and the same decoded as 8bit is zero. On the other side, if I open the image with LWLibavVideoSource, and doing the same subtraction, the results is a visible difference.
Maybe I'm doing something wrong somewhere?

poisondeathray
15th March 2021, 01:57
I have a question about ImageSource from AVS+.
Is it supposed to support 16bpc image input natively? Because I have a 16bpc PNG images sequence that by default is opened as RGB32 (with or without Devil library). If I force the pixel_type to RGB48 I get 16bpc but the difference (with subtract command) from this image and the same decoded as 8bit is zero. On the other side, if I open the image with LWLibavVideoSource, and doing the same subtraction, the results is a visible difference.
Maybe I'm doing something wrong somewhere?



Works ok for me (difference detected with subtract)

Are you converting 8bit up to 16bit, or 16bit down to 8bit to compare?

There is a difference for me when I convert 8bit to 16bit to compare vs. original 16bit; or 16 down to 8 to compare with imagesource default 8bit

(But if you downconvert 16 to 8, then the dithering algo choice can also make other difference)


a=imagesource("16bitpng.png")
b=imagesource("16bitpng.png", pixel_type="RGB48")

subtract(a.convertbits(16), b) => difference
#subtract(a, b.convertbits(8, dither=-1)) => difference


Another way to confirm this is write out the imagesource pixel_type="RGB48" png (e.g. pipe to ffmpeg) , then check in vapoursynth. Since vsedit can display >8bit values with the color picker (x=, y=, and R,G,B values) , you can check if it works. eg. You can use a known 16bit RGB test ramp such as x=0, RGB4096, to x=1919, RGB6015. And yes, imagesource pixel_type="RGB48" works correctly.

mp3dom
15th March 2021, 02:24
I tried both ways (16 to 8 and 8 to 16). There were slighty differences, while with LWLibav the differences were higher.
Anyway thanks for the check, I'll investigate further on my side.

poisondeathray
15th March 2021, 02:27
I tried both ways (16 to 8 and 8 to 16). There were slighty differences, while with LWLibav the differences were higher.
Anyway thanks for the check, I'll investigate further on my side.

No difference for me between ImageSource pixel_type="RGB48" and LSmash

b=ImageSource("16bit.png", pixel_type="RGB48")
l=LWLibavVideoSource("16bit.png")

subtract(b,l)

avs 3.7 x64 r3382
Maybe something peculiar about your png ?

LigH
15th March 2021, 08:42
Maybe one of the methods respects the Gamma flag in the PNG?

poisondeathray
15th March 2021, 18:06
Maybe one of the methods respects the Gamma flag in the PNG?

Yes, this can explain a difference in handling of PNG's in avisynth

ImageSource will adjust the image according to the cHRM and gAMA tags. LSmash will ignore.

You can examine png's with tweakpng

wonkey_monkey
19th March 2021, 23:14
http://avisynth.nl/index.php/Filter_SDK/Cplusplus_API

On this page it states:

MakeWritable only copies the active part of the frame to a completely new frame with a default pitch. You need this to recieve a valid write pointer to an existing frame.

a) What is meant by "active part"?
b) Does MakeWriteable make a new copy even if the frame is already writeable? (IsWritable() == true)

PS The section on IsWriteable() has a typo:

if (src->IsWritetable()) {...}

pinterf
20th March 2021, 11:26
http://avisynth.nl/index.php/Filter_SDK/Cplusplus_API

a) What is meant by "active part"?

MakeWritable makes a NewVideoFrame (NewVideoFrameP for avs+) and BitBlt for all planes.

Active part means that when a frame was created by the quick SubFrame method (e.g. ExtractY, Crop) if won't copy the whole memory content of the original framebuffer, only those which are really take part of the specific colorspace and frame.


b) Does MakeWriteable make a new copy even if the frame is already writeable? (IsWritable() == true)

No. It then copies nothing, returns immediately and leaves PVideoFrame pointer in its original state.

wonkey_monkey
20th March 2021, 18:40
Thanks pinterf!

wonkey_monkey
21st March 2021, 15:06
VideoInfo.GetPlaneWidthSubsampling and VideoInfo.GetPlaneHeightSubsampling both throw exceptions if called with a parameter of 0. Since "0" is the default parameter for GetReadPtr, etc, and so is effectively the plane ID for interleaved RGB video, could those functions be updated to return 0 if called with 0, rather than throwing an exception?

Also edit: could IsY(), IsYUV() and IsYUVA() be updated/replaced to be consistent and intuitive?

StainlessS
21st March 2021, 18:43
Maybe one of em should be VideoInfo.GetPlaneHeightSubsampling.

EDIT:

Function X_IsY(clip c) {
# True=Single Plane
# (!IsRGB)=True = Any type with Y, YUY2/YUVA/Y8 etc.
# BEWARE Y8_Clip.IsYUV returns True
c
IsAvsPlus ? IsY : IsAvs26 ? IsY8 : False
}

StainlessS
25th March 2021, 18:21
From here [Internal functions]:- http://avisynth.nl/index.php/Internal_functions#propSetInt

Not sure if this lot is correct,

propSetInt

propSetInt(clip, string key_name, function func_obj [, integer "mode"]) AVS+

propSetFloat

propSetFloat(clip, string key_name, function func_obj [, integer "mode"]) AVS+

propSetString

propSetString(clip, string key_name, function func_obj [, integer "mode"]) AVS+

propSetArray

propSetArray(clip, string key_name, function func_obj [, integer "mode"]) AVS+
these setters accept only the specific type

Should it be more like this

propSetInt

propSetInt(clip, string key_name, integer value [, integer "mode"]) AVS+

propSetFloat

propSetFloat(clip, string key_name, float value [, integer "mode"]) AVS+

propSetString

propSetString(clip, string key_name, string value [, integer "mode"]) AVS+

propSetArray

propSetArray(clip, string key_name, array value [, integer "mode"]) AVS+
these setters accept only the specific type


Also, something seems a bit messed up here,
propGetAsArray

propGetAsArray(clip, string key_name[, integer "index", integer "offset"]) AVS+
returns an array. For a single property array size will be 1. (only in array-aware AviSynth+ versions)

propGetAll

propGetAsArray(clip [, integer "offset"]) AVS+
returns an array. For a single property array size will be 1. (only in array-aware AviSynth+ versions)
Returns all frame properties in an array of [key-value] pairs. Array size will be 'numProps'
Each key-value pair is contained in a two dimensional subarray.
If the property value for a given key is an array again then "value" will be an array as well.
Once you have the array with all properties you can access them with the "associative" feature of AviSynth array access

Extracting from C prototypes I see this, [can only extract single C prototype]
propGetAsArray "cs[offset]i"

EDIT: And
propGetAll "c[offset]i"

pinterf
26th March 2021, 16:47
From here [Internal functions]:- http://avisynth.nl/index.php/Internal_functions#propSetInt

Not sure if this lot is correct,



Should it be more like this

propSetInt

propSetInt(clip, string key_name, integer value [, integer "mode"]) AVS+

propSetFloat

propSetFloat(clip, string key_name, float value [, integer "mode"]) AVS+

propSetString

propSetString(clip, string key_name, string value [, integer "mode"]) AVS+

propSetArray

propSetArray(clip, string key_name, array value [, integer "mode"]) AVS+
these setters accept only the specific type




They are O.K. These names are different only for parameter lists with function object.
Other plain propSet versions can establish the property type from the type of the provided value.

More on function objects:
http://avisynth.nl/index.php/Function_objects

EDIT: the mess with propGetAll is quick-fixed, thanks for the report.

wonkey_monkey
26th March 2021, 21:42
There's something very odd going on...

I was getting a crash with this script and version 3.6.1 (edit: also with 3.7.0):


Colorbars
ResampleAudio(48000) # any value


It would play back from any frame other than frame 0, but if played back (in VirtualDub) from frame 0, it would crash. It would also crash using AVSMeter (I wrote a simple plugin to GetAudio within GetFrame, so that I could benchmark audio using AVSMeter).

So I updated to 3.7.0. The good news is, no more crash (EDIT: scratch that: it still crashes from frame 0. Not if you add trim(1,0), though). The bad news is, when I playback a simple Colorbars clip (even without ResampleAudio) in VirtualDub2, the sound is all messed up, like it's clicking on and off at (very rough guess) 25Hz. EDIT: It seems to be almost exactly 40Hz. Here's an Audacity screenshot of a recording of VirtualDub2 playback:

https://i.imgur.com/a2jwqL7.png

Using my waveform plugin, the waveform looks okay, but I guess something about how VirtualDub is getting the audio is getting things messed up. Sound generated by the Tone function is similarly messed up. A Wavsource, though, is fine.

Edit: ffmpeg encoding to a file seems fine. Maybe it's a VirtualDub2 thing, but it wasn't doing it under 3.6.1.

Richard1485
26th March 2021, 22:57
Maybe it's a VirtualDub2 thing, but it wasn't doing it under 3.6.1.

It's not VirtualDub2, though I can hear it in VirtualDub2. I can also reproduce it in ffplay on the Linux build of AviSynth+ (latest version). It seems to me to be related to bit depth.
Colorbars
ConvertAudioTo16bit() # any bit depth

It's not audible in ffplay if I comment out the second line, but it is in VirtualDub2. VirtualDub never used to like playing back audio at anything other than 16-bit (though VirtualDub2 was an improvement), so maybe VirtualDub2 converts the audio as it comes in.

wonkey_monkey
27th March 2021, 00:02
Same with ffplay on Windows.

pinterf
27th March 2021, 09:24
There's something very odd going on...

I was getting a crash with this script and version 3.6.1 (edit: also with 3.7.0):


Colorbars
ResampleAudio(48000) # any value


It would play back from any frame other than frame 0, but if played back (in VirtualDub) from frame 0, it would crash. It would also crash using AVSMeter (I wrote a simple plugin to GetAudio within GetFrame, so that I could benchmark audio using AVSMeter).

Did it crash for you even at 48000? Because in this case the filter does nothing, no conversion occurs, just calls the child (colorbars) GetAudio. Anyway, I could not make it crash, neither from avsmeter not from vdub2.

wonkey_monkey
27th March 2021, 13:53
I could have sworn it did yesterday, but it's not doing it now.

Rates other than 48000 are still causing it to crash on the first frame.

ColorBars
ResampleAudio(44100)

# ^ crashes

ColorBars
ResampleAudio(44100)
Trim(1,0)

# ^ does not crash

Both of these are true for 3.6.1 and 3.7.0. Garbled VirtualdDub2/ffplay audio only occurs with 3.7.0 (and on ffplay only if ConvertAudioTo16Bit() or ConvertAudioTo8Bit() is used).

I removed all plugins just in case but it didn't make any difference.

EDIT: Adding a call to Amplify - even with a value of 1 - before ResampleAudio stops the crash occuring.

wonkey_monkey
27th March 2021, 14:19
Re the glitch, my previous screenshot was taken while I had my laptop's audio processing enabled which I think gave a misleading impression. Here's a closeup with processing disabled:

https://i.imgur.com/hXpPxtO.png

It happens at the positive peak every 11 positive peaks. I'm guessing some change in the code or perhaps floating point mode when compiling is causing the generated sample to go just over 1.0, which makes the glitch audible when it's converted to integer samples before sending to the sound card. Adding:

Amplify(0.99)

stops the playback glitch.

Richard1485
27th March 2021, 15:49
Both of these are true for 3.6.1 and 3.7.0. Garbled VirtualdDub2/ffplay audio only occurs with 3.7.0 (and on ffplay only if ConvertAudioTo16Bit() or ConvertAudioTo8Bit() is used).

On my end, it occurs in ffplay with ConvertAudioTo24Bit() and ConvertAudioTo32Bit() as well.

pinterf
29th March 2021, 09:00
I could have sworn it did yesterday, but it's not doing it now.

Rates other than 48000 are still causing it to crash on the first frame.

ColorBars
ResampleAudio(44100)

# ^ crashes

ColorBars
ResampleAudio(44100)
Trim(1,0)

# ^ does not crash

Both of these are true for 3.6.1 and 3.7.0. Garbled VirtualdDub2/ffplay audio only occurs with 3.7.0 (and on ffplay only if ConvertAudioTo16Bit() or ConvertAudioTo8Bit() is used).

I removed all plugins just in case but it didn't make any difference.

EDIT: Adding a call to Amplify - even with a value of 1 - before ResampleAudio stops the crash occuring.
No crash for me. Now to get any further: 32 or 64 bit Avisynth? Does it happen with SetMaxCPU("none") at the start of the script?
Which version of Virtualdub2 you are using (I'm at 44282). What are you exactly doing when vdub2 is crashing? Just load the script and press reload F2? Or File|Save audio.
I can see that after ResampleAudio, some samples can be more than 1.0, e.g. 1.00000023 but it cannot be a problem.

wonkey_monkey
29th March 2021, 12:29
It seems to affect 64 bit Avisynth only. SetMaxCPU("none") has no effect. I'm using 44282 as well but the crash happens with ffplay.exe, as well as avsmeter64.exe and my own AVS viewer (when using a plugin that forces the fetching of audio with video - my original Waveform plugin and a completely new purpose-written one that just calls GetAudio within GetFrame). I also added a call to GetAudio to my own viewer and that let me narrow it down a little:

With the following script:

SetMaxCPU("none")
ColorBars
ResampleAudio(44100)

, the crash occurs if I attempt

clip->GetAudio(buffer, X, 1, env);

, where X is between 0 and 41. For x=42 and above, no crash.

If I change the new sample rate to 34100, it crashes with X between 0 and 39.
If I change the new sample rate to 10000, it crashes with X between 0 and 34.

I can see that after ResampleAudio, some samples can be more than 1.0, e.g. 1.00000023 but it cannot be a problem.

I thought >1.0 samples might be the cause of the garbled playback with VirtualDub and ffplay, but may be entirely unrelated to the crash.

pinterf
29th March 2021, 13:59
It seems to affect 64 bit Avisynth only. SetMaxCPU("none") has no effect. I'm using 44282 as well but the crash happens with ffplay.exe, as well as avsmeter64.exe and my own AVS viewer (when using a plugin that forces the fetching of audio with video - my original Waveform plugin and a completely new purpose-written one that just calls GetAudio within GetFrame). I also added a call to GetAudio to my own viewer and that let me narrow it down a little:

With the following script:

SetMaxCPU("none")
ColorBars
ResampleAudio(44100)

, the crash occurs if I attempt

clip->GetAudio(buffer, X, 1, env);

, where X is between 0 and 41. For x=42 and above, no crash.

If I change the new sample rate to 34100, it crashes with X between 0 and 39.
If I change the new sample rate to 10000, it crashes with X between 0 and 34.



I thought >1.0 samples might be the cause of the garbled playback with VirtualDub and ffplay, but may be entirely unrelated to the crash.
Filter can request data for negative audio sample points in this case when we are in the very first frame. Resample is using overlapping buffers. Providing proper zeroified-samples for negative sample points is handled however when GetAudio is passing through "audio cache", so ColorBars is seeing only n>=0 audio sample requests.

EDIT: from 48000 to 44100 conversion, there is a -45 as the start parameter of GetAudio

StainlessS
30th March 2021, 16:46
Bit more audio weirdness, StackVertical audio should be from first clip.

# Stack filters should produce audio from first clip.

CHANNELS = 2 # Try with 2 and 1

V=Colorbars.KillAudio
A1=Tone (length=30.0, frequency=440, samplerate=44100, channels=2, type="Sine", level=1.0)
A2=Tone (length=30.0, frequency=440, samplerate=44100, channels=CHANNELS, type="Noise", level=1.0)
V1=AudioDub(V,A1).Trim(0,-1000)
V2=AudioDub(V,A2).Trim(0,-1000)
#S=StackHorizontal(V1,V2) # Seems OK
S=StackVertical(V1,V2) # Wrong, CHANNELS=(2)=Audio from bottom clip, CHANNELS=(1)= maybe some mix of audio from both clips

#V1
#V2
S


EDIT: Does not occur in v2.60/2.61 std.

EDIT: DOES OCCUR in avs+ v0.1 r2772.

zorr
31st March 2021, 00:16
How much support is there for array variables? My tests indicate that currently you can

create an array variable: arr = [0.1, 0.2]
read from an array: a = arr[0]
loop through an array: for (i = 0, ArraySize(arr)-1, 1) { ... }


However I wasn't able to update a value to a specific index: arr[0] = 0.1

Is there a way to create an array with a specific size without listing all the values, something like arr = float_array[10]?

Thanks!

pinterf
31st March 2021, 07:30
Bit more audio weirdness, StackVertical audio should be from first clip.

# Stack filters should produce audio from first clip.

CHANNELS = 2 # Try with 2 and 1

V=Colorbars.KillAudio
A1=Tone (length=30.0, frequency=440, samplerate=44100, channels=2, type="Sine", level=1.0)
A2=Tone (length=30.0, frequency=440, samplerate=44100, channels=CHANNELS, type="Noise", level=1.0)
V1=AudioDub(V,A1).Trim(0,-1000)
V2=AudioDub(V,A2).Trim(0,-1000)
#S=StackHorizontal(V1,V2) # Seems OK
S=StackVertical(V1,V2) # Wrong, CHANNELS=(2)=Audio from bottom clip, CHANNELS=(1)= maybe some mix of audio from both clips

#V1
#V2
S


EDIT: Does not occur in v2.60/2.61 std.

EDIT: DOES OCCUR in avs+ v0.1 r2772.
I suppose it happens only for packed RGB? Because this format has its lines upside down order, so input clip order is reversed as well. But then it has this side effect.

StainlessS
31st March 2021, 12:56
Well wadya know, I did not even think to try with non RGB interleaved when prob was audio, nice one P.

pinterf
31st March 2021, 16:16
Fixed, anyway.