JuliaIO / VideoIO.jl

Reading and writing of video files in Julia via ffmpeg
https://juliaio.github.io/VideoIO.jl/stable
Other
128 stars 53 forks source link

segfault on closing the TK window #32

Closed pfitzseb closed 10 years ago

pfitzseb commented 10 years ago

Hey there, while the following minimal example works (although veeeery slowly, something like maybe 5 frames/second)

import ImageView
import VideoIO
v=VideoIO.testvideo("annie_oakley")
VideoIO.playvideo(v)

on Windows, I get a segfault when I close the TK window. I can't reproduce that with the TK example program, so I'll just file that issue here. If it is indeed a problem with TK I can file it there, too.

Error message:

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x27c9cede -- render_to_cairo at C:\Users\...\julia\v0.3\Tk\src\tkwidget.jl:368
render_to_cairo at C:\Users\...\julia\v0.3\Tk\src\tkwidget.jl:368
configure at C:\Users\...\julia\v0.3\Tk\src\tkwidget.jl:236
view at C:\Users\...\julia\v0.3\ImageView\src\display.jl:347
timholy commented 10 years ago

Which TK example programs did you try? In particular, did you try the Canvas example? (The one implementing manipulate.)

What happens if you say include("runtests.jl") from inside ImageView's test folder? Does the example with the player (the green circle) also play very slowly?

pfitzseb commented 10 years ago

I think you're on to something there. It looks like there were some problems with installing ImageMagick which might explain things. When running runtests.jl I get

ERROR: RegistryKeyLookupFailed `CoderModulesPath' @ error/module.c/GetMagickModu
lePath/662
 in error at error.jl:21
 in error at C:\Users\...\julia\v0.3\Images\src\ioformats/libmagickwand.jl:
119
 in readimage at C:\Users\...\julia\v0.3\Images\src\ioformats/libmagickwand
.jl:197
 in imread at C:\Users\...\julia\v0.3\Images\src\io.jl:215
 in imread at C:\Users\...\julia\v0.3\Images\src\io.jl:113
 in testimage at C:\Users\...\julia\v0.3\TestImages\src\TestImages.jl:22
 in include at boot.jl:245
 in include_from_node1 at loading.jl:128
 in include at boot.jl:245
 in include_from_node1 at loading.jl:128
while loading C:\Users\...\julia\v0.3\ImageView\test\tile.jl, in expression
 starting on line 6
while loading C:\Users\...\julia\v0.3\ImageView\test\runtests.jl, in expres
sion starting on line 1

Right now I can't install ImageMagick manually since I'm no admin, but I'll report back if I get it to work.

I only tried the first example given in examples/README.md which worked fine. Following your suggestion I tried running examples/manipulate.jl but that fails because

ERROR: `min` has no method matching min(::UnitRange{Int64})
 in slider at C:\Users\...\julia\v0.3\Tk\examples\manipulate.jl:43
 in include at boot.jl:245
 in include_from_node1 at loading.jl:128
 in reload_path at loading.jl:152
 in _require at loading.jl:67
 in require at loading.jl:51
while loading C:\Users\...\julia\v0.3\Tk\examples\manipulate.jl, in express
ion starting on line 177

If I replace those calls with minimum() I get

has not defined
 in callback_add at C:\Users\...\julia\v0.3\Tk\src\core.jl:206
 in anonymous at C:\Users\...\julia\v0.3\Tk\examples\manipulate.jl:149
 in map at abstractarray.jl:1328
 in manipulate at C:\Users\...\julia\v0.3\Tk\examples\manipulate.jl:149
 in include_string at loading.jl:97

If I replace the call to has() with haskey() I don' get any errors, and everything works.

timholy commented 10 years ago

Wow, those examples haven't been updated in a long time. You can replace those min calls with minimum, and has has probably changed to in or contains (I'm short on time, or I'd look up that line of code).

Regarding your ImageMagick installation, you're the second such report this morning: https://github.com/timholy/Images.jl/issues/181. Something is borked in Windows/ImageMagick land...

pfitzseb commented 10 years ago

Heh, obviously. I got the manipulate.jl example to work and the plotting now works to (as in my edit above, don't know if you've see that). Still, is the segfault related to the problems with ImageMagick or is that a different issue?

timholy commented 10 years ago

ImageMagick is separate. Makes testing a little inconvenient, but we can work around that.

With the plotting example, does it segfault when you close the window? If not, then it's either in ImageView or VideoIO. You should be able to bypass your ImageMagick problem with

using ImageView
include("test4d.jl")
view(img)

in the ImageView/test directory. See whether playing that works at speed (should be approx 30fps) and whether it segfaults when you close the window.

pfitzseb commented 10 years ago

Alright. The Tk/examples/manipulate.jl example does not segfault and neither does ImageView/test/test4d.jl. The latter works pretty smoothly - a lot better then the video.

Oh, and the problem I had with has vs haskey is in Tk/src/core.jl, not in any example so that might be worth fixing.

timholy commented 10 years ago

OK, so these are VideoIO issues, not ImageView issues. Just wanted to check, and potentially save @kmsquire some headaches.

Take it away, @kmsquire!

kmsquire commented 10 years ago

:-) Thanks for trying, Tim.

@Varanas, I should be able to look at this tonight or tomorrow. I don't have a Windows machine, but I have run into the Tk segfaults on LInux on occasion. I'm wondering if we're closing the Tk window while it's being updated.

pfitzseb commented 10 years ago

I just tried my first example again on another machine and could reproduce the segfault as well as the super slow video playback. My guess is that the two are somewhat connected and that your suspicion might very well be correct.

kmsquire commented 10 years ago

@Varanas, regarding the speed, would you be able to run the profiler, so we can figure out where most of the time is being spent? If you haven't done this before, Tim Holy's ProfileView package is really nice (https://github.com/timholy/ProfileView.jl).

Also, what version of Tk do you have installed? If it's less than Tk 8.6, would you be able to try with that version?

timholy commented 10 years ago

My suspicion is that sleep is very inaccurate on Windows---from my limited experience, Windows pretty much stinks at timing. (I think the profiler doesn't work all that well on Windows, either.)

You could also comment out the sleep line and see how fast it plays without it.

pfitzseb commented 10 years ago

Okay, so I tried profiling, but Julia still segfaults after the video is finished and I try to print() or view() the profiler's gathered information. I then commented out this call to sleep(1/f.framerate) and I do not get much of an improvement. It certainly plays faster, but nowhere near what I get from a playback in VLC. Curiously, the task manager shows 35% CPU load for Julia... calls to sleep() don't really seem to be a problem.

From what I can see in WinRPM, I seem to have TK 8.5 installed. How would I install the newer version? Is there some way to do that with WinRPM.jl or would I need to build it myself?

timholy commented 10 years ago

I just did some profiling on Linux. If I disable the sleeping, then I get playback that is quite a bit faster than real time. Nevertheless, it's clear the performance is nowhere near where it could be. Interestingly, the frame-by-frame display ends up being dominated by a surprising component: the creation of the callbacks at this line. In the "proper" way of using ImageView, we'd pass the whole movie as an object, and so those callbacks would only be created once at the beginning and not affect the frame-by-frame performance.

@Varanas, it does seem possible that callback creation is even slower under Windows than Linux, and that would fit with your observation that the tile4.jl demo works more smoothly. If you were curious, you could try commenting out the line that creates the callbacks and see if that improves your performance.

kmsquire commented 10 years ago

I just merged Tim's PR #33, which effectively does this. (I haven't tagged a new version yet, but likely will tonight.) @Varanas, can you try this when you get the chance? Hopefully this helps the speed issue.

Regarding Tk 8.5, it looks like that's all that's available through WinRPM/Suse's build servers right now. It might be that you could build it yourself and install it somewhere VideoIO could find it, but I'm not quite sure how to do that. If you want to try, though, we can ping some Windows people who might be able to help out.

The segfault still probably needs some work--I'm going to try to debug that on Linux right now, where I've seen it before.

kmsquire commented 10 years ago

Okay, I've just fixed a missing NULL check in Tk.jl, which I think will address the segfault issue, and tagged both Tk.jl and VideoIO.jl.

@Varanas, can you run Pkg.update() and try again, and let us know what happens?

pfitzseb commented 10 years ago

Alright, so I updated and the segfault is gone. As expected, I get an error when closing the video mid-playback. And Tim's fix has improved performance a lot: I get a @time of 30.3 seconds as opposed to the ~24 seconds of the actual video (and there's some time until the video actually starts).

The segfault I was getting when profiling yesterday turns out not to be related to VideoIO but to profiling itself... I'll open a new issue at julia's repo (here)

kmsquire commented 10 years ago

Great, thanks for the update! Just to be clear, is the 30 seconds with or without the sleep in the loop? I'm just curious how much of a performance gap we still have.

pfitzseb commented 10 years ago

That's with the latest verison of VideoIO without any edits on my part. If I comment the sleep() out, it takes about 2 seconds form the second call on. And the 30s aren't accurate either, I think the compile-time was included there. After compilation, it's more like 27s - so not all that much difference to the actual length of the video. Thanks for your help, guys!

kmsquire commented 10 years ago

Thanks for your help and patience in testing and debugging! We should be able to get to the point eventually where things run at (at least) the proper speed. Cheers!