Log in

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


Pages : 1 [2] 3

Ebobtron
18th September 2007, 04: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, 21: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
19th September 2007, 23: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, 05:36
discussion about comments:
http://forum.doom9.org/showthread.php?t=94768

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

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

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

Leak
20th September 2007, 20: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, 00: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, 17: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, 15: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, 20: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, 15:06
Some new screenshots (from latest CVS). Looks much better i think.

IanB
7th October 2007, 00: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, 15: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, 13:48
Probably so people who used the public draft got it wrong ;)

Fizick
16th October 2007, 16: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