View Full Version : Avisynth+
qyot27
8th March 2020, 18:57
We dropped VS2008 ages ago. stdint and stdbool are part of C99, which Microsoft wasn't sufficiently compliant with until VS2013 (2015 added more support for C99). That's probably the earliest for plugins (although the core requires at least¹ VS 2015).
¹std::filesystem is a C++17 feature, but it looks like VS 2015 might have added it early.
StainlessS
8th March 2020, 19:10
So plugins also will not compile now with avs+ headers and older compiler, guess that means loads of plugins
will now revert to avs Std headers. [EDIT: Ones that only support v2.60 std colorspaces anyway, and that is most plugins]
EDIT: One plugin (by someone else) that I fixed up (maybe Watermark plugin not sure) used stdint.h and simply adding that
to include directory worked just fine, I have not as yet found the (M$) stdbool.h and dont know if adding that to include
would cause any problems, I do have VS2015, VS2017 community and also 2019, I guess I could get stdbool from any one of them,
but have no idea if would work properly for vs2008.
I have not really used either 2015, or 2017 or 2019, did not like the telemetry and need to register thing [I also like the ability to compile on XP on occasion, hence VS2008].
std::filesystem is a C++17 feature
Not though neccesary for plugins ???
EDIT: If avs+ headers are supposed to be compatible with avs std, then would not stdtype.h and stdbool.h only be needed by the core and not for [any/most] plugins ???
pinterf
8th March 2020, 20:03
So plugins also will not compile now with avs+ headers and older compiler, guess that means loads of plugins
will now revert to avs Std headers. [EDIT: Ones that only support v2.60 std colorspaces anyway, and that is most plugins]
EDIT: One plugin (by someone else) that I fixed up (maybe Watermark plugin not sure) used stdint.h and simply adding that
to include directory worked just fine, I have not as yet found the (M$) stdbool.h and dont know if adding that to include
would cause any problems, I do have VS2015, VS2017 community and also 2019, I guess I could get stdbool from any one of them,
but have no idea if would work properly for vs2008.
I have not really used either 2015, or 2017 or 2019, did not like the telemetry and need to register thing [I also like the ability to compile on XP on occasion, hence VS2008].
Not though neccesary for plugins ???
EDIT: If avs+ headers are supposed to be compatible with avs std, then would not stdtype.h and stdbool.h only be needed by the core and not for [any/most] plugins ???
Header and thus plugins are still compatible, the only thing that we are using standard types instead of Microsoft specific ones, e.g. int64_t instead of __int64. You can simply typedef them if you insist on your old compiler in 2020.
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
StainlessS
8th March 2020, 20:05
What is it that is required from stdbool.h, similar easy fix ?
[also need edit avs+ types.h whenever updated]
pinterf
8th March 2020, 20:15
What is it that is required from stdbool.h, similar easy fix ?
[also need edit avs+ types.h whenever updated]
Dunno, probably I put a check in the header against compiler version and define those types if compiler is Microsoft and compiler version is below a specific value. (A conditional ifdef'd section for typedefing the new types mentioned above)
StainlessS
8th March 2020, 20:17
Cheers P.
EDIT: Maybe stdbool.h for C interface, C does not have bool.
qyot27
8th March 2020, 20:17
Considering that a refusal to update from outdated compilers was one of the main reasons AviSynth+ was started in the first place, I don't consider that a convincing argument. Requiring C99 is not an unreasonable baseline in any way, shape, or form.
VS2013 is 7 years old at this point (the C99 standard itself is 21 years old), and systems that can't run at least that version are in a very small minority. That's not 'the runtime of vc2013', required to use stuff it produces, that's the compiler itself. Most devs interested in keeping their plugins up-to-date with AviSynth+ are not on Pentium IIIs running Windows XP.
The alternatives are Clang-cl, use the MSVC Build Tools without the IDE (https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=vs-2019) or in conjunction with non-branded VSCode (https://vscodium.com/) (probably; still requires a newer CPU/OS, though), or switch the plugin to the C interface and build with GCC.
C++17 features aren't used in the headers, no.
StainlessS
8th March 2020, 21:08
I understand that Avs+ core requires recent compiler and have no problem with that.
But seems that one should require later version compiler for plugins, for no other reason than "it is hip" to do so,
I dont wanna update just because it is fashionable.
I mainly now use VS2008 on W7x64 Q9550, sometimes use XPx64 on quad core Q6600, got rid of my PIII's some time ago, I have one P4 XP32.
I also on occasion use VS2008 x86 on W10x86(Baytrail) Tablet/Laptop 2_in_1 thingy, with only 2GB RAM, 32GB storage, no way I am gonna use 2015, 2017 or 2019 on that.
[I also have x64 4GB RAM 64GB storage CherryTrail W10, dont want to swamp that with 2015/17/19 either]
EDIT: Of course the worst thing is that existing plugin source will no longer compile using the compilers that they were developed with
(unless you switch to avs 2.60 std header, making all of the avs+ compatible header stuff a pointless exercise).
EDIT: OK, reverted to older Avs+ headers, can compile again.
qyot27
8th March 2020, 23:02
Dunno, probably I put a check in the header against compiler version and define those types if compiler is Microsoft and compiler version is below a specific value. (A conditional ifdef'd section for typedefing the new types mentioned above)
The issue isn't so much the absence of those types, it's that for the AviSynth+ core to properly use stdint, #include <stdint.h> is in the avs/types.h header. So anyone wanting to use versions of MSVC prior to 2013 to build plugins will have it choke on the header include.
It'd be something like this:
#include "config.h"
// Define all types necessary for interfacing with avisynth.dll
#if defined(AVS_WINDOWS)
#if _MSC_VER >= 1800 // C99 stdint.h is only supported by MSVC 2013 or higher
#include <stdint.h>
#include <stdbool.h>
#endif
#else // AVS_POSIX
#include <stdint.h>
#include <stdbool.h>
#endif
I don't personally care about us maintaining compatibility with versions older than MSVC 2013, especially since the core won't even build with 2013. But that block is less obnoxious than us not moving away from MSVC types and instead using a hideous block of #defines to hammer things into working on non-Windows vs. just using standard types and stdint.h.
StainlessS
10th March 2020, 05:26
I'm currently just about done with mod to DDigit metrics text renderer for plugin devs, implemented for all Avs+ colorspaces.
I'de just like to check if I'm doin' it right, in particular the chroma calcs.
where, output 32 bit float result required.
c1 is YUV-Y in 0->255 range [EDIT: Text color as YUV 8 bit]
c2 is YUV-U in 0->255 range
c3 is YUV-V in 0->255 range
const float cxy =(float)(c1/255.0);
const float cxu =(float)((c2-127.5)/255.0); # mid 127.5 rather than 128 (seems right for -0.5 to +0.5)
const float cxv =(float)((c3-127.5)/255.0);
Or Maybe
const float cxy =(float)(c1/255.0);
const float cxu =(float)((c2-128)/255.0); # mid 128, possible (but unlikely) lob sided out of -0.5, 0.5 range
const float cxv =(float)((c3-128)/255.0);
Or Limit
const float cxy =(float)(c1/255.0);
const float cxu =(float)(max(c2-128,-127)/255.0); # mid 128, limited
const float cxv =(float)(max(c3-128,-127)/255.0);
Results look ok as above. [EDIT: maybe above first attempt is wrong, 2nd better, just ignore possible lob sidedness, or limit ??? (EDIT: I've changed to 128 limited)]
Thanx in advance.
EDIT: And for 8 bit BYTE RGB to 16 bit RGB48
int cx1=(c1<<8)|c1
int cx2=(c2<<8)|c2
int cx3=(c3<<8)|c3
and 8 bit BYTE RGB to Bpc RGB (10, 12, 14, 16)
int cls=Bpc-8,crs=8-cls;
int cx1=(c1<<cls)|(c1>>crs);
int cx2=(c2<<cls)|(c2>>crs);
int cx3=(c3<<cls)|(c3>>crs);
and 8 bit BYTE YUV to Bpc YUV (10, 12, 14, 16) [simple shift only]
int cxy =c1<<(Bpc-8)
int cxu =c2<<(Bpc-8);
int cxv =c3<<(Bpc-8);
pinterf
10th March 2020, 10:23
RGB is always full scale, the ranges should be stretched like
x_new = x_old * target_max / source_max
EDIT: And for 8 bit BYTE RGB to 16 bit RGB48
int cx1=(c1<<8)|c1
int cx2=(c2<<8)|c2
int cx3=(c3<<8)|c3
O.K. x*65535/255 is x*257 exactly
and 8 bit BYTE RGB to Bpc RGB (10, 12, 14, 16)
int cls=Bpc-8,crs=8-cls;
int cx1=(c1<<cls)|(c1>>crs);
int cx2=(c2<<cls)|(c2>>crs);
int cx3=(c3<<cls)|(c3>>crs);
O.K. Good approximation. I met this method earlier but I'm not using it. Now I have checked it again (see Python script)
This python script is showing that this approximation differs only by 1 from the ideal result. The integer mul-add-rounder-div is giving the same results as doing all as float (no difference). This latter method is not too fast, it has an integer division (which can be replaced by multiply using magic-number tricks but using float for precison is better)
When you are using this approximation for font colors, it's more than enough.
sourcebits=10
targetbits=16
sourcemax = (1 << sourcebits) - 1
half_for_rounding = sourcemax // 2
cls = targetbits - sourcebits
crs = sourcebits - cls
targetmax = (1 << targetbits) - 1
errcount_approx = 0
errcount_intmuldiv = 0
maxdiff = 0
for x in range(0, sourcemax):
# reference: float
float32 = int(float(x) * targetmax / sourcemax + 0.5)
approx = (x << cls) | (x >> crs)
intmuldiv = (x * targetmax + half_for_rounding) // sourcemax
intmuldiv_no_round = (x * targetmax) // sourcemax
if approx != float32:
print("FLT_APPROX_DIFF x = {0} approx = {1} exact = {2} intround = {3} intnoround = {4} ".format(x, approx, float32, intmuldiv, intmuldiv_no_round))
errcount_approx = errcount_approx + 1
diff = abs(approx - float32)
if diff > maxdiff:
maxdiff = diff
if float32 != intmuldiv : # or approx != intmuldiv_no_round''':
print("FLT_INT_DIFF x = {0} approx = {1} exact = {2} intround = {3} intnoround = {4} ".format(x, approx, float32, intmuldiv, intmuldiv_no_round))
errcount_intmuldiv = errcount_intmuldiv + 1
print("Difference count (approx): {0}, maxdiff: {1}".format(errcount_approx, maxdiff))
print("Difference count (intmuldiv): {0}".format(errcount_intmuldiv))
# from-to # of differences
# 8->10 42
# 8->12 56
# 8->14 42
# 8->16 0
#10->12 170
#10->14 234
#10->16 234
and 8 bit BYTE YUV to Bpc YUV (10, 12, 14, 16) [simple shift only]
int cxy =c1<<(Bpc-8)
int cxu =c2<<(Bpc-8);
int cxv =c3<<(Bpc-8);
O.K. YUV is always bit-shifting
pinterf
10th March 2020, 11:36
I'm currently just about done with mod to DDigit metrics text renderer for plugin devs, implemented for all Avs+ colorspaces.
I'de just like to check if I'm doin' it right, in particular the chroma calcs.
where, output 32 bit float result required.
c1 is YUV-Y in 0->255 range [EDIT: Text color as YUV 8 bit]
c2 is YUV-U in 0->255 range
c3 is YUV-V in 0->255 range
const float cxy =(float)(c1/255.0);
const float cxu =(float)((c2-127.5)/255.0); # mid 127.5 rather than 128 (seems right for -0.5 to +0.5)
const float cxv =(float)((c3-127.5)/255.0);
Or Maybe
const float cxy =(float)(c1/255.0);
const float cxu =(float)((c2-128)/255.0); # mid 128, possible (but unlikely) lob sided out of -0.5, 0.5 range
const float cxv =(float)((c3-128)/255.0);
Or Limit
const float cxy =(float)(c1/255.0);
const float cxu =(float)(max(c2-128,-127)/255.0); # mid 128, limited
const float cxv =(float)(max(c3-128,-127)/255.0);
Results look ok as above. [EDIT: maybe above first attempt is wrong, 2nd better, just ignore possible lob sidedness, or limit ??? (EDIT: I've changed to 128 limited)]
Thanx in advance.
Ideally integer values are never using PC full scale, limited range has no problems, 16-235 Y and 16-240 UV. Latter is definitely symmetric to 128, unlike if one is stretching U and V to 0..255 which will never be exact, since the theoretical center (127.5) does not exist in the integer domain.
Either you are using 32 bit float format with a simple division
For 8 bits:
Y' = Y / 255.0
U' = (U - 128) / 255.0
(replace 255 with the acture max_bit_depth_value)
Internally 8 bit colors (historically we can pass only 8 bit colors using integer parameters e.g. text color or BlankClip) are converted by using this method.
Or you can keep the convention that float formas are always full scale and map Y 16-235 to 0..1.0 and U,V 16-240 to -0.5..0.5
I'm planning rechecking all such occurences when YUV 32 bit floats are used in such a mixed bit depth environment, incl. Colorbars. My opinion that 32 bit float YUV should be treated always as full scale Y=0 to 1 and U/V=-0.5 to +0.5
StainlessS
10th March 2020, 15:27
Thanks P, I've taken snap of both posts for posterity, not really that important (I dont think) that absolutely correct, is only for metrics
and colornames chosen (from Colors_Rgb.avsi) were really only so I would not end up making up my own names, eg FishFinger_Orange or Putrid_Puce.
I'll try get as close as I can to optimum, but might just do close to best if it will impact speed too much.
I'm surprised that it was so easy to do the mod, only started it two days ago, still some tinkering to do.
IanB did a re-factor of Info.h where optionally len of text could be given rather than hunting nul term sentinel, this allowed me to write the
utility partner header InfoF.h which allows Info.h metrics text to have embedded control codes eg '\n' and '\r', perhaps a similar arrangment could be used
with your Text() filter (AKA SimpeText class), might also allow for color control codes so that plug progger could use multi-line anti-aliased Text() with better
control of text rendering, and eg sprintf type insertion of variables into strings, as used in eg RT_String().
For this to work properley, would ideally be implemented as a frame renderer rather than a filter [requiring MakeWriteable already done by caller], so as to be
able to control text placement, or maybe the InfoF.h style control with additional sprintf style var to string substitution could be done internally and so the
interface would need be implemented with varidaic args [think thats what them there things are called, same as RT_string(), RT_DebugF(), RT_Subtitle()
and a few more].
As currently implemented as a filter, Text() would not be ideal where placement of multiple strings in different frame positions is needed.
I implemented similar in thread "Avisynth CPP interface for C Proggers":- https://forum.doom9.org/showthread.php?p=1538557#post1538557
Some excerpts from that thread.
#include "Info.h"
// Plugin text rendering header from Avisynth v2.6, (Use Version of 17 April 2011, or later, bugs fixed, OK for v2.5+)
// Provides white only horizontal print at pixel coordinates, no formatting of any kind.
// Obtainable here (look for 'Info.h'):-
// http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/core/
#include "InfoF.h" // New in v0.2
// A companion to Info.h, provides screen formatted printing via embedded control codes.
// Also provides stubs for character coord printing as well as pixel coordinates.
// Formatting control codes:-
// '\n', Newline, positioning cursor 1 line down and at left edge of screen.
// '\r', Newline Special, moves 1 line down and positions cursor at on-entry X position.
// '\b', Backspace, obvious, not sure how useful this will be.
// '\f', Forward Space, again obvious, re-uses formfeed code for this. Again, maybe not so useful.
// '\t', Tab, @ character positions, every 4 characters.(relative screen LHS).
//
// DDigit() from which this header originates, provides horizontal & vertical print at both pixel
// and character coords, 16 color printing and screen formatting (eg '\n') control codes together
// with color control codes. Control codes, vertical print and colorspace code are all controlled
// via compiler directives and so can be excluded from the binary if not required.
//
// DrawFStr() Draw a Formatted string of text at character position, a user defined member function.
// As with all class members defined outside of the class, it is preceded by the class name and scope operator.
void __stdcall INTERNALNAME::DrawFStr(PVideoFrame &dst,int x,int y,const char *format, ...)
{
// This member function added in v0.2, adds BOTH string and screen formatting, eg '%f' for string and '\n' for screen.
// Firstly, string formatting, into the buffer implemented in the class instance, formatted_buf[FMT_BUFSZ].
va_list args;
va_start(args, format);
_vsnprintf(formatted_buf,FMT_BUFSZ-1, format, args);
va_end(args);
// The DrawFStrXXX fn's are implemented in the InfoF.h file and provide screen formatting, eg '\'n and '\t'.
// As string formatting has already been done above (eg floats etc turned to character strings), and the below
// DrawFStrXXX functions provide screen formatting, so full formatting is achieved on the video frame.
//
// Formatting control codes (as provided by InfoF.h):-
// '\n', Newline, positioning cursor 1 line down and at left edge of screen.
// '\r', Newline Special, moves 1 line down and positions cursor at on-entry X position.
// '\b', Backspace, obvious, not sure how useful this will be.
// '\f', Forward Space, again obvious, re-uses formfeed code for this. Again, maybe not so useful.
// '\t', Tab, @ character positions, every 4 characters.(relative screen LHS).
//
if(vi.IsPlanar()) DrawFStrPlanar(dst,x,y,formatted_buf);
else if(vi.IsYUY2()) DrawFStrYUY2(dst,x,y,formatted_buf);
else if(vi.IsRGB32()) DrawFStrRGB32(dst,x,y,formatted_buf);
else if(vi.IsRGB24()) DrawFStrRGB24(dst,x,y,formatted_buf);
}
From InfoF.h
void __stdcall DrawFStringPlanar(PVideoFrame &dst,int x,int y,const char *s,bool pix = true)
{ // Draw formatted string at pixel or character coords, pix == false = character coords
if(pix == false) {x *= 10; y *= 20;} // To Chars
int in_x = x; // REM x for '\r'
const unsigned char *se=(unsigned char*)s; // unsigned
while(*se) { // while, some to do
int n;
for(s=(char*)se; n = *se, n>=' ' && n <= 223; ++se); // Find end+1 of printable
int len = (int)((char*)se - s); // Len of printable
if (len) { // Some to print
DrawStringPlanar(dst,x,y,s,len); // do the biz
x += len * 10; // update x coord
} else { // Ctrl code OR nonsense;
if(n == '\n') {
x = 0; y+=20; // Newline, down 1, LHS
} else if (n == '\r') {
x = in_x; y +=20; // Newline Special, Down 1, orig x coord
} else if(n == '\b') {
x -= 10; // Backward Space
} else if (n == '\f') {
x += 10; // Forward Space
} else if (n == '\t') {
x+= ((4*10)-(x%(4*10))); // H-Tab (step 4)
}
++se; // skip ctrl code (and unknowns, outer loop detects nul sentinel)
}
}
}
void __stdcall DrawFStrPlanar(PVideoFrame &dst,int x,int y,const char *s)
{ // Formatted Print @ character coords
DrawFStringPlanar(dst,x,y,s,false);
}
From Avisynth CPP interface for C Proggers
Using plain white only text using Info.h with InfoF.h layout control and sprintf style arg substitution as from above function.
https://i.postimg.cc/grJTjV5J/Synth-Infoh.jpg (https://postimg.cc/grJTjV5J)
https://i.postimg.cc/7f78P1Gz/Chr-Set-Info.jpg (https://postimg.cc/7f78P1Gz)
A few frames from current DDigitTest dll
https://i.postimg.cc/qNS1NSPM/dd1.jpg (https://postimg.cc/qNS1NSPM)
https://i.postimg.cc/WtYgpgLs/dd2.jpg (https://postimg.cc/WtYgpgLs)
https://i.postimg.cc/njc9pc3s/dd3.jpg (https://postimg.cc/njc9pc3s)
https://i.postimg.cc/4mh7J0Q1/dd4.jpg (https://postimg.cc/4mh7J0Q1)
pinterf
10th March 2020, 15:51
So positioning is done like left-right-down joystick movements between prints?
I'm working on further Text filter features which were in my mind but were omitted in the final rush of making linux version work.
Such cursor movements can probably be easily added without much speed penalty. (Though I'm sure that it's not this filter which is the bottleneck, I did some profiling and check of the generated asm code just for couriosity)
You noticed well that I have removed the string length argument, because it was of no use actually.
StainlessS
10th March 2020, 16:09
left-right-down joystick
Sort of yes.
I particularly like the ability to return to 'on-entry' X position, so can if required format text with a horizontal Offset to all lines (either pixel or char position).
EDIT: You can use only '\r' n/l special and change on-entry X position and, move the whole damn lot over left or right and maintain all layout.
I also use '\a' as color control code with additional chr code for color, but left one ctrl code free for any future expansion,
(8=\b=backspace, 9=\t=tab, 10=\n=newline, 11=free['\v' I think, cant remember, maybe vertical tab], 12='\f'=forward space, 13=\r=NewLineSpecialOnEntry-X)
You noticed well
Yep, Nobody Expects The Spanish Inquisition. :)
EDIT: From DDigitTest
if(!mono) {
char *ahi=(a1>235||a2>235||a3>235)?"\aA":"\aB";
char *blo=(b1<16||b2<16||b3<16)?"\a6":"\aB";
sprintf(buf,
"\b\b\b\b\f\bTesting Control & Color Codes:-\n\n\r"
"Frame: %-7u( \a2Red\a- / \a4Green\a- / \a1Blue\a- )\r"
" \a8Fred: (%7.2f /%7.2f /%7.2f )\r"
" Ted: (%7.2f /%7.2f /%7.2f )\r"
" Bill: ( %3d / %3d / %3d )\r"
" Ben: ( %3d / %3d / %3d )\r"
" %sJack\aB: ( %s%3d\aB / %s%3d\aB / %s%3d\aB )\r"
" %sJill\aB: ( %s%3d\aB / %s%3d\aB / %s%3d\aB )\r"
"\n\n\a-EVERYTHING VISIBLE (incl this) is 1 single printed string\n"
"\t\t\t\t\aEDATA is RANDOM ONLY"
,n,
rand()*255.0/RAND_MAX,rand()*255.0/RAND_MAX,rand()*255.0/RAND_MAX,
rand()*255.0/RAND_MAX,rand()*255.0/RAND_MAX,rand()*255.0/RAND_MAX,
rand()&255,rand()&255,rand()&255,rand()&255,rand()&255,rand()&255,
ahi,(a1>235)?ahi:"\aB",a1,(a2>235)?ahi:"\aB",a2,(a3>235)?ahi:"\aB",a3,
blo,(b1<16)?blo:"\aB",b1,(b2<16)?blo:"\aB",b2,(b3<16)?blo:"\aB",b3
);
} else {
char *ahi=(a1>235||a2>235||a3>235)?"\aV":"\aO";
char *blo=(b1<16||b2<16||b3<16)?"\aV":"\aO";
sprintf(buf,
"\b\b\b\b\f\bTesting Control & Mono Codes:-\n\n\r"
"Frame: %-7u( \aQBob\a- / \aQAlice\a- / \aQDave\a- )\r"
" \aTFred: (%7.2f /%7.2f /%7.2f )\r"
" Ted: (%7.2f /%7.2f /%7.2f )\r"
" Bill: ( %3d / %3d / %3d )\r"
" Ben: ( %3d / %3d / %3d )\r"
" %sJack\aO: ( %s%3d\aO / %s%3d\aO / %s%3d\aO )\r"
" %sJill\aO: ( %s%3d\aO / %s%3d\aO / %s%3d\aO )\r"
"\n\n\a-EVERYTHING VISIBLE (incl this) is 1 single printed string\n"
"\t\t\t\t\aODATA is RANDOM ONLY"
,n,
rand()*255.0/RAND_MAX,rand()*255.0/RAND_MAX,rand()*255.0/RAND_MAX,
rand()*255.0/RAND_MAX,rand()*255.0/RAND_MAX,rand()*255.0/RAND_MAX,
rand()&255,rand()&255,rand()&255,rand()&255,rand()&255,rand()&255,
ahi,(a1>235)?ahi:"\aO",a1,(a2>235)?ahi:"\aO",a2,(a3>235)?ahi:"\aO",a3,
blo,(b1<16)?blo:"\aO",b1,(b2<16)?blo:"\aO",b2,(b3<16)?blo:"\aO",b3
);
}
AStr(dst, 4, 0, buf);
EDIT:
DDigit / RT_Subtitle(), also has 16 shades of grey, but I'm not altogether happy with the dark ones on eg black background,
trying to figure out a way to brighten background for those, and with little overhead and hopefully no additional code path.
https://i.postimg.cc/Ffj9P1sM/c-00.jpg (https://postimg.cc/Ffj9P1sM)
Here is code for RGBPS and RGBAPS
} else if(ComponentSize==4) {
if (RGB && Planar) {
#if (defined DDIGIT_ENABLE_SUPPORT_RGB && defined DDIGIT_ENABLE_SUPPORT_PLANAR)
const int pitch = PitchArr[0];
const float cx1=(float)(c1/255.0);
const float cx2=(float)(c2/255.0);
const float cx3=(float)(c3/255.0);
const float cxArr[3]={cx2,cx3,cx1};
for(int pln=0;pln<=2;++pln) {
BYTE *dp=WrPtrArr[pln] + xx*4 + yy*pitch;
const float cx = cxArr[pln];
for (int ty = tytop; ty < tybot;++ty,dp += pitch) {
float* rp = (float*)dp;
unsigned int fbm= FontNum[ty] << txlft;
for (int tx = txlft; tx < txrgt; ++tx,++rp, fbm<<=1) {
if (fbm & 0x8000) { // Character Foreground SET Pixel ?
rp[0] = cx; // Set Luma Foreground Pixel
} else {
DD4_BGF_RGB(rp[0]); // fade background
}
}
}
}
#endif // (defined DDIGIT_ENABLE_SUPPORT_RGB && defined DDIGIT_ENABLE_SUPPORT_PLANAR)
EDIT: And the Fade background thing (opt 0=7/8 opt 1=3/4, there are 5 options) [DD4_BGF_RGB(rp[0]); // fade background]
#elif (DDIGIT_BACKGROUNDFADE == 1)
// Multiply background by 3/4
#if(0)
// Old 8 bit before simplify
#define DD_BGF_Y(dat) (dat)=(unsigned char) (((((dat)-16)*3)>>2)+16)
#define DD_BGF_C(dat) (dat)=(unsigned char) (((((dat)-128)*3)>>2)+128)
#define DD_BGF_RGB(dat) (dat)=(unsigned char) (((dat)*3)>>2)
#else
// ComponentSize=1 (8 bit)
// (dat*3>>2)-(16*3>>2)+16 == (dat*3>>2)+4
#define DD_BGF_Y(dat) (dat)=(unsigned char) ((((dat)*3)>>2)+4)
// (dat*3>>2)-(128*3>>2)+128 == (dat*3>>2)+32
#define DD_BGF_C(dat) (dat)=(unsigned char) ((((dat)*3)>>2)+32)
#define DD_BGF_RGB(dat) (dat)=(unsigned char) (((dat)*3)>>2)
// ComponentSize=2
// (dat*3>>2)-(64 *3>>2)+ 64 == (dat*3>>2)+ 16 10 bit
// (dat*3>>2)-(256 *3>>2)+ 256 == (dat*3>>2)+ 64 12 bit
// (dat*3>>2)-(1024*3>>2)+1024 == (dat*3>>2)+ 256 14 bit
// (dat*3>>2)-(4096*3>>2)+4096 == (dat*3>>2)+1024 16 bit
#define DD2_BGF_Yadd(bpc) (4<<((bpc)-8)) // Precalc add = (4<<(BitsPerComponent-8))
#define DD2_BGF_Y(dat,add) (dat)=(unsigned short) (((dat)*3>>2)+(add)) // Precalc add = (4<<(BitsPerComponent-8))
// (dat*3>>2)-( 512 *3>>2)+ 512 == (dat*3>>2)+ 128 10 bit
// (dat*3>>2)-( 2048 *3>>2)+ 2048 == (dat*3>>2)+ 512 12 bit
// (dat*3>>2)-( 8192 *3>>2)+ 8192 == (dat*3>>2)+ 2048 14 bit
// (dat*3>>2)-(32768 *3>>2)+ 32768 == (dat*3>>2)+ 8192 16 bit
#define DD2_BGF_Cadd(bpc) (32<<((bpc)-8)) // Precalc add = (32<<(BitsPerComponent-8))
#define DD2_BGF_C(dat,add) (dat)=(unsigned short) (((dat)*3>>2)+(add)) // Precalc add = (32<<(BitsPerComponent-8))
#define DD2_BGF_RGB(dat) (dat)=(unsigned short) ((dat)*3>>2)
// ComponentSize=4
#define DD4_BGF_Y(dat) (dat)=(float)((dat)*(3.0/4.0))
#define DD4_BGF_C(dat) (dat)=(float)((dat)*(3.0/4.0))
#define DD4_BGF_RGB(dat) (dat)=(float)((dat)*(3.0/4.0))
#endif
#elif (DDIGIT_BACKGROUNDFADE == 2)
pinterf
10th March 2020, 16:23
In Text \n (the control character, not the literal human visible \n) is line separator. When horizontal alignment is set to "center" each separated lines will be centered individually.
StainlessS
10th March 2020, 17:05
EDIT:
Yep, the centering thing would upset things
Here my code in DDigit, uses actual codes, RT_Subtitle (If I remember correctly) will take either real control code or human visible eg "\n" or "\a0"
and converts to real control codes "\n" to Chr(10) and then "\a0" to Chr(7)+Chr(48), for DDigit, also RT_Subtitle() does sprintf style arg substitution, and detects whether not will be wholly off frame (misses call to DDigit
when so, DDigit can do that itself, but RT_Subtitle is parsing anyways so avoids duplicate parsing when not necessary). Only on frame subs will be processed
by DDigit via RT_Subtitle. I have script that scroll quite long texts and in real time upwards, downwards, or Kareoke style, and DDigit only gets the valid on frame
text to bother with.
some ctrl code stuff
for (int s_ix=0;s_ix<length ;++s_ix) {
num=((unsigned char*)s)[s_ix]; // Cast to speed up ctrl code detect
#ifdef DDIGIT_ENABLE_SUPPORT_CONTROL_CODES
if(num <= '\r' && num >= '\a' && (ctrl)) { // Control Character ?
if(num == '\a') { // Color control character ?
int cc=s[s_ix+1];
if(cc >= 'a' && cc <= 'v')
cc -= ('a' - 'A'); // Upper Case
char *colstr="0123456789ABCDEFGHIJKLMNOPQRSTUV-!*";
char * ccp=colstr;
while(*ccp && *ccp != cc)
++ccp;
if(*ccp) {
++s_ix; // Color control code parsed with valid arg, skip ctrl code.('\a')
cc=int(ccp - colstr);
if(cc>31) {
if(cc==32) { // '-' = ddigit default color
cc = CMapdef[cmapix][0]; // Default
} else if(cc==33) { // '!' = ddigit hilite
cc = CMapdef[cmapix][1]; // Hilite
} else if(cc==34) { // '*' = Original starting color
cc=color;
}
}
c1=(RGB) ? DDigit_Cmap_RGB[cc] : DDigit_Cmap_YUV[cc];
c3=c1 & 0xFF; c1>>=8U;
c2=c1 & 0xFF; c1>>=8U;
c1 &= 0xFF;
continue;
}
} else if (!vert) { // Horizontal
switch(num) {
case '\n': // NewLine
x = 0; // Screen left
y += DDIGIT_CHAR_HEIGHT; // Next line down
continue;
case '\r': // 1 line down and back to original X position
x = in_x; // Below starting X input postion
y += DDIGIT_CHAR_HEIGHT; // Next line down
continue;
case '\t': // Horizontal Tab
x+= ((DDIGIT_TABCNT*DDIGIT_CHAR_WIDTH)-(x%(DDIGIT_TABCNT*DDIGIT_CHAR_WIDTH)));
continue;
case '\f': // Forward Space
x += DDIGIT_CHAR_WIDTH; // 1 char right
continue;
case '\b': // BackSpace
x -= DDIGIT_CHAR_WIDTH; // 1 char left
continue;
}
} else { // Vertical
EDIT: Try this script, no really try it. [Std v2.6 colorspaces only]
avi = RT_FSelOpen("Please select an AVI file",Filt="*.AVI|*.AVI")
Assert(avi.IsString,"RT_FSelOpen: Error="+String(avi))
AVISource(AVI)
txt = RT_FSelOpen("And now select a Text file",Filt="*.txt|*.txt")
Assert(txt.IsString,"RT_FSelOpen: Error="+String(txt))
Txt=RT_ReadTxtFromFile(txt)
Lines=RT_TxtQueryLines(Txt)
# config
DELAY=100
ALIGN=1 # As Numeric KeyPad
SCROLL=0 # 0 = Upwards : 1 = Downwards : 2 = Right to Left : 3 = Left to right : 4 = Karaoke
#
ORG=Last
Last=(SCROLL==4)? ORG.Blankclip(height=80) : Last
CMD_0 = """RT_Subtitle("%s",Txt,align=ALIGN,y=height+DELAY-current_frame,expx=true,expy=true)"""
CMD_1 = """RT_Subtitle("%s",Txt,align=ALIGN,y=-(Lines*20+DELAY) + current_frame,expx=true,expy=true)"""
CMD_2 = """RT_Subtitle("%s",Txt,align=ALIGN,x=width+DELAY-current_frame,expx=true,vcent=true)"""
CMD_3 = """RT_Subtitle("%s",Txt,align=ALIGN,x=-(width+DELAY)+current_frame,expx=true,vcent=true)"""
CMD_4 = """RT_Subtitle("%s",Txt,align=ALIGN,y=height+DELAY-current_frame,expx=true,expy=true)"""
CMD_5 = """RT_Subtitle("BAD SCROLL COMMAND (0->4)")"""
CMD = (SCROLL<0 || SCROLL>4) ? CMD_5 : Select(Scroll,CMD_0,CMD_1,CMD_2,CMD_3,CMD_4)
ScriptClip(CMD)
Return (SCROLL==4)? StackVertical(ORG,Last) : Last
here a little centered scrolling text that I had handy (its not that good).
https://i.postimg.cc/5jtpfPk6/RT-SCROLLDEMO-00.jpg (https://postimg.cc/5jtpfPk6)
EDIT: Also take peek at this:- https://forum.doom9.org/showthread.php?t=177366
EDIT:
RT_Subtitle(clip source,string format,dat1,...,datn,int "align",int "x","y",bool "vcent"=false,bool "expx"=false,bool "expy"=false,int "esc"=1)
Standard filter function.
This function is a standard filter graph function, not a runtime/compile time function.
v2.5 plugin dll limited to v2.58 colorspaces.
Prints formatted text to clip frame using Avisynth Info.h source font (monospaced) and DDigit font renderer, faster than using
Subtitle system fonts. The unnamed 'format' string and optional unnamed 'dat' args are used to construct the text string that is
printed on frame, uses C/CPP printf() style formatting. The args 'align', 'x', and 'y', work in a similar fashion to
Avisynth Subtitle()
expx and expy control whether x and y are same as in SubTitle when eg y = -1 (vertical centered) or y=height (bottom aligned),
or as explicit coords when expy = true.
esc int, default 1. (0 -> 2). Escape code processing eg '\n' converted to NewLine.
0 = No Escape code processing.
1 = Esc codes processed only in format string. (Default)
2 = Esc codes processed in both format and data strings.
RT_Subtitle(c,"Hello there %s and %s.\nGoodbye %d.","Fred","Ted",2013,align=4,x=100,vcent=true)
would print
Hello there Fred and Ted.
Goodbye 2013.
at x pixel position 100 and y pixel position centered, the vcent=true will vertical center a block of text (align=4 or 5 or 6),
whereas Subtitle() starts at centred position and prints downwards from there (as default vcent=false).
Align, default = 7 ie top left (as on numeric keypad).
x and y allow modification of alignment, eg x= -1, centers x at mid point, x=width, would right align,
y=height would align at bottom of frame.
It is necessary to specify the optional arg names of x,y,align and vcent etc, as the dat args can take 0 or more variables
of any type, so Avisynth cannot tell when the list of dat args ends and the named optional args begins. I did
try to use the dat args last but Avisynth seems to get confused when you use dat= etc, it throws an error
saying something like "dat arg specified more than once", even if it was not.
printf Format spec here:- http://msdn.microsoft.com/en-us/library/56e442dc%28v=vs.71%29.aspx
NOTE, the only support for printing Bool variables is %s as string, ie prints "True" or "False".
To print only 1st letter of type bool:- ColorBars.KillAudio.RT_Subtitle("%.1s",true) prints 'T'
Formatting supported %[flags] [width] [.precision] type
flags, one of "-,+,0, ,#"
width, integer, "*" supported (width supplied via dat arg).
Precision, integer, "*" supported (precision supplied via dat arg).
type,
"c,C,d,i,o,u,x,X", Integer type, c,C=character, d,i=signed, o,u,x,X=unsigned.
"e,E,f,g,G", Floating point type
"s,S", String type (also Bool).
eg
colorbars.killaudio
FMT="%d ] \a%cCurrent_Frame=\a-%d"
ALPHA="0123456789ABCDEFGHIJKLMNOPQRSTUV-!"
ScriptClip("""
RT_Subtitle(FMT,current_frame,RT_Ord(ALPHA,(current_frame/25)%32+1),current_frame,align=5)
""")
return last
In the above example you see the sequence "\a%c" where %c is replaced with a character from ALPHA, "\a0"
selects color 0, "\aV" selects the last color (31). "\a-" selects the default color, and "\a!" selects
the hilite color. You can in Scriptclip() select colors programmatically, perhap selecting red to show an
error or bad metrics condition. The initially selected color will always be the default color (white).
Ripped from DDigit source code:
// Color control codes as strings. ASCII Code of Final char
#define DDIGIT_CC_DARKGRAY "\a0" // 48
#define DDIGIT_CC_DODGERBLUE "\a1" // 49
#define DDIGIT_CC_ORANGERED "\a2" // 50
#define DDIGIT_CC_ORCHID "\a3" // 51
#define DDIGIT_CC_LIME "\a4" // 52
#define DDIGIT_CC_AQUAMARINE "\a5" // 53
#define DDIGIT_CC_YELLOW "\a6" // 54
#define DDIGIT_CC_WHITE "\a7" // 55
#define DDIGIT_CC_SILVER "\a8" // 56
#define DDIGIT_CC_CORNFLOWERBLUE "\a9" // 57
#define DDIGIT_CC_ORANGE "\aA" // 65
#define DDIGIT_CC_PLUM "\aB" // 66
#define DDIGIT_CC_CHARTREUSE "\aC" // 67
#define DDIGIT_CC_POWDERBLUE "\aD" // 68
#define DDIGIT_CC_GOLD "\aE" // 69
#define DDIGIT_CC_GAINSBORO "\aF" // 70
#define DDIGIT_CC_Y_0 "\aG" // 71
#define DDIGIT_CC_Y_1 "\aH" // 72
#define DDIGIT_CC_Y_2 "\aI" // 73
#define DDIGIT_CC_Y_3 "\aJ" // 74
#define DDIGIT_CC_Y_4 "\aK" // 75
#define DDIGIT_CC_Y_5 "\aL" // 76
#define DDIGIT_CC_Y_6 "\aM" // 77
#define DDIGIT_CC_Y_7 "\aN" // 78
#define DDIGIT_CC_Y_8 "\aO" // 79
#define DDIGIT_CC_Y_9 "\aP" // 80
#define DDIGIT_CC_Y_A "\aQ" // 81
#define DDIGIT_CC_Y_B "\aR" // 82
#define DDIGIT_CC_Y_C "\aS" // 83
#define DDIGIT_CC_Y_D "\aT" // 84
#define DDIGIT_CC_Y_E "\aU" // 85
#define DDIGIT_CC_Y_F "\aV" // 86
#define DDIGIT_CC_HILITE "\a!" // 33
#define DDIGIT_CC_DEFAULT "\a-" // 45
In color codes eg "\aV", the 'a' is strictly case sensitive however the color number ('V') can be upper ot lower case.
In addition to color control codes, the filter will accept "\n" (NOT "\N", strictly case sensitive) or "\r"
as newline, and "\f" as forward space (move 1 right without printing anything), no other control codes are supported.
"\t" and TAB control codes are converted to a single space, I could think of no sensible way to handle tab when center or
right aligned, if there is a demand, I could maybe handle tab for left alignment only and replace with single space
for other alignment.
To embed a single BackSplash ("\") into the format string or even an argument dat (when esc=2) string you must insert a double
BackSlash ie "\\". To embed a single percent character ("%") into a format string, you must embed a double percent
sequence ie "%%". Reason is that such characters are used for formatting eg "%f" flags a float arg to embed into
the string and eg "\n" would mean insert newline into string.
Note, the colored text is not great in YV12 and quite awful in YV411, try to avoid YV411 at all times,
tis truly nasty.
To Print contents of multiline text file on frame:
AVISource("D:\AVS\TEST.AVI")
S=RT_ReadTxtFromFile("test.txt")
Scriptclip("""RT_Subtitle("%s",S,align=5,vcent=True)""")
return last
As can be seen from above example, you can also use eg Chr(10) (in the file) instead of "\n" or Chr(13), or Chr(13)+Chr(10)
instead of "\r\n" with identical results, CR, NL and CR/NL pairs are internally replaced by a single Chr(10).
To Print contents of multiline text file on frame, Scrolling upwards as for end credits:
AVISource("D:\AVS\TEST.AVI").ConvertToRGB32()
S=RT_ReadTxtFromFile("D:\avs\avi\test.txt")
DELAY=100
Scriptclip("""RT_Subtitle("%s",S,align=5,y=height+DELAY-current_frame,expy=true)""")
The above example uses the "expy" arg, which tells the filter to NOT interpret y == -1 as screen vertical
center align and to NOT interpret y=height as bottom aligned. ExpX does the same for the x arg. If you change
above to ExpY=false, as the text scrolls on screen and again when text scrolls off top of frame, there will be
a single frame where y==height OR y==-1, will align the text an cause a glitch in the video clip.
You could also embed eg color control codes into any above such scrolling text file for your amusement, eg
embedding "\a!" into the text file would switch on Hi-Lite-ed text. [needs esc=2 for esc codes in data strings]
If you want you can run above script with this text file as "test.txt" and because it has color control codes
embedded into it (eg the ripped DDigit source code earlier) so it will show the file, some lines of which will be
colored. This text file has NOT been prepared for that particular reason but may demo the embedded color codes.
RT_Subtitle() has the advantage of not requiring string memory as the string is created internally and
released on plugin destruction, whereas SubTitle() within ScriptClip will keep accumulating string memory
which is not released until Avisynth closes. Of course any eg concatenated strings supplied to RT_Subtitle
will be accumulated unless eg assigned to string variable external to Scriptclip.
The RT_Subtitle filter is intended to be used in providing on-frame metrics in a script, and not for final
output, use SubTitle() for that.
For any script using standard Subtitle() for metrics, it would not be at all surprising if that script were
to double (or more) in speed when replaced by RT_Subtitle, it really is quite light weight in comparison.
EDIT: Oops, RT_Subtitle Does not process '\r' as described, I did not know how to handle with centering, and so treat either "\r" or "\n" or "\r\n" or even "\n\r" (ctrl code or human readable I think) as newline ctrl code 10.
DDigit handles as described, but RT_Subtitle converts to Chr(10) before it gets there.
StainlessS
11th March 2020, 19:46
I get slightly different result from Avs conversion of your (pinterf post #5211) Python script. [assuming that 10->16 234 was correct]
I have added an alternative method of the muldiv whotsit (It dont seem any better than muldiv, at least with the numbers tried, it should though be better occasionally).
Hope I did conversion from Python right.
/* Python AVS script results
# from-to # of differences approx intmuldiv altmuldiv
# 8->10 42 42 0 0
# 8->12 56 56 0 0
# 8->14 42 42 0 0
# 8->16 0 0 0 0
#10->12 170 170 0 0
#10->14 234 234 0 0
#10->16 234 233 1 1
10 -> 16
FLT_APPROX_DIFF x = 818 ALT = 52402 approx = 52403 exact = 52402.000000 intround = 52402 intnoround = 52402
FLT_APPROX_DIFF x = 819 ALT = 52466 approx = 52467 exact = 52466.000000 intround = 52466 intnoround = 52466
*ALT_APPROX_DIFF x = 820 ALT = 52530 approx = 52531 exact = 52531.000000 intround = 52530 intnoround = 52530 ***
!FLT_INT_DIFF x = 820 ALT = 52530 approx = 52531 exact = 52531.000000 intround = 52530 intnoround = 52530 !!!
Altmuldiv and muldiv both wrong above, but approx gets it right
FLT_APPROX_DIFF x = 832 ALT = 53299 approx = 53300 exact = 53299.000000 intround = 53299 intnoround = 53299
FLT_APPROX_DIFF x = 833 ALT = 53363 approx = 53364 exact = 53363.000000 intround = 53363 intnoround = 53363
Difference count (approx): 233, maxdiff: 1
Difference count (intmuldiv): 1
Difference count (altmuldiv): 1 maxdiff 1
*/
sourcebits=10
targetbits=16
sourcemax = BitLShift(1 , sourcebits) - 1
half_for_rounding = sourcemax / 2
cls = targetbits - sourcebits
crs = sourcebits - cls
targetmax = BitLShift(1,targetbits) - 1
errcount_alt = 0
errcount_approx = 0
errcount_intmuldiv = 0
maxdiff = 0
maxdiffalt = 0
for(x=0, sourcemax) {
# reference: float
float32 = int(float(x) * targetmax / sourcemax + 0.5)
approx = BitOr( BitLShift(x,cls) , BitRShiftL(x,crs))
intmuldiv = (x * targetmax + half_for_rounding) / sourcemax
intmuldiv_no_round = (x * targetmax) / sourcemax
altmuldiv = (x * targetmax * 2 + sourcemax) / (sourcemax*2) # new # EDIT: This ALWAYS produces exact same result as intmuldiv, ie no use at all.
if(altmuldiv != float32) {
RT_DebugF("*ALT_APPROX_DIFF x = %d ALT = %d approx = %d exact = %f intround = %d intnoround = %d ***",x,altmuldiv, approx, float32, intmuldiv, intmuldiv_no_round)
errcount_alt = errcount_alt + 1
diff = abs(altmuldiv - float32)
if (diff > maxdiffalt) {
maxdiffalt = diff
}
}
if(approx != float32) {
RT_DebugF(" FLT_APPROX_DIFF x = %d ALT = %d approx = %d exact = %f intround = %d intnoround = %d ",x,altmuldiv, approx, float32, intmuldiv, intmuldiv_no_round)
errcount_approx = errcount_approx + 1
diff = abs(approx - float32)
if (diff > maxdiff) {
maxdiff = diff
}
}
if(float32 != intmuldiv) { # or approx != intmuldiv_no_round''':
RT_DebugF("!FLT_INT_DIFF x = %d ALT = %d approx = %d exact = %f intround = %d intnoround = %d !!!",x, altmuldiv, approx, float32, intmuldiv, intmuldiv_no_round)
errcount_intmuldiv = errcount_intmuldiv + 1
}
}
RT_DebugF("Difference count (approx): %d, maxdiff: %d",errcount_approx, maxdiff)
RT_DebugF("Difference count (intmuldiv): %d",errcount_intmuldiv)
RT_DebugF("Difference count (altmuldiv): %d maxdiff %d",errcount_alt,maxdiffalt)
Return MessageClip("Done")
pinterf
11th March 2020, 22:14
I used // operator for integer division
StainlessS
11th March 2020, 22:32
Aint that exactly the same where two integers involved ???
EDIT: All these are int
intmuldiv = (x * targetmax + half_for_rounding) / sourcemax
EDIT: And approx is just bit shifts, no divide, but 233 rather than 234 diffs.
pinterf
11th March 2020, 22:41
In Python 3 the result is floating point
StainlessS
11th March 2020, 22:48
Maybe, and that is why you used integer divide, but not so in Avs,
Aint that exactly the same where two integers involved ???
EDIT: All these are int
intmuldiv = (x * targetmax + half_for_rounding) / sourcemax
EDIT: And approx is just bit shifts, no divide, but 233 rather than 234 diffs.
EDIT: Maybe altmuldiv is no better than intmuldiv, only where numbers involved, multiplier and divider are 2 ^ n - 1,
it should though be generally better [occasionally].
intmuldiv = (x * targetmax + (sourcemax/2)) / sourcemax # intermediate precision loss of least significant bit at stage (sourcemax/2)
altmuldiv = (x * targetmax*2 + sourcemax) / (sourcemax*2)
EDIT: Above is absolute rubbish, altmuldiv always produces same answer as intmuldiv.
Could only possibly work better if sourcemax is odd, and as ((x * targetmax*2) + sourcemax) would be odd, and (sourcemax*2) would be even
so would always lose the same least significant (odd) bit in the final result.
Arh well, it seemed like a good idea at the time.
qyot27
13th March 2020, 12:44
So, a general PSA:
In Windows 10, it is possible to actually set the locale to UTF-8 for the entire OS, the way basically every OS other than Windows handles this issue. Apparently this has been possible for close to two years. Doing so will allow AviSynth+ (and probably even classic 2.6, although I haven't tried) to handle international characters without any special workarounds like utf8=true or juggling MultiByteToWideChar/WideCharToMultiByte in the program loader.
stax76
13th March 2020, 15:31
Can be enabled at:
Time & Language > Language > Administrative Language > Language for non unicode programs > check UTF-8 checkbox > reboot
Works fine so far.
pinterf
13th March 2020, 15:54
Actually I was courious as well and was thinking about a build that would allow omitting 'utf8=true' parameters for Import, SubTitle, Text and AviSource and handle utf8 instead of ANSI.
I suppose classic substring and character position helper functions will not work as they did before for non-ascii-only strings
foobar2000
15th March 2020, 23:44
I have a problem regarding .avsi files, you can delete .avsi files during encoding (like by accident)
but you can't delete .dll during encoding (while in use), I'm using Simple x264 Launcher and I've been encoding something, and I deleted QTGMC.avsi but put it back later
the avs script requires QTGMC.avsi, does this (deleted but put it back) affect the output? it doesn't show errors, do I need to worry? thanks
or the .avsi will store and run in RAM once the task starts?
stax76
16th March 2020, 00:22
does this (deleted but put it back) affect the output? it doesn't show errors, do I need to worry?
It does not affect the output and you don't have to worry.
r0lZ
16th March 2020, 09:45
Can be enabled at:
Time & Language > Language > Administrative Language > Language for non unicode programs > check UTF-8 checkbox > reboot
Works fine so far.
At least one CLI tool crashes with an access violation when that option is enabled: MVCPlanes2OFS.exe (used indirectly by BD3D2MK3D). So, use that beta option with caution !
stax76
16th March 2020, 12:10
It has caused a small issue in the stable release of staxrip which I fixed by removing non ASCII chars from the code and adding an automated test to prevent it from happening again.
Nico8583
16th March 2020, 14:13
It has caused a small issue in the stable release of staxrip which I fixed by removing non ASCII chars from the code and adding an automated test to prevent it from happening again.
Hi, what kind of non ASCII chars have you removed from your app ? Thank you.
stax76
16th March 2020, 15:33
This one was shown in the crop dialog:
±
https://en.wikipedia.org/wiki/Plus%E2%80%93minus_sign
This was in the x265 dialog:
Level 1 + intra/inter modes, ref’s (https://x265.readthedocs.io/en/latest/cli.html#cmdoption-analysis-save-reuse-level)
Changed to ref's
A popular non ASCII char used in apps is this:
©
Using (C) instead.
I know that it's no problem and nothing wrong to use Unicode in apps, Microsoft usually works with Unicode files with BOM but the most popular way nowadays is UTF8 without BOM, I think it's the default everywhere in .NET Core. I usually prefer simple solutions, ASCII and UTF8 without BOM are compatible.
AviSynth headers are part of the staxrip source code so my test applies, it's pure ASCII.
StainlessS
17th March 2020, 00:32
Exist() is now broken in 3.5. [on folders]
z.avs
fn="D:\ME" # Directory this file is in
RT_DebugF("%s %s",Exist(fn),fn) # False
fn="D:\ME\z.avs" # This file
RT_DebugF("%s %s",Exist(fn),fn) # True
MessageClip ("Done")
00000265 0.13369642 [3052] RT_DebugF: False D:\ME
00000266 0.13383374 [3052] RT_DebugF: True D:\ME\z.avs
Note, (below in code block so that backslash dont disappear on-site)
"D:\ME\"
also fails, but then it always did [maybe not necessary to fix, current robust scripts will remove trailing slash before Exist() check on folder name with trailing slash].
Heads up, AvsInit.avsi now fails due to above [MACHINE conditional AutoLoad dll stuff].
EDIT: AviSynthPlus_3.4.0_20191020.exe Works ok, AvisynthPlus-r3.5test_20200207-filesonly.7z dont.
pinterf
17th March 2020, 06:10
Exist() is now broken in 3.5. [on folders]
z.avs
fn="D:\ME" # Directory this file is in
RT_DebugF("%s %s",Exist(fn),fn) # False
fn="D:\ME\z.avs" # This file
RT_DebugF("%s %s",Exist(fn),fn) # True
MessageClip ("Done")
00000265 0.13369642 [3052] RT_DebugF: False D:\ME
00000266 0.13383374 [3052] RT_DebugF: True D:\ME\z.avs
Note, (below in code block so that backslash dont disappear on-site)
"D:\ME\"
also fails, but then it always did [maybe not necessary to fix, current robust scripts will remove trailing slash before Exist() check on folder name with trailing slash].
Heads up, AvsInit.avsi now fails due to above [MACHINE conditional AutoLoad dll stuff].
EDIT: AviSynthPlus_3.4.0_20191020.exe Works ok, AvisynthPlus-r3.5test_20200207-filesonly.7z dont.
Got it. Perfect task for home office.
CrendKing
19th March 2020, 06:39
I'm developing a AviSynth DirectShow filter (similar to what ffdshow does). As you may know, when seeking happens, the whole stream will reset its reference time to 0. This means when the filter recreate the frames, all its frame number starts from 0 again. This completely messes up AviSynth' internal cache, causing it to return those "old" frames (because they have the same old frame numbers).
What I'm asking is that is there an API to invalidate all frame buffers? I read from http://www.avisynth.nl/index.php/Filter_SDK/Cplusplus_API#VideoFrameBuffer:
a VideoFrameBuffer once new'd generally is not released until the IScriptEnvironment is deleted
so I'm currently deleting the clips and IScriptEnvironment and re-instantiating them, which seems unnecessary.
pinterf
19th March 2020, 09:13
They are valid until IScriptEnvironment delete.
pinterf
19th March 2020, 09:15
Exist() is now broken in 3.5. [on folders]
Behaviour on folders is fixed, plus added a new bool utf8 parameter.
pinterf
22nd March 2020, 10:42
Test build, because there were huge internal changes along with some bug fixes.
With cherry-picking from Neo's early multithreading and ScriptClip fixes, old problems got solved.
And there was a week that I spent on Text filter having multiple sized fonts (mainly for helping Linux builds)
https://drive.google.com/open?id=1EI34RDOyjq8ilqGce-AP5FF1uqKzWXyy
- Fix: Multithreading enhancements and fixes (Nekopanda, from Neo fork)
- Fix old ScriptClip (runtime filters) issue
In this example "current_frame" variable was not seen by YDifferenceFromPrevious scripted within SubTitle
resulting in "ERROR: Plane Difference: This filter can only be used within run-time filters" message
Now this script finally works:
SetLogParams("log.txt", LOG_DEBUG)
ColorBars(width=640, height=480, pixel_type="yv12")
ScriptClip(last, "Subtitle(String(YDifferenceFromPrevious))")
Prefetch(4)
- Fix deadlock of ScriptClip on MT
- MT improvement
- Allow multiple Prefetchers
- Add argument to Prefetch to change # of prefetch frames without changing # of threads
Prefetch (clip c, int threads, int "frames")
In the original Plus, you could use only one Prefetch, but you can use any number of CUDA versions.
Also, an argument has been added to specify the number of frames to prefetch.
Prefetch (1,4) # Make 1 thread stand and prefetch 4 frames
By doing so, flexible parallelization configuration is possible, such as pipeline parallelization.
threads
Number of threads. If it is 0, it passes without doing anything.
frames
Number of frames to prefetch.
Again, if it is 0, it passes without doing anything.
- Fix: BuildPixelType: chroma subsampling of sample clip was ignored.
- POSIX: better behaviour under non-Windows because of having multiple sized fixed fonts, not only a single size=20 one.
e.g. MessageClip(), Info(), Version(), ColorYUV "show", internal ApplyMessage
- Text filter:
- font types with
- "Terminus" fixed fonts added (12-14-16-18-20-22-24-28-32, regular + bold)
- "Info_h" good old 10x20 fixed font kept under this name
- much more international unicode characters (1354), use utf8=true under Windows
- use fontname parameter (default "Terminus", other choice is "info_h")
- use font_filename parameter (accepts BDF fonts at the moment - import is probably not too smart but worked for Terminus)
- use size parameter (12 to 32, if no size is available, a smaller one is chosen but at least the smallest one)
- new parameter: bold (default false)
- Info() filter: when parameter "size" < 0, font is automatically enlarged over 640x480
(POSIX limit: minimum size is 12, maximum size is 32 - limited by available fixed fonts)")
- SIL OPEN FONT LICENSE added because of usage of Terminus fonts)
- able to build w/o GDI and font rendering engine under Windows, so that text-overlay filters
work like in POSIX version of AviSynth+ (mainly for my development test)
Use with NO_WIN_GDI define.
- Fix: ReplaceStr when the pattern string to be replaced is empty
- New:
Exist() to have bool utf8 parameter
This is another function to have utf8 option:
Usage: b = Exist("Здравствуй.mkv",utf8=true). Avs file is saved as utf8 w/o BOM
- Fix: broken Exist for directories (regression appeared in 3.5.0)
- Fix: ColorYUV: really disable variable search when parameter "conditional" is false
- Development:
ScriptEnvironment::VSprintf: parameter (void *) is changed back to va_list.
May affect C interface (avs_vsprintf) and CPP interface (ScriptEnvironment::VSprintf)
- Enhanced: Planar RGB to YUV 444 10-14 bits: more precision (32 bit float internally)
- Enhanced: Planar RGB to YUV 444 10-16 bits: AVX2 (speed improvement)
StainlessS
22nd March 2020, 18:16
Exist(), ReplaceStr(), Prefetch/Global stuff probs all gone, cheers P.
You are clearly self isolating, maybe current COVID-19 situation aint all bad :)
[I've just been coughing a little bit(just a couple of coughs), and throat is a bit dry, maybe just hypochondria, I can feel a bit of paranoia coming on]
EDIT: Gonna gobble up a few raw garlic cloves and a lump of ginger, probably of little use.
EDIT:
World Health Organization: Coronavirus disease (COVID-19) advice for the public: Myth busters
Can eating garlic help prevent infection with the new coronavirus?
Garlic is a healthy food that may have some antimicrobial properties.
However, there is no evidence from the current outbreak that eating garlic has protected people from the new coronavirus.
https://www.who.int/emergencies/diseases/novel-coronavirus-2019/advice-for-public/myth-busters
DJATOM
22nd March 2020, 18:27
You are clearly self isolating
Me too. Usually sitting at home, sometimes going to local mart to buy fresh food. No covid19 symptoms spotted so far, but last week I felt like I'd get sick soon, fortunately I'm fine now.
Groucho2004
22nd March 2020, 18:28
I've just been coughing a little bit(just a couple of coughs), and throat is a bit dry, maybe just hypochondria, I can feel a bit of paranoia coming onSame here. :scared:
Gonna gobble up a few raw garlic cloves and a luma of ginger, probably of little use.Some people recommended gargling with bleach. I'm sure it kills the virus but the side effects are apparently severe (death).
StainlessS
22nd March 2020, 19:11
gargling with bleach
Never tried that one yet, although a few years back I had been using [EDIT: a new] washing up liquid to wash my hands under the tap.
I had previously been thinking that it was a real lousy washing up liquid with hardly any lather (bubbles) and not much use
for washing the dishes. Anyways, this particular day I thought "what is that smell?", turns out it was actually household bleach,
was squirting it directly onto my hands, rubbing it in and then under the tap, never noticed any side effects of that.
Having lousy eyes is quite dangerous, is living 'on the edge'.
Same here.
Yep, well I'll write my Obituary and send it to you, if I go first then post it for me please (say that you wrote it), and I'll do the same for you.
EDIT: Oxo cube, 1 clove of garlic and a lump of ginger, finely chopped and into cup of water, nuked in microwave,
Is tolerable, WHO may say it dont work, but like many on-site I'm goin' for the Placebo Effect.
EDIT: New Avs+ files only fix for Exist() on folders, now AvsInit.avsi works fine again.
EDIT: I just got an old 2012 movie on DVD, "Iron Sky", never seen it before, love it and especially the intro music track, "Take me To Heaven" by Laibach, vocal by 'Severa Gjurin',
its near damned hynotic, love it. Maybe you [G2K4] can arrange to have it played when they shove me into the furnace [perhaps you'de even like to do the shoving].
A piece of it on YouTube [~2:30, Still frame music clip, ending chopped short; download of 360p version allowed; ~5.3MB]:- https://www.youtube.com/watch?v=sL2mF5lhwdk
EDIT: There is also a double feature "Iron Sky directors cut" and "Iron Sky 2 - The Coming Race", #2 aint supposed to be as good as #1,
but #1 is 20 mins longer, so I'm gonna get it for that.
pinterf
22nd March 2020, 20:32
Exist(), ReplaceStr(), Prefetch/Global stuff probs all gone, cheers P.
You are clearly self isolating, maybe current COVID-19 situation aint all bad :)
With the home office I'm saving the time of 2*65 minutes public transport or 2*40 min commute on bike.
StainlessS
22nd March 2020, 20:38
And you seem to be spending it all on Avs+ development, much thanks mate :)
Groucho2004
23rd March 2020, 01:30
Having lousy eyes is quite dangerous, is living 'on the edge'.I recently got myself lens implants, it's like having a new set of eyes.
Maybe you [G2K4] can arrange to have it played when they shove me into the furnace [perhaps you'de even like to do the shoving].I'd be honoured to do the shoving.
"Iron Sky 2 - The Coming Race", #2 aint supposed to be as good as #1,
but #1 is 20 mins longer, so I'm gonna get it for that.That's what we need these days - quantity. It applies to all kinds of things, length of movies, toilet paper, ...
real.finder
23rd March 2020, 01:38
Test build, because there were huge internal changes along with some bug fixes.
With cherry-picking from Neo's early multithreading and ScriptClip fixes, old problems got solved.
thank you, mt with runtime seems start working now, but I got this
https://i.imgur.com/qgdmdid.png
ColorBars(width=640, height=480, pixel_type="yv12")
last.ScriptClip("last.dfttest(Sigma=AverageLuma(last)/16)")
Prefetch(4)
and iirc avsneo at least when use with cpu only many runtime filters not working, even StainlessS note this before
StainlessS
23rd March 2020, 09:34
RF, With your script on x64 into VDub2 I get system exception, seems to be stack corruption
Problem signature:
Problem Event Name: APPCRASH
Application Name: VirtualDub64.exe
Application Version: 2.0.0.0
Application Timestamp: 5de45101
Fault Module Name: StackHash_bf55
Fault Module Version: 6.1.7601.24511
Fault Module Timestamp: 5d3fa9bd
Exception Code: c0000374
Exception Offset: 00000000000bf302
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 2057
Additional Information 1: bf55
Additional Information 2: bf55d1c52d0a6d38288ab4c5246e8999
Additional Information 3: c72e
Additional Information 4: c72e187c65f9e7299dbd4cad6f92f629
Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409
If the online privacy statement is not available, please read our privacy statement offline:
C:\Windows\system32\en-US\erofflps.txt
On x86 into VDub2 I get a sort of blank VDub2, nothing in frame, with 2.6GB ram use [just hangs, maybe some kind of recursive stack exhaustion].
PotPlayer just immediately closes without any indication of error.
This is no problem
ColorBars(width=640, height=480, pixel_type="yv12")
SSS="""
Y=AverageLuma
S=String(Y)
Subtitle(S)
Return Last
"""
ScriptClip(SSS)
Prefetch(4)
EDIT: For Avs Neo, functions within Scriptclip (when Scriptclip @ main script level, ie not within script function) had no access to local vars at main level.
This does not seem to be the same problem as with NEO.
EDIT: OK
ColorBars(width=640, height=480, pixel_type="yv12")
SomeString="Local String Var at Main Level: "
SSS="""
Y=AverageLuma # Testing current_frame
S=String(Y)
Subtitle(SomeString+S)
Return Last
"""
ScriptClip(SSS)
Prefetch(4)
EDIT: For rf scipt on x86, I removed AvsRecursion.dll from SysWOW64 and I get multiple "This Application has requested the to runtime to terminate in an unusual way" message.
In VDub2 error alert I get an "Crash details (best guess as to cause) - An Exception occurred in module libfftw3f-3".
EDIT:
https://i.postimg.cc/529NP252/rferr.jpg (https://postimages.org/)temporary upload image (https://postimages.org/)
pinterf
23rd March 2020, 10:00
RF, With your script on x64 into VDub2 I get system exception, seems to be stack corruption
Yep, just debugging the same problem, it's inside dfttest.
I have fixed the problem.
Good news: the script is working fine.
A new version of dfttest will be needed, I'll ask DJATOM if he wishes to maintain it further or I can make the update.
Any more wishes on dfttest?
pinterf
23rd March 2020, 10:05
EDIT: For Avs Neo, functions within Scriptclip (when Scriptclip @ main script level, ie not within script function) had no access to local vars at main level.
This does not seem to be the same problem as with NEO.
Yep, my another test case is srestore, "I don't know what "dm" means" in Neo, it appeared 1.5 years ago, my cherry-pick is some months before that point, thus the problem is not exhibited.
StainlessS
23rd March 2020, 10:13
Well if already figured out is dfttest, and easy fixed then is looking quite promising for MT stuff.
There was no problem with the fft3d libs then ?, all A.O.K. there.
Yep, halt cherry pickin' where NEO prob is first exhibited, good call :)
EDIT: To Below, thanks P.
pinterf
23rd March 2020, 10:17
Well if already figured out is dfttest, and easy fixed then is looking quite promising for MT stuff.
There was no problem with the fft3d libs then ?, all A.O.K. there.
Yep, halt cherry pickin' where NEO prob is first exhibited, good call :)
Parts of FFTW3 are not thread-safe
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.