Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 64 bit data types #423

Open
pinterf opened this issue Jan 21, 2025 · 5 comments
Open

Add 64 bit data types #423

pinterf opened this issue Jan 21, 2025 · 5 comments
Assignees

Comments

@pinterf
Copy link

pinterf commented Jan 21, 2025

Make AVSValue able to hold double and 64 bit integer types.
Also for 32 bit Avisynth.

  • new AVSValue constructors for 64 bit types (internal names: longlong and double)

  • Minor change: AVSValue::AsFloat already exists and should be able to return the new internal double value.

  • Minor change: AVSValue::AsFloatf already exists and is able to return float, if internal storage is double, it will be type-casted.

  • New: AVSValue::AsLong to be added, returns int64_t. Introduced, because AsInt (which returns only int) cannot be altered for compatibility reasons.

  • (*) Change: AVSValue::IsInt will return true also for long (int64_t) content as well. Note: AsInt still returns int; if content does not fit into the int value range then casting from int64_t may cause data loss. When plugin writer really needs 64 bit content, use AsLong().

  • (*) New: AVSValue::IsLong to be added, returns if type is really a long (int64_t) integer.

  • Change: AVSValue::IsFloat will return true also for double content and for the new 64 bit integer type - long - as well.

  • New: AVSValue::IsFloatf to be added to check if underlying type is simple 32 bit float or integer (like former IsFloat).

  • Change: function parameter signature type 'f' would automatically accept double as well.

  • (*) Change: function parameter signature type 'i' would automatically accept long (int64) typed AVSValue as well. This is a convenient and compatible way, since IsInt() returns true for any (32/64 bit) integer type. If the plugin function really needs int64_t content then AsLong() must be used. (Note: In this case the external plugin would be incompatible with older Avisynth versions. Plugin writers should make sure for checking against v11 interface and give a nice error message for older systems in filter constructor instead of just crashing the program by using AsLong unconditionally.)
    New: 64 bit integer parameters require 'l' (lowercase L) type in function parameter signatures

  • New: integer decimal constants in avs scripts are automatically promoted to long (int64_t) if they do not fit into integer

  • (*) New: integer decimal constants in avs scripts are automatically promoted to 64 bit double if they do not even fit into int64_t

  • (**) New: hexadecimal constants L suffix for 64 bit. In avs scripts (such as color constants $FFFFFFFF) hexadecimal constants remain integer unless L suffixed. $FFFFFFFF is like -1 (32 bit int), $FFFFFFFFL is a positive 64 bit value.

  • (*) New: floating point constants in avs script are stored as 64 bit double precision internally.

  • New: Float() script function cast converts to 32 bit 'float', if the integer source can fit without loss (2^24), else it goes into double

  • (*) Since i and f types can accept 64 bit data in place of the parameters, no need of distinct d or l types ~~Change: add user function definition parameter type keywords "long" and "double", latter is not necessary probably. ~~

  • Change: formatting functions (String(), etc.) to 64 bit data type aware.

  • Change: arithmetic: when both operands are 32 bit, the result is 32 bit as well (32 bit float / 32 bit float is also a 32 bit float)

  • (*) Frame properties already supported 64 bit double and int64_t content. Now getting/setting them to/from script variables (AVSValue's) would not truncate the data to 32 bits.

  • Change: Avisynth interface version to 11

  • (*) Change: ArraySort support 64 bit integer/double content

  • (*) Change: For loop accepts 64 bit integers

  • (*) bitwise functions must remain on 32 bit domain, 64 bit integer versions should have different names

  • (*) AudioLength now returns 64 bit integer, AudioLengthF puts data to double, (though it's now useless and still can lose precision)

  • (*) Change: Floor, Ceil, Round can result in 64 bit integer numbers

  • (*) New: HexValue64 because HexValue should still result in 32 bit number. E.g. the full 4 byte FF (FFFFFFFF) still results in a -1 integer and not a positive FFFFFFFF as in int64_t

(**) Modifications in C interface AVS_Value handlers as well.

Due to the "baked code" interface, Avisynth core cannot be sure if 64 bit types can be passed as long or double.

To access and recognize 64 bit data, interface has been extended (avisynth_c.h)

  • modified avs_is_int, avs_is_float, avs_as_int, avs_as_float
  • new avs_is_long, avs_is_floatf, avs_as_long

For compatibility reasons (plugins, ffmpeg, AvsPmod) these are still not API calls (inline functions).

Also for compatibility, long/double parameter values are converted to 32 bit integer/float for old plugins.

1.) To enable full 64 bit data to C plugins, implement avisynth_c_plugin_init2 as well.

Avisynth will mark the plugin as 64 bit friendly and pass long or double parameter values without casting them to 32 bit.
Now the plugin's task to accept these by avs_as_long. Since avs_as_float already returned double, the only change is that the value can really be of double precision, not converted up from a 32 bit float.

// Avisynth 3.7.4 tries this first: avisynth_c_plugin_init2 
// The existense signs to Avisynth that plugin is v11 (64 bit data) capable,
// 64 bit long and double parameters are not truncated to int and float on function calls
// Dont forget updating .def file
// as
/* LIBRARY AvsMyCPlugin
EXPORTS
avisynth_c_plugin_init@4 = _avisynth_c_plugin_init@4
avisynth_c_plugin_init2@4 = _avisynth_c_plugin_init2@4
*/
AVSC_EXPORT  const char* AVSC_CC  avisynth_c_plugin_init2(AVS_ScriptEnvironment* Env)
{
  return avisynth_c_plugin_init(Env);
}

2.) For non-plugin use: call avs_create_script_environment(version) with version>=11.
avs_invoke, avs_add_function will leave 64 bit data as-is, otherwise 32 bit cast happens.
This is still to be checked, e.g. ffmpeg calls this function with a very small version number (3), and only then, by detecting the real version number will adaptively call the interface functions (e.g. frame property related ones only over version 9)

(*)edited

@pinterf pinterf self-assigned this Jan 21, 2025
@qyot27
Copy link
Member

qyot27 commented Jan 21, 2025

Would it maybe be cleaner (or more compatible) if it was added as a separate struct that's designed to be more extensible? An AVSValue2 or whatnot.

Not that I can think of any immediate example where it might be absolutely necessary, but if we ever wanted to extend beyond 64-bit types (particularly with quad-precision or even octuple-precision float values), I'm assuming that that could not be shoehorned into even the extended AVSValue and would require something more/different.

@pinterf
Copy link
Author

pinterf commented Jan 21, 2025

Reference counted strings which come to my mind. Anyway, this 64 bit is quite "easy", and compabible. I remember, I was experimenting with it for many many weeks a few years ago, then dropped the project. Now it was much quicker to achieve success stories, but C and Avs2.5 interface tests will make me sleep bad, I'm sure.

@pinterf
Copy link
Author

pinterf commented Jan 26, 2025

@Asd-g, I saw that at least in one project you've changed to C interface from C++, and use direct static linking of the actual avisynth.lib. In posix and within mingw this is not problem, the installed avisynth in on par with their own avisynth_c.h and the libs.
In windows users are copying to andd for the dlls, so when you provide a release dll from e.g. jincresize, then the future 3.7.4 v11 interface version will fail (extra api entries in the lib will not be found) on the "old" 3.7.3 systems.
Question 1: this is a right assumption.

And I'd ask @qyot27 as well.
Regarding the 64 bit transition I have the largest compatibility problems with the C interface - still having baked codes in avisynth_c.h. So I have to work with extra caution. Two important - I suppose they have large user base - projects are out there (ffmpeg and AvsPMod) (ffmpeg is fortunately seems unaffected), AvsPMod cffi would need to be updated.

Question2:
Do you know other C interface plugins (I have among my projects AvsInPaint and assrender) which I can involve in my tests?

@qyot27
Copy link
Member

qyot27 commented Jan 26, 2025

The FFMS2 C-plugin variant, one of the yadif versions was a C plugin as well. x264 as a client.

@Asd-g
Copy link

Asd-g commented Jan 30, 2025

In windows users are copying to andd for the dlls, so when you provide a release dll from e.g. jincresize, then the future 3.7.4 v11 interface version will fail (extra api entries in the lib will not be found) on the "old" 3.7.3 systems.
Question 1: this is a right assumption.

then the future 3.7.4 v11 interface version will fail I guess by fail you mean that the features from the newer API wouldn't be used but there will be no crash. If I want to use the new features I will add avs version requirement for both building and running the plugin. For example, building and running requirement and filter internal check.

I have few C api plugins (statically linked): JincResize, avslibplacebo, RIFE, avs-mlrt, ssimulacra, MapNLQ, BlurDetect, BlockDetect, VMAF, w2xncnnvk...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants