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. |
1st June 2016, 09:36 | #1 | Link |
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) |
1st June 2016, 11:14 | #3 | Link |
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 |
1st June 2016, 17:16 | #5 | Link |
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) Last edited by Gavino; 1st June 2016 at 18:18. Reason: Had 939 instead of 932 as original clip height - effect is the same |
1st June 2016, 17:52 | #6 | Link |
HeartlessS Usurer
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) 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: 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; 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)
__________________
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. |
1st June 2016, 20:20 | #7 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,431
|
Quote:
Otherwise, the animation will use integer interpolation and you won't get a smooth variation. |
|
1st June 2016, 20:35 | #8 | Link |
HeartlessS Usurer
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. |
1st June 2016, 23:16 | #9 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,431
|
Quote:
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. |
|
2nd June 2016, 09:51 | #10 | Link |
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 |
2nd June 2016, 11:26 | #11 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,431
|
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. |
3rd June 2016, 18:10 | #12 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
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. |
Tags |
crash, memory, stackvertical |
Thread Tools | Search this Thread |
Display Modes | |
|
|