View Full Version : AviSynth 2.6.0 Alpha4 [Jan 14th, 2013]


IanB
14th January 2013, 09:26
Here is the 4th official release of Avisynth 2.6

Get AviSynth_130114.exe (4.9MiB) (http://sourceforge.net/projects/avisynth2/files/AviSynth_Alpha_Releases/AVS%202.6.0%20Alpha%204%20%5B130114%5D/AviSynth_130114.exe/download) from SourceForge.

========================
Changelist

Additions
* Info: Audio only clip now creates its own canvas video.
* AviSource: Include packed/padded processing and -ve biHeight logic for compressed input.
* Add Script Functions :- Tau, BitLRotate, BitRRotate, BitChange, BitClear, BitSet, BitTest and their asm aliases.
* Add WeaveRows (blit cost) and WeaveColumns (slow) frame combining filters.
* Add AudioDuration() [as float seconds], IsY8(), IsYV411() & PixelType() [as a string] script functions.
* Add Echo and Preroll filters.
* Add IScriptEnvironment::GetAVSLinkage() and DLLExport AVS_linkage for host usage of avisynth.dll.
* DirectShowSource, 2.6 plugin, support pixel types "AYUV" as YV24, "Y41P" and "Y411" as YV411.
* AviSource: Add Full and Auto pseudo pixel_types. Full is all supported. Auto is YV12, YUY2, RGB32, RGB24 & Y8.
* Add "AudioLengthS" [as a string], "Ord" & "FillStr" script functions.
* Add AudioTrim(clip, float, float) audio priority trimming, args in fractional seconds.
* Add Trim(M, Length=N[, Pad=False]) and Trim(M, End=N[, Pad=False]) function overloads for explicit Trimming. Length=0 means zero frame clip. End=0 means end at frame 0.
* Add SeparateRows (zero cost) and SeparateColumns (slow) frame slashing filters.
* Add Script Functions :- Acos, Asin, Atan, Atan2, Cosh, Sinh, Tanh, Fmod, Log10, BitLShift, BitRShiftS, BitRShiftU and Hex.
* Add "ConditionalSelect","csc+[show]b" runtime filter.
* Add dither option to Levels, RGBAdjust & Tweak.
* Add BitAnd(), BitNot(), BitOr() & BitXor() script functions.
* Add StrCmp() & StrCmpI() script functions.
* Add YV24 support for Limiter show option.
* Add "Global OPT_dwChannelMask={int}"
* Add 0x0063F speaker mask for 7.1 WAVE_FORMAT_EXTENSIBLE.
* Add .dll DelayLoad exception texts to crash message formatter.
* ImageWriter, add support for printf formating of filename string, default is ("%06d.%s", n, ext);
* Add avs_get_error(AVS_ScriptEnvironment*); to avisynth_c interface.
* Catch and save AvisynthError text in more avisynth_c entry points, for kemuri-_9.
* Add ScriptName(), ScriptFile(), ScriptDir() functions (WarpEnterprises).
* Add SkewRows filter.
* Histogram, Levels mode, Improve colour of chroma legends.
* ConditionalFilter, teach about string results.
* Add some more "Add/Remove Software" registry keys to the Installer (XhmikosR).
* AviSource: Support both packed and DWORD padded raw planar input like with DSS.
* Add IScriptEnvironment::ApplyMessage()
* Add ImageSourceAnim (Wilbert)
* Support user upgrade to 178 DevIL.dll (They need to manage CRT dependancies).
* ImageSource: palette and compressed bmp images load correctly now (issue 894702) [need 178 DevIL.dll]
* ImageSource: support for other formats like: gif, exr, jp2, psd, hdr [need 178 DevIL.dll]
* Add YV24 mode to ColorBars.
* Add ColorBarsHD based on arib_std_b28.
* C-api usability enhancements from kemuri9 [Work in progress!]
* Add Undefined(), AudioLengthLo(), AudioLengthHi(), IsYV16() & IsYV24() script functions
* Allow newlines (and hence comments) before '{' -- Gavino
* Added IScriptEnvironment::DeleteScriptEnvironment()
* Added Histogram, population clamp % factor for "Levels" mode,
* Histogram, revert "Stereo" mode to YV12, Add "StereoY8" mode,
* AviSource: Support fourcc "GREY" as Y8
* Added support for argument passing and EAX return value to SoftwireHelper.
* Added "Global OPT_VDubPlanarHack=True" to flip YV24 and YV16 chroma planes for old VDub's.
* Added "Global OPT_AVIPadScanlines=True" option for DWORD aligned planar padding
* Added Matrix="AVERAGE" mode.
* Added ContinuedDenominator/ContinuedNumerator(f[]i[limit]i) script functions.
* Tweak: fix MaskPointResizing + put back Dividee ISSE code (use sse=true).
* Added ChromaInPlacement, ChromaOutPlacement and ChromaResample options to planar colour conversions.
* Added MaskHS.
* Source tweaks to get ready for VC8.
* Add Y8 for DevIL, planarize EBMP.
* Planar support for many filters.
* Added Info() time indicator on audio length and video (current frame & total). (2.5.8)
* Added UtoY8 and VtoY8.
* Added more info to Info(). (2.5.8)
* ColorYUV: Added all adjustment parameters as conditional variables "coloryuv_SETTING". Enable by setting conditional=true.
* ConditionalReader: Added support for type String.
* ConditionalReader: Added offset keyword to offset all frame numbers after the keyword.
* Added SincResize() with optional taps parameter (default is 4).
* Added Custom band setting to SuperEQ to allow all 16 bands to be set from script. Usage: SuperEQ(clip,band1, band2, band3....) values are dB in float.
* Added fast 0-1-0 kernel for YV24 to ConvertBacktoYUY2().
* Added core formats: YV24, YV16, Y8, YV411.


Bugfixes
* Fixed HexValue parsing values greater than 7FFFFFFF, now as unsigned hex.
* Fixed ConditionalReader memory overrun parsing bools.
* Fixed ResampleAudio NOP test to compare vi.num_audio_samples, not sample rate.
* Fixed YV24 -> RGB24 overrun cleanup for widths%16 == 5.
* Fixed RGB24 AddBorders with right=0.
* Fixed conditional_functions error message names (Wilbert).
* Fixed Audio cache ac_expected_next regression.
* Fixed ImageSource deal with add 1 to IL_NUM_IMAGES bug (Wilbert)
* Fixed Overlay YV24 V plane conversion.
* Fixed Overlay YV24 mode with shared input clip, needed a MakeWritable.
* Fixed ImageReader upside down TIFF in 178 DevIL. (Wilbert)
* Fixed string+string bug when total length is 4096*K-1.
* Fixed SincResize misuse of "int abs(int)" (Gavino). Fix Lanczos and Blackman sinc use of float == 0.0, use small limit "> 0.000001".
* Fixed Classic mode legend drawing for planar right limit and yuy2 centre line.
* Fixed possible MT race. Use "env->ManageCache(MC_IncVFBRefcount, ...)" in ProtectVFB.
* Fixed SwapYToUV output image size bug for 3 clip case.
* Fixed Crop limit tests for RGB.
* Fixed Overlay yellow tint on rec601 RGB import conversion.
* Fixed YtoUV() output image size bug for 3 clip case.
* Fixed ConvertToPlanar chroma alignment.
* Fixed Levels (RGB) change use of PixelClip(x) to min(max(x, 0), 255).
* Fixed SwapYtoUV yuy2 crash (StainlessS).
* Fixed Overlay saturate UV in add and subtract mode.
* Fixed Info.h range protect display characters (StainlessS).
* Fixed AviSource packed planar import chroma offsets.
* Fixed AviSource NULL GetWritePtr() failure due to premature setting of last_frame.
* Fixed Mask rounding in greyscale calcs (Wilbert), minor refactor.
* Fixed SelectRangeEvery audio snafu (Gavino).
* Fixed LoadPlugin, SaveString of result string.
* Fixed LoadPlugin, use _vsnprintf.
* Fixed LoadVirtualdubPlugin, don't add vdub filter to chain on load failure.
* Fixed rounding in RGB HResize (JoshyD) (affects all resizers)
* Fixed error message name in the filter VerticalReduceBy2
* Fixed SeparateFields() with variable parity input clip (Wilbert)
* Fixed AviSource, cannot cast__int64* to long*, it does not work!
* Fixed ConditionalReader: Don't allow out of range "Range" to overwrite edge values
* Fixed MonoToStereo with stereo sources.
* Fixed MergeChannels with only 1 input clip.
* Fixed AviSource support for negative height DIB format AVI's.
* Fixed Audio cache crashes.
* Fixed resize with YV411, missing code.
* Fixed ConditionalReader rounding with integer interpolation.
* Fixed Softwire SSE2 bugs.
* Fixed SSSE3 CPU detection.
* Fixed SSSE3, SSE4.1 & SSE4.2 detection.
* Fixed Fastwire encoding of instructions that are >2 opcodes (SSSE3+4).
* Fixed _RPT5() macro for debug builds


Optimizations
* ConvertToPlanarGeneric explicit add Cache before chroma rescaler.
* Overlay minor refactor YV12 -> 444 chroma
* Speedup ConvertToMono(), minor refactor MixAudio().
* Change StackVertical/Horizontal to interative instead of recursive, 2^N performace increase for 3 and more clips, i.e. 1 blit total instead of blit(blit(blit(...
* RGBtoY8 Dynamic ASM code, support for RGB24.
* YV24backtoYUY2 Dynamic ASM code.
* UtoY8, VtoY8 abuse subframe, zero cost.
* YV24<->RGB Add SSE2 and SSSE3 code paths, get rid of wide_enough.
* ConvertToYUY2 Add SSE2, MMX restore full speed on platforms with poor ooox.
* ConvertAudio, manage tempbuffer and floatbuffer independantly.
* ConvertAudio, prefer SSE2 over 3DNow for super AMD cores.
* Info.h, full refactor, a good example of "Never look down", thx StainlessS
* DoubleWeaveFrames, If A not writable, try to write to B, else make new frame
* Histogram, fix GetFrame/NewVideoFrame call order
* HResizer, interleave code +4% faster
* YtoUV() Abuse Subframe to snatch the Y plane / UV planes, Derestrict destination colorformat autogeneration.
* ImageSource: Improve thread interlock code
* ConditionalReader/WriteFile: Full refactor.
* Replace _strdup with SaveString in AddFunction (Thanks Gavino)
* SuperEQ: Improve channel unpacking/packing code.
* H-Resize: Use SSE4.1 (movntdqa) loads for use once memory access.
* H-Resize: Added SSE2 horizontal unpacker.
* Resize: Use SSE3 (lddqu) loads for unaligned memory access.
* Added ultra fast vertical PointResizer (64 pixel/cycle).
* Added dynamic SSSE3 vertical resizer (16 pixel/cycle) ~ twice as fast as old MMX.
* Added dynamic SSE2 vertical resizer (16 pixel/cycle).
* Added dynamic MMX vertical resizer (8 pixel/cycle).
* Added SSSE3 version for RGB<->YV24 conversions.
* Added dynamic compiled MMX/iSSE for RGB<->YV24 conversions. Speed is approx 200% of C-code.


Changes
* BlankClip: Supply useful defaults for new Audio/Video when using a Video/Audio only template clip.
* BlankClip: Use duration from Audio only template as default length for new clip.
* Define new IClip::SetCacheHints cachehint constants.
* Force int call arguments to user script function float params to be explicit floats.
* Splice pass CacheHints through to both children in + and ++ mode.
* WriteFileStart/End save current_frame and set Last.
* ConditionalReader do not ignore syntax errors in input file.
* ImageSourceAnim Pad/Crop images to match first frame (Wilbert)
* ImageSource Add version to messages (Wilbert)
* Initial 2.6 API entry point linkage.
* Use Invoke for graph tail, enhance non-clip output error reporting.
* PopContext when inner block Asserts/throws (maxxon).
* Remove duplicate definitions (Wilbert).
* Enhance non-clip output error reporting.
* Explicitly specify calling sequence as __cdecl for Avisynth softwire routines, (was the compiler default)
* Use env->Invoke("Cache", ...) everywhere instead of Cache::Create_Cache(), allows for Cache to be overloaded by a plugin.
* ConvertToYUY2 Change from 0-1-1 kernel to 1-2-1 kernel.
* Tweak make Interp same units as minSat and maxSat.
* Check HKEY_CURRENT_USER for PluginDir first. (henktiggelaar)
* Make forced, -ve, planar alignment of chroma planes match subsampling.
* Enforce planar alignment restrictions.
* C-api: Remove func sub-struct from AVS_Library struct
* Add error code to plugin load failure message
* Make default planar AVI output packed. Control with OPT_AVIPadScanlines=True.
* WriteFile() now supports unlimited number of unlimited strings. (was 16 by 254 byte strings).
* ConvertToRGB*, make C++ code sample chroma the same as the MMX code i.e. use both pixels.
* ConvertToRGB*, use YV24 path for planar, complain when options are present for YUY2.
* ConvertToYUY2, use YV16 path for planar, complain when options are present for RGB see: http://forum.doom9.org/showthread.php?p=1378381#post1378381
* Thread safe code, part 2.
* Correct IClip baked documentation
* Passify compilation error/warnings (XhmikosR)
* for, const, extern and ansi patches for VC2008 (SEt)
* Disable OPT_RELS_LOGGING option
* Change implicit Last parsing for argless, bracketless calls to match bracketed cases. (Gavino)
* DirectShowSource: Support last minute format renegotiation thru IPin::QueryAccept() & Validate the size of the provided directshow buffer.
* Remove non ascii chars from comments.
* Add core stubs for DirectShowSource, TCPServer & TCPSource, report when plugins are missing.
* Add note for original source downloads - SoundTouch
* Add more lineage history to Info()
* Move convertaudio, alignplanar, fillborder & MIN/MAX_INT definitions.
* Run AtExit before dismantling world.
* Change setcachehints definition from void to int. Test IClip version >= 5.
* Move PixelClip definition to avisynth.cpp
* SubTitle, etc, make X & Y options float (0.125 pixel granularity).
* ShowSMPTE() supports all integer FPS and multiplies of drop frame FPS.
* SubTitle, stop overwriting string constants (Gavino).
* SubTitle, improve pixel registration (Gavino).
* Make Info() CPU display hierarchical.
* Thread safe code, part 1.
* SoftwireHelper: explicit hardware exception handling.
* Resize: Moved GetResampleFunction into Resamplefuntion, to allow overrides.
* Resampler: Removed dead stlf code.
* Updated Soundtouch to 1.31 (2.5.8)
* Put dynamic matrix conversion into separate file.
* Moved chroma subsampling to image_type section.
* Added specific error reporting when requesting chromasubsampling with Y8.
* Split up merge and plane Swappers.
* Split up Plane transfers into separate classes.
* Added automatic destination colorspace detection on planar YtoUV.
* Took out greyscale and RGB32<->RGB24 from convert.cpp and placed them in separate files.
* All code assuming UVwidth = Ywidth/2 and similar should be gone.

Chikuzen
14th January 2013, 10:03
What is lacking in order for alpha to grow up to be beta?

ARDA
14th January 2013, 17:57
Dear IanB;
Many years without posting, but I've been following all
avisynth news, and congratulations for the great progress you have done.

I was still using v 2.58 and today I installed this new alpha
Everything was working ok, till I accidentally introduced in my script(copy&paste)
a ConvertToYV16(),using an 2.58 plugin to my suprise it was not stopped by
(except Y8 that was stopped,checked afterwards)

if (!vi.IsYV12())
env->ThrowError("only planar (YV12) input");
1) Is it suppossed to be that way ?

When working in place, with src writable, and returning source, it worked
correctly with YV16 and YV24(just checked those two).
2) Is that expected to be that way as well ?

When creating a new frame with
PVideoFrame dst = env->NewVideoFrame(vi,32);
env->MakeWritable(&dst);
and return dst, if I am not wrong , heights and rows obtained
with for instance int height = src->GetHeight(PLANAR_Y);
or int dstheight = dst->GetHeight(PLANAR_Y);
are half the value they should be.
3) Is that correct ?, or I am missing something ?

4) every plugin should be compiled again with new api ?

5) if so, is there anywhere a simple sample, as it used to be
with invert to see how to use new api ?

My apologies if this has been answered before, but I couldn't find.

Thanks for all the effort done during all these years.
Arda

StainlessS
14th January 2013, 21:05
Mr B, :thanks: much appreciated.


5) if so, is there anywhere a simple sample, as it used to be
with invert to see how to use new api ?

this is the nearest that I'm aware of:
http://forum.doom9.org/showthread.php?p=1580772#post1580772

IanB
14th January 2013, 23:17
I was still using v 2.58 and today I installed this new alpha
Everything was working ok, till I accidentally introduced in my script(copy&paste)
a ConvertToYV16(),using an 2.58 plugin to my surprise it was not stopped by
(except Y8 that was stopped,checked afterwards)

if (!vi.IsYV12())
env->ThrowError("only planar (YV12) input");
1) Is it supposed to be that way ?
Yes, all the planar formats are designed to look like YV12 to the 2.5 baked code. If we look at the 2.5 baked code, it masks most of the pixel type bits and compares what is left :-bool IsYV12() const { return ((pixel_type & CS_YV12) == CS_YV12)||((pixel_type & CS_I420) == CS_I420); }As Y8 is not a 3 plane format it does not have a CS_VPlaneFirst or CS_UPlaneFirst bit so the match fails.

There was much discussion originally about new planar formats and letting the 2.5 plugins YV12 code run. It was agreed that it was more useful to allow it. So as usual the user is in charge and must be aware.
When working in place, with src writeable, and returning source, it worked
correctly with YV16 and YV24(just checked those two).
2) Is that expected to be that way as well ?
Yes, the beginning of the VideoFrame structure is still the same, so the 2.5 baked code correctly loads the offsetU and offsetV members. However the 2.5 code does not know about the new row_sizeUV or heightUV members so will assume the chroma planes are the shape for YV12, so only half a YV16 or quarter of a YV24 may be processed. For code that only processes the luma plane there is no problem. So as usual the user is in charge.class VideoFrame {
volatile long refcount;
VideoFrameBuffer* const vfb;
const int offset, pitch, row_size, height, offsetU, offsetV, pitchUV
const int row_sizeUV, heightUV;
...
When creating a new frame with
PVideoFrame dst = env->NewVideoFrame(vi,32);
env->MakeWritable(&dst);
and return dst, if I am not wrong , heights and rows obtained
with for instance int height = src->GetHeight(PLANAR_Y);
or int dstheight = dst->GetHeight(PLANAR_Y);
are half the value they should be.
3) Is that correct ?, or I am missing something ?
No, the 2.5 baked code for PLANAR_Y the VideoFrame height member is correctly returned. For PLANAR_U and PLANAR_V height/2 is returned, which will be correct for YV12 but wrong otherwise.int GetHeight(int plane) const {
switch (plane) {
case PLANAR_U:
case PLANAR_V:
if (pitchUV)
return height>>1;
return 0;}
return height;
}As the code for env->NewVideoFrame(vi,32); was always within Avisynth.dll the structure returned to the 2.5 plugin is correct for the rest of the 2.6 world.
4) every plugin should be compiled again with new api ?
If they are complete with the 2.5 feature set then no. If they need something from the 2.6 feature set then yes. A correctly written planar format plugin that correctly uses GetPitch(plane), GetRowSize(plane), GetHeight(plane), etc should work correctly with all planar formats when recompiled, otherwise it may only work with YV12. Of course luma only code will work in both cases.
5) if so, is there anywhere a simple sample, as it used to be
with invert to see how to use new api ?
The thread StainlessS pointed to is the active discussion on the subject, but yes if someone would update the API doco and examples it would be appreciated by all.

ARDA
15th January 2013, 00:20
Thanks once more IanB;

No, the 2.5 baked code for PLANAR_Y the VideoFrame height member is correctly returned.
For PLANAR_U and PLANAR_V height/2 is returned, which will be correct for YV12 but wrong otherwise.

... otherwise it may only work with YV12. Of course luma only code will work in both cases.

I think I have understood; so those plugins that work in YV12 space and create a new frame
only will be able to work in new planar formats(except for lumas) if they are recompiled with new api.
As for example the one I was using Removegrain(mode=1) or Undot(); those that work in place
will continue working correctly recompiled or not.

I will follow the thread StainlessS (thanks) pointed and see what I can do.

Thanks for taking the time to answer. Arda

cyberbeing
15th January 2013, 00:26
DirectShowSource, 2.6 plugin, support pixel types "AYUV" as YV24

This behavior seems very broken. When a decoder outputs AYUV mediatype (packed 4:4:4 YUV + alpha) to DirectShowSource, Avisynth outputs pink video to madVR with a "YV24" (planar 4:4:4 YUV) mediatype. Why isn't the "YV24" pixel type being used here for DirectShowSource input, if Avisynth doesn't support the AYUV format internally?

IanB
15th January 2013, 01:57
@cyberbeing,

As far as I know Direct Show MEDIASUBTYPE_YV24 (http://www.google.com.au/search?q=MEDIASUBTYPE_YV24) does not exist except for lavfilters LAVPixFmtConverter.cpp.

Direct Show MEDIASUBTYPE_AYUV seems to be the only compatible 8 bit YUV 4:4:4 format commonly available. Avisynth's DirectShowSource unpacks the data into the Avisynth internal YV24 planar format, discarding the alpha channel, using this code written by Sh0dan many years ago:-for(int x=0; x<rowsize; x++) {
dstY[x] = srcP[(x*4)+1];
dstU[x] = srcP[(x*4)+2];
dstV[x] = srcP[(x*4)+3];
}I don't have any AYUV samples, so I have never tested this code path.

Pink YUV output usually means the U and/or V data values are 255. (similarly green is for U,V=0).

Conflicting information about byte order :-
1. http://www.fourcc.org/yuv.php
AYUV

This is a 4:4:4 YUV format with 8 bit samples for each component along with an 8 bit alpha blend value per pixel. Component ordering is A Y U V (as the name suggests).

2. http://msdn.microsoft.com/en-us/library/windows/desktop/dd206750%28v=vs.85%29.aspx
4:4:4 Formats, 32 Bits per Pixel
AYUV

A single 4:4:4 format is recommended, with the FOURCC code AYUV. This is a packed format, where each pixel is encoded as four consecutive bytes, arranged in the sequence shown in the following illustration.

Figure 2. AYUV memory layout
http://i.msdn.microsoft.com/dynimg/IC162364.gif
The bytes marked A contain values for alpha.


Looks like number 2 might be the answer.

Try this script to see if you get some half arse picture back :-DirectShowSource(...blah..., pixel_type="AYUV")
A=VtoY8()
Y=UtoY8()
U=ConvertToY8()
UVtoY(U, U, Y) # Use U as dummy V which is lost

cyberbeing
15th January 2013, 04:23
As far as I know Direct Show MEDIASUBTYPE_YV24 does not exist except for lavfilters LAVPixFmtConverter.cpp.
Considering LAV Video can output YV24, and madVR can accept YV24 (including Avisynth output), does it ultimately matter that it's not a Microsoft approved MEDIASUBTYPE?
I still believe that DirectShowSource accepting and preferring YV24 over AYUV would be a good idea, even if initial support is limited.

Try this script to see if you get some half arse picture back
UVtoY doesn't exist as a function. Did you mean YtoUV?

Using YtoUV(U, U, Y) with your sample script produces a green & purple image.

IanB
15th January 2013, 08:01
Yes YtoUV() is it, dyslexia to the rescue. :o

And green/purple is the 45/225 degrees hues one would expect for the U=V case. I will check in a fix for the AYUV unpacker byte order.


It seems lavfilter are declaring their own guid's and these appear to be the values they are using :-const GUID MEDIASUBTYPE_YV24 = {'42VY', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};
const GUID MEDIASUBTYPE_YV16 = {'61VY', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};
I'll add them to the DirectShowSource wish list when someone confirms I have the correct guid's.

Blue_MiSfit
15th January 2013, 10:30
Thank you, IanB!

Mystery Keeper
17th January 2013, 19:25
I'm getting "there is no function named..." error for all 2.58 plugins I've got. Examples work fine.

SOLVED: Had to modify registry key at HKEY_CURRENT_USER\Software\AviSynth.

vcmohan
18th January 2013, 08:08
What is lacking in order for alpha to grow up to be beta?

Chikuzen's question was unanswered. If I download the alpha exe file and run it will it overwrite on the existing avisynth dll? If so what all files I need to save prior to experimenting with 2.6 alpha4 ?

THEAST
18th January 2013, 10:14
Wow, just wow! When I saw this new version on VideoHelp, I couldn't believe my eyes, it has been so long! Really thanks for resuming to update Avisynth, IanB! :worship:

IanB
18th January 2013, 13:25
What is lacking in order for alpha to grow up to be beta?Time and testing.

If I download the alpha exe file and run it will it overwrite on the existing avisynth dll? If so what all files I need to save prior to experimenting with 2.6 alpha4 ?The standard Avisynth*.exe installers are designed to install their current Avisynth.dll and associated files over the top of any existing standard Avisynth version. To flip back just reinstall the previous version.

For the inveterate fiddlers I guess you need to save Avisynth.dll and DirectShowSource.dll (it is now a full bird 2.6 plugin), possible the docs as well.

vcmohan
18th January 2013, 13:44
Thanks. When I try compiling using the new avisynth.h I get errors wherever it has lines as #include &lt;windef.h&gt; and for all such calls
D:\---avisynth_2_6.h(54) : error C2006: #include expected a filename, found '&'
I am on windows XP 32 bit using MS VC 6

Groucho2004
18th January 2013, 13:55
Thanks. When I try compiling using the new avisynth.h I get errors wherever it has lines as #include &lt;windef.h&gt; and for all such calls
D:\---avisynth_2_6.h(54) : error C2006: #include expected a filename, found '&'
I am on windows XP 32 bit using MS VC 6

The HTML Troll invaded your file and substituted HTML entities when you weren't looking. :D

You were probably browsing the SVN/CVS tree and screwed up when saving the file or something to that effect.

vcmohan
19th January 2013, 04:25
Thanks. Silly of me

vcmohan
19th January 2013, 11:55
I am still getting compilation errors
In the avisynth.h for 2.6 which I googled for and got an official version and it does not have VSLinkage
in "IScriptEnvironment::GetAVSLinkage() and DLLExport AVS_linkage for host usage of avisynth.dll." which was mentioned at the begining of the thread. Where do I get the latest vfersion of Avisynth.h ?

StainlessS
19th January 2013, 12:54
vcmohan
http://forum.doom9.org/showthread.php?p=1385169#post1385169

EDIT: perhaps try this:
http://www.tortoisecvs.org/

using:

cvs -d :pserver:anonymous@avisynth2.cvs.sourceforge.net:/cvsroot/avisynth2 checkout -P avisynth

ARDA
19th January 2013, 13:58
avisynth.h(Revision 1.39) that is
in core directory in avisynth sources, Wed Oct 10 06:15:00 2012 UTC.
http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/core/avisynth.h?view=log

vcmohan
20th January 2013, 04:41
Thanks

GrofLuigi
23rd January 2013, 16:28
Thank you very much for the new version!

About DevIL.dll: How do we get the new goodies with version 178 while "managing CRT dependencies"?

GL

Groucho2004
23rd January 2013, 16:51
About DevIL.dll: How do we get the new goodies with version 178 while "managing CRT dependencies"?

GL
http://openil.sourceforge.net/download.php
Grab the non-Unicode version.

Wilbert
23rd January 2013, 19:53
@GrofLuigi,

See the two lines above the examples section: http://avisynth.org/mediawiki/ImageReader

vcmohan
24th January 2013, 13:16
Are there functions like vi.IsPRGB(), vi.IsPRGB24(), vi.IsPRGB32() for planar rgb formats?
In case of Planar RGB what are the values one can get for PLANAR_A, PLANAR_R, PLANAR_G and PLANAR_B?
Will it be possible to get the ReadPtr or WritePtr for non planar RGB formats as pointer value + 0, 1, 2, and 3 for r,g,b and A? In such a case possibly code for plugins for RGB and all Planar formats can be( where geometry does not matter) simpler?
Is it possible to get number of planes so that Y8 or such can be also be handled with ease?

Wilbert
24th January 2013, 22:47
Are there functions like vi.IsPRGB(), vi.IsPRGB24(), vi.IsPRGB32() for planar rgb formats?
In case of Planar RGB what are the values one can get for PLANAR_A, PLANAR_R, PLANAR_G and PLANAR_B?
These are commented out and thus not available yet ...

IanB
25th January 2013, 05:58
@cyberbeing,

Try this replacement DirectShowSource_2601.zip (http://sourceforge.net/projects/avisynth2/files/AviSynth_Alpha_Releases/AVS%202.6.0%20Alpha%204%20%5B130114%5D/DirectShowSource_2601.zip/download).

Please confirm all AYUV, YV24 and YV16 now work as expected.

mandarinka
31st January 2013, 04:33
I'll just spam a bit with a sort of useless feedback :)
I installed Alpha4 (32bit) on Win8 64 instead of the previously used 2.5.8. Everything seems to work fine when processing/encoding, using my usual scripts and filterchains. Also including Yatta. Yay!

Farfie
3rd February 2013, 08:33
Hello. I believe I have found a bug regarding the newest Avisynth with open-gop. I've tried opening many different files in megui and virtual dub, regardless of encoder used, 10bit or 8bit, or any other setting I can find. Files with open-gop make things hang, error, or just crash.
One thing I noticed is that with a shorter duration clip (with open-gop), it might work at first, or for awhile, but eventually hang/error. Perhaps longer duration = more recovery points = more problems?

On a brighter note, this version seems to have fixed this problem with NLMeansCL that I could not find another soul to reproduce for me. Though, I'll need to test more to be 100% sure.
Regardless, thanks for the new version!

StainlessS
3rd February 2013, 09:34
@Farfie,

You might like to say which source filter you are talking about, perhaps DirectShowSource?

Farfie
3rd February 2013, 10:43
Ah, my bad. It occurs with FFVideoSource.

IanB
3rd February 2013, 21:53
FFVideoSource is not part of the core, it is an independent plugin. Report problems in the FFmpegSource (http://forum.doom9.org/showthread.php?t=127037&page=42) thread. You will need to report the version and the build information for that version (who built it).

cyberbeing
4th February 2013, 00:19
@cyberbeing,

Try this replacement DirectShowSource_2601.zip (http://sourceforge.net/projects/avisynth2/files/AviSynth_Alpha_Releases/AVS%202.6.0%20Alpha%204%20%5B130114%5D/DirectShowSource_2601.zip/download).

Please confirm all AYUV, YV24 and YV16 now work as expected.
When using pixel_type="AYUV" I'm seeing "DirectShowSource: RenderFile, the filter graph manager won't talk to me" error under the following circumstances:

Win7DSFilterTweaker
Preferred Decoders = Use Merit
+
Haali Splitter
Auto-load VSFilter = Yes
+
LAV Video
All color formats checked
+
xy-VSFilter
default settings
+
madVR
+
Open a 10bit H.264 MKV with subtitles


Various changes which make it work without error for reasons unknown:

Uncheck P010 in LAV Video
or
Uncheck P016 in LAV Video
or
Uncheck RGB24 & RGB32 in LAV Video
or
Uncheck NV12 in LAV Video
or
Uncheck all RGB formats in xy-VSFilter
or
Uncheck "Follow Preferred Order of Upstream Filter" in xy-VSFilter

IanB
4th February 2013, 02:51
@cyberbeing,Please confirm all AYUV, YV24 and YV16 now work as expected.You had a specific example where the AYUV byte ordering was wrong, is this now correct?

You asked for YV16 and YV24 support, as this was fairly trivial, I have provided it. Is the byte order correct for these? Are the GUID's I used acceptable?
"DirectShowSource: RenderFile, the filter graph manager won't talk to me" errorIs the error displayed when the DirectShowSource pseudo renderer input pin remains unconnected after IGraphBuilder::RenderFile call has completed.

If you specify pixel_type="AYUV" then only connect attempts with MEDIATYPE_Video, MEDIASUBTYPE_AYUV will be accepted. I guess any of the changes you note cause MEDIASUBTYPE_AYUV to be one of the video subtype to be attempted.

madVR is a renderer and should not effect DirectShowSource graphs (it provides it's own renderer to snaffle the video frames).

cyberbeing
4th February 2013, 09:30
@cyberbeing,You had a specific example where the AYUV byte ordering was wrong, is this now correct?
Yes.

You asked for YV16 and YV24 support, as this was fairly trivial, I have provided it. Is the byte order correct for these? Are the GUID's I used acceptable?
YV24 seems to be correct, but you would need confirm the YV16 mediatype with madshi, since I have no way to test it myself.


Is the error displayed when the DirectShowSource pseudo renderer input pin remains unconnected after IGraphBuilder::RenderFile call has completed.
How would I test this?


If you specify pixel_type="AYUV" then only connect attempts with MEDIATYPE_Video, MEDIASUBTYPE_AYUV will be accepted. I guess any of the changes you note cause MEDIASUBTYPE_AYUV to be one of the video subtype to be attempted.
When pixel_type is specified, does DirectShowSource behave any differently when a filter attempts to connect with an unsupported mediatype, compared to attempts to connect with a supported mediatype which isn't the pixel_type specified? xy-VSFilter always connects twice. Once to determine the mediatypes supported by the video decoder & render, and then reconnects using the preferred mediatype of the decoder which is supported by the renderer.

A) The renderer pin which xy-VSFilter connects to via DirectShowSource is listing mediatypes other than the pixel_type specified
OR
B) The DirectShowSource renderer is rejecting xy-VSFilter's second connection, when the first connection is a mediatype unsupported by Avisynth.
OR
C) Some sort of bug in LAV Filters or xy-VSFilter mediatype negotiations.

Not overly important, but if you don't see anything wrong about DirectShowSource behavior in this case, I'll have the xy-VSFilter dev look into it at some point.

Mystery Keeper
4th February 2013, 12:40
YV24 does not seem correct. I get some frames alright and others with 3/4 of chroma broken.

cyberbeing
4th February 2013, 13:38
Is there a particular method needed to reproduce that?

Using LAV Video 0.55.2 I haven't noticed any issues with DirectShowSource 2.6.0.1 YV24 input, with output to madVR 0.85.8 or AvsPMod 2.4.1

Mystery Keeper
4th February 2013, 16:56
Not really. Just use some filters on it. Got that glitch with both my TempLinearApproximate and dfttest.

cyberbeing
4th February 2013, 20:50
Ah, I was testing it without filters with DirectShowSource only in the script.

ARDA
4th February 2013, 23:23
@Mistery Keeper

You have almost all your answers in this same thread

http://forum.doom9.org/showthread.php?p=1610888#post1610888


I think you're using the wrong avisynth.h to compile for new planar colorspaces
look this post

http://forum.doom9.org/showthread.php?p=1611790#post1611790


and as an example how to link your plugin with the new api
look at end of page of directshowsource.cpp

http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/plugins/DirectShowSource/
directshow_source.cpp?revision=1.38&view=markup

IanB
4th February 2013, 23:49
@Mystery Keeper, To 2.5 plugins all planar formats look like YV12. If you use 2.6 colour spaces with 2.5 filters you have to manage the conflict. TempLinearApproximate and dfttest are both 2.5 filters.


@cyberbeing,You asked for YV16 and YV24 support, as this was fairly trivial, I have provided it. Is the byte order correct for these? Are the GUID's I used acceptable?YV24 seems to be correct, but you would need confirm the YV16 mediatype with madshi, since I have no way to test it myself.One would assume you specify pixel_type="YV16" and see if LAV Video can output YV16 as it appears to do for YV24, and/or leave YV16 as the only checked LAV Video format.
Is the error displayed when the DirectShowSource pseudo renderer input pin remains unconnected after IGraphBuilder::RenderFile call has completed.How would I test this?In GraphEdit or GraphStudio, drop a renderer onto the canvas, the Null Renderer is okay but another may be more suitable. Then choose File>Render Media File with your file as the source. See what gets connected. Interrogate the input pin to the original renderer. Delete the connection to the Renderer input pin, interrogate the now disconnected upstream output pin to see what formats it offers. It needs to match a type DirectShowSource can process.

Also take a DirectShowSource log file, with LogMask=1+16+32, Format Negotiation+Requests to Directshow+Errors, to see what happened during the IPin negotiation.
If you specify pixel_type="AYUV" then only connect attempts with MEDIATYPE_Video, MEDIASUBTYPE_AYUV will be accepted. I guess any of the changes you note cause MEDIASUBTYPE_AYUV to be one of the video subtype to be attempted.
When pixel_type is specified, does DirectShowSource behave any differently when a filter attempts to connect with an unsupported mediatype, compared to attempts to connect with a supported mediatype which isn't the pixel_type specified?
Specifying the pixel_type argument to DirectShowSource() enables the DirectShow interface, IPin::EnumMediaTypes, processing. By default DirectShowSource() returns E_NOTIMPL for this method. Also the IPin::Connect will only accept the specified media type. The special pseudo types YUV, RGB, AUTO and FULL both enumerate multiple types and accept any of those types. See this thread :- Problems with DirectShowSource (http://forum.doom9.org/showthread.php?t=143321)

Mystery Keeper
5th February 2013, 00:07
Will 2.6 plugin work with AviSynth 2.5, or should I make different versions?

cyberbeing
5th February 2013, 03:57
@cyberbeing,One would assume you specify pixel_type="YV16" and see if LAV Video can output YV16 as it appears to do for YV24, and/or leave YV16 as the only checked LAV Video format.
I see why I couldn't get it to work.

In order for LAV Video to use YV16 with DirectShowSource, you need to set all output formats in the following registry key to 0 except YV16 which needs to be set to 1:
HKEY_CURRENT_USER\Software\LAV\Video\Output

LAV Video -> DirectShowSource -> madVR seems to display YV16 normally.

It seems impossible to make LAV Video connect directly to madVR with YV16 during normal DirectShow playback outside of Avisynth.

Also take a DirectShowSource log file, with LogMask=1+16+32, Format Negotiation+Requests to Directshow+Errors, to see what happened during the IPin negotiation.
Here are some logs of the LAV Video + xy-VSFilter + 10-bit 4:2:0 Video + pixel_type="AYUV" mediatype negotiation problem:

http://www.mediafire.com/?s38n5b4asbobcsi

Mystery Keeper
5th February 2013, 10:21
Fixed my plugin. Both YV16 and YV24 seem fine.

IanB
6th February 2013, 00:02
In order for LAV Video to use YV16 with DirectShowSource, you need to set all output formats in the following registry key to 0 except YV16 which needs to be set to 1:
HKEY_CURRENT_USER\Software\LAV\Video\Output

LAV Video -> DirectShowSource -> madVR seems to display YV16 normally.Interesting that madVR accepts YV16.
It seems impossible to make LAV Video connect directly to madVR with YV16 during normal DirectShow playback outside of Avisynth.Not that surprising, seeing YV16 is not a known Direct Show media subtype. You could possible force it in GraphStudio, but I would not expect the default graph builder to have a bar of this.
Here are some logs of the LAV Video + xy-VSFilter + 10-bit 4:2:0 Video + pixel_type="AYUV" mediatype negotiation problem:GraphStudio_(Can't_Render_Media_File)_LAV_AYUV_Only_Enabled.log
AVC1, AYUV Okay!

GraphStudio_(Can't_Render_Media_File)_LAV_P016_Disabled.log
AVC1, P010, NV12, YV12, YUY2, RGB32, RGB32, RGB24, RGB24, RGB565, ARGB32, RGB565, ARGB32, AYUV Okay!

GraphStudio_(Color_Space_Converter_Disabled_Can't_Render_Media_File)_LAV_All_Formats_Error.log
GraphStudio_(Connects_Color_Space_Converter)_LAV_All_Formats_Error_RGB32_Output.log
MPC-HC_madVR_LAV_All_Formats_Error_RGB32_Output.log
AVC1, P010, P016, NV12, YV12, YUY2, RGB32, RGB32, RGB24, RGB565, RGB24, ARGB32, RGB565, ARGB32, IYUV, I420, RGB565, MEDIATYPE_Audio, .... Fail!

MPC-HC_madVR_LAV_AYUV_Only_Enabled_AYUV_Output.log
AVC1, AYUV Okay!

MPC-HC_madVR_LAV_P016_Disabled_AYUV_Output.log
AVC1, P010, NV12, YV12, YUY2, RGB32, RGB32, RGB24, RGB24, RGB565, ARGB32, RGB565, ARG32, AYUV Okay!

Looks like the graph builder has a limit of 16 attempts.

I would guess the format negotiation is going somewhat like this ...AVC1 -- try raw x264 video stream

Add an AVC1 decoder
P010, P016, NV12, YV12, YUY2, RGB32 -- X264 codec bids these formats

Add a P010 format converter
RGB32, RGB24, RGB565 -- Try these

Add a P016 format converter
RGB24, ARGB32, RGB565 -- Try these

Add a NV12 format converter
ARGB32 -- Try this

Add a YV12 format converter
IYUV, I420 -- Try these

Add a YUY2 format converter
RGB565 -- Try these, oops that 16When you disable P016 you also avoid the P016 format convert attempts, freeing up more slots for other format converters.

Given your AVC1 decode bids P010 before P016 and they are the same data layout except for the bottom 6 bits being masked and the input data is only 10 bits anyway. I would leave P016 turned off until you have a real need. As P010 is bid first you probably need to turn off P010 to force P016 to get priority.

mirkosp
11th February 2013, 09:14
I'm not sure if this is the intended behaviour, but I think "multiply" mode has a small bug, since to my understanding it is supposed to be the perfect opposite of the "subtract" mode in behaviour (no change with white, maximum change with black).
Basically, from what I understand, a pure white clip (255, working with pc_range=true for this specific need) is supposed to keep the clip pixel identical, however, checking with subtract(c,last) (in which last is the overlay result, c is the source), I noticed that it actually... I think darkens by 1, as checking the YPlaneMin and YPlaneMax gives 127 for both instead of 126. If I do mt_invert on the overlay clip (and thus getting a 0 pure black clip instead of the 255 pure white) and use the mode "subtract", I do get the intended result, and the same subtract gives 126 on both min and max value.

IanB
12th February 2013, 00:12
@mirkosp,

I assume you are talking about the multiply mode of Overlay().

With no mask clip and default Opacity the code implements this for the Luma channel, a scaled multiply :-baseY[x] = (baseY[x] * ovY[x]) >> 8;
For a Base pixel=255 and an Overlay pixel=255 you get 255*255=65025, and 65025>>8=254.004, so yes you get a unit reduction in value.

For the Chroma channels :-baseU[x] = (baseU[x] * ovY[x] + 128 * (256-ovY[x]) ) >> 8;

Which is more clearly expressed as

baseU[x] = ((baseU[x] - 128) * ovY[x] + 128 * 256) / 256

For Subtract mode the code implements this, a simple subtraction :-Y = baseY[x] - ovY[x];
U = baseU[x] - ovU[x] + 128;

mirkosp
13th February 2013, 13:35
Yes, that's what I was referring to. Of course I'm aware that subtract and multiply aren't exactly the opposite, I just meant that with a value of 0 and 255 the opposite situation should arise, as in subtract keeps the same pixel with a 0 overlay and gives black for sure with a 255 overlay, whereas multiply gives black with a 0 overlay and is supposed to keep the input value with 255.
That said, I assume the current approach is for speed purposes... in the meantime I just decided to manually do a multiply with masktools since the very slight speed drop isn't so much of a concern to me as accuracy is, though I'm not sure if at this point the behaviour of overlay's multiply should stay unchanged or not.

IanB
24th February 2013, 23:55
Notes about AVISYNTH_INTERFACE_VERSION usage.

Some early adopter 2.6 filter authors seem a little confused. The AVISYNTH_INTERFACE_VERSION is about describing the level of features available, both in the core avisynth.dll and the third party plugin.

For a plugin author it describes what the core IScriptEnvironment vtable contains.

Version 1 is Avisynth 2.0

Version 2 is Avisynth 2.5, with the vtable having members up to IScriptEnvironment::SetWorkingDir(const char * newdir)

Version 3 introduced with Avisynth 2.5.6, with the IScriptEnvironment vtable adding 3 new members ManageCache, PlanarChromaAlignment and SubframePlanar.

Version 4 is reserved and does not apply to any Avisynth version. It's only significance is it greater then 3 and less then 5.

Version 5 introduced with Avisynth 2.6.0, with the IScriptEnvironment vtable adding 3 more new members DeleteScriptEnvironment, ApplyMessage and GetAVSLinkage. Also with version 5 the core provides AVS_Linkage support for baked code replacement.


And through the IClip interface it is the authors responsibility to declare the level of support the plugin provides.virtual int __stdcall IClip()::GetVersion() { return AVISYNTH_INTERFACE_VERSION; }Version 1 is Avisynth 2.0

Version 2 and 3 are Avisynth 2.5, supporting YV12, YUY2, RGB32 and RGB24 colour spaces.

Version 4 is reserved and does not apply to any Avisynth version. It's significance is it greater then 3 and less then 5.

Version 5 is Avisynth 2.6, and the IClip interface must support this updatevirtual int __stdcall IClip::SetCacheHints(int cachehints,int frame_range);Plugins that do not implement the interface must always return zero.

The plugin should also gracefully handle the new colour spaces, YV24, YV16, YV411 and Y8.

Stephen R. Savage
28th February 2013, 09:08
I am encountering an access violation with this script:


ImageSource("what.png")
ConvertToYV24()
Tweak(sat=1.25)
Tweak(sat=0.8)
ConvertToRGB()


The error reads: "Avisynth read error: Software caught an access violation at 0x00000320(code+4249890016), attemping to write to 0x00000320". The image dimensions are 785x900.

paradoxical
28th February 2013, 17:44
*ignore me*

Chikuzen
28th February 2013, 18:24
It may or may not be the issue but YV24 requires mod4 dimensions and 785 is not mod4.

wut?
YV24 (and Y8) can accept even odd width/height.

paradoxical
28th February 2013, 18:30
Okay, then either I misread or the source was wrong, but I did see a source say that mod4 was required for YV24. My bad, then.

Groucho2004
28th February 2013, 18:34
I am encountering an access violation with this script:


ImageSource("what.png")
ConvertToYV24()
Tweak(sat=1.25)
Tweak(sat=0.8)
ConvertToRGB()


The error reads: "Avisynth read error: Software caught an access violation at 0x00000320(code+4249890016), attemping to write to 0x00000320". The image dimensions are 785x900.
Which version of devil.dll are you using?
Which program produces the error?

IanB
28th February 2013, 21:36
@Stephen R. Savage, and What CPU processor are you using? What OS?

Does this fail the same way?BlankClip(1001, 785, 900, Pixel_type="rgb24")
ConvertToYV24()
Tweak(sat=1.25)
Tweak(sat=0.8)
ConvertToRGB()

Stephen R. Savage
1st March 2013, 06:23
@Stephen R. Savage, and What CPU processor are you using? What OS?

Does this fail the same way?BlankClip(1001, 785, 900, Pixel_type="rgb24")
ConvertToYV24()
Tweak(sat=1.25)
Tweak(sat=0.8)
ConvertToRGB()

I am using Windows 8 AMD64 on an Ivy Bridge CPU. Your fragment does not produce any exceptions as far as I can tell.

Edit: Never mind, exceptions are still there. I managed to reproduce it by loading it in VirtualDub and then switching the tweak parameters and reloading a few times. Eventually it tells me "script open failed".

Groucho2004
3rd March 2013, 11:44
@IanB
Which compiler did you use to build Alpha4?

SEt
4th March 2013, 10:51
It's compiled with VC 6. And packed with 6 years old upx after that.

Wilbert
4th March 2013, 19:20
Edit: Never mind, exceptions are still there. I managed to reproduce it by loading it in VirtualDub and then switching the tweak parameters and reloading a few times. Eventually it tells me "script open failed".
So, you can't produce a script which always fails??

forclip
5th March 2013, 21:22
I can easily reproduce this AccessViolations with simple script like this:

BlankClip(1001, 754, 562, Pixel_type="y8")
ConvertToRGB32()

In VirtualDubMod - by pressing F5 button or reloading the script again and again.
In MPC-HC - by reloading the script.
In MeGUI script creator - by reloading preview window.
...

All the time it is AccesViolation, or app just dissapeared, or other things like "Parser: Unknown error".

Actually, I came to this not from this bugreport, but from my own bug report, when the user told me that everything works fine when he uses DirectShow preview of the script (a simple player that based on DirectShow), but when switching to our own preview engine (that uses AviSynth.dll directly via AviSynthWrapper.dll) he've got alot of AcessViolations. Most of the time - on unloading AviSynth (when PClip var = some_clip; do something; and then on unloading var=NULL; - here, when destroying IClip on Release()). And then I remembered that in second case everything is Convert`edToRGB32() in AviSynthWrapper. Added ConvertToRGB32() at the end of the script - and now I can reproduce AVs with DirectShow too.

Tested with Alpha4 and latest MT build; on Win XP SP2 with Intel Q6600 cpu.

StainlessS
6th March 2013, 09:02
Confirmed with VDMod and VD 1.9.11

Also Access violation with arg names supplied ie



#BlankClip(1001, 754, 562, Pixel_type="y8")
BlankClip(length=1001, width=754, height=562, Pixel_type="y8")
ConvertToRGB32()


Seems to mostly work ok on first load but on reload bombs.

VD 1st load may play OK, bomb on reload.

VDMod, Bombs on reload and if exit without reload or play.

XP32SP3

AppCompat.txt From VDMod bomb on noplay exit:

http://www.mediafire.com/?dmy86jv3uxsogke

IanB
6th March 2013, 13:06
Failure is for aligned SSE3+ code path in ConvertYV24toRGB for widths 16*N+1, N a positive integer greater than 1.N=2
BlankClip(10, 16*N+1, 16, Pixel_type="YV24")
ConvertToRGB()The packbuf array was being overrun. Repeatedly reloading the script eventually clobbers something that matters. It may happen on the first try, it may take 50 tries.

Fixed in CVS.

forclip
6th March 2013, 16:23
Thanks! :thanks:

Gavino
6th March 2013, 16:38
I can easily reproduce this AccessViolations with simple script like this:
BlankClip(1001, 754, 562, Pixel_type="y8")
ConvertToRGB32()

Failure is for aligned SSE3+ code path in ConvertYV24toRGB for widths 16*N+1, N a positive integer greater than 1.N=2
BlankClip(10, 16*N+1, 16, Pixel_type="YV24")
ConvertToRGB()
754 does not have the form 16*N+1. (754%16 is 2, not 1)
:confused:

forclip
6th March 2013, 17:06
There is also different source colorspaces (Y8 in my sample and YV12 was reported to me), but I hope that it makes no difference and affected code path is the same.

P.S. it would be nice to have a project files for something like MSVC2008\2010 on the CVS..

IanB
6th March 2013, 22:20
Well it's actually 16*N+[1..7] that are wrong, but they get harder to expose.

Wrong buffer length is (width*4 + 32), used buffer length is ((width+15)/16*64), the overrun is ((7 - (width-1)%16)*4)

W%16 Overrun
1 28
2 24
3 20
4 16
5 12
6 8
7 4

Wilbert
13th March 2013, 15:03
I was looking at the additions for BlankClip. Why not add video (with the default parameters) when supplying an audio only template, instead of checking of the one the parameters width, height or pixel_type is set? Likewise for a video only template.

IanB
13th March 2013, 21:58
@Wilbert,

So when you do BlankClip(Clip) you get identical clip properties to the template. If it's audio only you get a blank audio only clip. If it's video only you get a blank video only clip. If you start to modify the parameters to force a video or audio track, now you start with good defaults rather then possibly (probably) invalid junk from the template.

Wilbert
14th March 2013, 17:01
... If it's audio only you get a blank audio only clip. ...
Somehow I missed that. Makes sense now. Thanks.

Wilbert
17th March 2013, 17:58
Mmmm, i didn't realize you already documented everything ;( My fault of course.

Regarding the bit functions. Is there a difference between BitRShiftL, BitRShiftU and BitRShiftU for example? If not, why the need for three of them?
I would also like to ask you to remove tau (as being 2 pi). It's not used in the scientific literature: http://en.wikipedia.org/wiki/Tau_%282%CF%80%29#In_popular_culture, while it can denote a lot of other things: http://en.wikipedia.org/wiki/Tau.

IanB
17th March 2013, 23:44
Possibly a bit over-redundant but this is what we have, it allows building selections from Bit[LR]shift[AL] or Bit[LR]shift[SU] :-

7 synonyms for Left Shift, X << Y, bottom bits are always zero filled.
bitlshift Left Shift
bitlshiftl Left Shift Logical
bitlshifta Left Shift Arithmetic
bitlshiftu Left Shift Unsigned
bitlshifts Left Shift Signed
bitshl Shift Left
bitsal Shift Arithmetic Left


3 synonyms for Unsigned Right Shift, (unsigned int)X << Y, top bits are zero filled.
bitrshiftl Right Shift Logical
bitrshiftu Right Shift Unsigned
bitshr Shift Right


3 synonyms for Signed Right Shift, (int)X << Y, top bits are sign filled.
bitrshifta Right Shift Arithmetic
bitrshifts Right Shift Signed
bitsar Shift Arithmetic Right


2 synonyms for Rotate Left, Top bit rolls to Bottom bit.
bitlrotate Left Rotate
bitrol Rotate Left


2 synonyms for Rotate Right, Bottom bit rolls to Top bit.
bitrrotate Right Rotate
bitror Rotate Right


I added Tau() as a stir of a friend who is an avid Tau'ist, who I regularly poke with "The area of a circle is ∏r²". So I will take it out.

Reino
8th April 2013, 13:03
Since v2.60 you can trim the audio using AudioTrim. The start_time, end_time and duration need to be specified in seconds (but can be float)Is it really?
I'm trying to load a cue-indexed audiosong from a TAK-image which starts at 40053972 samples (908.25333s) and is 16986144 samples (385.17333s) long:
LoadDll("C:\Program Files\AviSynth 2.6.0\plugins\tak_deco_lib.dll")
BassAudioSource("D:\Test\Image.tak")

AudioTrim(40053972/44100,-16986144/44100)
AudioTrim(Float(40053972)/44100,Float(-16986144)/44100)

ConvertAudioTo16bit
With the 1st AudioTrim foobar returns a length of 16978500 samples or exactly 385s. It seems the start_time and end_time are floored somehow. I'd figure the starting point would also be 40042800 samples or 908s.

With the 2nd AudioTrim foobar returns 16986144 samples, but when I then bit-compare (http://www.foobar2000.org/components/view/foo_bitcompare) the Avisynth-script and the cue-indexed TAK-song, it doesn't seem to be accurate:
Differences found in 1 out of 1 track pairs.

Comparing:
"D:\Test\Image.tak" / index: 3
"D:\Test\Image.avs"
Differences found: 33952821 sample(s), starting at 0.0000000 second(s), peak: 1.4393005 at 35.8453061 second(s), 2ch

- How come Float() is needed?
- Is it possible to AudioTrim with sample accuracy?

Rumbah
8th April 2013, 15:03
- How come Float() is needed?

If you divide two integers the result will be an integer.
Just add a .0 to the integers to do a floating point division.

Reino
8th April 2013, 20:05
Ah, got it. Thanks for the heads-up, Rumbah.

Another weird example:
Another song within the same TAK-image starts at 113414616 samples (2571.76s) and is 21692496 samples (491.89333s) long:
LoadDll("C:\Program Files\AviSynth 2.6.0\plugins\tak_deco_lib.dll")
BassAudioSource("D:\Test\Image.tak")

AudioTrim(113414616/44100.0,-21692496/44100.0)
AudioTrim(113414616/44100.0,135107112/44100.0)

ConvertAudioTo16bit
The 1st AudioTrim returns a length of 21692497 samples (491.89337s), but although code for the 2nd AudioTrim should have the same result as the 1st, it returns 21692485 samples (491.89308s)! Does anyone have an explanation?

Happens to WavSource() too, so at least BassAudio isn't faulty. Remove both AudioTrim()'s and bit-compare that to the entire TAK-image also results in 'no differences found'.

Gavino
8th April 2013, 23:32
AudioTrim(113414616/44100.0,-21692496/44100.0)
AudioTrim(113414616/44100.0,135107112/44100.0)
The 1st AudioTrim returns a length of 21692497 samples (491.89337s), but although code for the 2nd AudioTrim should have the same result as the 1st, it returns 21692485 samples (491.89308s)! Does anyone have an explanation?
You are being hit by the accuracy limits of floating point representation.
Avisynth floats have 24 bit precision, which gives an accuracy of about 1 part in 16.8 million (2^24).
So any sample start, end or length values larger than this (which your examples all have) will not be sample-accurate.

IanB
9th April 2013, 00:56
@CoRoNe,

You are running into lack of precision with single precision floats.

Floats only have a 24 bit mantissa so numbers bigger than 16,777,216 can not be represented exactly. Which for the way you are using the arithmetic and with 44100Hz streams is about 380.4 seconds (349.5 for 48000Hz).

The code internally uses 64 bit integers and double precision floats, so as long as you feed it from the script with single precision numbers that can be represented exactly you can achieve audio sample exact results.

You can trim between 1.0 and 16,777,215.0 integer seconds of audio exactly from the start of a clip.

So to crib the precision do the AudioTrim in stages. Using integer arithmetic calculate whole seconds and a remainder....
Start=113414616/44100
Sremainder=(113414616%44100)/44100.0

Duration=21692496/44100
Dremainder=(21692496%44100)/44100.0

AudioTrim(Start, 0) # Chop off start integer seconds
AudioTrim(Sremainder, 0) # Chop off start remaining fractional second
# Chop full seconds and join with remaining fractional second
AudioTrim(0, -Duration) + AudioTrim(Duration, -Dremainder)

The relevant code inside AudioTrim :- Trim::Trim(double starttime, double endtime, PClip ...
...
__int64 esampleno = 0;
...
audio_offset = min(max(__int64(starttime*vi.audio_samples_per_second + 0.5), 0), ...
...
if (endtime == 0.0)
esampleno = vi.num_audio_samples;
else if (endtime < 0.0)
esampleno = __int64((starttime-endtime)*vi.audio_samples_per_second + 0.5);
else
esampleno = __int64(endtime*vi.audio_samples_per_second + 0.5);

Reino
9th April 2013, 21:29
LoadDll("C:\Program Files\AviSynth 2.6.0\plugins\tak_deco_lib.dll")
BassAudioSource("D:\Test\Image.tak")

AudioTrim(113414616/44100, 0)
AudioTrim((113414616%44100)/44100.0, 0)
AudioTrim(0, -21692496/44100) + AudioTrim(21692496/44100, -(21692496%44100)/44100.0)

ConvertAudioTo16bitAll tracks decoded fine, no differences found.

Comparing:
"D:\Test\Image.tak" / index: 7
"D:\Test\Image.avs"
No differences in decoded data found.
:goodpost: IanB!

However, I've tried to come up with some script to mimic the cutting I did with Audacity earlier, but although the amount of samples are the same, there's a glitch at the cutting-point:
Src=BassAudioSource("D:\Test\Image.tak")
Prt1=Src.AudioTrim(113414616/44100, 0)
Prt1=Prt1.AudioTrim((113414616%44100)/44100.0, 0)
Prt1=Prt1.AudioTrim(0, -11161180/44100) + AudioTrim(11161180/44100, -(11161180%44100)/44100.0)
Prt2=Src.AudioTrim(128129206/44100, 0)
Prt2=Prt2.AudioTrim((128129206%44100)/44100.0, 0)
Prt2=Prt2.AudioTrim(0, -6977906/44100) + AudioTrim(6977906/44100, -(6977906%44100)/44100.0)
Prt1+Prt2
Yesterday this code still looked like this:
A=AudioTrim(113414616/44100.0, 124575796/44100.0)
B=AudioTrim(128129206/44100.0, 135107112/44100.0)
A+BI haven't touched Avisynth in quite some time, so I must be doing something rather silly.

Gavino
9th April 2013, 23:38
I've tried to come up with some script to mimic the cutting I did with Audacity earlier, but although the amount of samples are the same, there's a glitch at the cutting-point:
Src=BassAudioSource("D:\Test\Image.tak")
Prt1=Src.AudioTrim(113414616/44100, 0)
Prt1=Prt1.AudioTrim((113414616%44100)/44100.0, 0)
Prt1=Prt1.AudioTrim(0, -11161180/44100) + AudioTrim(11161180/44100, -(11161180%44100)/44100.0)
Prt2=Src.AudioTrim(128129206/44100, 0)
Prt2=Prt2.AudioTrim((128129206%44100)/44100.0, 0)
Prt2=Prt2.AudioTrim(0, -6977906/44100) + AudioTrim(6977906/44100, -(6977906%44100)/44100.0)
Prt1+Prt2
It should be:
...
Prt1=Prt1.AudioTrim(0, -11161180/44100) + Prt1.AudioTrim(11161180/44100, -(11161180%44100)/44100.0)
...
Prt2=Prt2.AudioTrim(0, -6977906/44100) + Prt2.AudioTrim(6977906/44100, -(6977906%44100)/44100.0)
Does the quoted script match the one you actually used?
It should give an error 'invalid params to AudioTrim()' (unless some earlier part of the script sets an implicit 'last').

Reino
10th April 2013, 00:14
(unless some earlier part of the script sets an implicit 'last').Yeah, that! Lot's of '#'s for testing, but I forgot one it seems. Prt1 and Prt2 did the trick. Thanks! Silly me. Like I said, it's been a while. :p

IanB
10th April 2013, 00:18
...
However, I've tried to come up with some script to mimic the cutting I did with Audacity earlier, but although the amount of samples are the same, there's a glitch at the cutting-point:
...I take it you mean between the join between Prt1 and Prt2.

Are the sample numbers you have chosen zero crossing points. I believe Audacity does soft joins, Avisynth does hard joins of audio segments which can lead to significant discontinuities (loud pop) if one clip ends with a non-zero value and the next clip starts with a value of the opposite sign. Apart from selecting zero crossing points you can use a very short duration FadeOut0() and FadeIn0() on the two clips or you could use Dissolve() with a short overlap. I typically set FPS=1000 and use a value between 2 to 10 depending on the sound type, i.e a 2 to 10 millisecond fade....
AudioDubEx( A+B, A.KillVideo().FadeOut0(2, Fps=1000)+B.KillVideo().FadeIn0(2, fps=1000) )

There are also joins between the clips and the small residual segment at the end of the clips. To make the method bullet proof you need to test for (duration%rate)==0 if using the classic script form of AudioTrim. If using the new Length= form the code handles a zero length request correctly.

To help debug your audio trimming use AudioLengthS() to display the full 64 bit value of audio sample count property as a string.

Reino
10th April 2013, 17:48
I take it you mean between the join between Prt1 and Prt2.Exactly, but "unless some earlier part of the script sets an implicit 'last'" caused the glitch.

I don't know about hard- or soft joins, but all I did was decode the 7th cue-entry to WAV, load it in Audacity and remove 3553310 samples at 11161180 samples from the start.
Src=BassAudioSource("D:\Test\Image.tak")
Prt1=Src.AudioTrim(113414616/44100, 0).AudioTrim((113414616%44100)/44100.0, 0)
Prt1=Prt1.AudioTrim(0, -11161180/44100) + Prt1.AudioTrim(11161180/44100, -(11161180%44100)/44100.0)
Prt2=Src.AudioTrim(128129206/44100, 0).AudioTrim((128129206%44100)/44100.0, 0)
Prt2=Prt2.AudioTrim(0, -6977906/44100) + Prt2.AudioTrim(6977906/44100, -(6977906%44100)/44100.0)
Prt1+Prt2
And this Avisynth-script has the same result,...
All tracks decoded fine, no differences found.

Comparing:
"D:\Test\Audacity_edit.wav"
"D:\Test\Image.avs"
No differences in decoded data found.
...as it's bit-exact.

To help debug your audio trimming use AudioLengthS() to display the full 64 bit value of audio sample count property as a string.Like Subtitle(String(AudioLengthS)), right? Foobar (and foo_input_avs (http://www.foobar2000.org/components/view/foo_input_avs)) already shows me that.

IanB
10th April 2013, 22:31
AudioLengthS() returns a string so Subtitle(AudioLengthS()) or WriteFileStart("AudioLengthS()")

Yeah, that! Lot's of '#'s for testing, but I forgot one it seems. Prt1 and Prt2 did the trick. Thanks! Silly me. Like I said, it's been a while. :pI missed it as well, so don't feel to bad.

A hard join is just appending the audio segments without processing. This can lead to clicks and pops if done carelessly. This is what Avisynth does by default.

A soft join checks the audio samples at the join and applies some processing to eliminate any clicks or pops. In Avisynth you can carefully select the splice points or use very short fades or a dissolve.

StainlessS
15th April 2013, 15:26
Dont think this has been reported:


Colorbars().Killaudio()
#ConvertToYV24() # Uncomment to swamp pagefile.
ScriptClip("""
Overlay(Last.BlankClip(Width=4,height=height,color=$FF0000),x=0,y=0)
Overlay(Last.BlankClip(Width=4,height=height,color=$FF0000),x=10,y=0)
Overlay(Last.BlankClip(Width=4,height=height,color=$FF0000),x=20,y=0)
Overlay(Last.BlankClip(Width=4,height=height,color=$FF0000),x=30,y=0)
Overlay(Last.BlankClip(Width=4,height=height,color=$FF0000),x=40,y=0)
Overlay(Last.BlankClip(Width=4,height=height,color=$FF0000),x=50,y=0)
""")
return last.ConvertToRGB32()


Produces error message on frame when ConvertToYV24 line uncommented,:

GetFramebuffer: Returned a VFB with a 0 data pointer!
size=23104, max=536870911, used=64378496
I think we have run out of memory folks!
(scriptClip, line 3)


Run it with Taskmanager showing perfomance tab and watch Pagefile.

VDUB/VDUBMOD/MediaPlayer

Other colorspaces stabilize at about 1GB pagefile.

EDIT: This Also problem


Colorbars().Killaudio()
ConvertToYV24() # Uncomment to swamp pagefile.
Z=Last.BlankClip(Width=4,height=height,color=$FF0000)
ScriptClip("""
Overlay(Z,x=0,y=0)
Overlay(Z,x=8,y=0)
Overlay(Z,x=16,y=0)
Overlay(Z,x=24,y=0)
Overlay(Z,x=32,y=0)
Overlay(Z,x=40,y=0)
""")
return last.ConvertToRGB32()


EDIT: Also tried with Groucho2004 ICL Avisynth.dll (current updates @ 8 March 2013), same thing.

The second script seems more likely to survive in VDMod rather than VD current which bombs after about 30 secs.
Media Players, MPC Home Cinema latest, goes Black Screen.
Other Media Players may put the mentioned error message on screen.

EDIT: Multiple Overlays to make it bomb quicker.

bxyhxyh
17th April 2013, 19:39
Is 2.6a4 more stable than 2.5.8?

StainlessS
20th April 2013, 19:26
Chroma displacement problem with YV411 in Info.h.

around about this line:


for (int tx = _xs; tx < 10; tx+=xSubS, dpU++, dpV++, fontline<<=xSubS) {


Is to do with font being 10 pixels wide and chroma sample representing 4 pixels, eg last 2 pixels in a character jumps
forward 1 whole choma sample and is 2 pixel positions or half chroma sample in error (for each character ie error grows).

See problem in DDigitTest v1.04 using non greyscale clip.

IanB
21st April 2013, 00:06
Hmmmmm, yes YV411 chroma subsampling is a pita. How to fix it, but keep it fast and generic. One thought is to process 2 chars at a time so we mask through 20 pixels per loop, as 20%4 == 0 the algorithm will work correctly as opposed to 10%4 == 2 which creeps.

One issue would be odd length strings. Okay in the length=0 case, we can use the null terminator, but in the length specified case the next char can be anything.

Or for YV411 we just bang the chroma to 128 across the region. The sub-sampling is pretty rough already so it won't actually look that bad skipping the chroma dimming between glyphs.

More thoughts .... ?

IanB
21st April 2013, 00:12
@bxyhxyh,

Yes the consensus seems to be the 2.6 series makes a very good 2.5.9. The 2.5 code has many fixes over 2.5.8, hopefully without regressions. Most bugs found are related to new 2.6 code paths. e.g the overlay memory leak 3 posts up only happens with YV24.

mandarinka
21st April 2013, 02:22
I am normally rather conservative but I switched over and saw no trouble yet in the two to three months or so.

StainlessS
21st April 2013, 18:42
@IanB,

Still chewing on the YV411 problem.

I've done a mod of a debug plug for DDigit, InfoPrint, just allows to view zoomed Info.H output as here:

https://s20.postimg.cc/wv1zjhfnh/Grid_zps7ecfb526.jpg (https://postimg.cc/image/5kgobkcqh/)

Uses V.C Mohan's Grid plugin (included with source in zip), zip here:
http://www.mediafire.com/?9p876ru232wpbv7 (http://www.mediafire.com/?i2syabkp5u3skti)

and supplied script here:


BlankClip(length=1,width=100,height=80,fps=25.0,color=$ff8000).KillAudio()

#ConvertToRGB24()
#ConvertToRGB32()
#ConvertToYUY2()
#ConvertToYV12()

#ConvertToY8() # v2.6 Only
#ConvertToYV16() #
#ConvertToYV24() #
ConvertToYV411() #

X=0 Y=0

InfoPrint("ABCDEFG",X+0,Y+00)
InfoPrint("abcdefg",X+1,Y+20)
InfoPrint("0123456",X+2,Y+40)
InfoPrint("NoPqRsT",X+3,Y+60)

PointResize(width*10,Height*10)
ConvertToRGB24()

Grid(lineint=10,bold=10,vbold=1) # Small grid=1x1 pixels
#Grid(lineint=20,bold=5,vbold=1) # Small grid=2x2 pixels
#Grid(lineint=40,bold=5,vbold=1) # Small grid=4x4 pixels
return Last
# ------------------------------------------------------------------------
# InfoPrint(clip,string,int "x"=0,int "y2"=0,bool "pix"=true)
#
# Formatting control codes in string:-
# '\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).
# ------------------------------------------------------------------------
# Grid.dll by V.C Mohan
# ------------------------------------------------------------------------


Perhaps of some use to you.

IanB
21st April 2013, 23:26
Yes the problem is obvious just from reading the code, with 4 time sub-sampling the inner most chroma only does 2 iterations when it needs to do 2.5, oops 2.5 is not an integer.

I tried just banging all the chroma in the 10x20 pixel cell to 128, it looks shitty.

I have also tried using 12x20 pixels cells for YV411, but that also looks shitty, the characters look divorced from one another with the extra gap between them.

So it looks like I have to process the chroma for the characters in pairs, which becomes a little untidy when handling all the edge conditions.

IanB
22nd April 2013, 08:35
Fixed the memory leak in overlay.cpp (http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/filters/overlay/overlay.cpp?revision=1.21&view=markup)

Have a play with this version of info.h (http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/core/info.h?revision=1.10&view=markup), the first attempt code is under a "#if 0" so you can see what I mean. Just bump all the 10's to 12's to try the increased spacing (yuck!).The main code has only had minimal testing, YV411 suck for this sort of text rendering. Let me know how it goes for you.

Gavino
22nd April 2013, 13:46
Fixed the memory leak in overlay.cpp (http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/filters/overlay/overlay.cpp?revision=1.21&view=markup)
Related to this area, should this code at the end of GetFrame():
if (vi.IsYV24() && inputCS == vi.pixel_type) { // Fast path
delete img;
img = NULL;
return frame;
}
also be added on the earlier path where overlayImg->IsSizeZero()?
This would avoid not only a redundant copy, but also possible problems in the Overlay destructor (when calling img->Free()).

StainlessS
22nd April 2013, 16:58
Thanx for the Overlay fix. :)

I know that you understood the YV411 problem without it being shown to you, I thought the utility might assist
in testing solutions. Also can show how eg supplied length performs as the control codes eg '\n' and '\r' send
intervening substrings with len specified.

Will download new info.h and give it a whirl. Thankyou.

EDIT: Perhaps someone knows of a collection of Open Source fonts, perhaps even with YV411 compatible
source that already exists ?

EDIT: Google on "open source font" bring up plenty of links.

EDIT: Or probably more targetted, "open source monospace bitmap screen font rendering bdf"

EDIT: This might be useful in search "BDF" (Glyph Bitmap Distribution Format) :-
http://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format

StainlessS
27th April 2013, 15:53
Problem in post #90 InfoPrint.dll zip, v2.6 project file, mistakenly got AVISYNTH_PLUGIN_25 defined for Release, remove or it will compile
to a v2.5 version dll. have updated post #90 link with fixed project file and dll's.

link again:
http://www.mediafire.com/?i2syabkp5u3skti

EDIT:- By the way, can use either eg "Test"+Chr(10)+"Test2" as well as "Test\nTest2" in InfoPrint

StainlessS
28th April 2013, 01:20
From ImageSource docs
The first file in the sequence, i.e., corresponding to 'start', MUST exist in order for clip parameters to be computed. Any missing files in the sequence are replaced with a blank frame.



ColorBars().Trim(0,-100).ShowFrameNumber()
ImageWriter("TEST_",type="BMP") # Create test frames




ImageSource("TEST_%06d.BMP",start=0,end=1000) # Test ImageSource


In both v2.58 and 2.6a4, non existing frames (100 -> 1000) alternate between BLACK frame and copies of ColorBars, rather than blank.

When I tested same with a 640x400 live video clip, I got some frames which looked like multiple miniature copies of frames, along with black frames
and some black frames with streaks in them.

Also see previous post EDIT.

Gavino
29th April 2013, 11:01
In both v2.58 and 2.6a4, non existing frames (100 -> 1000) alternate between BLACK frame and copies of ColorBars, rather than blank.
Looking at the source code in ImageSeq.cpp, it seems that (unless using DevIL) the frame is never written to in these cases and so contains random junk.

I think all the error paths in function checkProperties() should be setting the frame to blank (before, if appropriate, writing an error message). Of course, this will have to allow for setting chroma to 128 for YUV output, so can't just set all bytes to zero.

StainlessS
6th May 2013, 15:56
Probably just a copy/paste typo, in new filtersdk/DataStorageInAviSynth.htm


Y8

width mod-1 (no restriction)
height mod-1 (no restriction) if progressive
height mod-2 if interlaced

YV411

width mod-4
height mod-1 (no restriction) if progressive
height mod-1 (no restriction) if interlaced

Wilbert
12th May 2013, 17:13
Did anyone get SoundOut to work with Avisynth v2.60a4? When i open a script (ending with SoundOut()) in Virtualdub i get the error message:

Avisynth open failure:
Cache: Filter returned invalid response to CACHE_GETCHILD_CACHE_MODE. 176310176

Is it supposed to work in 2.60 or is something not implemented properly?

poisondeathray
12th May 2013, 20:04
Did anyone get SoundOut to work with Avisynth v2.60a4? When i open a script (ending with SoundOut()) in Virtualdub i get the error message:

Avisynth open failure:
Cache: Filter returned invalid response to CACHE_GETCHILD_CACHE_MODE. 176310176

Is it supposed to work in 2.60 or is something not implemented properly?



Works ok here...

IanB
13th May 2013, 00:49
Did anyone get SoundOut to work with Avisynth v2.60a4? When i open a script (ending with SoundOut()) in Virtualdub i get the error message:

Avisynth open failure:
Cache: Filter returned invalid response to CACHE_GETCHILD_CACHE_MODE. 176310176

Is it supposed to work in 2.60 or is something not implemented properly?
You probably have an early development version compiled with AVISYNTH_INTERFACE_VERSION = 5, this of course will not work with 2.5.8 or versions of 2.6 that rely on the version correctly describing the API level expected.

Any plugin that purports to be version 5 must support all the requirements of the latest 2.6 API. In this case CACHE_GETCHILD_CACHE_MODE returning a valid mode.

Plugin authors may use the reserved version 4 to prevent loading in 2.5.8 but still be treated as a 2.5 plugin by 2.6.

I will have a look to see if I can add some protection code for AvisynthPluginInit2 plugins that try to lie that they are version 5.

Wilbert
14th May 2013, 20:58
You probably have an early development version compiled with AVISYNTH_INTERFACE_VERSION = 5, this of course will not work with 2.5.8 or versions of 2.6 that rely on the version correctly describing the API level expected.
I guess so. So i need to recompile the plugins with the latest avisynth.h? Will try that later.

IanB
14th May 2013, 22:30
Given we are talking about SoundOut (pass through video) it would be more useful to compile it as a 2.5 plugin, then it would work with all versions.

Groucho2004
19th May 2013, 14:07
Do you think it's "fair" to say that AviSynth 2.5.8 is better than 2.6.0 just because the former is tagged as being "Stable" whereas the latter is tagged as being "Alpha" (like Zathor basically is argumenting)?

Or would you agree with SEt, that AviSynth 2.6.0 is better than 2.5.8, even though it's tagged as being "Alpha"?
SEt was comparing MT versions and their MT implementations.

As for the official (non-MT) Avisynth versions - 2.6 has had many bug fixes and added features since 2.58 and it seems to be just as stable.
Also, the more people use it, the more testing is done and we may finally get out of Alpha stage.

IanB
19th May 2013, 15:05
As a 2.5.8 replacement 2.6.0 should be just as stable. It passes all current the 2.5 regression tests, while 2.5.8 fails a few due to bugs being fixed and test to expose them being added. Most problems show up in new code, so if you use the new 2.6 features, that is where you might expect to find problems. A lot of people are downloading 2.6. And the only 2.5 bug reports I seem to get are for things broken in 2.5.8 as well, the few 2.6 bug reports are to do with things like YV24 overlay and YV411 text painting.

I have most of the API changes mapped out to cover hooks for expected features for 2.6.1 and 2.6.2 like extra colour spaces and threading so that 2.6 plugins won't need to be recompiled. I have a long standing bug in the cache from 2.5.7 that I am working on at present and I intend to do an Alpha 5 release when I finish and test that fix. If Alpha 5 stands up without any new bugs I will probably promote it to Release Candidate 1, i.e. 1st Beta release.

StainlessS
19th May 2013, 15:29
As IanB says, you can use v2.6a4 as a more stable v2.58 so long as you dont use new features.

Me RECOMMENDED's. :)

I use v2.6a4 (well Groucho2004's ICL version usually, for a couple of recent fixes), and MeGUI uses that one
and not 2.5.8.5 in MeGUI directory. (Although recently a user found he also had to manually update the MeGUI copy on
W7 64bit for some reason or it was not using 2.6).

EDIT: Of course (slaps head), MeGUI only uses the MeGUI local copy for its built in tools eg Avisynth Script Creator,
if feeding AVS files directly into MeGUI, then it uses the system copy.

EDIT: Zathor reply to below post (linked to from following post) :-
Btw even if MeGUI provides 2.6 it will only be used when no AviSynth is installed at all on the system. Therefore it will be used by the more inexperienced users and the AviSynth build must work.

StainlessS
19th May 2013, 19:19
FYI, Mr B,

I've decided to ignore chroma altogether for YV411 in DDigit, it seems to provide the least objectionable results,
although might look a little weird on something like colorbars, looks not too bad on live video.
Could not manage to find a good fix for chroma as DDigit is inherently character based and the control characters in the
stream make things much harder to implement as opposed to a raster scan implementation like your Info.h without any control codes.
(At least without slowing it down significantly, and it would still look ropey).
EDIT: Above problem in DDigit relates to faint chroma stripes due to background fade applied twice, at the end a character and
beginning of next character, when on non greyscale frame.


Will though try to implement (using the reserved and last available 'C' escape sequence {'\v'}) an alternative luma only
colormap for eg Y8 and YV411, something like '\v0' to '\vF' == luma 0 -> 255 in steps of 17 (== 255/15).

EDIT: Looks OK over Colorbars(). Might want to reduce background multiplier a little from 7/8, 3/4, and 5/8 both seem OK,
and improves visibility if chroma background not faded.

real.finder
20th May 2013, 14:44
ver. 2.5.8 supports 6 (5.1) Channels in audio

is 2.6 supports 8 (7.1)?

tebasuna51
20th May 2013, 21:33
ver. 2.5.8 supports 6 (5.1) Channels in audio

ver 2.5.8 support also 7.1.

real.finder
20th May 2013, 22:05
ver 2.5.8 support also 7.1.

um, but there http://avisynth.org/mediawiki/GetChannel

Did not mention 7.1

Wilbert
20th May 2013, 22:38
It says "it returns one or more channels of a multichannel signal". It support a large amount of channels (there might be some limit, but i'm too lazy to look that up). The main question is whether your source filter loads them all.

tebasuna51
21st May 2013, 13:09
um, but there http://avisynth.org/mediawiki/GetChannel

Did not mention 7.1

Like Wilbert say: "It support a large amount of channels"

More important is this:
"The ordering of the channels is determined by the ordering of the input file, because AviSynth doesn't assume any ordering (1). In case of stereo 2.0 WAV and 5.1 WAV files the ordering should be as follows (2)"

(1) AviSynth don't have a essential property of audio to manage multichannel audio (MaskChannels), to identify each channel.
Then the user must be careful only with the channel order, trying to preserve the standard order not always obvious.

(2) No problem with standard stereo: FrontLeft, FrontRight

With 5.1: FL, FR, FCenter, LFE, RearL, RearR

Here there are a difference with Microsoft defined channels:
SideL, SideR (-+90º from Center channel) and BackL, BackR (-+130º from Center channel).
BTW, both can be assumed like standard 5.1:
FL, FR, FC, LFE, BL, BR or FL, FR, FC, LFE, SL, SR

With 7.1: the standard order don't have problems, must be:
FL, FR, FC, LFE, BL, BR, SL, SR

With 6.1: here we must be careful because don't exist a standard order defined and the BackCenter can be before or after the Rear channels depending if we consider the Rear like Back or Side.

You must know if the input is:
1) FL, FR, FC, LFE, BL, BR, BC
or
2) FL, FR, FC, LFE, BC, SL, SR
and if the output must have the order 1) or 2)

ajp_anton
21st May 2013, 17:33
Is there a 64-bit build of 2.6 available? I just need to combine a few 2.6 features with large amounts of RAM (not expecting any speed boosts or plugin support).

Reino
24th June 2013, 17:23
E=Import("sample_E.avs")
A=BassAudioSource("sample_A.wav").DelayAudio(3388169/44100.0)
W=Import("sample_W.avs").DelayAudio(3599778/44100.0)

Mix1=MixAudio(W,A,1.0,1.0)
Mix2=MixAudio(Mix1,E,1.0,1.0)

ConvertAudioTo16bit(Mix)I'm doing some audio mixing (A begins before E ends, and W begins before A ends) and I've noticed something odd. By closely examining the script's outcome in Audacity, I noticed for W I have to lower the DelayAudio with 1 sample (3599777) to align everything perfectly, which isn't necessary for A.
Can any developer/anyone who knows the inner workings of Avisynth confirm this is how Import() works?
-----------------

In reference to this post, I was wondering if this would also work for DelayAudio. Something like this?
A=BassAudioSource("sample_A.wav")
A.DelayAudio(113414616/44100).DelayAudio((113414616%44100)/44100.0)

Gavino
24th June 2013, 19:03
Can any developer/anyone who knows the inner workings of Avisynth confirm this is how Import() works?
Import() should have no effect on audio delay.
What do the scripts sample_E.avs and sample_W.avs contain?

In reference to this post, I was wondering if this would also work for DelayAudio.
Yes, it should work - DelayAudio() converts time to samples in the same way as AudioTrim().

Reino
27th June 2013, 22:43
Sorry for the late response, but in the end it turned out to be a stupid little mistake on my part. It was all just a rough draft. I then rewrote the script and worked out the rest.
It's all about doing this (https://www.youtube.com/watch?v=4Y3aKcQ0HK4) (view in 720p!) with Avisynth (http://pastebin.com/YZDx0ND8).

Follow-up question:
Subtitle(String(Int(AudioDuration)/60)+":"+String(Int(AudioDuration)%60)+MidStr(String(Frac(AudioDuration)),2,4)+" ("+AudioLengthS+" samples)")
...produces: "2:4.278 (5480666 samples)".
Do you know how I can change this so that 0-9s always have a preceding 0 and that the example thus becomes "2:04.278 (5480666 samples)".

Gavino
27th June 2013, 22:57
Subtitle(String(Int(AudioDuration)/60)+":"+String(Int(AudioDuration)%60)+MidStr(String(Frac(AudioDuration)),2,4)+" ("+AudioLengthS+" samples)")
...produces: "2:4.278 (5480666 samples)".
Do you know how I can change this so that 0-9s always have a preceding 0 and that the example thus becomes "2:04.278 (5480666 samples)".
Use the second argument of String() to control the formatting: String(..., "%02.0f")
http://avisynth.nl/index.php/Internal_functions/Conversion_functions

Reino
27th June 2013, 23:09
Man, you're fast! Thanks a lot! ;)

Reino
30th June 2013, 12:44
Small problem with the Subtitle-string still:
12962398 samples / 44100Hz = 4:53.931927... -> 4:53.932, but with MidStr(String(Frac(AudioDuration)),2,4) that obviously results in 4:53.931. I thought of using Round(float), but it converts to an integer, so that's of no use.
Do you know of a clever way to round off with an accuracy of 3 decimals, Gavino?

Chikuzen
30th June 2013, 13:35
MidStr(String(Frac(AudioDuration + 0.0005)),2,4)

Reino
30th June 2013, 14:40
That's very clever indeed. Haven't thought of that. Thanks!

Gavino
30th June 2013, 14:57
Another way is again to use the formatting function of String():
MidStr(String(Frac(AudioDuration), "%5.3f"),2,4)

Gavino
30th June 2013, 17:13
Actually, it occurs to me there is now a further problem (with both Chikuzen's solution and mine).

If the fractional part is greater than 0.9995, you need to round up to the next whole second.
Even worse, when seconds > 59.9995, you need to change the minute count too.

A solution is to round the duration to the nearest millisecond before calculating the minute and second parts:
duration = round(AudioDuration*1000)/1000.0
then use this new duration in place of AudioDuration to display as before.

Reino
30th June 2013, 21:02
The samples I had thus far didn't reveal this flaw, so I probably wouldn've never known. Thanks a lot, Gavino!

The end of my script now:
Duration=Round(AudioLengthF/44.1)/1000.0
Subtitle(String(Int(Duration)/60)+":"+String(Int(Duration)%60,"%02.0f")+\
MidStr(String(Frac(Duration),"%5.3f"),2,4)+" ("+AudioLengthS+" samples)")

Btw, AviSynth Wiki's description on the formatting function of String() (http://avisynth.nl/index.php/Internal_functions/Conversion_functions) was a little confusing, so I changed the text a tiny bit and corrected a small mistake in one of the examples.

StainlessS
7th July 2013, 05:39
There seems to be a mismatch between docs and source for Subtitle().

Doc

Align | Normally 4 <left and baseline>; if x=-1, then 5 <horizontal center and baseline>



Subtitle::Create

const int align = args[10].AsInt(args[2].AsFloat(0)==-1?2:7);


ie default = 7, if x == -1 then 2. (perhaps 2 should be 8, if so both docs and source wrong).

Can it be verified which is intended behavior please. (doing something similar).

Gavino
7th July 2013, 09:52
There seems to be a mismatch between docs and source for Subtitle().
Looking at source file text-overlay.cpp (http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/filters/text-overlay.cpp?view=log) in CVS, it seems code originally matched docs, but defaults changed in file revision 1.6 (23 Apr 2005).

StainlessS
7th July 2013, 15:28
Thanx G. I still think both docs and code may be wrong, seems odd that default top left (7)
and if x== -1, then applies 2, ie bottom middle. For Top-center, 2 might be correct on a mobile
numeric keypad, but on a PC keypad that position is 8.

The question remains, what is intended behavior ?

Gavino
7th July 2013, 15:51
The question remains, what is intended behavior ?
Change was made by IanB, so perhaps he can explain.
No reason given in CVS, except 'tidy'.

IanB
8th July 2013, 00:06
Sorry, I can't remember that far back. Possibly making the default text be all inside the frame. Maybe there was a thread discussing the issue around that time?

Anyway just document what it does now.

Wilbert
8th July 2013, 18:21
Anyway just document what it does now.
I updated the docs (offline will follow later).

Robert Martens
30th July 2013, 04:07
Trying to generate some test clips over the weekend, I stumbled over what I believe is a bug when converting RGB32 to Y8 in Avisynth 2.6; clips with a width of eight or more show a shift to the right by four pixels, the right side cropped by four and the left side padded with copies of the left four columns. I've tried every width from one through seven pixels, and they all work as expected. I've been testing with this script:

pixel_type = "RGB32"
width = 1
height = 16

a = BlankClip(width=width, height=height, color=$0F0F0F, pixel_type=pixel_type)
b = BlankClip(width=width, height=height, color=$555555, pixel_type=pixel_type)
c = BlankClip(width=width, height=height, color=$AAAAAA, pixel_type=pixel_type)
d = BlankClip(width=width, height=height, color=$F0F0F0, pixel_type=pixel_type)
e = BlankClip(width=width, height=height, color=$FEFEFE, pixel_type=pixel_type)

StackHorizontal(a, b, c, d, e, d, c, b)
ConvertToY8()

Commenting out ConvertToY8 should produce a visually identical clip, but instead the content is shifted to the right. The conversion works as expected in the September 27th, 2009 build, but the May 25th, 2011 and January 14th, 2013 builds show the behavior. Converting to Y8 from RGB24 works correctly in all three releases.

I tried checking out and building the project myself at a few points, and though the code has since been broken out into its own file, it seems that the update of src/convert/convert_planar.cpp from revision 1.12 to 1.13 (rewriting the ConvertToY8 functions in Softwire) is where things changed.

I've spent a few hours between yesterday and today going over this, but I'm getting nowhere; I thought perhaps I could notice something between comparing the RGB32 and RGB24 code paths, or by comparing those with an older revision, but Assembly is proving my superior, and I'm stumped. Is this a real bug, or have I sent myself on a wild goose chase?

IanB
30th July 2013, 07:37
Yep it's a bug. The "x86.add(ecx, 4);" at line 166 in convert_rgbtoy8.cpp was moved after the dependant pixel load at line 163 to fill the stall on mm3, the load code did not get the offset updated to match.

vcmohan
17th August 2013, 13:35
I am trying to port my TransAll to 2.6
The compiler gives an error at a line reading
const int bytes = vi.BytesFromAudioSamples(count);

fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'E:\8168\vc98\p2\src\P2\main.c', line 494)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
Error executing cl.exe.

I am unable to make out this. I am on XP and VC6.
Request help.

cretindesalpes
17th August 2013, 15:14
I remember VC 6 was crashing sometimes with bad syntax, typically when forgetting the parenthesis after the definition of a constructor or something like this. The indicated line is generally irrelevant. Also, changing the order of the included files may magically prevent this kind of crash. Check carefully your syntax, or better, use a more recent compiler.

vcmohan
18th August 2013, 07:44
No. The error reporting is definitely from that line. It did not like specifying bytes as int. changing it to __int64 worked. With Avisynth 2.5.8 I did not get this error though.

StainlessS
19th August 2013, 21:51
I seem to have found an Avisynth v2.6a4 BUG (not checked in V2.58)


A=Colorbars().convertToYV12()
#MergeRGB(a,a,a) # ERROR:- "MergeRGB: Input to filter must be in RGB colorspace"
MergeARGB(a,a,a,a) # OK

Groucho2004
19th August 2013, 22:43
I seem to have found an Avisynth v2.6a4 BUG (not checked in V2.58)


A=Colorbars().convertToYV12()
#MergeRGB(a,a,a) # ERROR:- "MergeRGB: Input to filter must be in RGB colorspace"
MergeARGB(a,a,a,a) # OK


Can't reproduce this. Tried 2.6A4 (my ICL build and official), Set's MT and 2.58.

Edit: That error message is not part of the Avisynth source so Ian seems to be on the right track - as usual.

IanB
19th August 2013, 22:53
@StainlessS,

Maybe you are using TSP's RGBmanipulate, feature request: extract red/green/blue() ; mergergb() (http://forum.doom9.org/showthread.php?t=93090).


And people with your experience are allowed (expected) to read the source and refer to the lines that you think are in error.

StainlessS
20th August 2013, 01:41
OK, guys, you got me.
RGBManipulate, goes in the bin.

vcmohan
20th August 2013, 04:20
I am still confused about usage of AVISYNTH_INTERFACE_VERSION. Can a plugin access the version at run time? If so how? I find that in the avisynth header file it is already defined. So at compile time one can get this info.

IanB
21st August 2013, 00:26
Have you read post #50 "Notes about AVISYNTH_INTERFACE_VERSION usage."?

AVISYNTH_INTERFACE_VERSION is a compile time constant, and without trickery the core API does not directly expose the value it was compiled with. Think about it as an indicator to how much API you have, low numbers -> old shorter API set, higher numbers -> more features available.

You are expected to ask "Do you support version X ?" with IScriptEnvironment::CheckVersion(int version) and either complain you need a later version or provide remedial code paths to support older versions.

In all plugins you provide the IClip member "virtual int __stdcall IClip ::GetVersion() { return AVISYNTH_INTERFACE_VERSION; }" which the core uses to determine the feature set available from the filter class.

StainlessS
21st August 2013, 01:34
I am not a CPP programmer and have been and still am totally oblivious to the concerns in this thread
(EDIT correction, under previous question),
so mainly I just ignore them, compile time stuff fulfills my need as I am not able to distinguish the difference.
why I need to add an IClip member, dont know, presumed only for eg source filter.
Am equally informed about Cache usage, am yet to see a single simple example other than returning 0, and no
real idea what that does.

V.C. Mohan, if you can sort it out, send me a PM, I'de quite like to understand it myself.

Some things about Avisynth, are to me, a complete mystery.

EDIT: I have read previous linked thread more than once, still non the wiser.

EDIT: My guess is that there are a lot of people that do not understand, but are reluctant to expose themselves as
stupid, hands up, I am stupid. If I were wrong, then there would not be the repeated queries about same,
all of which seem to repeatedly misunderstand the already existing posts. We need it spelt out in words of 1 syllable
or less, so the the vast majority of stupid people (like me) can understand.

Robert Martens
21st August 2013, 03:05
You are expected to ask "Do you support version X ?" with IScriptEnvironment::CheckVersion(int version) and either complain you need a later version or provide remedial code paths to support older versions.

In all plugins you provide the IClip member "virtual int __stdcall IClip ::GetVersion() { return AVISYNTH_INTERFACE_VERSION; }" which the core uses to determine the feature set available from the filter class.

I've been having trouble understanding this subject myself, and so far I've been distinguishing between 2.5 and 2.6 by way of separate build configurations. There are two things that confuse me:

First is the unfamiliar behavior of CheckVersion. I imagine I'm showing my ignorance of design patterns here, but I'd have expected a function one could simply call to get a version number, which could then be used to branch in various directions. Instead, it appears that all you do is call the function (optionally providing an API version number, which defaults to the value of AVISYNTH_INTERFACE_VERSION) and the core will check whether or not the plugin has been compiled for a later version, throwing an error if so:

src/core/avisynth.cpp
----

void ScriptEnvironment::CheckVersion(int version) {
if (version > AVISYNTH_INTERFACE_VERSION)
ThrowError("Plugin was designed for a later version of Avisynth (%d)", version);
}

Poking through the Avisynth source while typing up this post, I saw a call to CheckVersion that shows the function used in a try...catch block:

src/core/avisynth_c.cpp
----

extern "C"
int AVSC_CC avs_check_version(AVS_ScriptEnvironment * p, int version)
{
p->error = 0;
try {
p->env->CheckVersion(version);
return 0;
} catch (AvisynthError err) {
p->error = err.msg;
return -1;
}
}

This makes the usage clearer, but wasn't apparent just from the avisynth header. Off the top of my head I'm still not sure if I can use it in the way I'd like to in my project, but hopefully that points someone else in the right direction for their own work.


My other difficulty was with part of post 50, where you mention IClip::GetVersion, saying

And through the IClip interface it is the authors responsibility to declare the level of support the plugin provides.

which to me suggests that I have to do something beyond inherit from either IClip or GenericVideoFilter. The definition of IClip, however, shows the GetVersion function is already defined to return the value of AVISYNTH_INTERFACE_VERSION defined in the header I'm using, and I am in fact able to call my filter's GetVersion and retrieve the right value, even though I haven't overridden the header's copy of the function anywhere in my own code.

Is there something else I need to do with GetVersion? I feel like I've asked that before and gotten an answer, but I can't remember since I'm dumb, so please bear with me.

vcmohan
21st August 2013, 04:12
Still unclear to me.
Does older to avisynth version 2.6 check the version from the plugin through GetVersion?
Does only avisynth 2.6 and presumably later versions check the version?
At what stage the version is checked? . Is it prior to Get Frame and or Get audio ?
I am trying to avoid multiple compilations of the plugins.

Chikuzen
21st August 2013, 06:37
At what stage the version is checked? . Is it prior to Get Frame and or Get audio ?

The version check is done at LoadPlugin().
If your plugin's AVISYNTH_INTERFACE_VERSION is 5, then avisynth.dll older than 2.6 can't load your plugin.

Groucho2004
21st August 2013, 12:30
It's really simple guys (and documented (http://avisynth.nl/index.php/Cplusplus_API#CheckVersion)!):

CheckVersion(5) throws an error when a avisynth.dll is used that does not support this interface version (2.58 for example).

GetVersion() simply returns the interface version of the loaded avisynth.dll.

vcmohan
21st August 2013, 13:57
" chicuzen :- If your plugin's AVISYNTH_INTERFACE_VERSION is 5, then avisynth.dll older than 2.6 can't load your plugin."

I thought the older to 2.6 avisynth does not check the version, and therefore plugins compiled with avisynth.h of 2.6 can still be loaded and if properly coded these plugins can operate. Now it appears that particular doorway was shut. Pity.

StainlessS
21st August 2013, 20:45
Avisynth v2.6 plugs now use a different plugin initialization routine AvisynthPluginInit3(), v2.58 AvisynthPluginInit2().

#ifdef AVISYNTH_PLUGIN_25
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
#else
/* New 2.6 requirement!!! */
// Declare and initialise server pointers static storage.
const AVS_Linkage *AVS_linkage = 0;

/* New 2.6 requirement!!! */
// DLL entry point called from LoadPlugin() to setup a user plugin.
extern "C" __declspec(dllexport) const char* __stdcall
AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {

/* New 2.6 requirment!!! */
// Save the server pointers.
AVS_linkage = vectors;
#endif
env->AddFunction("RoboCrop", "c[Samples]i[Thresh]f[Laced]b[wMod]i[hMod]i[RLBT]i[Debug]b[Ignore]f[Matrix]i[Baffle]i"
"[ScaleAutoThreshRGB]b[ScaleAutoThreshYUV]b[CropMode]i[Blank]b[BlankPC]b[Align]b[Show]b"
"[LogFn]s[LogAppend]b"
,Create_RoboCrop, 0);
return "`RoboCrop' RoboCrop plugin";
// A freeform name of the plugin.
}

Wilbert
21st August 2013, 23:15
In all plugins you provide the IClip member "virtual int __stdcall IClip::GetVersion() { return AVISYNTH_INTERFACE_VERSION; }" which the core uses to determine the feature set available from the filter class.
Let me ask a dumb question too ;) I'm probably misunderstanding this, but i want to document something about creating new plugins.

Suppose i created a plugin with the new v5 avisynth.h. It's a plugin that should work with AviSynth 2.5 too (let's say minimal v3 because i used SubframePlanar somewhere). Does the above mean i should add the line

int __stdcall GetVersion();

in the constructor? And add the lines

int __stdcall NamePlugin::GetVersion() {
return int(3);
}

after it? So how and where (in the code) does the core uses this to determine the feature set available from the filter class?

IanB
22nd August 2013, 00:31
The version checking stuff is more for apps that load Avisynth.dll and call the CreateScriptEnvironment entry point.

You would give the lowest version you can live with on the CreateScriptEnvironment call, then check if some extra API's are available with some IScriptEnvironment::CheckVersion calls.


The IClip::GetVersion is mostly for the core to find out about plugins. For most applications the inherited implementation is satisfactory. Of course if you need something special then like the other IClip members you can override it in your class. Currently the 2.6 core call IClip::GetVersion to test if IClip::SetCacheHints support the version 5 calls. Apps that load Avisynth.dll it may be useful to know the versions of returned PClip's from Invoke and friends.


It was never intended for 2.6 plugins to be loadable by earlier versions of the Avisynth core. The brief was 2.6 would load and support 2.5 plugins, period! That said, it is fairly easy to write a single .dll plugin that could be loaded and used by a 2.5 Avisynth core and still be a complete 2.6 plugin to a 2.6 Avisynth core.

To do so the .dll only needs to provide both AvisynthPluginInit2 and AvisynthPluginInit3 entry points. One brute force solution would be to have separate 2.5 and 2.6 filter classes and reference each behind the appropriate AvisynthPluginInit* entry point. A less brutish solution could be to provide a local static copy of the AVS_linkage for use with a 2.5 core case, hopefully the 2.6 core version of the AVS_linkage is used in the 2.6 code paths. Just needs a little imagination .....


I am not a CPP programmer ....Yet you write quite an number of plugins and usefully contribute to the discussions.

IanB
22nd August 2013, 00:41
@Wilbert,

In a strictly authoritarian sense you could return 3 to be totally anal about it, but in practise it's not necessary. Prior to 2.6 nothing ever used GetVersion.

The key point is you need to support all the API features up to the level you return.

vcmohan
22nd August 2013, 04:20
That said, it is fairly easy to write a single .dll plugin that could be loaded and used by a 2.5 Avisynth core and still be a complete 2.6 plugin to a 2.6 Avisynth core.

To do so the .dll only needs to provide both AvisynthPluginInit2 and AvisynthPluginInit3 entry points. ----- A less brutish solution could be to provide a local static copy of the AVS_linkage for use with a 2.5 core case, hopefully the 2.6 core version of the AVS_linkage is used in the 2.6 code paths. Just needs a little imagination .....



I am not a CPP geek and also due to my age, difficult to grasp quickly. This is completely above me. Hope some thing like simple simon example will be available soon to guide.

Wilbert
22nd August 2013, 18:15
To do so the .dll only needs to provide both AvisynthPluginInit2 and AvisynthPluginInit3 entry points. One brute force solution would be to have separate 2.5 and 2.6 filter classes and reference each behind the appropriate AvisynthPluginInit* entry point.
Ok, lets start with the brutal one ;) Since others have given up :( The code below works for 2.6 and it crashes for 2.58. Yes it's only one class, but i don't see what other things i need to change to make it work for 2.5 too. I want them to use the same InvertNeg::GetFrame or isn't that possible?


#include <windows.h>
#include "avisynth.h"

class InvertNeg : public GenericVideoFilter
{
public:
InvertNeg(PClip _child, IScriptEnvironment* env);
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
};

InvertNeg::InvertNeg(PClip _child, IScriptEnvironment* env) :
GenericVideoFilter(_child) {
if (!vi.IsPlanar() || !vi.IsYUV()) {
env->ThrowError("InvertNeg: planar YUV data only!");
}
}

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

PVideoFrame src = child->GetFrame(n, env);
PVideoFrame dst = env->NewVideoFrame(vi);

const unsigned char* srcp;
unsigned char* dstp;
int src_pitch;
int dst_pitch;
int row_size;
int height;

int p, x, y;

if ((vi.IsPlanar()) && (vi.IsYUV())) {
int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};

for (p=0; p<3; p++) {
srcp = src->GetReadPtr(planes[p]);
dstp = dst->GetWritePtr(planes[p]);

src_pitch = src->GetPitch(planes[p]);
dst_pitch = dst->GetPitch(planes[p]);
row_size = dst->GetRowSize(planes[p]);
height = dst->GetHeight(planes[p]);

for (y = 0; y < height; y++) {
for (x = 0; x < row_size; x++) {
dstp[x] = srcp[x] ^ 255;
}
srcp += src_pitch;
dstp += dst_pitch;
}
}
return dst;
} else {
return src;
}
}

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

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

const AVS_Linkage *AVS_linkage = 0;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", Create_InvertNeg25, 0);
return "`InvertNeg' sample plugin";
}

StainlessS
22nd August 2013, 20:06
To do so the .dll only needs to provide both AvisynthPluginInit2 and AvisynthPluginInit3 entry points. One brute force solution would be to have separate 2.5 and 2.6 filter classes and reference each behind the appropriate AvisynthPluginInit* entry point. A less brutish solution could be to provide a local static copy of the AVS_linkage for use with a 2.5 core case, hopefully the 2.6 core version of the AVS_linkage is used in the 2.6 code paths. Just needs a little imagination .....




This DOES work for both v2.58 and v2.6a4 (Brute Force approach)

InvertNeg25.cpp

#include <windows.h>
#include "avisynth25.h"

class InvertNeg25 : public GenericVideoFilter
{
public:
InvertNeg25(PClip _child, IScriptEnvironment* env);
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
};

InvertNeg25::InvertNeg25(PClip _child, IScriptEnvironment* env) :
GenericVideoFilter(_child) {
if (!vi.IsPlanar() || !vi.IsYUV()) {
env->ThrowError("InvertNeg: planar YUV data only!");
}
}

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

PVideoFrame src = child->GetFrame(n, env);
PVideoFrame dst = env->NewVideoFrame(vi);

const unsigned char* srcp;
unsigned char* dstp;
int src_pitch;
int dst_pitch;
int row_size;
int height;

int p, x, y;

if ((vi.IsPlanar()) && (vi.IsYUV())) {
int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};

for (p=0; p<3; p++) {
srcp = src->GetReadPtr(planes[p]);
dstp = dst->GetWritePtr(planes[p]);

src_pitch = src->GetPitch(planes[p]);
dst_pitch = dst->GetPitch(planes[p]);
row_size = dst->GetRowSize(planes[p]);
height = dst->GetHeight(planes[p]);

for (y = 0; y < height; y++) {
for (x = 0; x < row_size; x++) {
dstp[x] = srcp[x] ^ 255;
}
srcp += src_pitch;
dstp += dst_pitch;
}
}
return dst;
} else {
return src;
}
}


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

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", Create_InvertNeg25, 0);
return "`InvertNeg' sample plugin";
}


InvertNeg26.cpp

#include <windows.h>
#include "avisynth26.h"

class InvertNeg26 : public GenericVideoFilter
{
public:
InvertNeg26(PClip _child, IScriptEnvironment* env);
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
};

InvertNeg26::InvertNeg26(PClip _child, IScriptEnvironment* env) :
GenericVideoFilter(_child) {
if (!vi.IsPlanar() || !vi.IsYUV()) {
env->ThrowError("InvertNeg: planar YUV data only!");
}
}

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

PVideoFrame src = child->GetFrame(n, env);
PVideoFrame dst = env->NewVideoFrame(vi);

const unsigned char* srcp;
unsigned char* dstp;
int src_pitch;
int dst_pitch;
int row_size;
int height;

int p, x, y;

if ((vi.IsPlanar()) && (vi.IsYUV())) {
int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};

for (p=0; p<3; p++) {
srcp = src->GetReadPtr(planes[p]);
dstp = dst->GetWritePtr(planes[p]);

src_pitch = src->GetPitch(planes[p]);
dst_pitch = dst->GetPitch(planes[p]);
row_size = dst->GetRowSize(planes[p]);
height = dst->GetHeight(planes[p]);

for (y = 0; y < height; y++) {
for (x = 0; x < row_size; x++) {
dstp[x] = srcp[x] ^ 255;
}
srcp += src_pitch;
dstp += dst_pitch;
}
}
return dst;
} else {
return src;
}
}

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


const AVS_Linkage *AVS_linkage = 0;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", Create_InvertNeg26, 0);
return "`InvertNeg' sample plugin";
}


But, you need two of everything.

EDIT: Wilbert, v2.6 sets AVS_linkage = vectors; in v2.58 case it remains NULL and no Baked Code available from v3 header, CRASH.
v2.5, Needs something similar to whatever sets up vectors for AVS_linkage in Avisynth v2.6 source, AND a new v3 header similar to V5 redirecting via AVS_linkage.
Seems you are planning ahead for planar RGB, but repeated check in GetFrame() seems redundant.

EDIT: Above in red gotta be wrong, unless for v2.5 only (I think).

Wilbert
22nd August 2013, 20:47
But, you need two of everything.
Yes i was afraid of that.

EDIT: Wilbert, v2.6 sets AVS_linkage = vectors; in v2.58 case it remains NULL and no Baked Code available from v3 header, CRASH.
That brings us to the second method
A less brutish solution could be to provide a local static copy of the AVS_linkage for use with a 2.5 core case, hopefully the 2.6 core version of the AVS_linkage is used in the 2.6 code paths. Just needs a little imagination .....

How does this work? How do you provide a local static copy of the AVS_linkage for use with a 2.5 core case?

Seems you are planning ahead for planar RGB, but repeated check in GetFrame() seems redundant.
I'm sure there will be planar RGB one day ;) Yes i know the repeated check is redundant.

StainlessS
22nd August 2013, 20:49
See edit. Could be coded for static linkage.

IanB
22nd August 2013, 23:55
To stop having 2 of stuff you could use the namespace trick the 2.0 import wrapper uses.

Place all the filter generic code into a separate file, "InvertNeg.hpp", and #include it twice. Technically you have 2 copies of everything binary, but only a single source code. Note: outside the namespace you uniquely access object names as avs25::name or avs26::name
/* InverNeg.cpp */

namespace avs25 {

#include "avs25/avisynth.h"

#include "InvertNeg.hpp"

}

namespace avs26 {

#include "avs26/avisynth.h"

const AVS_Linkage *AVS_linkage = 0;

#include "InvertNeg.hpp"

}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env, const avs26::AVS_Linkage* const vectors) {
avs26::AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", avs26::Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", avs25::Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

IanB
23rd August 2013, 00:46
A less brutish solution could be to provide a local static copy of the AVS_linkage for use with a 2.5 core case, hopefully the 2.6 core version of the AVS_linkage is used in the 2.6 code paths. Just needs a little imagination .....
So snaffle and modify a copy of avisynth2/avisynth/src/core/interface.cpp /* Modified Interface.cpp */
....
// 50 #include "stdafx.h"
#include <windows.h>

#define AVISYNTH_CORE // pretend we are avisynth.dll
#include "avisynth.h"

....

// 746 extern __declspec(dllexport) const AVS_Linkage* const AVS_linkage = &avs_linkage;
....


Initialise AVS_linkage to the local copy and set it to the core value in the AvisynthPluginInit3 entry code.
....
const AVS_Linkage *AVS_linkage = &avs_linkage;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env,
const AVS_Linkage* const vectors) {

AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(
IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

StainlessS
23rd August 2013, 01:34
....
const AVS_Linkage *AVS_linkage = &avs_linkage;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env,
const AVS_Linkage* const vectors) {

AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(
IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

dont quite work

interface.cpp

static const AVS_Linkage avs_linkage = { // struct AVS_Linkage {


as static.

MS Docs
When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage
(its name is not visible from outside the file in which it is declared).


Errors:

InvertNeg.cpp
m:\sj\source archive\vc\avisynth filters\25\invertneg\invertneg.cpp(65) : error C2065: 'avs_linkage' : undeclared identifier
m:\sj\source archive\vc\avisynth filters\25\invertneg\invertneg.cpp(65) : error C2440: 'initializing' : cannot convert from 'int *' to 'const struct AVS_Linkage *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


Added to Interface.cpp

extern __declspec(dllexport) const AVS_Linkage* const AVS_linkage_Ptr = &avs_linkage;


and to InvertNeg.cpp

extern __declspec(dllexport) const AVS_Linkage* const AVS_linkage_Ptr;

const AVS_Linkage *AVS_linkage = AVS_linkage_Ptr; // Init for For v2.5


Both Interface.cpp and InvertNeg.cpp compile OK but on linking


Compiling...
interface.cpp
InvertNeg.cpp
Linking...
InvertNeg.obj : error LNK2005: "public: bool __thiscall VideoInfo::IsYUV(void)const " (?IsYUV@VideoInfo@@QBE_NXZ) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: bool __thiscall VideoInfo::IsPlanar(void)const " (?IsPlanar@VideoInfo@@QBE_NXZ) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: int __thiscall VideoFrame::GetPitch(int)const " (?GetPitch@VideoFrame@@QBEHH@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: int __thiscall VideoFrame::GetRowSize(int)const " (?GetRowSize@VideoFrame@@QBEHH@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: int __thiscall VideoFrame::GetHeight(int)const " (?GetHeight@VideoFrame@@QBEHH@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: unsigned char const * __thiscall VideoFrame::GetReadPtr(int)const " (?GetReadPtr@VideoFrame@@QBEPBEH@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: unsigned char * __thiscall VideoFrame::GetWritePtr(int)const " (?GetWritePtr@VideoFrame@@QBEPAEH@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: __thiscall PClip::PClip(class PClip const &)" (??0PClip@@QAE@ABV0@@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: __thiscall PClip::~PClip(void)" (??1PClip@@QAE@XZ) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: __thiscall PVideoFrame::PVideoFrame(class PVideoFrame const &)" (??0PVideoFrame@@QAE@ABV0@@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: __thiscall PVideoFrame::~PVideoFrame(void)" (??1PVideoFrame@@QAE@XZ) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: __thiscall AVSValue::AVSValue(class IClip *)" (??0AVSValue@@QAE@PAVIClip@@@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: __thiscall AVSValue::~AVSValue(void)" (??1AVSValue@@QAE@XZ) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: class PClip __thiscall AVSValue::AsClip(void)const " (?AsClip@AVSValue@@QBE?AVPClip@@XZ) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: __thiscall PClip::PClip(class IClip *)" (??0PClip@@QAE@PAVIClip@@@Z) already defined in interface.obj
InvertNeg.obj : error LNK2005: "public: class AVSValue const & __thiscall AVSValue::operator[](int)const " (??AAVSValue@@QBEABV0@H@Z) already defined in interface.obj
InvertNeg.obj : warning LNK4006: "public: bool __thiscall VideoInfo::IsYUV(void)const " (?IsYUV@VideoInfo@@QBE_NXZ) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: bool __thiscall VideoInfo::IsPlanar(void)const " (?IsPlanar@VideoInfo@@QBE_NXZ) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: int __thiscall VideoFrame::GetPitch(int)const " (?GetPitch@VideoFrame@@QBEHH@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: int __thiscall VideoFrame::GetRowSize(int)const " (?GetRowSize@VideoFrame@@QBEHH@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: int __thiscall VideoFrame::GetHeight(int)const " (?GetHeight@VideoFrame@@QBEHH@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: unsigned char const * __thiscall VideoFrame::GetReadPtr(int)const " (?GetReadPtr@VideoFrame@@QBEPBEH@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: unsigned char * __thiscall VideoFrame::GetWritePtr(int)const " (?GetWritePtr@VideoFrame@@QBEPAEH@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: __thiscall PClip::PClip(class PClip const &)" (??0PClip@@QAE@ABV0@@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: __thiscall PClip::~PClip(void)" (??1PClip@@QAE@XZ) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: __thiscall PVideoFrame::PVideoFrame(class PVideoFrame const &)" (??0PVideoFrame@@QAE@ABV0@@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: __thiscall PVideoFrame::~PVideoFrame(void)" (??1PVideoFrame@@QAE@XZ) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: __thiscall AVSValue::AVSValue(class IClip *)" (??0AVSValue@@QAE@PAVIClip@@@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: __thiscall AVSValue::~AVSValue(void)" (??1AVSValue@@QAE@XZ) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: class PClip __thiscall AVSValue::AsClip(void)const " (?AsClip@AVSValue@@QBE?AVPClip@@XZ) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: __thiscall PClip::PClip(class IClip *)" (??0PClip@@QAE@PAVIClip@@@Z) already defined in interface.obj; second definition ignored
InvertNeg.obj : warning LNK4006: "public: class AVSValue const & __thiscall AVSValue::operator[](int)const " (??AAVSValue@@QBEABV0@H@Z) already defined in interface.obj; second definition ignored
Creating library Debug/InvertNeg.lib and object Debug/InvertNeg.exp
Debug/InvertNeg.dll : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

InvertNeg.dll - 17 error(s), 16 warning(s)

Robert Martens
23rd August 2013, 02:30
Stainless, I think you just need to forward declare avs_linkage to get rid of the "undeclared identifier" message:

...
static const AVS_Linkage avs_linkage;
const AVS_Linkage* AVS_linkage = &avs_linkage;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env, const AVS_Linkage* const vectors)
...

And then take care of the duplicate symbol errors by making sure every inclusion of avisynth.h in your project's files is done with #define AVISYNTH_CORE before it. I hate to dive into the discussion having only just tried this, but that cleared up the build errors for me, and it seems like it works after building and testing in both 2.6 and 2.5.8. I'm open to being smacked upside the head if I'm doing this wrong.

StainlessS
23rd August 2013, 02:42
Tried as in my previous post with additional #define AVISYNTH_CORE,

and with

static const AVS_Linkage avs_linkage;
const AVS_Linkage* AVS_linkage = &avs_linkage;

in InvertNeg (removing the ptr),

both compile and link OK (thought the static forward decalre would fail, but did not) but
provided an access violation error in v2.5.

You are such a tease. :)

EDIT: works after building and testing in both 2.6 and 2.5.8, maybe I did something wrong.

EDIT: Would this not create a second avs_linkage, static in InvertNeg module (whereas the initialized one is static
in Interface module) rather than combining into a single static AVS_Linkage.


static const AVS_Linkage avs_linkage;
const AVS_Linkage *AVS_linkage = &avs_linkage;

Robert Martens
23rd August 2013, 03:12
Would this not create a second avs_linkage, static in InvertNeg module (whereas the initialized one is static
in Interface module) rather than combining into a single static AVS_Linkage.


static const AVS_Linkage avs_linkage;
const AVS_Linkage *AVS_linkage = &avs_linkage;


Yes, I'd think it would; I made the mistake of using "static" when I'd meant "extern", but correcting my code I see that introduces a new set of errors.

Using the approach I rather irresponsibly suggested, though, still seems to work for my own plugin, if only I could decipher why. I can't successfully use InvertNeg, though, so obviously something's wrong with my idea.

I should probably learn C++ one of these days.

StainlessS
23rd August 2013, 03:17
I should probably learn C++ one of these days.

Me too.

Strange but if I try to debug, it does not crash (although output video is weird, with some kind of temporal chroma lead/lag).

EDIT:
Wilbert,
int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};

PLANAR_U(1) and PLANAR_V(2) transposed (should not cause problems though).

EDIT: and ++x; produces better code than x++;although not much in it.

EDIT: The above x++; ++x;
The first one 'x++;' implies for a stack variable, that the variable x is gotten off stack , incremented and then updated
on-stack afterwards. The 2nd '++x;' can increment variable directly on-stack (if possible in assembler instruction set),
rather than doing it post increment.

Robert Martens
23rd August 2013, 06:24
I think I've managed to work this out; my plugin, TurnsTile, was working because I use my own computed tile width and height, and the input videoinfo's width and height members, but never call GetRowSize or GetHeight. It seems that in the 2.58 code those follow the old fashioned approach of assuming U/V pitch and height are equal to half the Y plane pitch and height, respectively. The 2.6 code for both of those functions relies upon the VideoFrame members row_sizeUV and heightUV, which go uninitialized in 2.58 since they don't actually exist in that version. They end up with insane values, which then affect InvertNeg's loop count, leading to access violations.

I came to the conclusion by first following Ian's instructions as he provided them, then doing what I mentioned earlier and adding #define AVISYNTH_CORE before all includes of the header. Next, in the copy of interface.cpp that I swiped from Avisynth, I removed the static and const keywords from AVS_Linkage; apparently each of those implies, among other things, internal linkage, so the object in question won't be visible outside that source file. If this is a bad idea, please do let me know, I suppose in that case we can put the keywords back and just combine interface.cpp with our own code into one source file.

Over in my other source file, where I define the plugininit functions, I did the same as I did a few posts up but with the proper keyword this time:

...
extern AVS_Linkage avs_linkage;
const AVS_Linkage* AVS_linkage = &avs_linkage;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env, const AVS_Linkage* const vectors) {
...

This lets the project build properly, but it still doesn't work, so I just threw a little something into the logic of the filter for testing purposes:

...
row_size = dst->GetRowSize(planes[p]);
height = dst->GetHeight(planes[p]);
if (p == 1 || p == 2) {
row_size = child->GetVideoInfo().width / 2;
height = child->GetVideoInfo().height / 2;
}

for (y = 0; y < height; y++) {
for (x = 0; x < row_size; x++) {
...

The plugin then loads (in 2.58; comment out the blue section for 2.60), and YV12 video is processed as expected. As for the proper way to modify the local copy of interface.cpp to handle this, assuming there is one, I'm still working my way through that.

TurboPascal7
23rd August 2013, 07:54
I'm not sure if someone asked this already, but is there any reason why we can't remove unaligned crop or at least make it optional? I believe it's the only function that might produce unaligned results in 2.6 and I really don't see any reasons to keep it this way. Am I missing something?

Also, any plans on making frames 32-bytes aligned for AVX?

ultim
23rd August 2013, 13:00
I'm hacking around in the AviSynth code, currently mainly familiarizing myself with it, but with ambitious goals. I've already made some progress, and I will probably open a thread for my efforts once I feel confident enough, but now I just have a general question. Given that the "standard/official" AviSynth is single-threaded by nature, why is it littered full with atomic increments and critical sections? Is there some aspect I missed that these are needed?

vcmohan
23rd August 2013, 14:40
The brief was 2.6 would load and support 2.5 plugins, period!

For me I do not want to meddle with Avisynth core. The alternatives suggested possibly produce in one package two plugins one for each version. It will double the size.
I will stick to the mandate and have a cpp file as suggested by stainless in his earlier post.

IanB
24th August 2013, 00:40
I did sayJust needs a little imagination .....so the hacking of Interface.cpp was obviously going to need a little thought and effort apart from the obvious #include's at the top and the extern __declspec at the bottom. All the old 2.5 code is still there in the comments.

In terms of size most plugin code is tiny. Things like fancy tables and runtime libraries usually make up most of the .dll size and these would occur only once. So I would not expect most dual mode plugins to be very much bigger.


@TurboPascal7,

Aligned crop costs an unaligned bitblt, i.e. unaligned read with aligned write in a loop.

For a plugin that does not have an unaligned path and crashes on unaligned reads, then you have no choice.

But for code with a usable unaligned path you are comparing [unaligned read + aligned write + aligned read] with [unaligned read] clearly the second case is faster.

So why do some filters suffer so badly with the unaligned case. Maybe they revert from a fast SSE path to a slow C++ code path, yes that's a bit slack, but maybe an unaligned SSE path won't go fast. More insidious is needing to read the input multiple times then the comparing becomes [1 *unaligned read + 1 * aligned write + N * aligned read] with [N *unaligned read], here the first case pulls ahead as N increases.

As for 32 byte alignment it may become the default in the future, but you have always been able to ask for extra alignment on the env->NewVideoFrame call.

TurboPascal7
24th August 2013, 02:13
@IanB,

The problem is added complexity. By having unaligned crop in the core, you essentially destroy all alignment guarantees said core might provide, asking all developers to add multiple code paths to handle unaligned case, thus making implementation harder (and helping introducing template/macro hell), always using slow unaligned loads or simply break with (https://github.com/chikuzen/TCannyMod/blob/master/avisynth/src/tcannymod.cpp#L139) or without error message. Is marginal performance difference in one filter in some cases worth it? You might make unaligned crop optional so people who think it matters for them could still shoot in their feet, but I don't think it's reasonable.

Strict alignment (16 or even better - 32) guarantee would IMHO simplify a lot of things for developers, especially when plugin is using the same codebase for avisynth and vapoursynth versions (vsynth guarantees 32-bytes alignment). It might be even better to completely ignore alignment parameter in env->NewVideoFrame or make 32 the minimum accepted value, but I'm not sure how many (broken) filters that might break.

Groucho2004
24th August 2013, 02:41
@IanB

I have a question about AVS_Linkage. In the following code, my program crashes (exactly here: "~AVSValue() AVS_BakedCode( AVS_LinkCall(AVSValue_DESTRUCTOR)() )") if the script (test.avs) does not return a clip. However, if I uncomment the line "AVS_linkage = 0" (bold and red in the code) it seems to work OK. Just wondering if setting "AVS_linkage" to 0 is correct in this context.

Or maybe I should just use "ThrowError()" and let Avisynth clean up by itself.


#include "avisynth.h"

const AVS_Linkage *AVS_linkage = 0;

int main()
{
HINSTANCE hDLL = ::LoadLibrary("avisynth");
if (!hDLL)
return -1;

try
{
IScriptEnvironment *(__stdcall *CreateEnvironment)(int) = (IScriptEnvironment *(__stdcall *)(int))::GetProcAddress(hDLL, "CreateScriptEnvironment");
if (!CreateEnvironment)
{
::FreeLibrary(hDLL);
return -1;
}

IScriptEnvironment *AVS_env = CreateEnvironment(AVISYNTH_INTERFACE_VERSION);
if (!AVS_env)
{
::FreeLibrary(hDLL);
return -1;
}

AVS_linkage = AVS_env->GetAVSLinkage();
AVSValue AVSV_main;
AVSV_main = AVS_env->Invoke("Import", "test.avs");

if (!AVSV_main.IsClip()) //not a clip
{
//AVS_linkage = 0;
AVSV_main = 0;
AVS_env->DeleteScriptEnvironment();
::FreeLibrary(hDLL);
return -1;
}
}
catch(AvisynthError err)
{
}

::FreeLibrary(hDLL);

return 0;
}

IanB
25th August 2013, 00:09
If we look under the covers of the baked macros :-# define AVS_BakedCode(arg) { arg ; }
# define AVS_LinkCall(arg) !AVS_linkage || offsetof(AVS_Linkage, arg) >= AVS_linkage->Size ? 0 : (this->*(AVS_linkage->arg))
We see :-
~AVSValue() AVS_BakedCode( AVS_LinkCall(AVSValue_DESTRUCTOR)() )
which becomes after we unwrap AVS_BakedCode :-
~AVSValue() { AVS_LinkCall(AVSValue_DESTRUCTOR)() ; }
and finally becomes :-
~AVSValue() {
!AVS_linkage
||
offsetof(AVS_Linkage, AVSValue_DESTRUCTOR)()) >= AVS_linkage->Size
?
0
:
(this->*(AVS_linkage->AVSValue_DESTRUCTOR)()));
}
and if we follow the function pointer :-
void AVSValue::DESTRUCTOR() { if (IsClip() && clip) clip->Release(); }
So I find it a little strange the crash report is on the link call itself rather than in the actual code, but that may be a lack of symbols thing with the debugger.

Of course setting AVS_linkage = 0 cause the code to be skipped, so what ever is wrong is ignored.

I suspect your problem may be earlier with AVSV_main not being constructed correctly :-

AVS_linkage = AVS_env->GetAVSLinkage();
AVSValue AVSV_main;
AVSV_main = AVS_env->Invoke("Import", "test.avs");

it depends on the order the compiler does things, but I suspect AVSV_main tries to get made with AVSValue::CONSTRUCTOR0() before AVS_linkage gets assigned.

So setting AVS_linkage back to zero before the ::FreeLibrary is the right thing to do, but setting it to zero before all the classes are finished is not right. Just like trying to start classes is not right before you initially set AVS_linkage.

I think we need some notes about lifetime and scope of things needing a valid AVS_linkage.

Groucho2004
25th August 2013, 00:30
So setting AVS_linkage back to zero before the ::FreeLibrary is the right thing to do, but setting it to zero before all the classes are finished is not right.
Thanks Ian. I now tested these 2 options:
if (!AVSV_main.IsClip()) //not a clip
{
AVSV_main = 0;
AVS_env->DeleteScriptEnvironment();
AVS_linkage = 0;
::FreeLibrary(hDLL);
return -1;
}

if (!AVSV_main.IsClip()) //not a clip
AVS_env->ThrowError("Script did not return a video clip");

Both let the program (a function actually) exit without crashing. I guess I'll use the former.

Edit: Static linking with avisynth.lib also works fine.

vcmohan
28th August 2013, 14:10
The windows 32 bit dll is dated jan 2013. Since then a number of changes/ corrections were done. Will it be possible to update the dll and make available for down load?

StainlessS
28th August 2013, 20:16
vcmohan,
See Grouch02004 ICL compiler version v2.6a4 with updates, current April 25 2013, works great. :)
You just need install v2.6a4 and overwrite dll in system32 (SysWOW64 64bit) with the new dll.

http://forum.doom9.org/showthread.php?t=167358

Robert Martens
29th August 2013, 01:03
Ian, I wonder if you'd be so kind as to offer a little more help regarding your idea for the dual-host plugin as described here:

Initialise AVS_linkage to the local copy and set it to the core value in the AvisynthPluginInit3 entry code.
....
const AVS_Linkage *AVS_linkage = &avs_linkage;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env,
const AVS_Linkage* const vectors) {

AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(
IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

I've spent the past few days going over C++ books, websites, Stack Overflow posts, basically all the reference material I could get my hands on, digging further into function pointers than I ever thought I would, along with inheritance and a variety of other related topics, but I feel like I'm going around in circles.

Including the Avisynth header with AVISYNTH_CORE defined means the linkage macros evaluate to nothing, so all the header contains are function declarations. I'm then free to implement them as I see fit in interface.cpp. That's great for 2.5, but loading the plugin in 2.6 shows that it uses those same local implementations, since the various methods aren't defined to call AVS_linkage and get the appropriate function pointers from the core.

Trying to include the header twice (once in interface.cpp with AVISYNTH_CORE defined, and once in invertneg.cpp without it) just ends up defining the functions twice, which won't work, and I spun my wheels in the mud playing around with derived classes, friend functions, and function pointer casts only to find myself back where I started.

The only answer I could come up with involves initializing AVS_linkage to zero, and then making every function in my copy of interface.cpp look like this (after copying some of the macro code into the file so it'll evaluate to code calling the function pointer):


bool VideoInfo::HasVideo() const
{

if (AVS_linkage) {
return AVS_LinkCall(HasVideo)();
} else {
return (width!=0);
}

}

As seen above, however, you suggested initializing AVS_linkage differently, so I'm fairly sure this isn't what you had in mind. Would you by any chance be able to give me a hint where I should go next? I don't expect you to teach me remedial C++, or walk me through the intricacies of the Avisynth codebase, but a nudge in the right direction would be a big help; maybe just the names of the C++ or general programming concepts I'd need to study to solve the problem the way you intended?

StainlessS
29th August 2013, 02:12
Mucho admiration that you seem to be pursuing this, thought it might better be in the domain of a CPP progger, (me given up),
Hope Mr B gives you an audience.

IanB
29th August 2013, 06:31
A solution to the functions defining twice is to wrap one instance in a namespace, then they become distinct. This is pretty much how the first brute solution gets around the same problem of duplicate names.

I did warn that some imagination would be required.
namespace Interface {
/* Modified Interface.cpp */
....
// 50 #include "stdafx.h"
#include <windows.h>

#define AVISYNTH_CORE // pretend we are avisynth.dll
#include "avisynth.h"

....

// Old 2.5 version of code
int VideoFrame::GetHeight(int plane) const {
switch (plane) {
case PLANAR_U:
case PLANAR_V:
if (pitchUV)
return height>>1;
return 0;
}
return height;
}
/* int VideoFrame::GetHeight(int plane) const {
switch (plane) {
case PLANAR_U:
case PLANAR_V:
if (pitchUV)
return heightUV;
return 0;
}
return height;
}*/

....

// 746 extern __declspec(dllexport) const AVS_Linkage* const AVS_linkage = &avs_linkage;
....
}
And of course you need to reference the namespace version of thing in Interface.cpp
...
const AVS_Linkage* AVS_linkage = &Interface::avs_linkage;
...

ultim
29th August 2013, 15:40
In the definition of the ScriptEnvironment::NewPlanarVideoFrame method, what is the point of letting plugins force a smaller alignment than the default? Anything else than those very few bytes of memory savings?

Chikuzen
29th August 2013, 22:44
From core/parser/script.cpp

AVSValue Import(AVSValue args, void*, IScriptEnvironment* env)
{
...
TCHAR full_path[MAX_PATH];
TCHAR* file_part;
if (strchr(script_name, '\\') || strchr(script_name, '/')) {
DWORD len = GetFullPathName(script_name, MAX_PATH, full_path, &file_part);
if (len == 0 || len > MAX_PATH)
env->ThrowError("Import: unable to open \"%s\" (path invalid?)", script_name);
} else {
DWORD len = SearchPath(NULL, script_name, NULL, MAX_PATH, full_path, &file_part);
if (len == 0 || len > MAX_PATH)
env->ThrowError("Import: unable to locate \"%s\" (try specifying a path)", script_name);
}
...

Although Windows API can handle MAX_PATH(260) characters(not bytes) as filepath, 'Import' causes an error by about 130 non-ASCII characters by shortage of a buffer.
(Generally, non-ASCII characters require 2bytes on ACP.)
I think that 'TCHAR full_path[MAX_PATH]' should be changed into 'TCHAR full_path[MAX_PATH * 2]'.

IanB
29th August 2013, 22:58
@ultim,

Forcing alignment is generally for setting a PVideoFrame to describe an existing foreign video buffer layout. This can avoid an unnecessary copy of the data. e.g. a source filter to match the memory layout delivered by a codec, or matching the memory layout of a hardware device.

Setting some pointers and a few describing numbers is of order a million times faster than actually copying the data bytes. TurboPascal7 above was advocating always making Crop that million times slower for the sake of always maintaining memory alignment.

IanB
29th August 2013, 23:21
@Chikuzen,

Not sure how you this is coming unstuck here, dumb ansi code page encoding was unimaginatively designed with 1 char is 1 byte. When (If) we move to UTF-8 then some code points can be up to 4? bytes so we will certainly need to cope with it then. Do you have a specific ansi code page in mind that exceeds this crippled design, one of the Japanese sets maybe?

I can certainly bump the buffer size, I just want to be able to make sure some internal library buff[MAX_PATH] is still not going to crash and burn.

Chikuzen
29th August 2013, 23:54
Do you have a specific ansi code page in mind that exceeds this crippled design, one of the Japanese sets maybe?
yes, I consider about CP932 (http://en.wikipedia.org/wiki/Code_page_932) .
I don't know which code page is used in China, Korea, Vietnam,etc...it will be the same since tens of thousands of characters are used in East Asia.
it will be better to make it MAX_PATH * 4, of course.
Stack overflow does not happen only 1KB array.

ultim
30th August 2013, 13:07
@ultim,

Forcing alignment is generally for setting a PVideoFrame to describe an existing foreign video buffer layout. This can avoid an unnecessary copy of the data. e.g. a source filter to match the memory layout delivered by a codec, or matching the memory layout of a hardware device.

Setting some pointers and a few describing numbers is of order a million times faster than actually copying the data bytes. TurboPascal7 above was advocating always making Crop that million times slower for the sake of always maintaining memory alignment.

Thanks for your help. I understand your reasoning, but the situation you described does not fully apply here, as far as I can tell. Because NewPlanarVideoFrame/NewVideoFrame always request a VideoFrame with an internal VideoFrameBuffer as a backing store (either a new one or a cached one, but always an internal one). So the existing foreign buffer that needs to be mimicked must still be copied over anyway. And in that case we might as well request a buffer with the highest alignment, so that future filters can employ special instruction sets.

Also, another thing that for me seems to invalidate your argument, is that to completely mimic a foreign buffer, you also need to mimic its pitch. NewPlanarVideoFrame/NewVideoFrame do not take pitch as an argument, so by method declaration it is impossible to use these methods to always describe an external buffer correctly. Internally these methods use rowsize and align to "guess" the pitch, but that won't always work and you're just relying on luck.

Here is an example where guessing the pitch as now won't work:
- foreign buffer rowsize is mod8/mod4/mod2/odd
- foreign rowsize = foreign pitch
- requesting alignment on 16 byte boundary
Here, because rowsize=pitch, rows after the 1st will not be 16-byte aligned, but it still makes sense to accelerate processing (e.g with SSE) if neighboring pixels are independent of each other (e.g. brightness/exposure adjustment, or simple recoloring techniques). Yet, the current methods will calculate a pitch that is mod16, so you can't describe the foreign buffer at all.

So, to summarize my points,
- because the method declarations are inadaquate to describe foreign video correctly in every case
- and because these methods will always use an internal backing store for the frame anyway, thus a copy must always be made ...
... even after your previous explanation, I still think that in these methods it doesn't make sense to force small alignments (using a negative alignment value). It only hinders later processing filters.

I hope I didn't embarass myself by writing something stupid in this long post :)

IanB
30th August 2013, 23:42
@ultim, It's not a perfect system but it serves what has been required so far.

Clarification :- The start of first line of the video frame is always 16 byte aligned! The "align" value only determines how the "pitch" is calculated from the "rowsize"....
const int pitch = (row_size+align-1) / align * align;
...
const int offset = (-int(vfb->GetWritePtr())) & (FRAME_ALIGN-1); // align first line offset
...

ultim
31st August 2013, 23:12
...
const int pitch = (row_size+align-1) / align * align;
...
const int offset = (-int(vfb->GetWritePtr())) & (FRAME_ALIGN-1); // align first line offset
...

Yes I know, that is what I meant when I said 'these methods use rowsize and align to "guess" the pitch'. I made changes to avisynth already, and I am also trying to correct this shortcoming of "align usage". Unfortunately I had to realize at some point that it is impossible to correct this in a sane way without breaking ABI compatibility. Currently, it seems at the very least I'd need to change the constructor parameters to VideoFrameBuffer, which broke at least the ffms2 plugin :( So I am still thinking about how to improve this aspect without too much trouble.

I forked avisynth locally and I'm making various "improvements". I have a variety of changes ranging from bugfixes and performance improvements, to improving developer friendliness, adding new functionality, and interface extensions in a backwards-compatible way (using COM rules ofc). I'll push my code to GitHub at some later point. I'm afraid you won't like many of them, coz I also restructured the project, moved files and code around and cleaned up header files. These add a LOT of noise to the commits, but thanks to these I feel the code is much less scary for newcomers (so I hope more contributors will show up), and I also reduced compile time by more than 50% (half!).

Anyway, thanks for your help, and I'm pretty sure I'll come back for more :)

IanB
31st August 2013, 23:49
@ultim,

There is no "guess". It is the Avisynth API definition of pitch.

What is there to improve? The API does not mandate alignment, it's historical. Recent caveats do strongly suggest that performance critical memory addresses should be appropriately aligned such that fast code paths are possible, but code must work correctly (but it is allowed to be slow) with what is provided. It is not acceptable to chuck an exception or other wobbly at runtime just because something is not aligned as you would like. It is however acceptable to throw the exception at script load time.


If you have bugs, Report them!

ultim
1st September 2013, 00:33
There is no "guess". It is the Avisynth API definition of pitch.

Well, to understand my problem, you have to keep in perspective my original issue: what the use of forced alignment is. You told me it is to mimic external buffers. Fair enough, except that now you define pitch using alignment, and external code (except for avisynth filters) will not. So you shouldn't be using alignment as pitch, OR you shouldn't be able to force it.

What is there to improve?
Exactly what I just described a line before.

If you have bugs, Report them!
From the top of my head, I have three things on my fixed-list as of now.
- Messed up SEH+C++ exception interoperation, which borkes under many compilers. Fixed.
- A frame number clamping issue in ComparePlane::CmpPlaneSame, which requires already faulty input parameters to actually manifest, so no big deal, very minor. And actually, because I have not taken the time to properly understand that function, I am only 99% sure it is a bug to begin with, but reasonably sure. Fixed.
- Two BitBlt errors. This is the "funniest" one of all, one correctness error, and another one which prevents it from manifesting but causes performance degradation, both fixed. Unfortunately I have only recently found out that some external plugins (TIVTC at least) already rely on the buggy behavior (darn!), so this cannot be fixed anyway without breaking some plugins. Not good. Which means I will probably revert this change and add the corrected version in a new interface, but I'm still thinking about the best way to handle such cases. Fixing the plugins themself is actually also an option, coz some changes that I'm planning for the future are gonna make that necessary anyway.

See, except maybe for CmpPlaneSame, your are either not affected, or no-fix-possible. So pls don't go all red on me. Also, as you see, I fix anything that I find, so reporting bugs becomes an extra (and tbh somewhat needless) hassle for both you and me when I'm gonna publish the fix anyway. I'm not gonna keep them to myself, don't worry, I'm also working on the code for others, just like you.

Robert Martens
1st September 2013, 06:14
I did warn that some imagination would be required.

I completely understand the value of "exercises left to the reader", as they say, and I'd even go so far as to say I enjoy them. It feels good to figure things out for oneself. At a certain point, however, my imagination gets tapped out, and the options are either ask for help or give up and walk away. I felt the former would be more productive, and possibly more helpful to others.

Thank you for the namespace advice, I'd toyed with that briefly but only around a few functions, not the entire file. I'm not having much luck with it so far, but I'll keep at it and see if I can get anywhere.

In the meantime, I felt I should share what my imagination has gotten me so far, so I put up a Gist with my changes: https://gist.github.com/ItEndsWithTens/6402453 The changes are summarized at the top of interface.cpp. I didn't include a project, just to keep this lightweight, but you should be able to just add the three files to your own and build it without too much hassle.

I can't promise it's the best solution (adding those branches to each function will no doubt have some performance impact), but I'm tentatively confident that it's at least working, so if anyone would like to take a look, or correct my thinking, feel free. If I ever manage a cleaner approach, I'll commit it to the Gist and make a note here.

IanB
2nd September 2013, 09:17
@Robert Martens,

I think your main difficulty was not grasping there needs to be 2 distinct API instances. One AVS_Linkage based standard 2.6 API in the InvertNeg.cpp filter and a second 2.5 API stand in from the modified interface.cpp, this second API stand in of course needs to be in a separate namespace so this implementation does not conflict with the first AVS_Linkage based implementation.

Robert Martens
2nd September 2013, 14:50
I think your main difficulty was not grasping there needs to be 2 distinct API instances.

That actually did get through to me, I understood what you meant when you offered the broad overview of "create a static copy of the linkage and initialize with that"; I didn't understand how to do that, though. That namespaces were the solution didn't occur to me, and once you mentioned that I tried it only to run into problems (which I'll get to presently). The code I posted as a Github gist is merely my desperate, last ditch effort to find a solution that offered one copy of the source code, and one copy of everything binary. Since I couldn't figure out how to do what you'd suggested, I wanted to at least find some way to make it work.

I was confused primarily because I was never sure what exactly was expected of me. You don't owe me your time, and I don't like to say these things for fear of seeming a belligerent ingrate, but I had trouble understanding your posts when you first suggested this, with regard to InvertNeg.cpp:

....
const AVS_Linkage *AVS_linkage = &avs_linkage;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env,
const AVS_Linkage* const vectors) {

AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(
IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

Then went on to mention the namespace solution, clarifying the initialization to this:

...
const AVS_Linkage* AVS_linkage = &Interface::avs_linkage;
...

Before coming to the end result which in your sample project turns out to be:

const AVS_Linkage* AVS_linkage = 0;

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env, const AVS_Linkage* const vectors) {
AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

namespace AVSInterface25 {

const AVS_Linkage* AVS_linkage;

}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
AVS_linkage = AVSInterface25::AVS_linkage;
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

I've always operated under the assumption that when you, or anyone else on these boards, describe things in only broad strokes, we're expected to put our minds to it and discover the answer ourselves, but when you offer specific lines of code, they are to be treated as sacrosanct and left untouched. We may have to add to them to complete the solution, but we're not meant to meddle in what specific details were already spelled out. I only reached the solution I posted earlier by hesitantly changing your directions, in a flailing, grasping-at-straws desire to get anything that worked; I certainly wasn't comfortable abandoning your instructions. In the future I'll try to be more flexible in my problem solving.

Unfortunately, although VC6 works as expected, I'm having trouble with your sample in my usual environment of Visual Studio 2010 Express; building the project spits out a series of errors related to sourceannotations.h, the first of which is

sourceannotations.h(244): error C3083: 'vc_attributes': the symbol to the left of a '::' must be a type

Including Windows.h inside the namespace seems to be the issue here. Moving the include out of it solves that problem, but introduces a new one:

crtdbg.h(1064): error C2039: 'delete[]' : is not a member of '`global namespace''

Since the crtdbg header is only included inside avisynth.h, I'm left believing the only option would be modifying the Avisynth header, but I'm not entirely sure what I should do, or that I even should be doing something so intrusive. I could always pull the crtdbg/debug macro definition block out of the header and add it by hand to all my source files, but that seems ugly. Is it my only option?

IanB
2nd September 2013, 23:04
Okay more than fair enough, you got the concept, just your SDK is putting up a fight about how to make it work.

I find it very hard to describe this sort of stuff without resorting to "loose" code examples, generally code snippets I use for discussion should be treated as definitely untested and probably requiring some sort of context.

Looks like I underestimated the amount of sugar that was going to be needed here. As you note I gave up on this actual construct :-const AVS_Linkage* AVS_linkage = &Interface::avs_linkage;I tried to make that idea fly for a full 5 minutes and replaced it with this :-namespace AVSInterface25 {
const AVS_Linkage* AVS_linkage;
}
.....
AVS_linkage = AVSInterface25::AVS_linkage;
.....and yes I got that "is not a member of '`global namespace''" old flannel from the compiler along the way. You just have to keep punching away until you find a syntax that represents the idea and will actually compile.

Not sure about the sourceannotations.h(244), maybe some "LEAN_AND_MEAN" declarations can help.

Pier
3rd September 2013, 11:25
I was wondering if it was possible to add an ,int "offset" to ConditionalReader in the next version to replace the offset value in the txt file, i mean, for example, if have written varius .txt files with varius kind of data to make something like IsSectionStatic() i would need to write a very large ammount of .txt files for every frame with a different offset value, but if could just use an int "offest", a recursion would allow me to check all the frames until the next scenechange and some other nice thing.

Wilbert
3rd September 2013, 22:08
I thought let's try the second brute force method again (with InvertNeg.hpp as you posted; and changed red parts):


/* InvertNeg.cpp */

#include <windows.h>

namespace avs25 {
#include "avisynth25.h"
#include "InvertNeg.hpp"
}

namespace avs26 {
#include "avisynth26.h"
const AVS_Linkage *AVS_linkage = 0;
#include "InvertNeg.hpp"
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(avs25::IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", avs25::Create_InvertNeg, 0);
return "InvertNeg sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(avs26::IScriptEnvironment* env, const avs26::AVS_Linkage* const vectors) {
avs26::AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", avs26::Create_InvertNeg, 0);
return "InvertNeg sample plugin";
}


If I only keep the avs25 sections (including the namespace) it works. If I only keep the avs26 sections (including the namespace) it works. But keeping both, just as above, when compiling i get the errors:

Compiling...
InvertNeg.cpp
F:\CompilingPlugins\InvertNeg\InvertNeg.cpp(11) : error C2143: syntax error : missing ';' before '*'
F:\CompilingPlugins\InvertNeg\InvertNeg.cpp(11) : error C2734: 'AVS_Linkage' : const object must be initialized if not extern
F:\CompilingPlugins\InvertNeg\InvertNeg.cpp(11) : error C2501: 'AVS_linkage' : missing storage-class or type specifiers
F:\CompilingPlugins\InvertNeg\InvertNeg.hpp(2) : error C2504: 'GenericVideoFilter' : base class undefined
F:\CompilingPlugins\InvertNeg\InvertNeg.hpp(4) : error C2629: unexpected 'class avs26::InvertNeg ('

etc ... No idea why it doesn't work. Btw line 11, is the const AVS_Linkage *AVS_linkage = 0; line.

Robert Martens
5th September 2013, 00:44
Wilbert, I think that's the include guard you're bumping up against. Both versions of the Avisynth header define the same name, and you're including them both in the same file. If you just undefine it between your namespace blocks you should avoid the problem:

namespace avs25 {

#include "avs25/avisynth.h"

#include "InvertNeg.hpp"

}

#undef __AVISYNTH_H__

namespace avs26 {

#include "avs26/avisynth.h"

const AVS_Linkage *AVS_linkage = 0;

#include "InvertNeg.hpp"

}


On the topic of the method Ian and I had been discussing, the problem seems to be that sourceannotations, when __cplusplus is defined, creates a namespace called "vc_attributes", then ends up using the scope resolution operator to assume it's directly under the global namespace, i.e. ::vc_attributes. Wrapping the include of that file in our own namespace means the full name ends up being ::AVSInterface25::vc_attributes, and the code in that header can't find anything. The same goes for crtdbg.h.

A little further digging with the /showIncludes switch (in VS2010 it's under Properties->C/C++->Advanced->Show Includes) shows that the aforementioned problem header is being pulled in by way of windows.h->excpt.h->crtdefs.h->sal.h->codeanalysis\sourceannotations.h.

The file's inclusion in sal.h is wrapped with this:

#if defined(_MSC_EXTENSIONS) && !defined( MIDL_PASS ) && !defined(__midl) && !defined(RC_INVOKED)

My brief research leads me to think those are of no use, though I suppose if push came to shove one could always use RC_INVOKED to pretend the resource compiler is active. Of course, even if you manage to avoid including the file, what happens to the rare bird who wants to use source code annotation? Academic, maybe, but the thought crossed my mind.

In any event, I finally got around to toying with VS 2012 Express, and it has no problems with the code, even with both includes under a custom namespace. Personally I don't mind switching, despite the disappointing Metro UI, but I'm still curious to see if I can come up with a solution for 2010. I'll keep at it.

Wilbert
6th September 2013, 22:06
Wilbert, I think that's the include guard you're bumping up against. Both versions of the Avisynth header define the same name, and you're including them both in the same file. If you just undefine it between your namespace blocks you should avoid the problem:
Yes that works fine. Thanks!

Robert Martens
7th September 2013, 20:12
Ian, I'm sorry to say that although I got your version of the project to build successfully, I realized I'd never actually tried to use it in 2.5.8. I gave it a shot a short while ago, only to see everyone's favorite "System Exception: Access Violation" message. Stepping through the code with the debugger showed that the assignment in AvisynthPluginInit2 wasn't actually taking effect, for some reason that still escapes me.

There is nonetheless what I've convinced myself is excellent news! Find at the Github Gist (https://gist.github.com/ItEndsWithTens/6402453) a new version of the code, more in keeping with your original idea. Again, the changes to interface.cpp from revision 1.13 of that file are summarized at the top, but to explain what I did in relation to our discussion so far:

I was off base regarding VS 2012 before; the inclusion of sourceannotations.h appears to occur under different criteria than in 2010, but the file is still there, and may still cause problems for anyone using that functionality. crtdbg.h seems more robust, in that although operator delete and operator delete[] are declared in the file, they are no longer defined there as in 2010.

That's only in Visual Studio 2012, of course, so to account for both of those issues in all compiler/SDK versions, in interface.cpp I kept the inclusion of Windows.h out of the namespace (thereby addressing sourceannotations) and pilfered the debug macro definition from avisynth.h. Contrary to my earlier muddled expectation, this only needs to be done in interface.cpp, since it's the only place we're wrapping the header in a namespace. Placing the include of crtdbg and assert.h outside the namespace has the added benefit that if you ever use anything else in that file that expects to find the assert features, it'll work properly (I ran into that myself with avxsynth (https://github.com/avxsynth/avxsynth/issues/99)). I took the liberty of commenting out the _RPTX macros to avoid warnings about their redefinition, since I know the header will always be there to define them if _MSC_VER is undefined.

I then made avs_linkage non-static and non-const, so it's visible outside interface.cpp.

Over in invertneg.cpp, I made everything below Create_InvertNeg look like this:

namespace AVSInterface25 {

struct AVS_Linkage;
extern AVS_Linkage avs_linkage;

}

const AVS_Linkage* AVS_linkage = reinterpret_cast<AVS_Linkage*>(&AVSInterface25::avs_linkage);

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(
IScriptEnvironment* env, const AVS_Linkage* const vectors) {
AVS_linkage = vectors;
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
env->AddFunction("InvertNeg", "c", Create_InvertNeg, 0);
return "`InvertNeg' sample plugin";
}

I found the cast necessary to allow the initialization. reinterpret_cast is ugly, but it expresses what we're doing more clearly than a C-style cast, and although it's a dangerous cast to develop the habit of using, in this case we know the two structures are identical, differing only by one's existence in a namespace.

How does this approach strike everyone?

vcmohan
9th September 2013, 02:14
When the input video is not planar format, GetWidthSubsampling() and GetHeightSubsampling() give an error message while GetReadPtr or GetPitch and other calls do not. Why this special treatment?

IanB
9th September 2013, 03:27
New code enforces correctness, old code a little bit slack.

Also GetPlaneWidth/HeightSubsampling are members of VideoInfo and do not have a useful value to return on error. (0 is no subsampling, -1 --> times 2 super sampling, 1 --> times 2 subsampling)

And GetReadPtr, GetPitch are members of VideoFrame and can usefully return zero for non existent planes.

StainlessS
9th September 2013, 17:30
@VcMohan

As you recently posed a query on compiling for both v2.58 and v2.6a4, I assume that you want subsampling for both.
Below some code I use in RoboCrop, perhaps of use:

myName="RoboCrop: ";

if(vi.width==0 || vi.num_frames==0) env->ThrowError("%sClip has no video",myName);
# ifdef AVISYNTH_PLUGIN_25
if(vi.IsPlanar() && vi.pixel_type != 0xA0000008) { // Planar but NOT YV12, ie Avisynth v2.6+ ColorSpace
// Here Planar but NOT YV12, If v2.5 Plugin Does NOT support ANY v2.6+ ColorSpaces
env->ThrowError("%sColorSpace unsupported in v2.5 plugin",myName);
}
# endif

bool isyuv=false,isplanar=false,isyuy2=false,isrgb=false,isy8=false;
int xmod=1,ymod=1;

if(isyuv=vi.IsYUV()) {
if(isplanar=vi.IsPlanar()) {
PVideoFrame src = child->GetFrame(0, env); // get frame 0
int rowsizeUV=src->GetRowSize(PLANAR_U);
if(rowsizeUV!=0) { // Not Y8
const int ywid=src->GetRowSize(PLANAR_Y);
const int yhit=src->GetHeight(PLANAR_Y);
const int uhit=src->GetHeight(PLANAR_U);
xmod=ywid/rowsizeUV;
ymod=yhit/uhit;
} else {
isy8=true;
}
} else {
isyuy2=true;
xmod=2;
}
} else {
isrgb=true;
}

xSubS=xmod; // for Planar GetFrame
ySubS=ymod;

laced = args[3].AsBool(true);
ymod = (laced)? ymod*2 : ymod;


v2.58 header does not contain GetWidthSubsampling/GetHeightSubsampling :helpful:

martin53
9th September 2013, 21:46
Please forgive me if I'm wrong or if the issue is already known - I couldn't find a similar post.

I suspect a 'memory leak' in the ConvertToYV24() function of V2.60.
I load the test script
ColorBars()
#~ ConvertToYV24()
ScriptClip("return last")
with XMediaRecode and observe its memory usage with ProcessExplorer. While converting the script to a HuffYuv AVI file, XMediaRecode's memory usage stays constant btw. 87 and 90 MBytes.
With the uncommented ConvertToYV24() Line, memory usage grows and grows. With more complex scripts (a ~15 line scriptclip that overlays 4 lines calculated with RTE stats functions over a Histogram("color2") :( ), the encoder crashes when memory usage reaches about 1,8MBytes.
VDub Portable (1.9.11) also crashes with a message "Think we ran out of memory folks".
OS details in this thread (http://forum.doom9.org/showthread.php?t=168538)

EDIT: This is the crash script. Omit 'ConvertToYV24()', then it uses about 560MB, not more.
#=====================================================================================================================
function UVMeterBad(clip c) {
c
ScriptClip(""" #"
c = Last
c1 = c.crop(0,0,-256,0)
cU = c1.UToY.BicubicResize(c1.width, c1.height)
cV = c1.VToY.BicubicResize(c1.width, c1.height)
MYStats(cU, flgs=$23)
Um= MYS_yMin #cU.RT_YPlaneMin()
Ux= MYS_yMax #cU.RT_YPlaneMax()
Us= round(MYS_yStdev) #round(cU.RT_YPlaneStdev)
MYStats(cV, flgs=$23)
Vm= MYS_yMin #cV.RT_YPlaneMin()
Vx= MYS_yMax #cV.RT_YPlaneMax()
Vs= round(MYS_yStdev) #round(cV.RT_YPlaneStdev)
Ymax = c1.YPlaneMax()
MYStats(cU, c1, flgs=$10, prefix="MUS_", MaskMin=Ymax-1)
MYStats(cV, c1, flgs=$10, prefix="MVS_", MaskMin=Ymax-1)
c
Overlay(BlankClip(c,pixel_type="RGB32",color=$80ff00,width=57,height=1),x=c.width-157,y=127,mode="Exclusion") #cross hor.
Overlay(BlankClip(c,pixel_type="RGB32",color=$80ff00,width=1,height=57),x=c.width-129,y=99,mode="Exclusion") #cross vert.
Overlay(BlankClip(c,pixel_type="RGB32",color=$ffffff,width=Ux-Um,height=1),x=c.width-129+Um-128,y=127+round(MVS_yAve)-128,mode="Exclusion") #range hor.
Overlay(BlankClip(c,pixel_type="RGB32",color=$ffffff,width=1,height=Vx-Vm),x=c.width-129+round(MUS_yAve)-128,y=127+Vm-128,mode="Exclusion") #range vert.
return last
""", local=true) #"
return last
}
#=====================================================================================================================
ColorBars(pixel_type="YV12")
ConvertToYV24()
Histogram("color2")
UVmeterBad()

Groucho2004
9th September 2013, 22:16
ColorBars()
#~ ConvertToYV24()
ScriptClip("return last")
I can't reproduce this with the given script. I loaded it into VDub and encoded also to HuffYUV. Memory usage settles at about 140K. OS is XPSP3.

Groucho2004
9th September 2013, 22:33
This is the crash script.
Script error: ScriptClip does not have a named argument "local"

StainlessS
9th September 2013, 22:37
@Martin53,
There is a known Overlay bug in v2.6a4, here:
http://forum.doom9.org/showthread.php?p=1624303#post1624303

Use Groucho2004's ICL Avisynth.dll with fixed OverLay for YV24. (just overwrite dll in sytem32/SysWOW64)

EDIT: Groucho, Local is for the GScript version Scriptclip. EDIT: Actually Grunt, not Gscript.

martin53
9th September 2013, 22:38
I can't reproduce this with the given script.
Did you remove the comment marks?

Groucho2004
9th September 2013, 22:43
Groucho, Local is for the GScript version Scriptclip.
Ah, I see.

martin53
9th September 2013, 22:44
Use Groucho2004's ICL Avisynth.dll
Please give me a hint where I find this dll.

Groucho2004
9th September 2013, 22:46
Please give me a hint where I find this dll.
Here you go. (http://forum.doom9.org/showthread.php?t=167358)

StainlessS
9th September 2013, 22:49
Groucho, see here for recent nasty little problem concerning GScript Local solution. EDIT: Actually Grunt, not Gscript.
http://forum.doom9.org/showthread.php?t=168538

martin53
9th September 2013, 22:49
yes, I did.
OK, I also rechecked in parallel and found after the 1st post that some of my experiments stabilized, so what I had assumed to be bad was not always. I always try to give a most simple example, but alas, that misleads me sometimes. Please look at my edit, but StainlessS already posted that it's not ConvertToYV24() alone, but together with Overlay() - as in my real problem script. So, if you'd be so kind to indicate where I can find the fixed dll, thank you!

martin53
9th September 2013, 22:52
Here you go.Many thanks!

Gavino
9th September 2013, 22:52
Local is for the GScript version Scriptclip.
Actually, it's from the GRunT version.

But I expect you can just leave out local=true as I doubt it has anything to do with the problem.

EDIT: Looks like you've now found the solution anyway.

StainlessS
9th September 2013, 22:53
OOooops, yes of course. :(

vcmohan
10th September 2013, 03:37
@stainless .Thanks. But I avoided the hassle by adding three calls in avisynth.h 2.5. IsY8() returning false, GetHeight/width subsampling returning 0 or 1. At parameter checking itself I ensure the input formats . In my plugin code I do not by name check any other Planar formats.

ultim
12th September 2013, 20:17
Hello, I've got another question about the alignment code, this time though it is purely technical and not ideological :)

In both NewVideoFrame and NewPlanarVideoFrame, assuming that we need a buffer of size large, the methods reserve size+align*4. For alignment only, size+align-1 is enough, so I was wondering if this overreserve is accidential, or it this on purpose and the align*4 is needed for some implementation detail that I was too stupid to spot.

Contextual information (rant): You might be thinking,"WUUT, this strange dude is still working on alignment?" Yes and no. Well, first of all I cannot allow myself to work on avisynth every day, so progress is steady, but slow. But more importantly, since my last questions about alignment in avisynth I have done a lot of magic (many-many hours) using Git's rebase to clean up my repository, in the hope that upstream (IanB) will accept my proposals this way, when I finally publish them. So that he'll get nice patches :) Now that I'm done, I'm continuing where I left off, which is (yeah you guessed right) alignment. It looks like I am reverting about 99.9% of my alignment patches, but I still like to understand things even if I don't modify them, which is why I'm asking the question in the beginning of this post. Cheers and thank you for your help!

IanB
12th September 2013, 22:54
The off hand answer is so you can run off the end safely with an sse load or store, but as you say size+align-1 would be sufficient. So I don't know, may be you can do some archaeology and find an answer. Here is a link to version 1.1 of Avisyntn.cpp, Thu Jul 4 13:16:41 2002 UTC (11 years, 2 months ago) by richardberg (http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/avisynth.cpp?hideattic=0&revision=1.1&view=markup) as originally supplied by BenRG. Around version 1.9 Sh0dan started doing something with improving alignment.

ultim
13th September 2013, 18:49
The off hand answer is so you can run off the end safely with an sse load or store, but as you say size+align-1 would be sufficient. So I don't know, may be you can do some archaeology and find an answer. Here is a link to version 1.1 of Avisyntn.cpp, Thu Jul 4 13:16:41 2002 UTC (11 years, 2 months ago) by richardberg (http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/avisynth.cpp?hideattic=0&revision=1.1&view=markup) as originally supplied by BenRG. Around version 1.9 Sh0dan started doing something with improving alignment.

Thanks IanB! I really appreciate you being here for us every day and helping us.

As for the reason of the memory allocation in question, I looked at the repository, but unfortunately, there is nothing there to answer me. In the initial checkin (first-ever version 1.1 of avisynth), where the supported alignment was only 8 bytes, the reserved extra space was already 32 bytes. So even here, farthest back in the history, we see that align*4 is used. "+32" was then refactored to "+align*4" in revision 1.12 (Mon Feb 10 16:42:40 2003), but even there, the commit only contains the unhelpful message of "Moved avisynth_2_1 onto MAIN".

"so you can run off the end safely with an sse load or store" cannot be the reason either, because the row pitch (which is calculated based on the alignment) already makes sure that such things cannot happen.

So I have no explanation for the current code right now, so I'm gonna try changing it to "+align-1", do some tests and see if anything breaks apart. My bet is that everything will still work as expected, but ofc it wouldn't be the first time for me to be wrong. :)

Wilbert
29th September 2013, 16:31
I moved all the posts about the fork of ultim to this thread: http://forum.doom9.org/showthread.php?t=168856

IanB
29th September 2013, 23:38
Next version, AviSynth 2.6.0 Alpha5 [Sep 18th, 2013]

Also a clickable link for the post above Avisynth forks

I wish link parsing could be re-enabled, in the meantime I wish people would manually do the tags themselves,
i.e. http://forum.doom9.org/showthread.php?t=168856

Richard1485
12th November 2013, 22:51
Did anyone get SoundOut to work with Avisynth v2.60a4? When i open a script (ending with SoundOut()) in Virtualdub i get the error message:

Avisynth open failure:
Cache: Filter returned invalid response to CACHE_GETCHILD_CACHE_MODE. 176310176

Is it supposed to work in 2.60 or is something not implemented properly?

Did you ever get SoundOut() to work? You mentioned that you might try to recompile the plugin. I receive the same error in v2.60a5. This page (http://avisynth.nl/index.php/SoundOut#Installation_and_Usage) says: "It will be included in AviSynth from v2.6 on", but I guess that that has not happened yet.

EDIT: It seems to work with Wavsource() but not other sources e.g. NicAC3Source(). With Wavsource() I can render to FLAC, but Virtualdub crashes when rendering AC-3.

ultim
13th November 2013, 09:07
Avisynth open failure:
Cache: Filter returned invalid response to CACHE_GETCHILD_CACHE_MODE. 176310176

This usually means the plugin needs to be updated to the 2.6 interface. Recompiling with the newest header should solve the issue.

Wilbert
13th November 2013, 19:15
Did you ever get SoundOut() to work? You mentioned that you might try to recompile the plugin.
Haven't tried yet. Will do so on Sunday.

Richard1485
13th November 2013, 19:20
Haven't tried yet. Will do so on Sunday.

Thanks. Now I know that I haven't overlooked an update to the plugin.

Gavino
13th November 2013, 21:13
SoundOut() works for me with 2.6a4.
Also worked for poisondeathray (post #100).

Does it always fail for you, Wilbert, or is it dependent on script contents?
I only tried a simple test - perhaps you need something which heavily exercises the audio cache to provoke the error?

EDIT: I notice now Jeff B above reports failure is source-dependent.

Wilbert
23rd November 2013, 20:25
Does it always fail for you, Wilbert, or is it dependent on script contents?
I only tried a simple test - perhaps you need something which heavily exercises the audio cache to provoke the error?

EDIT: I notice now Jeff B above reports failure is source-dependent.
I guess so, but i don't remember. A simple Tone() didn't work either. Anyway I managed to compile it finally: http://forum.doom9.org/showthread.php?p=1654982#post1654982. It was a bit more involved than ultim said since some header files were missing too among some other things. Let me know if there are any issues.