Hi lists,
Obviously it is possible that simply nobody knew the answer to my question, or nobody felt like (or had the time to) replying, in which case everything's ok.
But now I have the suspect that the way I started my question, asserting there's a bug in GEM without supporting such an assertion with any fact, may have upset those who may have the answer, so that they preferred not to reply.
If that is the case, please forgive me and let me rephrase.
I am having troubles with pix_movie and pix_film when opening a huge amount of files on a relatively great number of pix_movie/pix_film objects over time, though always only few at a time.
I get a "GL: out of memory" error message and some movies are not opened, so that white blank or some previously used image or garbage appears instead of the expected movie. Eventually PD crashes. I suspect my troubles may be due to some bug in GEM, though I haven't been able to isolate the problem completely. As soon as I menage to do so, I will provide test patches to reproduce the problem, and simplified patches to illustrate what I'm trying to do. However at the moment I can't do so because the only way I can reproduce the problem is playing around a long while with a patch that is extremely complex and with a huge amount of gigabytes of videos.
In order to understand the problem better, and discard the bug theory or isolate the bug if it exists, it would help me a lot if anybody can answer any or both of the following questions:
window, does it mean that it has run out of computer RAM, or is it the graphics card's memory?
when you shouldn't indeed be running out of memory? Does it happen for example: a - when playing just one very very long video file? b - when using very few pix_movie/pix_film objects but loading new video files into them again and again and again? (i.e. files that are no longer open keep staying in memory until the memory is filled up) c - when repeatedly switching on/off various [gemhead] chain each one including a [pix_movie] and terminating on a [rectangle]? ... or performing the [open( operation on pixmovie when it is not rendering (i.e. the [gemhead] above it is turned off) d - any other situations in which you unexpectedly run out of memory (which memory, see question 1)
I did a hard work to optimize my patches (however I could still optimize them further) and I checked them over and over again and I really think there's nothing *I* am doing that could justify running out of (whichever) memory. Obviously I may be wrong.
Now I will explain what my patch does, in case anyone is curious, or in case it may give any clue about what part of what I'm doing may be the source (or triggering factor) of the problem. I don't expect everybody to read all this boring stuff, so in case you just stop here, well, thank you and see you later ;)
Here it goes.
*) In my patch, there is a huge amount of "render chains" (maybe 400), where each "render chain" is made up basically of: -a [gemhead] -a [pix_movie] or [pix_film]+[pix_texture] (or viceversa, whichever is correct, can't remember now) -a [rectangle]
*) At any given moment, at most 5 of these "render chains" are active, i.e. have their [gemhead] turned on (by sending it a 1), all the others are inactive, i.e. have their [gemhead] turned off (sending them a 0). So at most 5 rectangles (with their texture coming from a movie) are being rendered at every frame. Furthermore all pix_movie/pix_films have their "auto" flag set to 0, even the active ones. I "play" the active movies by sending them an increasing (and looping if needed) frame number in their right inlet. To the ones that belong to inactive chains, I don't even send the frame number.
*) The visible rectangles (i.e. the ones that belong to active chains, i.e. the ones that are being rendered, textured with a movie playing) are arranged in such a way that they're filling regions of the screen, sometimes overlapped sometimes not, always in a 2D-like fashion. The position of the inactive rectangles is irrelevant as they're not being rendered.
*) At any given moment, at most 50 chains are "eligible" (a word I am inventing now and whose meaning I'll explain soon). The set of "eligible" movies changes after a period of several minutes. I'll call such a period a "chapter" of the performance. During a chapter, the set of "eligible" movies keeps the same. All chains that are not "eligible" are always off during the chapter. During a chapter, AT ANY MOMENT any of the currently active chains may be turned off and any inactive "eligible" chain may be turned on - provided that no more than 5 chains are ever active at the same time
*) At the beginning of each "chapter", I perform the following operations:
-- If the pix_movie/pix_film in that chain has never opened any file yet, I do nothing -- If the pix_movie/pix_film in that chain had a file open, I "close" it (see below what I mean by "close").
pix_movie/pix_film objects by sending it an [open( message with a valid filename. This may "replace" a file previously opened on that pix_movie/film, or not if it is the first time that pix_movie is chosen as "eligible".
*) REGARDING THE "CLOSE" OPERATION. Regretfully, afaik, pix_movie/pix_film doesn't recognize any "close" message to close the file it has opened. I personally think that's an oversight of the developers, I mean, such a function should exist. You should be able to tell pix_movie that you're no longer using that file. One reason for that is that while the file is open by a pix_film, the operating system won't let you overwrite or rename it. If you're not really using that file any more, you have to close PD or open another one in order to "free" it. Indeed I think that even opening another one won't always free/unlock the file - I have to check that out. I tried 3 "implementation" of my "closing" operation:
"eligible". It will stay open untill the chain is chosen again as eligible in another chapter and another file is loaded into it. 2) Sending a [open( with an invalid file name. This closes the previous file but doesn't open a new one since it can't find it 3) Sending a [open( message to open a 1-frame-long video of all black pixels (which however won't ever be used). This black one-frame movie will occupy some memory, but certainly less than the movie that was previously open.
Now, why not just implementation (1) (which is a non-implementation)? Because. Consider what happens when I start the performance: I have at most 50 videos "open", of which only 5 or less actually playing (i.e. actually reading them in realtime from disk and displaying on screen). At any moment I may stop one video and access ANY of the 50 videos. I have tested this very very much, and it is quite reliable: i.e., "jumping" from any video to any other almast always is performed in really real time, i.e., randomly accessing any of the 50 currently open videos is fast enough. Obviously sometimes I do get a little noticeable pause, or some jerkyness, but not too much. With more than 50 videos this is not possible (obviously this number will vary from machine to machine, in my case it is around 50), i.e. access times become long, and accumulating stress will eventually make the system unresponsive or even make it crash. I guess this is because somebody, either the operating system or GEM itself, is keeping a fragment of each currently open file (around the "playhead" I guess) in a cache. Then, suppose I change chapter, i.e. I change the set of videos that I am actually using. If I open the new ones on different pix_movie objects (which is often my case) and do nothing in order to close the ones I was previously using, I now have around 100 files open, though I am gonna use only 50 of them. Now the system becomes unreliable and unstable. Every time I try to access a video that I hadn't played before, the access time is slow and the playback jerky for a few seconds. I guess this is because the system has no clue to the fact that I am not gonna use the first 50 files any more, so it doesn't take them off the cache. Since there's not sufficient RAM to keep the 100 files in the cache, every time I access a new one, it probably discards the oldest one (but only one) and caches the new one; but only one at a time. Or maybe it is caching everything, but since there's not enough physical RAM it is using virtual RAM. In both cases every file access implies much disk reading/writing. When I start re-using videos that I have already been accessing (the new 50 ones), it becomes fast.
So, that's why I resorted to implementation (2). And indeed it worked!!! Now, when I change "chapter", the new set of video works just as fast and reliable as the first one, and so does the third, and the fourth, and so on. Except that at some point I get the "GL: out of memory" and everything crashes.
Note that this very same trick didn't work on another version of GEM I tested. That is, (if my previous hypothesis of the caching mechanism is correct) it seems like "closeing" the files didn't empty the supposed cache.
So, why implementation (3)? Because (2) is slow. When I tell it to open a file which doesn't exist, it retries a few times untill it gives up. It also outputs a huge lot of debugging messages in the PD window and I think that also takes time. If I open a small but existing file, it finds it at the first try and takes less time. This will waste a little memory but shouldn't be too much.
By the way, I get the GL-out-of-memory issue both with implementaion (2) and (3).
Now, I am using more pix_movie/pix_film objects than is really necessary. I am doing this for a matter of programming style. Since I am doing different things with these video, I have created abstractions that play with videos in different ways, and it is easier to do that by having them include the pix_movie objects inside them. I can change my approach by building a sort of "video server" with 50 pix_movie/pix_film objects and sending it commands in order to change the way videos are used, and to load video files.
But I dubt to take that effort now, since I am not sure at all that the out-of-memory problem I'm having would be solved. If there's some memory leak, I may reduce it by using that approach, but I would only be delaying the problem. It shouldn't be running out of memory even doing things the way I'm doing, so how can I be sure I won't run out of memory by doing them another way...
That's why I need to know more about the issue. I need to take a decision: change my patch design or change platform (I am already trying out Max/Jitter in the meantime).
If anybody at all has read all the message to this point, well... I really appreciate that and I am really grateful.
Bye m.
----- Original Message ----- From: "Matteo Sisti Sette" matteo.sistisette@email.it To: pd-list@iem.at; gem-dev@iem.at Sent: Tuesday, July 24, 2007 9:31 PM Subject: [GEM-dev] "GL: out of memory" - which memory?
Hi,
I am experiencing a bug in GEM, some kind of bad memory leak.
Before I try to report the bug in detail (which I will) or even just to isolate it better, I need to know one thing: When the error message "GL: out of memory" appears on the PD output window, does it mean that it has run out of computer RAM, or is it the graphics card's memory?
Thanks in advance matteo sisti sette
-- Email.it, the professional e-mail, gratis per te: http://www.email.it/f
Sponsor: Problemi di Liquidità ? Con Logos Finanziaria 30.000 ? in 24 ore a dipendenti e lavoratori autonomi con rimborsi fino a 120 mesi, clicca qui
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=2911&d=24-7
GEM-dev mailing list GEM-dev@iem.at http://lists.puredata.info/listinfo/gem-dev
-- Email.it, the professional e-mail, gratis per te: http://www.email.it/f
Sponsor: Non perderti nella giungla di facili promesse, Logos ti da credito sempre!
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=6559&d=29-7