PDA

View Full Version : AviSynth 2.5.8 Alpha 2 [September 19th] - Release!


Wilbert
18th May 2007, 15:53
The changelog of the most recent version (v2.58a2) can be found here (http://forum.doom9.org/showthread.php?p=1046774#post1046774).

AviSynth 2.5.8 Alpha [May 18th] - Release!

Changelist with respect to 2.5.7:

Additions:

* ColorKeyMask: Allow independant tolerance levels for each channel.
* Added Tweak Hue/Saturation range limiting (ported from 2.6).
* Added AudioLevels and Color2 modes to Histogram (ported from 2.6).
* Adding global OPT_UseWaveExtensible=True to your script enables WAVE_FORMAT_EXTENSIBLE audio output.
* Added ShowTime() script verb, like ShowSMPTE() but with milliseconds (ported from 2.6).
* Added BlackmanResize() and Spline64Resize().
* Modified DeleteFrame()/DuplicateFrame() to process multiple arguments.
* Added Min()/Max() script functions.

Bugfixes:

* Fixed WriteFile(), Now remembers absolute path to file.
* Fixed Info() frame pitch, reports pitch of input frame.
* Fixed Invert() right edge memory overrun/corruption.
* Fixed Histogram() Classic mode pixel values exceeding YUV limits.
* Fixed Histogram() chroma plane initialization to 128.
* Fixed Conditional reader/writer illegally saving IScriptEnvironment pointer.
* Fixed YV12 Blur()/Sharpen() right edge pixel corruption with non-writable input frames.
* Fixed MMX Blur()/Sharpen() code to full 8 bit precision.
* Fixed IsAudioFloat()/IsAudioInt() script functions.
* Fixed Cache memory oversubscription of SetMemoryMax() limit.

Optimizations:

* Make audio cache actually functional.
* Tweak speed improvments.
* Subtract speed improvments.
* Tuneup Overlay() ISSE Convert444ChromaToYV12 and also provide MMX version.
* PokeCache interface implemented.
* Cache and Memory management enhancements.

Changes:

* AVISource/WavSource map WAVEFORMATEXTENSIBLE back to equivalent WAVEFORMATEX.
* DirectShowSource() now recognises incorrect AM_MEDIA_TYPE subtype for WAVE_FORMAT_EXTENSIBLE audio and corrects the data and accepts it.
* DirectShowSource() now attempts to use partial graph from failing RenderFile call.
* DirectShowSource() now detects and handles non 32 bit aligned picture lines from dud codecs.
* Crop(align=true) tests actual alignment in each GetFrame call.
* Relax YV12 resizer width restriction, now mod 2 was mod 4.
* .AVSI failures during env->CreateScriptEnvironment() are now available to the GetError() interface.
* SetCacheHints(CACHE_RANGE, n) will now surrender frames to satisfy SetMemoryMax().
* CoInitialize()/CoUninitialize() now done as part of ScriptEnvironment creation/deletion.
* Much code from 2.6 base included. Typically IsYV12() changed to IsPlanar().

As usual download from Sourceforge (http://sourceforge.net/project/showfiles.php?group_id=57023).

Enjoy!

Leak
18th May 2007, 16:57
Changelist with respect to 2.5.7:
[...]
* PokeCache interface implemented.
* Cache and Memory management enhancements.
Ummm... exactly what does PokeCache do?

For my update to the ffdshow AviSynth filter (https://sourceforge.net/tracker/?func=detail&atid=867362&aid=1676882&group_id=173941) I could really use a NukeAllCaches function to, well, nuke all caches (from orbit, if need be) to make sure nothing is reused after the input video stream has been seeked in...

Of course, a "ForgetAllMetricsYouCalculatedAhead" would be nice too, but it's a bit late to retrofit that into old filters... :D

So on the other hand, I guess I'll have to live with seeking ahead a lot of (not-really-existing) frames to get filters to start calculating metrics anew and dodge cached frames.

np: Hug - Birds (Heroes)

Terranigma
18th May 2007, 21:53
Nice. An update. Thanks A Lot! :D

Does anyone know if This (http://forum.doom9.org/showpost.php?p=967060&postcount=164) still hold true?
Would Spline36 be the more efficient resizer to use over Spline64 or... ?
Nvm, I read the resizer doc, so it still seems to be the same. :)

Warpman
19th May 2007, 00:11
There is no function named SetCacheHints

i used
SetCacheHints(510, 10)

Avisynth 2.5.8 verified with version()

foxyshadis
19th May 2007, 02:07
It's an internal function, made for dll filters, not useful as part of an avisynth script. It allows a filter to tell avisynth that there's no need to cache more than n frames around it.

J-Wo
19th May 2007, 02:57
does 2.5.8 support multithreading? I recall reading a while ago a recommendation to use one of Tritical's avisynth binaries since they were more "memory friendly", but according to his website they are now out of date. Just wondering if people recommend 2.5.7 final, the latest 2.5.8 alpha, or an older 2.5.7 RC build from Tritical's website. thanks!

IanB
19th May 2007, 06:05
@Leak,

PokeCache currently is internal only, it is intended to jam a message at all the cache instances. Currently the memory manager uses it to say "I have run out, give some back". Adding a hook to tell all the caches to run in CACHE_NONE mode would be a no brainer. For your ffdshow purposes a reset all caches hook might be more useful to you, that way temporal filters could still use the cache between resets. Have a look at the current CVS code and start a thread to discuss it some more.

@Terranigma,

It is still the original 4 node Spline64 I originally implemented. :confused: Maybe you should start a Dev thread to discuss the parameters for this resizer.

@J-Wo,

No multithreading yet, probably not until 2.6.0.

The intent is to make this version obey SetMemoryMax(). A shortcoming in the cache code allowed cache buffers to be locked indefinitly, all 2.5.6 and 2.5.7 releases suffer this problem, Triticals mods helped a little but didn't solve the problem.

If you have a problem, run 2.5.8, reproduce the problem and REPORT IT!

foxyshadis
19th May 2007, 06:21
Can PokeCache be used in a filter? So that if a filter itself attempts to malloc or new something internal (not that I think I've ever seen C++ allocation in an avisynth filter...), and hits an out-of-memory condition, it can partially flush the cache and try again? Right now crashing makes as much sense as anything, because hey, what else are you going to do without a working space?

IanB
19th May 2007, 06:48
If needed I could add access thru a new key for the env->ManageCache() interface. However doing so would not solve this problem. The cache never Free's/delete's memory, this new hook just unlocks/unprotects VFB's so that env->NewVideoFrame() can reuse an existing frame from the pool instead of allocating a brand new one.

Bring on all your worst memory hog scripts and see how they behave now.

techreactor
19th May 2007, 09:50
can you also shed some light about blackmanresize()

Leak
19th May 2007, 11:27
can you also shed some light about blackmanresize()
There was some discussion that ultimately lead to it being added to AviSynth here (http://forum.doom9.org/showthread.php?p=957735#post957735) in case you're interested... :)

np: Adult. - You Don't Worry Enough (Why Bother?)

Leak
19th May 2007, 11:50
For your ffdshow purposes a reset all caches hook might be more useful to you, that way temporal filters could still use the cache between resets. Have a look at the current CVS code and start a thread to discuss it some more.
Will do, although I'm wondering if there aren't too many legacy filters already for this to be added now - it's not just the caches, after all, it's also metrics and stuff that's been (pre-)calculated ahead; applying those to totally different images isn't going to be pretty.

That's why I resorted to increase the number of the current frame by 1000 whenever such a break is needed - that should work in almost all cases.

Oh, another thing - wouldn't it make sense to also add the multithreading additions from 2.6? TSP did so for 2.5.6 and 2.5.7 and released his own versions of avisynth.dll, so I guess it shouldn't be too hard to incorporate these changes in 2.5.8 for good...

np: Adult. - Harvest (Why Bother?)

Ebobtron
19th May 2007, 16:26
Hello,
@Ianb
Thank you.The changes to the memory manager seem to work very well. Comparing to 2.57, with a memory hog script using my slide animate function which at 10% of an encode would begin its climb beyond 500 Meg of PF Usage, tests this morning with 2.58 showed no climb above 500 Meg during the entire encode.
Both tests used #SetMemoryMax()

".AVSI failures during env->CreateScriptEnvironment() are now available to the GetError() interface."This looks really good too."CoInitialize()/CoUninitialize() now done as part of ScriptEnvironment creation/deletion."Can I assume that this does not prevent AviSynth from un-initializing COM when it was initialized prior to loading AviSynth. I see no difference in behavior.

:)
Otherwise all looks very good from my limited point of view, except who was the wise guy that make the version string longer.
Thanks to every one
Rob

Leak
19th May 2007, 18:12
Oh yeah, another thing I wanted to ask:

Since I'm using VS2005, would you be interested in a patch for the current CVS code that fixes the errors caused by 2005's tighter scoping? It's all just pulling the loop variables out before for statements, so it should work just as well in VC6.

I'd also have project/solution files for VS2005 that could be put into CVS, like ffdshow does with it's VC6/VS2k5/ICL9 files.

Oh, and distributing MSVCRTD in distrib/bin/debug might be also a good idea, since it doesn't ship with 2005 and devil-d.dll depends on it.

It's not much that needs to be changed to at least make avisynth itself compile, but why not add it to CVS so people don't have to reinvent the wheel every time? :)

np: The Go Find - Monday Morning (Stars On The Wall)

squid_80
19th May 2007, 19:06
Oh, and distributing MSVCRTD in distrib/bin/debug might be also a good idea, since it doesn't ship with 2005 and devil-d.dll depends on it.
I don't think you're allowed to distribute MS debug libraries. Probably better to recompile it as static if that's possible.

Leak
19th May 2007, 19:26
I don't think you're allowed to distribute MS debug libraries. Probably better to recompile it as static if that's possible.
Oh, great... of course, you could also put a VS2005 build of devil-d.dll in there, but why bother?

Yeah, I could have dug out my VS6 CDs and installed the missing library from there, but you wouldn't believe what just googling for it turns up... :D

np: Mikkel Metal - Dromos (Brone And Wait)

Leak
19th May 2007, 23:10
Okay, so if someone else wants to compile AviSynth with Visual Studio 2005 or would like to commit my changes to CVS - you can find my changes here (http://leak.no-ip.org/AviSynth/VS2005/).

DISCLAIMER: I didn't thoroughly test everything, I simply checked that it would happily run my DVD-IVTC/resize script inside of ffdshow. Also, pretty much all of the changes consist of straight-forward pulling loop variables out of a for-loop. It's also chock-full of warnings, but I think almost all of them can be safely ignored.

I've also replaced lstrcpyW with wcscpy, as the former is both deprecated *and* commented out in it's header file, while the latter is just deprecated and should do the same.

The diff contains all code changes and VS2005 project files (plus some line noise from my local SVN repository), while the ZIP file contains a VS2005 debug and release build of the SoundTouch library.

If the debug version of AviSynth doesn't want to run, you'll probably have to hunt down a copy of MSVCRTD.dll, or throw out your devil-d.dll (and possibly the code that tries to use it).

np: David Sylvian - Ride (Everything And Nothing)

IanB
20th May 2007, 00:51
Okay M$ won't let MSVCRTD.DLL be distributed.

devil-d.dll comes from the devIL distribution, we don't build it.

The debug versions of things in CVS are usually pretty useless because they have absolute path references for the symbols, but they linger on.

The CoInitialize()/CoUninitialize() change should only avoid the deadlock from the DllMain exit code (got global lock, CoUninit.. code also needs same lock, etc, etc, ...) The concept is still under review. There is a dormant thread on the issue, read that and contribute any ideas you have in there.

Version string :confused: I haven't checked Wilbert build, but it should just have 8 instead of 7 and a new date. Will check.

Leak, thanks for the 2005 updates. Are these really all from compiler warnings, it seems a bit excessive or did you do a global seek and destroy. I am relucant to put any new .vcproj files into CVS (sh0dan already has some) because people tend to update them directly instead of updating the VC6 files and reimporting.

For the lstrcpyW/wcscpy we should be using the function for which the compile generates inline code. Need to check.

Whew, pause, take breath ......

Leak
20th May 2007, 01:13
Leak, thanks for the 2005 updates. Are these really all from compiler warnings, it seems a bit excessive or did you do a global seek and destroy.
If you mean the changes to loops - those aren't absolutely neccessary, since you can configure VS2005 to fall back to the non-standard behaviour of it's earlier iterations, but that has been violating the C++ standard all along.

I didn't do a seek and destroy, though - I just fixed it everywhere the compiler choked on me. Sure, a few of these could have been fixed by re-declaring the loop variable in for statements further down the code, but I figured just declaring the variable once and reusing it like it's been done before was the way to go.

I am relucant to put any new .vcproj files into CVS (sh0dan already has some) because people tend to update them directly instead of updating the VC6 files and reimporting.
Am I the only one here that thinks VC6 needs to die a quick death, especially since there's Visual C Express Edition? *wonders*

Anyway, the auto-conversion process didn't go totally smooth for DirectShowSource and TCPDeliver at least, both needed some tweaking to compile. That's why I included them...

And the SoundTouch libraries need to be rebuilt with VS2005 to link properly.

For the lstrcpyW/wcscpy we should be using the function for which the compile generates inline code. Need to check.
Argh... looking still a bit closer at this I see that lstrcpyW gets redefined into la-la land in wxutil.h, which is part of DirectShow's base classes... :rolleyes:

But rectifying it in wxutil.h in every installation can't be the solution either... :(

np: David Sylvian - Cover Me With Flowers (Everything And Nothing)

Fizick
20th May 2007, 02:45
can Soundtouch be converted to DLL? with non-compiler version-dependent calls from avisynth (LoadLibrary, .....)
like devil.dll

Ebobtron
20th May 2007, 04:21
@Ianb

The CoInitialize()/CoUninitialize() change should only avoid the deadlock from the DllMain exit code (got global lock, CoUninit.. code also needs same lock, etc, etc, ...) The concept is still under review. There is a dormant thread on the issue, read that and contribute any ideas you have in there.My ideas are posted in that or another thread, I have nothing to add. I was just checking to see if a particular issue was the same as before. That being will it (as written) always un-initialize.

"CoInitialize()/CoUninitialize() now done as part of ScriptEnvironment creation/deletion."
I really don't know what that means. My guesses suck normally but if I must, it got moved out of dll main.

Thanks anyway professor.


Version string :confused: I haven't checked Wilbert build, but it should just have 8 instead of 7 and a new date. Will check.
Sorry, I was kidding, it is only a few pixels longer.
Thanks
Rob

IanB
20th May 2007, 04:58
Basically for each "open" of an AVS script you get a CoInit and for each "close" you get a CoUnInit instead of one global CoInit when avisynth.dll loads and one global CoUnInit when avisynth.dll unloads (possibly from a different thread and when all the other dll's/resources have been (are being) released and the process global lock is asserted).

Not sure if it is going to help or hurt, but this is why we try these things in prerelease builds. As I said if you have thoughts or problems please post them in the appropriate thread.

And the wink icon ; ) is for making jokes about a few pixels wider ;)



And Soundtouch etc as .dll's is a double edge sword. Which .dll has the user currently got active? Really these routines should be separate plugins so if they screw up it doesn't kill the core. And yes static linking against the matching .lib is pretty dumb, using LoadLibrary etc is much more controlled and safer and you get to print a helpless error message but you have search path problems hmmm fft.dll!

Fizick
20th May 2007, 09:43
other possible solution with Soundtouch is to put (integrate) its needed sources to Avisynth CVS tree, with or without intermediate lib production.

It is no joke ;)

Leak
20th May 2007, 17:13
For your ffdshow purposes a reset all caches hook might be more useful to you, that way temporal filters could still use the cache between resets. Have a look at the current CVS code and start a thread to discuss it some more.
Well, after looking at the sourcecode some more I think I'll retract my request - yeah, clearing the cache et al wouldn't be too hard, but I've found that nothing really keeps track of all filter instances that are being used in a ScriptEnvironment, so asking them all to forget their calculations with regard to future frames (without destroying and recreating the ScriptEnvironment, which often takes too long for realtime use depending on the filters being used) is quite impossible now, and I don't think retrofitting everything to be able to do that is worth it - at least not for my purposes, where I can just make up new frame numbers for the source frames that are off far enough that any caching and pre-calculation that may have happened isn't an issue.

Of course, if there's some other use for clearing the caches I'm all for adding it... :)

np: The Go Find - Everything Is Low (Stars On The Wall)

tin3tin
30th June 2007, 00:35
With this version I get a much slower playback on even simple avisynth transitions like a dissolve(in DVD slideshow GUI). The previous version almost played it realtime. :confused:

IanB
30th June 2007, 06:33
:script: How much slower are we looking for?

tin3tin
30th June 2007, 09:41
The script is the generated script in DVD slideshow GUI. What I've noticed is with ex. 32 slides 2.5.7 slows down with 0.2 fps and 2.5.8 slows down with 5-10 fps in dissolve transitions when previewing in Media Player Classic. So it is quite visible.

DVD slideshow GUI can export to .avs. However the scripts is very dependent on a installed DVD slideshow GUI folder structure, so if you want to see the slow down, the easiest thing is to install it and export to avs(Avisynth 2.5.7 included, but you can cancel it).

You can download from here:DVD slideshow GUI (http://download.videohelp.com/tin2tin/download.html)

IanB
30th June 2007, 09:49
No! I want your script!

tin3tin
30th June 2007, 13:25
Okay, here's my script. MyScript.avs (http://download.videohelp.com/tin2tin/MyScript.avs)
But you will need a lot of files (automatic generated by DsG) to see the slow down. Ex. 36 different eBmp files (720x576)ect.

I hope you will find it useful.

IanB
2nd July 2007, 01:45
Fixed Cache memory oversubscription of SetMemoryMax() limit.The default SetMemoryMax() is not high enough for your script. As from 2.58 it is enforced, ruthlessly!

Maybe we need a bigger default now? Thoughts?

tin3tin
2nd July 2007, 02:23
Okay, I'll test that.

Just a thought - it would be great if it also would be possible to set the memory limit as chosen procentage of the available physical and virtual memory. :)

[EDIT: ... Yes, if SetMemoryMax() is set high enough it runs fine. Can it be set too high? Will that have any bad influence on the playback?]

Myrsloik
7th August 2007, 23:33
Would it be possible to use LoadLibraryEx for loading plugins when it's available (xp and later)?

Doing so would make it possible to add the directory the plugin is stored in to the search path and avoid most trouble when dealing with plugins that have multiple files.

IanB
8th August 2007, 00:42
Doing so would make it possible to add the directory the plugin is stored in to the search path and avoid most trouble when dealing with plugins that have multiple files.Not sure I understand your premise, adding the .DLL directory to the path is already the current solution to the problem.

Also problems usually occur when plugins try to dynamicly load there support files and don't implement an adequate search proceedure for their own LoadLibrary calls. Changing this will not help in this case at all. This will only effect loading .DLL's staticly linked against a matching .LIB, which I am not aware has caused any problems.
You select these optional behaviors by setting the dwFlags parameter; if dwFlags is zero, LoadLibraryEx behaves identically to LoadLibrary.
DONT_RESOLVE_DLL_REFERENCES
LOAD_LIBRARY_AS_DATAFILE
LOAD_WITH_ALTERED_SEARCH_PATH
LOAD_IGNORE_CODE_AUTHZ_LEVEL
LOAD_LIBRARY_AS_IMAGE_RESOURCE
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE

..., the search order is as follows: The directory from which the application loaded.
The current directory.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key.

..., the alternate search order is as follows: The directory specified by lpFileName.
The current directory.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key.If I have missed a point here, please spell it out.

There is a SetWorkingDir script function that is intended to resolve these problems, perhaps it need some care and feeding.

Myrsloik
8th August 2007, 01:54
The point was, as you suspected, dlls statically linked with a matching lib. I mostly suggested it because I've seen a couple of posts suggesting that all files of FFmpegSource should be dumped in system32 to "make it work".

I know there are other ways like stabbing the ignorant until they learn how to modify the PATH but LoadLibraryEx with LOAD_WITH_ALTERED_SEARCH_PATH just seemed like a simpler solution that shouldn't break anything. Or at least not that many things...

foxyshadis
8th August 2007, 05:47
Another option is for avisynth to internally add the avisynth plugin folder, as well as every (unique?) folder it encounters in the script's loadplugin calls. The environment is always per-process, after all, unless you export it; you can walk environ from stdlib.h until you get to path and add to it, from then on everything inherits from it. (putenv and setenv are global, unfortunately.) Edit: Oh, here's what I was looking for, screw that C cruft: SetEnvironmentVariable (http://msdn2.microsoft.com/en-us/library/ms686206.aspx).

As long as we're bitching and moaning, is there any good reason LoadPlugin can't check for the virtualdub or C/stdlib export name and hand off the loading appropriately? And by extension enable autoloading of C plugins?

IanB
8th August 2007, 14:40
We can't autoload VDub or VFAPI plugins because you have to manually name the the function and set the preroll. Interestingly the auto load code does LoadPlugin(*.dll) and then LoadPlugin(*.vdf). Hmmmmm!

We don't autoload C plugins because we can't tell one's which need to be loaded by avisynth_c.dll and ones which will load directly. I will be able to fix this for 2.6 C plugins, they are gonna get a new entry point name. And yes old one will still load the same as now.

The recommend proceedure is to explicitly load them in an .AVSI.

Also during autoloading of plugins the Current directory is the plugin directory. Any plugins that change the CWD will screw it for the remaining plugins.

And during a script Import the Current directory is the scripts directory. Any SetWorkingDir() calls get popped.

It might be possible to also set the current directory to the plugins directory during the LoadLibrary call, I would have to put it back for the PluginInit2 call to maintain current behaviour. However this would break the use of SetWorkingDir() calls anyone is using to manage this issue. Thoughts?

Fizick
19th August 2007, 08:21
I met some bug in v2.5.8 with any script.
Take version.avs
Play it with windows media player (mplayer2.exe, not MPplayerClassic) by right click - play (or by open).
Video is playing fine.
Stop playing and close player (file-exit).
I have crash with Windows Media Player messagebox:
error found, application will be closed.....
Send to Microsoft...
AppName: mplayer2.exe AppVer: 6.4.9.1125 ModName: quartz.dll
ModVer: 6.5.2600.2749 Offset: 000398b2

on debug - unhandled exception in quartz.dll,
0xC0000005 - access violation

Config: XP SP2
v2.5.7 works fine.

GrofLuigi
19th August 2007, 14:36
I met some bug in v2.5.8 with any script.
Take version.avs
Play it with windows media player (mplayer2.exe, not MPplayerClassic) by right click - play (or by open).
Video is playing fine.
Stop playing and close player (file-exit).
I have crash with Windows Media Player messagebox:
error found, application will be closed.....
Send to Microsoft...
AppName: mplayer2.exe AppVer: 6.4.9.1125 ModName: quartz.dll
ModVer: 6.5.2600.2749 Offset: 000398b2

on debug - unhandled exception in quartz.dll,
0xC0000005 - access violation

Config: XP SP2
v2.5.7 works fine.

Yes, I get (a different?) error too with version.avs :

ActiveMovie Window: mplayer2.exe - Application Error ( <- this is the title bar )

The instruction at "0x748498d0" referenced memory at "0x75f41508". The memory could not be "read".

Click on OK to terminate the program
Click on CANCEL to debug the program


All other players (and I have many :) ) play it fine.

GL

* edit: mplayer2.exe version is the same, quartz.dll is 6.5.2600.3024. OS is XPSP2

Zarxrax
2nd September 2007, 21:24
I'm getting an odd error here with AssumeFPS with the preset parameter.

If I explicitly name the parameter like so:
AssumeFPS(preset="ntsc_film")
I get an invalid argument error.

Simply doing it like this works fine though:
AssumeFPS("ntsc_film")

foxyshadis
2nd September 2007, 23:34
It's not documented as using a named argument, so I assume it isn't supposed to. (No quotes around the argument name in the docs.)

Zarxrax
3rd September 2007, 01:56
Ah, really. I had assumed every argument for every filter was named.

Ebobtron
3rd September 2007, 02:25
Nope there are alot of unnamed arguments in many of the internal filters.
The one or ones in question return the following

Reported by AviSynth:
AssumeFPS In -{ cc[sync_audio]b }-
AssumeFPS In -{ cc[sync_audio]b }-
AssumeFPS In -{ cc[sync_audio]b }-
AssumeFPS In -{ cc[sync_audio]b }-

I am assuming here that AviSynth can't tell the difference between AssumeFPS and AssumeFPS, I know I can't. :)

From the docs:
AssumeFPS (clip, float fps, bool "sync_audio")
AssumeFPS (clip, int numerator [, int denominator], bool "sync_audio")
AssumeFPS (clip1, clip2, bool "sync_audio")
AssumeFPS (clip, string preset, bool "sync_audio")

as compared to

AVIFileSource In -{ s+[audio]b[pixel_type]s[fourCC]s }-

AVIFileSource (string filename [, ...], bool "audio" = true, string "pixel_type" = YV12, [string fourCC])

these strings, s+[audio]b[pixel_type]s[fourCC]s, are what is reported by AviSynth when you ask.
FilmCutter can display them all for you

Wilbert
3rd September 2007, 19:45
It's not documented as using a named argument, so I assume it isn't supposed to. (No quotes around the argument name in the docs.)
A quoted argument has a default value, and bracket [] one is optional. So you can't see which arguments are named ones.

At least that's how i thought it was, if not, then we have some correcting to do :)

Fizick
3rd September 2007, 20:29
quoted agruments is named arguments, it is not dependent on default values.

Wilbert
3rd September 2007, 21:12
Then many of the lines in quick_ref.htm are wrong and should be corrected. RGBAdjust is an example, but there are many more ...

Fizick
3rd September 2007, 23:26
I wold like to have almost all argument named...
IanB, please :)

IanB
5th September 2007, 01:51
@F, Naming arguments makes them optional, this means more coding effort in the creator code i.e. not working with the API.

@W, As I interpreted it, for the documentation, quoted names means optional named argument i.e. int "name" means it's an int, it is optional and it is called name.

Unquoted names are for documentation reference only, and the inclusion of [...] implies optionality i.e. clip Src1[, clip Src2] means arg1 is a clip, arg2 is an optional clip. See Src1 and Src2 in the documentation for an explanation of their function.

Yes much of our documentation is inconsistant. I think we need a page "How to read this Avisynth documentation", and we need to make all the documentation conform to this.

@E, Yes there is a deficiency retrieving duplicate function entries. Perhaps somebody has ideas how to design around this.

masscamp24
6th September 2007, 16:38
I notice a problem with Avisynth 2.5.8 alpha. Since reading this post I tried it and when the source is played through windows media player, it played ok, but at the end of play and when WMP closed I get an error message (the normal windows error message when a program is not closed properly). Therefore I revert back to 2.5.7 and the problem went away. That's the only problem I notice with 2.5.8 so far and thought I should report it.:helpful:

Wilbert
15th September 2007, 23:15
@IanB,

Regarding the latest v2.58 CVS and Subtitle (default values). A bit of the displayed stuff is chopped off at the right hand side (i guess at the top too). See attachment.

IanB
16th September 2007, 04:18
@Wilbert,

edit: Test Subtitle("2 2 2 2 2 2 2 2\n2 2 2 2 2 2 2 2\n2 2 2 2 2 2 2 2", Lsp=1) :edit

Yes on the surface it does not look right, but it is obeying the algorithm as I understand it. Perhaps you can review the code changes for sanity. I have made the assumption that the algorithm should have been fully symetrical, the original was clearly not.

One point that is apparent is the algorithm might be improved by considering the effects of Gamma. At present the assumtion is brightness is linear, and the brightness results are only [0..64], we count lit pixels in an 8x8 grid. The halo aggregates weight from the distance from the edge to the nearest lit pixel.

The relevant code is this. Code I thought was wrong is in Red :-for(i=0; i<=8; i++) {
cenmask |= (BYTE)(((long)-src[srcpitch*i ])>>31);
cenmask |= bitexl[src[srcpitch*i-1]];
cenmask |= bitexr[src[srcpitch*i+1]];
}

mask1 = mask2 = cenmask;

for(i=0; i<8; i++) {
mask1 |= (BYTE)(((long)-src[srcpitch*(-i)])>>31);
mask1 |= bitexl[src[srcpitch*(-8+i)-1]];
mask1 |= bitexr[src[srcpitch*(-8+1)+1]];
mask2 |= (BYTE)(((long)-src[srcpitch*(8+i)])>>31);
mask2 |= bitexl[src[srcpitch*(8+i)-1]];
mask2 |= bitexr[src[srcpitch*(8+i)+1]];

tmasks[i] = mask1;
bmasks[i] = mask2;
}

for(i=0; i<8; i++) {
alpha2 += bitcnt[cenmask | tmasks[7-i] | bmasks[i]];
}
I changed to this, corrected code in Blue, there are now short cut case, which need verifying as well.
if (alpha1) {
// If we have any lit pixels we fully occupy the cell.
alpha2 = 64;
}
else {
// No lit pixels here so check the neighbours
BYTE cenmask = 0, mask1, mask2;

// Check left and right neighbours for lit pixels
for(i=0; i<8; i++) {
cenmask |= bitexl[src[srcpitch*i-1]];
cenmask |= bitexr[src[srcpitch*i+1]];
}

if (cenmask == 0xFF) {
// If we have hard adjacent lit pixels we fully occupy this cell.
alpha2 = 64;
}
else {
mask1 = mask2 = cenmask;

for(i=0; i<8; i++) {
// Check the 3 cells above
mask1 |= bitexl[ src[srcpitch*(-1-i)-1]];
mask1 |= (BYTE)(((long)-src[srcpitch*(-1-i) ])>>31);
mask1 |= bitexr[ src[srcpitch*(-1-i)+1]];

// Check the 3 cells below
mask2 |= bitexl[ src[srcpitch*(8+i)-1]];
mask2 |= (BYTE)(((long)-src[srcpitch*(8+i) ])>>31);
mask2 |= bitexr[ src[srcpitch*(8+i)+1]];

// Strength of occupancy based on neighbours distance
alpha2 += bitcnt[ mask1 | mask2 ];
}
}
}

Ebobtron
18th September 2007, 05:30
@E, Yes there is a deficiency retrieving duplicate function entries. Perhaps somebody has ideas how to design around this.
@I "AssumeFPS", "ci[]i[sync_audio]b"
"AssumeFPS", "cf[sync_audio]b"
"AssumeFPS", "cs[sync_audio]b"
"AssumeFPS", "cc[sync_audio]b"

Reports only "cc[sync_audio]b" for all four forms.

Looking at this strictly from this end, all that is needed is a parameter string delimiter.

"ci[]i[sync_audio]b*cf[sync_audio]b*cs[sync_audio]b*cc[sync_audio]b"

This issue is not very common considering the total number of functions, although I suppose it could emerge in future implementations. My point, for this case of the fps functions I might prefer to hard code these exceptions compared to writing a function string parser that detects and interprets them plus the almost equivalent of the hard code to interface to the user.

There is my three bucks (2 cents adjusted for inflation)

Wilbert
19th September 2007, 22:57
AviSynth 2.5.8 Alpha 2 [September 19th] - Release!

Changelist with respect to 2.5.7:

Additions:

* ConvertAudio(cii) available to plugins via env->Invoke().
* Added font aspect, rotation and alpha to text routines.
* Added /* xxx */ block comments.
* Added [* [* xxx *] *] nestable block comments.
* SetMemoryMax(0) to just return current Memory Max value.
* Added planar YV12 color format to Compare() [Fizick].
* ColorKeyMask: Allow independant tolerance levels for each channel.
* Added Tweak Hue/Saturation range limiting.
* Added AudioLevels and Color2 modes to Histogram.
* Adding global OPT_UseWaveExtensible=True to your script enables WAVE_FORMAT_EXTENSIBLE audio output.
* Added ShowTime() script verb, like ShowSMPTE() but with milliseconds.
* Added BlackmanResize() and Spline64Resize().
* Modified DeleteFrame()/DuplicateFrame() to process multiple arguments.
* Added Min()/Max() script functions.

Bugfixes:

* Fixed ImageReader incompletely inited videoInfo.
* Fixed Layer RGB32 100% alpha implementation, use level=257 (new default).
* Fixed avisynth_c.h avs_is_parity_known().
* Fixed C++ ConvertAudio::Saturate_int32() rounding.
* Fixed WriteFile(), Now remebers absolute path to file.
* Fixed Info() frame pitch, reports pitch of input frame.
* Fixed Invert() right edge memory overrun/corruption.
* Fixed Histogram() Classic mode pixel values exceeding YUV limits.
* Fixed Histogram() chroma plane initialization to 128.
* Fixed Conditional reader/writer illegally saving IScriptEnvironment pointer.
* Fixed YV12 Blur()/Sharpen() right edge pixel corruption with non-writable input frames.
* Fixed MMX Blur()/Sharpen() code to full 8 bit precision.
* Fixed IsAudioFloat()/IsAudioInt() script functions.
* Fixed Cache memory oversubscription of SetMemoryMax() limit.

Optimizations:

* DirectShowSource() FPS last attempt try for duration of 1st frame.
* DirectShowSource() convertfps rely only on sample start time.
* Refactor horizontal planar resizer, no width restrictions or 2 byte overwrite.
* Provide a simple and fast text writing primatives, see info.h
* Make audio cache actually functional.
* Tweak speed improvements.
* Subtract speed improvements.
* Tuneup Overlay() ISSE Convert444ChromaToYV12 and also provide MMX version.
* PokeCache interface implemented.
* Cache and Memory management enhancements.

Changes:

* Convert to Dynamic Assembled rgb to yuy2 code.
* Avisynth_c.h boolean functions return 1 for true instead of arbitrary non-zero.
* Internal RGB2YUV() now copies Alpha top byte through.
* CoUninitialize() done immediately for S_FALSE CoInitialize() returns, i.e we do not hold a COM use count.
* Pfc, Softwire and SoundTouch updated and added as dependency projects.
* UPX updated to version 2.03 (2006-11-07).
* Default Memory Max value increased to half minus 64Mb when over 256MB free.
* AVISource/WavSource map WAVEFORMATEXTENSIBLE back to equivalent WAVEFORMATEX.
* DirectShowSource() now recognises incorrect AM_MEDIA_TYPE subtype for WAVE_FORMAT_EXTENSIBLE audio and corrects the data and accepts it.
* DirectShowSource() now attempts to use partial graph from failing RenderFile call.
* DirectShowSource() now detects and handles non 32 bit aligned picture lines from dud codecs.
* Crop(align=true) tests actual alignment in each GetFrame call.
* Relax YV12 resizer width restriction, now mod 2 was mod 4.
* .AVSI failures during env->CreateScriptEnvironment() are now available to the GetError() interface.
* SetCacheHints(CACHE_RANGE, n) will now surrender frames to satisfy SetMemoryMax().
* CoInitialize()/CoUninitialize() now done as part of ScriptEnvironment creation/deletion.
* Much code from 2.6 base included. Typically IsYV12() changed to IsPlanar().

As usual download from Sourceforge (http://sourceforge.net/project/showfiles.php?group_id=57023&package_id=105994).

Enjoy!

Btw, could anyone give some meaningful examples of the use of nested block comments ? :)

Ebobtron
20th September 2007, 00:04
do something /*whatever*/
do something else /*whatever else*/
ok

/*
do something /*whatever*/
do something else /*whatever else*/
*/
not wanted

do something [*whatever*]
do something else [*whatever else*]
ok

[*
do something [*whatever*]
do something else [*whatever else*]
*]
ok

"/*" ends on first "*/"
"[*" ends on last "*]"

if you wish to comment out a block that contains a block already commented out the use
of /**/ will end at first */

also

/*/**/*/ reports an error correctly at column seven

[*/**/*] works and /*[**]*/ works too.

anyone have a clue or preference on some lexer colors for the different combinations,
gee this ought to be fun.

:) I think?

Fizick
20th September 2007, 06:36
discussion about comments:
http://forum.doom9.org/showthread.php?t=94768

Fizick
20th September 2007, 20:26
The bug with mediaPlayer (http://forum.doom9.org/showthread.php?p=1035303#post1035303) is fixed.
Thanks!

Fizick
20th September 2007, 20:56
can somebody translate to English or Russian this:
* DirectShowSource() FPS last attempt try for duration of 1st frame.
:)

Terranigma
20th September 2007, 21:08
Thanks a lot for the updates/bug fixes guys. :)

Leak
20th September 2007, 21:22
can somebody translate to English or Russian this:
* DirectShowSource() FPS last attempt try for duration of 1st frame.
:)
My guess would be that DirectShowSource uses the duration of the first frame to calculate the FPS if it can't figure out the FPS any other way, but yeah - the wording above is definitely b0rked.

np: John Dahlbäck - Wet Summer (Speicher CD3)

IanB
21st September 2007, 01:25
B0rked wording, yep! I avoid coding in the wee hours, looks like I also should stop documenting in the wee hours as well.

Yes Leak has guessed correctly. Of course this grates against the other change to avoid using sample stop time from all those fsck'd splitters. I can't win here. Various splitter versions don't provide FPS and don't give correct sample stop time and don't like to seek.

And Fizick you can always examine the CVS differences to see what got changed in the code.

Wilbert
30th September 2007, 18:11
Yes on the surface it does not look right, but it is obeying the algorithm as I understand it. Perhaps you can review the code changes for sanity. I have made the assumption that the algorithm should have been fully symmetrical, the original was clearly not.

Some screenshots comparing v2.57 and latest CVS. If you look at the top, the yellow of the text is being mirrored upside down. I'm not sure how to say that properly, but i hope you will understand what i mean.

Are you sure that this
I re-analysed the original code and found I was scanning the upper 3 neighbours for the halo the wrong way round.
was indeed the "wrong way around"?

Btw, the subs were created at the default size, and resized to 640x480.

<removed pics>

IanB
1st October 2007, 16:31
@Wilbert,

Well thats a cunning way of examining how the antialiaser is working. I have been using PointResize. However no points for the 1280 wide image in your post :(

Your example clearly shows the fault with 2.57 and prior version of the excessive halo along the top edge.

And yes there is still something wrong with the 2.58 code. I think the left and right extention tables are backwards as well. The smudging apparent at the top should normally be expected on all sides of a glyph.

The algorithm as I have come to understand it draws the glyphs at 8 times size. The antialiaser simply counts the number of lit dots in an 8x8 grid to get the text weight for each output pixel. The halo is added as an 8 dot border against the lit dots of a glyph. Again the antialiaser simply counts the number of halo dots in an 8x8 grid to get the halo weight for each output pixel. Halo pixels around the edge of a glyph should be expected to have a halo weight of 1 to 64 with a text weight of 0 to 63.

E.g. a glyph edge 8x8 cell has the left 4x8 dots lit, the right 4x8 dots will be halo, this should result is a pixels with 32 weight text + 32 weight halo. The right adjacent 8x8 cell will have the left 4x8 dots halo (making a total 8 dot wide halo) and the right 4x8 dots transparent, this should result in a pixel with a 0 weight text + 32 weight halo.

2.57 renders more than 1 100% weight halo pixel along the top edge.

Wilbert
1st October 2007, 21:12
Well thats a cunning way of examining how the antialiaser is working. I have been using PointResize. However no points for the 1280 wide image in your post
I always forget that you have a small screen :) I'm sorry ...

Thanks for your explanation about how it should work. Where did you get the algorithm from?

Your example clearly shows the fault with 2.57 and prior version of the excessive halo along the top edge.
Yes, i saw that too, but i've never noticed that before :) At least the algorithm in 2.58 is better than the one in 2.57!

Wilbert
6th October 2007, 16:06
Some new screenshots (from latest CVS). Looks much better i think.

IanB
7th October 2007, 01:43
Full marks for the sensible width image:p

Notice there is now the illusion of a gap between the 1 and the 8 and the smudging is consistant on all sides.

The big test is to set the text color 100% transparent, i.e. $FF000000, so that only the halo is visible. When correct, the halo will be a consistant 1 pixel antialiased width on all sides, i.e. it should affect only 2 pixels in any given axis and the gamma corrected weight of those 2 pixels should be 64/64.

Wilbert
13th October 2007, 16:02
@IanB, outdated coefficients are used for Rec.709.

In the first draft of the spec, they use: kr = 0.2125, kg = 0.7154, kb = 0.0721. These are also used in AviSynth, iirc.

In the final spec, they use: kr = 0.2126, kg = 0.7152, kb = 0.0722. It's not clear to me why those are changed though.

MfA
16th October 2007, 14:48
Probably so people who used the public draft got it wrong ;)

Fizick
16th October 2007, 17:54
IMHO, values are same :)
we have only 8 bit precision (0.004)

Ebobtron
29th October 2007, 04:47
Sorry I have a problem with the latest alpha. Searched the thread, didn't see anything about this. If you guys already know about this, then never mind.
Having trouble with version 2.58 alpha 2 dated September 19, 2007 in two areas AVISource and DirectShowSource.

Working with DSS to input DV.avi, FilmCutter's new little thumbnails in the timeline were gray. Use of FilmCutter's frame snapshot routine basically the same method renders gray “720x480.bmp“.CoCreateInstance(CLSID_MediaDet,NULL,CLSCTX_INPROC_SERVER,IID_IMediaDet, (void**)&pMDet);

pMDet->put_Filename(wfile);
pMDet->WriteBitmapBits(grabFrame,SourceWidth,SourceHeight,grabFile);Thinking this was the fault of recent test installation of some DirectShow filters I changed them around a little and saw no change.

I switched the input filter to get the thumbnails working with a particular source wanted for a screen cap for some web docs. AviSynth reported an error.
AviSource: Could not open video stream in any supported format.
(C:/mypath/my.avs, line 2)

Now I is raging around the house kicking my dogs (not really). Looked over the vfw codex’s installed, nothing. Open the avi file in VDub, all ok. Open the avs file using AviSource in VDub. same error.

Now for the real test. Open the avi file in FilmCutter’s text editor so that FilmCutter can push the file name into the AviFileInterface for the save wave thingy, that works fine.

Problem not me, problem latest alpha, alpha from May 18 is OK. With the May release thumbnail grab works fine in DSS and AviSource and AviFileSource both work. DSS seem much quicker when seeking DV.avi in the earlier alpha.

:thanks:

IanB
29th October 2007, 12:57
Yep, latest DSS doesn't seek right. Fixed in CVS.

Wilbert
3rd November 2007, 00:01
@IanB,

http://www.itu.int/rec/T-REC-H.262-200011-I!Amd1/en says something about 23.976 Hz and drop-frame counting. I didn't check it yet, so i don't know whether it's the same as the current implementation in AviSynth.

IanB
3rd November 2007, 01:51
0.5 cigar. :( The time codes are still based on the post RFF flag processing rate, i.e. 29.97 fps.

So maybe we would print the timecode that would be present if a 3:2 pull down was done. If this was done the frame offset number would be [0..29] instead of [0..23], with a pattern something like this, 0 1 3 4 5 6 8 9 10 11 13 14 ... 25 26 28 29

I do not like this thought at all.

DeathTheSheep
11th November 2007, 18:38
DirectShowSource [now] uses the duration of the first frame to calculate the FPS if it can't figure out the FPS any other way.
This behavior is causing problems in vfr sources with specified forced framerate. Example: directshowsource("file.mkv",23.976,convertfps=true). Directshowsource is now assuming the video to be a constant X fps because the first frame reported this rate, and it won't correct its behavior when/if the framerate shifts, leading to very choppy output with skipped frames where there shouldn't be. Is there a way to disable this new behavior, at least when using convertfps?

IanB
11th November 2007, 21:25
... if it can't figure out the FPS any other wayThe code is a last ditch attempt before throwing an error, so if you spec the FPS it is not active.

Also the current 2.58 DSS is very borked.

Brother John
14th November 2007, 00:35
Mod 2 width does not work for me.
BlankClip(width=720, height=576).ConvertToYV12
Crop(0,0,-2,0)
This script results in the ususal "YV12 width must be mod 4" error. Same behaviour with real video loaded via dgdecode. My AviSynth installation should be alright. At least version() shows: 2.58 Sep 19 2007 [22:10:51]

Can anyone confirm this?

IanB
14th November 2007, 03:19
Yes, the Width for final output must still be mod 4. Some functions now have a more relaxed mod 2 restriction for internal processing i.e. you can rezize to a mod 4 + 2 width and then add a 2 pixel border before final output.

j0g0
19th November 2007, 17:26
Please check DLLMain function. CoInitialzie and CoUninitialize should not be called from DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH.

IanB
19th November 2007, 23:14
@j0g0, :confused: :confused: :confused:

Very confused! I moved the CoInit/CoUninit code from DllMain to the CreateIScriptEnvironment code a fair while ago. I also now check for S_FALSE returns and immediatly CoUninit. And to add belts and braces I also save the original ThreadId and compare it in the Destructor and only call CoUninit if it matches the current ThreadId, if it does not match I leaks a COM instance, tough but better than crashing!

j0g0
20th November 2007, 11:15
@IanB:
I was looking into 2.5.7 release source code.

IanB
20th November 2007, 12:04
You can peruse the current CVS source here :- http://avisynth2.cvs.sourceforge.net/avisynth2/avisynth/src/

Wilbert
16th December 2007, 18:05
Regarding http://forum.doom9.org/showthread.php?t=132374, i think the 444toRGB conversions in Overlay are not correct. I think they should be (I commented out the old code):


/***** YUV 4:4:4 -> RGB24/32 *******/

PVideoFrame Convert444ToRGB::ConvertImage(Image444* src, PVideoFrame dst, IScriptEnvironment* env) {
// const int crv = int(1.403*255/219*65536+0.5);
// const int cbu = int(1.770*255/219*65536+0.5);
// const int cgu = int(0.344*255/219*65536+0.5);
// const int cgv = int(0.714*255/219*65536+0.5);
const int crv = int(1.402*65536+0.5); // 2*(1-Kr) = 1.4020
const int cbu = int(1.772*65536+0.5); // 2*(1-Kb) = 1.7720
const int cgu = int(0.344*65536+0.5); // 2*(1-Kb)*Kb/Kg = 0.3441
const int cgv = int(0.714*65536+0.5); // 2*(1-Kr)*Kr/Kg = 0.7141

env->MakeWritable(&dst);

const BYTE* srcY = src->GetPtr(PLANAR_Y);
const BYTE* srcU = src->GetPtr(PLANAR_U);
const BYTE* srcV = src->GetPtr(PLANAR_V);

int srcPitch = src->pitch;

BYTE* dstP = dst->GetWritePtr();
int dstPitch = dst->GetPitch();

int w = src->w();
int h = src->h();

dstP += h*dstPitch-dstPitch;
int bpp = dst->GetRowSize()/w;

for (int y=0; y<h; y++) {
int xRGB = 0;
for (int x=0; x<w; x++) {
int Y = ((srcY[x] - 16) * int(255.0/219.0*65536+0.5))>>16;
// int U = ((srcU[x] - 128) * int(255.0/239.0*65536+0.5))>>16;
// int V = ((srcV[x] - 128) * int(255.0/239.0*65536+0.5))>>16;
int U = ((srcU[x] - 128) * int(255.0/224.0*65536+0.5))>>16;
int V = ((srcV[x] - 128) * int(255.0/224.0*65536+0.5))>>16;

int r = Y + ((V * crv)>>16);
int b = Y + ((U * cbu)>>16);
int g = Y - ((V * cgv + U * cgu)>>16);

dstP[xRGB] = min(max(b,0),255);
dstP[xRGB+1] = min(max(g,0),255);
dstP[xRGB+2] = min(max(r,0),255);
xRGB += bpp;
}
srcY+=srcPitch;
srcU+=srcPitch;
srcV+=srcPitch;
dstP-=dstPitch;
}
return dst;
}

PVideoFrame Convert444NonCCIRToRGB::ConvertImage(Image444* src, PVideoFrame dst, IScriptEnvironment* env) {
// const int crv = int(1.403*65536+0.5);
// const int cbu = int(1.770*65536+0.5);
// const int cgu = int(0.344*65536+0.5);
// const int cgv = int(0.714*65536+0.5);
const int crv = int(1.402*65536+0.5); // 2*(1-Kr) = 1.4020
const int cbu = int(1.772*65536+0.5); // 2*(1-Kb) = 1.7720
const int cgu = int(0.344*65536+0.5); // 2*(1-Kb)*Kb/Kg = 0.3441
const int cgv = int(0.714*65536+0.5); // 2*(1-Kr)*Kr/Kg = 0.7141

env->MakeWritable(&dst);

const BYTE* srcY = src->GetPtr(PLANAR_Y);
const BYTE* srcU = src->GetPtr(PLANAR_U);
const BYTE* srcV = src->GetPtr(PLANAR_V);

int srcPitch = src->pitch;

BYTE* dstP = dst->GetWritePtr();
int dstPitch = dst->GetPitch();

int w = src->w();
int h = src->h();

dstP += h*dstPitch-dstPitch;
int bpp = dst->GetRowSize()/w;

for (int y=0; y<h; y++) {
int xRGB = 0;
for (int x=0; x<w; x++) {
int Y = srcY[x];
int U = srcU[x] - 128;
int V = srcV[x] - 128;

int r = Y + ((V * crv)>>16);
int b = Y + ((U * cbu)>>16);
int g = Y - ((V * cgv + U * cgu)>>16);

dstP[xRGB] = min(max(b,0),255);
dstP[xRGB+1] = min(max(g,0),255);
dstP[xRGB+2] = min(max(r,0),255);
xRGB += bpp;
}
srcY+=srcPitch;
srcU+=srcPitch;
srcV+=srcPitch;
dstP-=dstPitch;
}
return dst;
}


/******* RGB 24/32 -> YUV444 *******/

void Convert444FromRGB::ConvertImage(PVideoFrame src, Image444* dst, IScriptEnvironment* env) {
// const int cyb = int(0.114*219/255*65536+0.5);
// const int cyg = int(0.587*219/255*65536+0.5);
// const int cyr = int(0.299*219/255*65536+0.5);
const int cyb = int(0.114*65536+0.5);
const int cyg = int(0.587*65536+0.5);
const int cyr = int(0.299*65536+0.5);

const BYTE* srcP = src->GetReadPtr();
int srcPitch = src->GetPitch();

BYTE* dstY = dst->GetPtr(PLANAR_Y);
BYTE* dstU = dst->GetPtr(PLANAR_U);
BYTE* dstV = dst->GetPtr(PLANAR_V);

int dstPitch = dst->pitch;

int w = dst->w();
int h = dst->h();

int bpp = src->GetRowSize()/w;
srcP += h*srcPitch-srcPitch;

for (int y=0; y<h; y++) {
int RGBx = 0;
for (int x=0; x<w; x++) {
int b = srcP[RGBx];
int g = srcP[RGBx+1];
int r = srcP[RGBx+2];

int y = (cyb*b + cyg*g + cyr*r + 0x108000) >> 16; // 0x108000 (why not 0x100000???)
int scaled_y = (y - 16) * int(255.0/219.0*65536+0.5);
int b_y = (b << 16) - scaled_y;
int r_y = (r << 16) - scaled_y;

dstY[x] = y;
// dstU[x] = ((b_y >> 10) * int(1/2.018*1024+0.5) + 0x800000)>>16;
// dstV[x] = ((r_y >> 10) * int(1/1.596*1024+0.5) + 0x800000)>>16;
dstU[x] = ((b_y >> 10) * int(1/1.772*1024+0.5) + 0x800000)>>16;
dstV[x] = ((r_y >> 10) * int(1/1.402*1024+0.5) + 0x800000)>>16;

RGBx += bpp;
}

srcP-=srcPitch;

dstY+=dstPitch;
dstU+=dstPitch;
dstV+=dstPitch;
}
}

void Convert444NonCCIRFromRGB::ConvertImage(PVideoFrame src, Image444* dst, IScriptEnvironment* env) {
const int cyb = int(0.114*65536+0.5);
const int cyg = int(0.587*65536+0.5);
const int cyr = int(0.299*65536+0.5);

const BYTE* srcP = src->GetReadPtr();
int srcPitch = src->GetPitch();

BYTE* dstY = dst->GetPtr(PLANAR_Y);
BYTE* dstU = dst->GetPtr(PLANAR_U);
BYTE* dstV = dst->GetPtr(PLANAR_V);

int dstPitch = dst->pitch;

int w = dst->w();
int h = dst->h();

int bpp = src->GetRowSize()/w;
srcP += h*srcPitch-srcPitch;

for (int y=0; y<h; y++) {
int RGBx = 0;
for (int x=0; x<w; x++) {
int b = srcP[RGBx];
int g = srcP[RGBx+1];
int r = srcP[RGBx+2];

int y = (cyb*b + cyg*g + cyr*r + 0x8000) >> 16; // 0x8000 ???

dstY[x] = y;
// dstU[x] = ((b - y) * int(1/2.018*65536.0+0.5) + 0x800000)>>16;
// dstV[x] = ((r - y) * int(1/1.596*65536.0+0.5) + 0x800000)>>16;
dstU[x] = ((b - y) * int(1/1.772*65536.0+0.5) + 0x800000)>>16;
dstV[x] = ((r - y) * int(1/1.403*65536.0+0.5) + 0x800000)>>16;

RGBx+=bpp;
}

srcP-=srcPitch;

dstY+=dstPitch;
dstU+=dstPitch;
dstV+=dstPitch;
}
}

I'm not entirely sure about the last two functions, since i can't figure out where the numbers 2.018, 1.596 are coming from. I also put question marks after two lines of code.


When using the script:

#a = ColorBars(pixel_type="YV12")
#c1 = BlankClip(length=10, width=640, height=480, color=$000000)
#c2 = Overlay(c1, a, x=0, y=0)
#StackVertical(c2, a.ConvertToRGB32)

a = BlankClip(color=$800000).ConvertToYV12
# RGB = (128,0,0)
# YUV = (49,109,184)

c1 = BlankClip(length=10, width=640, height=480, color=$000000).ConvertToYV12
c2 = Overlay(c1, a, x=0, y=0, output="RGB32")
StackVertical(c2, a.ConvertToRGB32)

you can see the problem.

IanB
16th December 2007, 22:54
Regarding http://forum.doom9.org/showthread.php?t=132374, i think the 444toRGB conversions in Overlay are not correct. I think they should beYes I saw that thread, thanks for looking into the problem.
PVideoFrame Convert444ToRGB::ConvertImage(...
// const int crv = int(1.403*255/219*65536+0.5);
// const int cbu = int(1.770*255/219*65536+0.5);
// const int cgu = int(0.344*255/219*65536+0.5);
// const int cgv = int(0.714*255/219*65536+0.5);
const int crv = int(1.402*65536+0.5); // 2*(1-Kr) = 1.4020
const int cbu = int(1.772*65536+0.5); // 2*(1-Kb) = 1.7720
const int cgu = int(0.344*65536+0.5); // 2*(1-Kb)*Kb/Kg = 0.3441
const int cgv = int(0.714*65536+0.5); // 2*(1-Kr)*Kr/Kg = 0.7141
...
int Y = ((srcY[x] - 16) * int(255.0/219.0*65536+0.5))>>16;
// int U = ((srcU[x] - 128) * int(255.0/239.0*65536+0.5))>>16;
// int V = ((srcV[x] - 128) * int(255.0/239.0*65536+0.5))>>16;
int U = ((srcU[x] - 128) * int(255.0/224.0*65536+0.5))>>16;
int V = ((srcV[x] - 128) * int(255.0/224.0*65536+0.5))>>16;

int r = Y + ((V * crv)>>16);
int b = Y + ((U * cbu)>>16);
int g = Y - ((V * cgv + U * cgu)>>16);
...Oh my god :eek: and there are twice as many multiplies and shifts than are needed. This needs a rewrite. :D
PVideoFrame Convert444NonCCIRToRGB::ConvertImage(...
// const int crv = int(1.403*65536+0.5);
// const int cbu = int(1.770*65536+0.5);
// const int cgu = int(0.344*65536+0.5);
// const int cgv = int(0.714*65536+0.5);
const int crv = int(1.402*65536+0.5); // 2*(1-Kr) = 1.4020
const int cbu = int(1.772*65536+0.5); // 2*(1-Kb) = 1.7720
const int cgu = int(0.344*65536+0.5); // 2*(1-Kb)*Kb/Kg = 0.3441
const int cgv = int(0.714*65536+0.5); // 2*(1-Kr)*Kr/Kg = 0.7141
...Yes the coefficients are slightly imprecise. This is why I prefer to express the full equation using only the raw coefficients.
void Convert444FromRGB::ConvertImage(...
// const int cyb = int(0.114*219/255*65536+0.5);
// const int cyg = int(0.587*219/255*65536+0.5);
// const int cyr = int(0.299*219/255*65536+0.5);
...
int y = (cyb*b + cyg*g + cyr*r + 0x108000) >> 16; // 0x108000 = 128.5*65536
int scaled_y = (y - 16) * int(255.0/219.0*65536+0.5);
int b_y = (b << 16) - scaled_y;
int r_y = (r << 16) - scaled_y;

dstY[x] = y;
// dstU[x] = ((b_y >> 10) * int(1/2.018*1024+0.5) + 0x800000)>>16;
// dstV[x] = ((r_y >> 10) * int(1/1.596*1024+0.5) + 0x800000)>>16;
...This was correct. The range limit is included into the coefficients. The chroma should be limited range.
void Convert444NonCCIRFromRGB::ConvertImage(...
const int cyb = int(0.114*65536+0.5);
const int cyg = int(0.587*65536+0.5);
const int cyr = int(0.299*65536+0.5);
...
int y = (cyb*b + cyg*g + cyr*r + 0x8000) >> 16; // 0x8000 = 0.5 * 65536

dstY[x] = y;
// dstU[x] = ((b - y) * int(1/2.018*65536.0+0.5) + 0x800000)>>16;
// dstV[x] = ((r - y) * int(1/1.596*65536.0+0.5) + 0x800000)>>16;
dstU[x] = ((b - y) * int(1/1.772*65536.0+0.5) + 0x800000)>>16;
dstV[x] = ((r - y) * int(1/1.403*65536.0+0.5) + 0x800000)>>16;
...Yes this is wrong. The chroma should be max range.
I'm not entirely sure about the last two functions, since i can't figure out where the numbers 2.018, 1.596 are coming from. I also put question marks after two lines of code.2*(1-K)*255/224

IanB

Fizick
19th December 2007, 06:41
kassandro got some problem with MakeWritable
http://videoprocessing.11.forumer.com/viewtopic.php?t=99&sid=8db3e7578dc37b75f3e3657bd95fac0c

IanB
19th December 2007, 14:09
Please point him to MakeWritable bug by you, 1st October 2005.

This is where he is coming unstuckPVideoFrame df = child2->GetFrame(n, env);
AVSenvironment->MakeWritable(&df);
PVideoFrame sf = child->GetFrame(n, env);Have him move it down one line.

Fizick
19th December 2007, 19:53
OK, it is not hard in this case. So, any chance for MakeWritable be more safe in next versions?

IanB
19th December 2007, 22:17
any chance for MakeWritable be more safe in next versions?More safe how? This is another simple case of misusing the API. (And yes TSP's bump the serial# hack does improve the resilance to bad code.)

I thought you understood the issue from 2 years ago :confused:

Given the code for IsWritable() is this :-bool IsWritable() const { return (refcount == 1 && vfb->refcount == 1); }
And if I unwrap the MakeWritable() code and explicitly use only child in the following example code, can you see the obvious logic error now?PVideoFrame df = child->GetFrame(n, env);
If (!df.IsWritable()) { // refcounts are both 1
PVideoFrame df2 = env->NewVideoFrame(vi);
BitBlt(df2->GetWritePtr(), df2->GetPitch(),
df->GetReadPtr(), df->GetPitch(),
df->GetRowSize(), df->GetHeight() );
df = df2;
}
PVideoFrame sf = child->GetFrame(n, env); // Opps! vfb->refcount is now 2By using child in both GetFrame call this code is obviously always wrong. In the original example with both child and child2 it is only wrong when child == child2 via some devious script contortion.

Fizick
19th December 2007, 23:47
so, your answer is "no".
Well, i will continue do not use this function.
No problem.

May be more safe: convert makewritable to newVideoFrame, always make a new copy.

IanB
20th December 2007, 02:37
@Fizick,

Are we talking at cross purposes here :confused:

Please re-explain what you expect.

And always making a copy is a terrible idea, Blits are very expensive

Wilbert
29th December 2007, 15:25
@IanB,

Two comments :)

1) Nic reported the following issue in 2.56 (which is probably also present in the latest alpha):

AviSynth (2.56 at least) doesn't seem to report no more audio frames even if requesting a sample beyond the total number. Hence the audio would encode forever. Hopefully this quick fix to avs2asf should workaround the problem.
http://forum.doom9.org/showthread.php?p=1080451#post1080451

2) Regarding Overlay. I saw your comment in:

void Convert444FromRGB::ConvertImageLumaOnly(PVideoFrame src, Image444* dst, IScriptEnvironment* env) {

...
for (int y=0; y<h; y++) {
int RGBx = 0;
for (int x=0; x<w; x++) {
dstY[x] = srcP[RGBx]; // Blue channel only ???
RGBx+=bpp;
}
...
}
}

I always thought that only the luma of the mask was used when supplying a mask, but that's apparently wrong.

If i understand it correctly, by default (since greymask=true by default), the luma of the mask is used, at least when the mask is YUY2/YV12. Apparently when supplying a RGB mask (with greymask=true), only the blue channel (which is copied to the Y plane internally, also when the output is RGB) is used instead of the luma. I'm not sure why this is done this way, but perhaps it is better to use the luma instead or calculate the luma as (R+G+B)/3.

When greymask=false, the luma of the mask is removed and only the chroma (U/V planes) is used as mask. Nice :) Perhaps a more useful addition is to use both luma/chroma info in the mask.

Wilbert
29th December 2007, 17:50
The big test is to set the text color 100% transparent, i.e. $FF000000, so that only the halo is visible. When correct, the halo will be a consistant 1 pixel antialiased width on all sides, i.e. it should affect only 2 pixels in any given axis and the gamma corrected weight of those 2 pixels should be 64/64.
script:

v = colorbars()
c1 = subtitle(v, "180", text_color=$00FFFF00).Crop(0,0,-600,-450)
c2 = subtitle(v, "180", text_color=$FF000000).Crop(0,0,-600,-450)
v1 = c1.BicubicResize(320,240).Subtitle("Bicubic / v2.58",align=2)
v2 = c1.BilinearResize(320,240).Subtitle("Bilinear / v2.58",align=2)
v3 = c2.BicubicResize(320,240).Subtitle("Bicubic / v2.58",align=2)
v4 = c2.BilinearResize(320,240).Subtitle("Bilinear / v2.58",align=2)
s1 = StackHorizontal(v1,v2)
s2 = StackHorizontal(v3,v4)
StackVertical(s1,s2)

screenshot:

IanB
29th December 2007, 23:42
1) Nic reported the following issue in 2.56 (which is probably also present in the latest alpha):
AviSynth (2.56 at least) doesn't seem to report no more audio frames even if requesting a sample beyond the total number. Hence the audio would encode forever. Hopefully this quick fix to avs2asf should workaround the problem.http://forum.doom9.org/showthread.ph...51#post1080451Apart from a buffer bounds fix Avery donated this code has never changed. Not sure what to do here :confused:

I guess our implementation of IAVIStream::Read() is somewhat lacking. None of the possible HRESULT codes seem that appropriate for out of stream bounds access cases.

I had a troll thru Avery's code and he scrupulously avoids any interaction with out of stream bounds conditions, by checking for <0 and >=Length. So I guess this is generally a known trouble black spot in the AVIFile world.

For the end of stream case we probably should be setting *plBytes and *plSamples to zero (or the partial bytes on hitting EoS). For the before the start case hmmmm???? Fill with silence I guess.

2) Regarding Overlay. I saw your comment in:Yes I thought is was strange, hence the comment. Sh0dan wrote it that way so I guess he is best placed to explain why. My guess is it was a performance thing.

-------------------------------

And I guess from the image you approve of how the text antialiaser now works?

shirohamada
30th December 2007, 00:17
directshowsource seems to be b0rk
it loads the first frame, when seeking in vdub. it crash.

IanB
30th December 2007, 04:52
@shirohamada,

Thank you for reporting it. It has already been fixed in CVS.

sh0dan
31st December 2007, 13:55
@Wilbert: RGB-masks should be greyscale, where r=g=b for it to be used sensibly as a mask. If you want to be sure how your RGB mask responds, use greyscale() or something similar.

Wilbert
1st January 2008, 13:54
@Wilbert: RGB-masks should be greyscale, where r=g=b for it to be used sensibly as a mask. If you want to be sure how your RGB mask responds, use greyscale() or something similar.
Yes, ok thanks. I will clarify the docs slightly. What about the last comment?

When greymask=false, the luma of the mask is removed and only the chroma (U/V planes) is used as mask. Nice :) Perhaps a more useful addition is to use both luma and chroma info in the mask.

IanB
1st January 2008, 22:20
When greymask=false, the luma of the mask is removed and only the chroma (U/V planes) is used as mask. Nice Perhaps a more useful addition is to use both luma and chroma info in the mask.Greymask=True forces all calculations to use only the Y channel of the Mask clip for the effect density.

Greymask=False allows all calculations to use the Y, U & V channels of the Mask clip for effect density. Note all 3 channels are expected to be [0..255] density values. There is no 128 offset for the U or V mask channels. It does not make a lot of sense to do any RGB->YUV conversion for the Mask clip when Greymask=False as the U & V Mask channels will be offset by 128. Personally I would have disallowed a RGB mask clip with Greymask=false or directly loaded B->Y G->U & R->V to avoid the obvious clash

More or less the Mask clip channel values are used in the following manner to modulate the strength of the applicable effect.FX = SomeFunction(base[x], overlay[x]);
Mask = (opacity*mask[x])>>8;
base[x] = (base[x]*(256-Mask) + FX[x]*Mask + 128)>>8;Note when using a Mask clip even with a 255 mask value there is still 1/256th of the original base value leaking thru.

Fizick
5th January 2008, 17:37
Sorry, may it will be false alarm, but I am confused.
I try this script

colorbars()
crop(0,0,636,0)
converttoyv12()

And I got this crap:
http://avisynth.org.ru/tmp/bug.png
(for any width not mult 8, but only 4)
I tryed replace HelixYUV codec to XVid without any difference.
Media player 6.4 produce same bug.
I tryed Avisynth versions 2.5.5 to 2.5.8
Is it my system fault or Avisynth limitation?

Ebobtron
5th January 2008, 17:56
@Fizick
Must be you, works for me with the Helix YV12 decompressor in VirtualDubMod. Works in MPC and FilmCutter also. ??? :(

Good Luck

Leak
5th January 2008, 18:08
I try this script

colorbars()
crop(0,0,636,0)
converttoyv12()

And I got this crap:
http://avisynth.org.ru/tmp/bug.png
(for any width not mult 8, but only 4)
What happens when you put a ConvertToRGB() at the end? If the image looks fine then I doubt it's an AviSynth bug, but whatever is converting YV12 to RGB for display...

np: Saul Williams - Guns By Computer (Y34RZ3R0R3MIX3D)

IanB
5th January 2008, 20:57
@Fizick, ATI YV12 codec? (FourCC in info block)

tebasuna51
5th January 2008, 21:27
@Fizick, I don´t know if this can help:

Same problem than you using VirtualDubMod v1.5.10.2 (Decompressor: Xvid MPEG-4 Codec), MPC and GraphEdit (Avi decompressor -> Color Space Converter -> Video Renderer), but work fine with VirtualDub v1.7.7 (Decompressor: YCbCr 4:2:0 Planar YV12)

With ConvertToRGB() all work fine, now MPC and GraphEdit only need Color Space Converter -> Video Renderer.

Edit: and yes also ATI YV12 codec in FourCC

Wilbert
5th January 2008, 22:26
work fine with VirtualDub v1.7.7 (Decompressor: YCbCr 4:2:0 Planar YV12)
VirtualDub uses its own YCbCr -> RGB converter (for display) since a while.

Same problem than you using VirtualDubMod v1.5.10.2 (Decompressor: Xvid MPEG-4 Codec)
VirtualDubMod doesn't. So set this vidc.yv12 thingie in your registry to xvidvfw.dll or whatever MPEG-4 ASP codec you have installed. See YV12 FAQ.

Fizick
5th January 2008, 23:02
Yes, new VirtualDub has option in preferences "directly uncompress YCrCb (YUV) sources".

I reinstall HelixYUV codec, and now all is correct.
(without Color Converter in Graphedit)
But the Helix was installed previously, probably some "smart" program partially disabled it.
Thanks to all. :)

May be some moderator can cut this part of posts and merge to YUV12 faq http://forum.doom9.org/showthread.php?t=37276

Fizick
7th January 2008, 13:34
One more suggestion :)
Converttoyv12 gives throw exception error (''matrix...."), if I try convert YV12 to YV12 or YUY2 to YV12 with matrix=XXX option.
It is really not error, but sort of warning (matrix will not be used, of course). I suggest to remove the message.

IanB
7th January 2008, 21:36
@Fizick,

Yes there are a number of these "Warning" level exceptions throughout Avisynth.

For the Novice user I think they help them avoid a lot of pitfalls, but for the Advanced user they tend to cripple usage inside library functions.

We probably need to implement a graded error level, a bit like the compiler warning/error level concept.

For maximum usefullness I think being able to "Push" and "Pop" as well as just setting the tolerance level could be nice.

Thoughts?

Fizick
9th January 2008, 18:29
warning level is great idea. Somewhat similar to:

if (OPT_ErrorLevel > WARNING_LEVEL) ThrowError (...)

Wilbert
19th January 2008, 10:39
I saw that Avery is creating an 'Directshow Input Driver' for VirtualDub. I noticed the following comment of him:

Avisynth's DirectShowSource() uses PulseEvent(). This is a no-no, as PulseEvent() has known bugs in the Windows kernel with losing wakeups if a kernel APC happens at the wrong time. Thought I'd told someone about this, but I guess it couldn't hurt to go file a bug.
http://forums.virtualdub.org/index.php?act=ST&f=7&t=15093&

What does PulseEvent do, and is there a way to avoid it?

Oh, when reading the remainder of that thread, i see that you have been participating in it :)

Fizick
23rd February 2008, 00:14
v2.5.7

script:


testcard = ColorBars()
BlankClip(clip=testcard, color=$0f0fb4)


---------------------------
VirtualDub Error
---------------------------
Avisynth open failure:
Script error: the named argument "clip" was passed more than once to BlankClip
(F:\Internet\080222\AviSynth Script.avs, line 4)
---------------------------

Fizick
5th March 2008, 19:01
addition: the scipt above works well in Avisynth v2.5.5, but does not in 2.5.6 and above.
It is example from "overlay" documentation.

Probably is was canged in:

Revision 1.14 - (view) (download) (annotate) - [select for diffs]
Tue Jan 25 04:53:58 2005 UTC (3 years, 1 month ago) by ianb1957
Branch: MAIN
Changes since 1.13: +7 -4 lines
Diff to previous 1.13
BlankClip() not use implicit Last clip as Template

squid_80
5th March 2008, 20:01
Using it without the argument name works...

IanB
5th March 2008, 21:24
Okay, it's bug in the parser, you cannot name the 1st argument (bad boundary code).

DeathTheSheep
27th March 2008, 22:50
Alpha 2 has been out for a very long time, and its directshowsource is hopelessly broken. Please tell me there's some hope of an alpha 3 with fixed directshowsource--or a fixed directshowsource with the new features for alpha 2.
The entire alpha 2 is utterly useless without the power of directshowsource; has nobody cared to fix it? Or is the fixed dll/binary just not posted on sourceforge?


IanB, any word on this?

Didée
27th March 2008, 23:22
Oh, I didn't even note that DSS is broken. Seems I don't use it that often.

The entire alpha 2 is utterly useless without the power of directshowsource
Isn't there someone utterly exaggerating? I mean, example, now that we have seen the potential of VAQ 2.0 for x264, you could as well say that x264 is utterly useless with any earlier versions of VAQ. Would you please immediately stop using x264 for anything, until VAQ 2.0 is out!! :p

DeathTheSheep
28th March 2008, 00:15
Well said, indeed. But as they say, strong words are oft necessary for small change. ;)

And as regards your VAQ comment, VAQ 0.45 is very, very good--perhaps significantly more so than 0.48 (and that is no exaggeration, see the test). So I'm not always the promoter of the most modern, you see. :p

But I'm not exactly sure I should sit here silently with a broken alpha 2 when all the cool new dshowsource features have been announced but...failed to deliver. So why not let'em know somebody at least wants it working!

Wilbert
20th May 2008, 22:54
@IanB,

I was looking at ImageWriter, because I needed it :)

From the docs of ImageWriter:

# Write frame 5 to "C:\000000.PNG"
ImageWriter("", 5, 5, "png")
# note: prior to v2.56 the output filename would be "000005.PNG"

I'm not sure how that comment got there, but the frame is still saved as "000005.PNG", which is good as far as i'm concerned. So i will correct that example.

Also:
start and end are the frame range that will be written. They both default to 0 (where end=0 means last frame)
This behaviour is non-consistent (and worse it's not possible to save only the first frame using start/end). When setting start=end=0 it would be consistent to save only the first frame (as "C:\000000.PNG"). Replacing the code

// check bounds (where end=0 implies no upper bound)
if (n < start || (end > 0 && n > end))
...
AVSValue __cdecl ImageWriter::Create(AVSValue args, void*, IScriptEnvironment* env)
{
return new ImageWriter(args[0].AsClip(),
env->SaveString(args[1].AsString("c:\\")),
args[2].AsInt(0),
args[3].AsInt(0),
env->SaveString(args[4].AsString("ebmp")),
args[5].AsBool(false), env);
}

by

// in constructor:
// check bounds
if (end>vi.num_frames-1)
env->ThrowError("ImageWriter: make sure that end<framecount(clip)");
if (start>end)
env->ThrowError("ImageWriter: make sure that start<=end");

// in GetFrame:
// check bounds
if ((n<start)||(n>end))
...
AVSValue __cdecl ImageWriter::Create(AVSValue args, void*, IScriptEnvironment* env)
{
return new ImageWriter(args[0].AsClip(),
env->SaveString(args[1].AsString("c:\\")),
args[2].AsInt(0),
args[3].AsInt((args[0].AsClip()->GetVideoInfo().num_frames)-1),
env->SaveString(args[4].AsString("ebmp")),
args[5].AsBool(false), env);
}

corrects that problem.

IanB
20th May 2008, 23:26
@Wilbert,

Yes, this Last=0 concept I really do not like, but it is what has become the "Avisynth Way".

What is missing here (and in other places, I am sure, as well) is the -1 case processing.

Wilbert
21st May 2008, 21:08
@Wilbert,

Yes, this Last=0 concept I really do not like, but it is what has become the "Avisynth Way".
The behaviour among filters is not consistent. In Trim(x,0) it means the end of the clip, but in Loop(times,x,0) it means Loop(times,x,x). I guess it's too late to change any of this :)

What is missing here (and in other places, I am sure, as well) is the -1 case processing.
So (start=0, end=-1) should return frame 0, and (start=0, end=0) the whole clip?

IanB
21st May 2008, 23:50
I guess it's too late to change any of thisSigh! :(
So (start=0, end=-1) should return frame 0, and (start=0, end=0) the whole clip?Yes, in the general case end=-N should return N frames

edit mod: removed new feature request, see: http://forum.doom9.org/showthread.php?t=137991

mikeytown2
22nd May 2008, 21:31
The behaviour among filters is not consistent. In Trim(x,0) it means the end of the clip, but in Loop(times,x,0) it means Loop(times,x,x). I guess it's too late to change any of this :)

So (start=0, end=-1) should return frame 0, and (start=0, end=0) the whole clip?

You could make 2.6 break it. 2.0 to 2.5 broke some stuff. How would you fix it, which way would you consider to be the "correct" way?

Manao
23rd May 2008, 19:41
The proper way imho is trim(x,y) keeping frames [x, y[, ie includes x and excludes y. That way, trim(x,y) + trim(y,z) gives trim(x,z), which is practical and avoid headaches.

IanB
24th May 2008, 01:27
@Manao,

This is as per Stickboys Trim2() function?

Manao
24th May 2008, 07:22
Yes. The other nice thing is that trim2(x, y) does return y-x frames, not y-x+1.