Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 1st June 2016, 09:36   #1  |  Link
jsryork
Registered User
 
Join Date: Mar 2016
Posts: 3
Crash using StackVertical

Hi,
I have been working on an abstract animation moving cropped images around the screen.
I have encountered a crash:
Traceback (most recent call last):
File "avsp.pyo", line 8727, in OnMenuVideoNextFrame
File "avsp.pyo", line 14183, in ShowVideoOffset
File "avsp.pyo", line 13855, in ShowVideoFrame
File "avisynth.pyo", line 462, in GetFrame
WindowsError: exception: access violation writing 0x04B36000

Attached is a reduced example which shows the crash. I am using Avisynth.dll 2.6.0.6. I see the same effect with both Avspmod 2.5.1 or VirtualDub 1.10.5. I see the same effect on both my desktop (HP XW6600, 16Gb ram, Win7 Pro) and my laptop (HP G7, 6Gb ram, Win7 Home Premium).

The problem seems to relate to using StackVertical when I slide from one image into another vertically. Similar coding for a horizontal slide is OK. I have a 'safe' work-around not using StackVertical, but it is considerably slower. So I am not blocked on my project, but there is resumably an underlying issue which may give rise to other problems.

Thanks for a splendid piece of software.

John Robinson

Last edited by tebasuna51; 1st June 2016 at 11:27. Reason: removed attachment (included in next post)
jsryork is offline   Reply With Quote
Old 1st June 2016, 10:02   #2  |  Link
Groucho2004
 
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
Post your complete script.

Edit: Don't attach the script, post it embedded in [code] tags.

Last edited by Groucho2004; 1st June 2016 at 10:09.
Groucho2004 is offline   Reply With Quote
Old 1st June 2016, 11:14   #3  |  Link
jsryork
Registered User
 
Join Date: Mar 2016
Posts: 3
Here is the code

Sorry, here is the code:
Code:
# using avspmod 2.5.1
# using avisynth.dll 2.6.0.6
# using Windows 7 Pro, HP xw6600, 16Gb ram

# start of scene:psq_seq_0_tile_0
global bn_border = 1
# import ("..\common\my_funcs.avs") 
global use_pc_range = false # scale RGB values
global fpbeat = 19.5 # frames per 'beat'
global fpbar = 39.0 # frames per 'bar'
global dest_width = 1920
global dest_height = 1080
global my_fps = 25
#Start sequence:psq_seq_0_tile_0
#Still_subimage:still_bg_si_0_0:1:1@0:0:932:932:fetching:

global p6mp_w = 2816
global p6mp_h = 2112

Function slide_clip_before_after_l_to_r(clip before, clip after, int start_frame, int move_frames)
{
	return StackHorizontal(after, before).Animate(start_frame, start_frame + move_frames - 1, "Crop", before.width, 0, 0, 0,  0, 0, -after.width, 0)
}

Function slide_layer_t_to_b(clip before, clip after, float yfrac)
{
	rv_clip = BlankClip(pixel_type = "RGB32", before.Framecount, width=before.width, height=before.height, color=$ffffff)
	rv_clip = rv_clip.Layer(before.ResetMask, "add", 257, 0, Floor(before.height * yfrac)) 	
	return (yfrac <= 0.01) ? before : (yfrac >= 0.99) ? after : rv_clip.Layer(after.ResetMask.Crop(0, Floor(after.height * (1.0 - yfrac)), 0, 0), "add", 257, 0, 0) 	
}

Function slide_clip_before_after_t_to_b(clip before, clip after, int start_frame, int move_frames)
{
	return StackVertical(after, before).Animate(start_frame, start_frame + move_frames - 1, "Crop", 0, before.height, 0, 0,   0, 0, 0, -after.height)
}

Function slide_clip_before_after_t_to_b_safe(clip before, clip after, int start_frame, int move_frames)
{
	return Animate(start_frame, start_frame + move_frames - 1, "slide_layer_t_to_b", before, after, 0.0, before, after, 1.0)
}

white_1s = BlankClip(pixel_type = "RGB32", my_fps, width=dest_width, height=dest_height, fps=my_fps, color=$ffffff, stereo = true)
still_6mp_red = BlankClip(pixel_type = "RGB32", 1, width=p6mp_w, height=p6mp_h, fps=my_fps, color=$AA0000)
still_6mp_red_br = still_6mp_red.BilinearResize(932, 932, 480, 60, 1941, 1941 )
d_39 = still_6mp_red_br.Loop(39)

still_6mp_blue = BlankClip(pixel_type = "RGB32", 1, width=p6mp_w, height=p6mp_h, fps=my_fps, color=$0000BB)
still_6mp_blue_br = still_6mp_blue.BilinearResize(932, 932, 480, 60, 1941, 1941 )
v_39 = still_6mp_blue_br.Loop(39)

block_0_0_0_0_2_tb = slide_clip_before_after_t_to_b(d_39, v_39, 4, 24).AddBorders(bn_border, bn_border, bn_border, bn_border, $000000).ResetMask
block_0_0_0_0_2_lr = slide_clip_before_after_l_to_r(d_39, v_39, 4, 24).AddBorders(bn_border, bn_border, bn_border, bn_border, $000000).ResetMask
block_0_0_0_0_2_tb_safe = slide_clip_before_after_t_to_b_safe(d_39, v_39, 4, 24).AddBorders(bn_border, bn_border, bn_border, bn_border, $000000).ResetMask

# show preview in Avspmod, step from frame 4 to 5, with following results
return block_0_0_0_0_2_tb # error : WindowsError: exception: access violation writing 0x0C066000
return block_0_0_0_0_2_lr # ok
return block_0_0_0_0_2_tb_safe # ok
jsryork is offline   Reply With Quote
Old 1st June 2016, 11:57   #4  |  Link
Groucho2004
 
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
I'm no avs debugging specialist like StainlessS but it seems that "-after.height" in "slide_clip_before_after_t_to_b" is the culprit and returns an invalid value at frame #5.
Groucho2004 is offline   Reply With Quote
Old 1st June 2016, 17:16   #5  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
The problem arises from applying Animate() to Crop(), varying both the top and bottom parameters in parallel (from (932, 0) at frame 4 to (0, -932) at frame 27).

Because the variation in these parameters over the animation (932) is not a multiple of the number of animation steps (23), truncation after integer division occurs when calculating the intermediate values at each frame.
Since top is positive and bottom is negative, the truncation affects them differently, so they don't actually move precisely in parallel - the values at frame 5 are (891, -40) and the height of the resulting Crop is one pixel greater than it should be (933 instead of 932).
This produces an access violation when the unexpectedly larger frame is written. (Animate() checks that the dimensions of the starting and ending frames match, but not the intermediate ones.)

You can fix this by animating only the top parameter and explicitly setting the height to a constant value.
Code:
 ... Animate(..., "Crop", 0, before.height, 0, after.height,   0, 0, 0, after.height)
(Alternatively, animate a resizer instead of Crop(), and use the floating point arguments src_top etc to get a smoothly varying change)
__________________
GScript and GRunT - complex Avisynth scripting made easier

Last edited by Gavino; 1st June 2016 at 18:18. Reason: Had 939 instead of 932 as original clip height - effect is the same
Gavino is offline   Reply With Quote
Old 1st June 2016, 17:52   #6  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Arh, beaten by some visitor

Like what G said,
decomposed
Code:
Function slide_clip_before_after_t_to_b(clip before, clip after, int start_frame, int move_frames) {    
	cc=StackVertical(after, before)
### Animate (clip, int start_frame, int end_frame, string filtername, start_args, end_args)
    cc.Animate(start_frame, start_frame + move_frames - 1, 
        \ "Crop",
        \ 0, before.height,   0,              0,   
        \ 0,             0,   0,  -after.height)
    return Last
}

red   = BlankClip(length=39,width=932,height=932,pixel_type="RGB32",fps=25,color=$AA0000)
blue  = red.BlankClip(color=$0000BB)
                                                       # EXCEPTION BELOW WHEN ADDBORDERS
return slide_clip_before_after_t_to_b(red,blue, 4, 24) #.AddBorders(1,1,1,1,0)
alternative keeping crop widths and height same (result MUST be same, clip size cannot vary)
Code:
Function slide_clip_before_after_t_to_b(clip before, clip after, int start_frame, int move_frames) {    
	cc=StackVertical(after, before)
    cc.Animate(start_frame, start_frame + move_frames - 1, 
        \ "Crop",
        \ 0, before.height,   Before.Width,  Before.height,   
        \ 0,             0,   Before.Width,  Before.height)
    return Last
}

red   = BlankClip(length=39,width=932,height=932,pixel_type="RGB32",fps=25,color=$AA0000)
blue  = red.BlankClip(color=$0000BB)

return slide_clip_before_after_t_to_b(red,blue, 4, 24).AddBorders(1,1,1,1,0)
EDIT: G2004, you flatter me

EDIT: These are numbers I figure (rel start frame [float calc, addition at each stage, loses a bit of precision <done quick>])
Code:
00000004	17:35:30	RT_DebugF: 0 ] 932.000000  0.000000	
00000005	17:35:30	RT_DebugF: 1 ] 891.478271  -40.521740	
00000006	17:35:30	RT_DebugF: 2 ] 850.956543  -81.043480	
00000007	17:35:30	RT_DebugF: 3 ] 810.434814  -121.565216	
00000008	17:35:30	RT_DebugF: 4 ] 769.913086  -162.086960	
00000009	17:35:30	RT_DebugF: 5 ] 729.391357  -202.608704	
00000010	17:35:30	RT_DebugF: 6 ] 688.869629  -243.130447	
00000011	17:35:30	RT_DebugF: 7 ] 648.347900  -283.652191	
00000012	17:35:30	RT_DebugF: 8 ] 607.826172  -324.173920	
00000013	17:35:30	RT_DebugF: 9 ] 567.304443  -364.695648	
00000014	17:35:30	RT_DebugF: 10 ] 526.782715 -405.217377	
00000015	17:35:30	RT_DebugF: 11 ] 486.260986 -445.739105	
00000016	17:35:30	RT_DebugF: 12 ] 445.739258 -486.260834	
00000017	17:35:30	RT_DebugF: 13 ] 405.217529 -526.782593	
00000018	17:35:30	RT_DebugF: 14 ] 364.695801 -567.304321	
00000019	17:35:30	RT_DebugF: 15 ] 324.174072 -607.826050	
00000020	17:35:30	RT_DebugF: 16 ] 283.652344 -648.347778	
00000021	17:35:30	RT_DebugF: 17 ] 243.130600 -688.869507	
00000022	17:35:30	RT_DebugF: 18 ] 202.608856 -729.391235	
00000023	17:35:30	RT_DebugF: 19 ] 162.087112 -769.912964	
00000024	17:35:30	RT_DebugF: 20 ] 121.565369 -810.434692	
00000025	17:35:30	RT_DebugF: 21 ] 81.043625  -850.956421	
00000026	17:35:30	RT_DebugF: 22 ] 40.521885  -891.478149	
00000027	17:35:30	RT_DebugF: 23 ] 0.000145   -931.999878
EDIT: But of course nicely smoother less jittery if using resize instead of crop.

EDIT; Like so
Code:
Function slide_clip_before_after_t_to_b(clip before, clip after, int start_frame, int move_frames) {
    w=before.width  h=before.height    
	cc=StackVertical(after, before)
    cc.Animate(start_frame, start_frame + move_frames - 1, 
        \ "Spline36Resize",
        \ w, h,   0,   h,  w,  h,   
        \ w, h,   0, 0.0,  w,  h)
    return Last
}

red   = BlankClip(length=39,width=932,height=932,pixel_type="RGB32",fps=25,color=$AA0000)
blue  = red.BlankClip(color=$0000BB)

return slide_clip_before_after_t_to_b(red,blue, 4, 24).AddBorders(1,1,1,1,0)
Although jumps are so big as to make little difference to smoothness, but probably better method to adopt in general.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 1st June 2016 at 18:33.
StainlessS is offline   Reply With Quote
Old 1st June 2016, 20:20   #7  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by StainlessS View Post
Code:
    cc.Animate(start_frame, start_frame + move_frames - 1, 
        \ "Spline36Resize",
        \ w, h,   0,   h,  w,  h,   
        \ w, h,   0, 0.0,  w,  h)
It's worth emphasising that you must use that 0.0 there (for the varying argument) and not just plain 0
Otherwise, the animation will use integer interpolation and you won't get a smooth variation.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 1st June 2016, 20:35   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Yep thank you G, that was an afterthought addition (initially missed it myself), perhaps I should have made the importance more explicit.

I am though unsure as to why the original error reveals itself at AddBorders() statement (bug ?, exception needs investigation).

EDIT: Just checked with AVS+ (r1576) and also has exception.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 1st June 2016 at 20:50.
StainlessS is offline   Reply With Quote
Old 1st June 2016, 23:16   #9  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by StainlessS View Post
I am though unsure as to why the original error reveals itself at AddBorders() statement (bug ?, exception needs investigation).
AddBorders() is getting its input frames from Animate(), the previous filter in the chain.
For frame 5 (in the example above) it receives a frame that is one row bigger than it was told by Animate() to expect, so it writes beyond the end of its frame buffer when constructing its output data.

Is it a bug?
Well, the original error is in the script itself (erroneous argument combination to Animate()), but it would be better if it was detected and reported gracefully instead of crashing.
However, it cannot be detected until run-time, so it's not clear what action could be taken.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 2nd June 2016, 09:51   #10  |  Link
jsryork
Registered User
 
Join Date: Mar 2016
Posts: 3
Thanks for the solutions

Thanks to all for your prompt explanation and solutions.

I am still a bit puzzled as to why the StackHorizontal was OK.

But now I can use the faster coding (I will check if I can see a speed difference between animating Crop or a Resizer). I use similar coding in some other areas (scrolling credits, for instance), so I will update those for a floating-point interpolation, to see if they appear smoother.

Great support, thanks guys.

John
jsryork is offline   Reply With Quote
Old 2nd June 2016, 11:26   #11  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by jsryork View Post
I am still a bit puzzled as to why the StackHorizontal was OK.
The horizontal case still goes wrong since, on the first frame into the animation, the Crop() produces a frame that is one pixel wider than expected.
However, in this case AddBorders() doesn't crash - the way the code happens to be written, the extra pixel just replaces the right-hand border and you (sort of) get away with it.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 3rd June 2016, 18:10   #12  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by Gavino View Post
and you (sort of) get away with it.
There is a similar-ish "sort of get away with it" in C.

Many noobie C/CPP proggers think that its OK to not add 1 to strlen() when allocating a string buffer (for the nul term sentinel).
Reason being that for small strings [strlen() 7 or less], you also "sort of get away with it".
You get away with it because the library functions (malloc/new) allocate in blocks of 8 bytes. 8 byte block size due to
optimizations in the library code and also because malloc pointer has to be castable to a pointer of any type (including alignment).
Optimization reasons include, it is more efficient to have minimum size allocated as 8 bytes as this reduces memory fragmentation
and does away with extended search times looking for a free memory block that is big enough to satisfy a malloc request.
A second optimization is that a free memory block uses it's OWN memory (1st 8 bytes) to store its size (4 bytes) and a pointer
to the next free memory block (4 bytes).
So, a noobie progger will get away with it when requesting a string of eg 7 bytes length when 8 are actually required, as 8 bytes are actually
given, (only 7 of which belong to the caller). The problem arises when noobie requests 8 bytes for strlen()==8 string and 9 bytes
are actually required, malloc will in such case only carve off 8 bytes, just as requested, and bang!!! noobie got a problem.

For 64 bit malloc/new, it is likely that minimum block size will be 16 bytes, giving noobies even more confidence that they are doing it right.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 3rd June 2016 at 18:19.
StainlessS is offline   Reply With Quote
Reply

Tags
crash, memory, stackvertical

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 11:02.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.