4 Replies Latest reply: Oct 24, 2011 4:36 AM by 895898 RSS

    Possible memory leak when playing videos in a loop

    848203
      Hi,
      i'm developing an application that plays video files in an infinite loop. I've created a small sample application which just plays a couple of videos all over again but it seems to be leaking. I can't find the source of my leak in my code and i am pretty desperate. I've tried playing various videos (wmv, avi (divx), and flv) with the same result - exception (or in some cases a blank screen in the GUI and processor activty on that process). The program didn't release the file handles to any of the videos rendered by ffdshow (i'm using k-lite codec pack). It did release handles in case of playing .wmv files but the program resulted in an exception too. The last time the program stopped after 56 cycles (== after playing 56 video files). Here is my source code (two source files in a package called "videotest"):

      Main.fx
      package videotest;
      
      import javafx.stage.Stage;
      import javafx.scene.Scene;
      import javafx.scene.media.MediaView;
      import videotest.VideoCreator;
      
      def vids = ["c:/Movie1.wmv", "c:/movie.mov"];
      
      var scene:Scene;
      
      def mediaView = MediaView {
          
          preserveRatio: true;
          fitWidth: bind scene.width;
          fitHeight: bind scene.height;
          x: 0;
          y: 0;
      }
      
      Stage {
          title: "Application title"
          scene: scene = Scene {
              width: 250
              height: 80
              content: mediaView;
          }
      }
      
      var dur:Duration;
      var vidCreator:VideoCreator;
      var count:Integer = 0;
      
      function addVid():Void {
          vidCreator = VideoCreator {
              mediaView: mediaView;
              videoPath: vids[count++ mod vids.size()];
              onDone: function():Void {
                  println("cycle {count} done");
                  vidCreator = null;
                  addVid();
              }
          };
          vidCreator.play();
      }
      
      addVid();
      ... and the VideoCreator class
      package videotest;
      
      import javafx.scene.media.MediaView;
      import javafx.scene.media.MediaPlayer;
      import javafx.scene.media.Media;
      import javafx.scene.media.MediaError;
      
      public class VideoCreator {
          
          public-init var videoPath:String;
          public-init var mediaView:MediaView;
          var duration:Duration;
          var player:MediaPlayer;
          public-init var onDone:function():Void;
      
          init {
              this.player = mediaView.mediaPlayer = MediaPlayer{
                  media: Media{
                      source: videoPath;
                  };
                  mute: true;
              };
              this.duration = player.media.duration;
              this.player.onError = function(me:MediaError):Void {
                  println(me.message);
              };
              this.player.onEndOfMedia = function():Void {
                          player.media = null;
                          player.stop();
                          this.onDone();
                      };
      
              this.mediaView.mediaPlayer = player;
          }
      
          public function getDuration():Duration {
              println("Duration: {this.duration.toSeconds()}");
              return this.duration;
          }
      
          public function play():Void {
              player.play();
          }
      
      }
      Memory Consuption graph (Netbeans profiler): http://img156.imageshack.us/i/memoryconsumption.jpg/
      Initialized classes snapshot: http://img820.imageshack.us/i/liveobjects.jpg/

      I'm running Windows XP SP3, Java 1.6.0_24 and JFX 1.3.1

      Thanks in advance

      Edited by: 845200 on Mar 17, 2011 4:59 AM
        • 1. Re: Possible memory leak when playing videos in a loop
          shakir.gusaroff
          Hi. Please define the var vidCreator:VideoCreator inside addVid() function and try again.
          //var vidCreator:VideoCreator;
          function addVid():Void {
               println("vidCreator is {vidCreator}");
             var vidCreator:VideoCreator = VideoCreator {
                  mediaView: mediaView;
                  videoPath: vids[count++ mod sizeof vids];
                  onDone: function():Void {
                      println("cycle {count} done");
                      vidCreator = null;
                      addVid();
                  }
              };
              vidCreator.play();
          
          }
          • 2. Re: Possible memory leak when playing videos in a loop
            848203
            Hi,
            thanks for your advice. Unfortunately it didn't solve the problem. Any clues anyone?
            • 3. Re: Possible memory leak when playing videos in a loop
              Narayan
              Hello user ,

              Every time you run addVid() you are making new Object VideoCreator all the time. If you really need to run many videos then please re-use the same Object and only change the attribute/property of object then run it . It would definetly increase your performace and minimize memory leakage

              Thanks,
              narayan
              • 4. Re: Possible memory leak when playing videos in a loop
                895898
                Hi again,
                thanks for your suggestion. I've altered my code but i'm still having the same result (= the leak). Here's the current code:

                Main.fx:
                /*
                 * To change this template, choose Tools | Templates
                 * and open the template in the editor.
                 */
                
                package videotest;
                
                import javafx.stage.Stage;
                import javafx.scene.Scene;
                import javafx.scene.media.MediaView;
                import videotest.VideoCreator;
                import javafx.scene.media.Media;
                
                def vids = ["file:///c:/video.avi"];
                
                var scene:Scene;
                
                def mediaView = MediaView {
                    
                    preserveRatio: true;
                    fitWidth: bind scene.width;
                    fitHeight: bind scene.height;
                    x: 0;
                    y: 0;
                }
                
                Stage {
                    title: "Application title"
                    scene: scene = Scene {
                        width: 250
                        height: 80
                        content: mediaView;
                    }
                }
                
                var dur:Duration;
                var count:Integer = 0;
                
                var vidCreator:VideoCreator = VideoCreator {
                        mediaView: mediaView;
                        onDone: function():Void {
                            println("cycle {count} done");
                            vidCreator = null;
                            addVid();
                        }
                    };
                
                function addVid():Void {
                    var media:Media = Media {
                        source: vids[count++ mod vids.size()];
                    }
                    vidCreator.setMedia(media);
                    vidCreator.play();
                }
                
                addVid();
                VideoCreator.fx:
                package videotest;
                
                import javafx.scene.media.MediaView;
                import javafx.scene.media.MediaPlayer;
                import javafx.scene.media.Media;
                import javafx.scene.media.MediaError;
                
                public class VideoCreator {
                    
                    public-init var mediaView:MediaView;
                    var duration:Duration;
                    var player:MediaPlayer;
                    public-init var onDone:function():Void;
                
                    init {
                        this.player = mediaView.mediaPlayer = MediaPlayer{
                            mute: true;
                        };
                        this.duration = player.media.duration;
                        this.player.onError = function(me:MediaError):Void {
                            println(me.message);
                        };
                        this.player.onEndOfMedia = function():Void {
                                    player.stop();
                                    player.media = null;
                                    this.onDone();
                                };
                
                        this.mediaView.mediaPlayer = player;
                    }
                
                    public function getDuration():Duration {
                        println("Duration: {this.duration.toSeconds()}");
                        return this.duration;
                    }
                
                    public function setMedia(media:Media):Void {
                        this.player.media = media;
                    }
                
                
                    public function play():Void {
                        player.play();
                    }
                
                }
                I need to stick with the pre 2.0 Version of JavaFX because the JavaFX 2.0 does not support any video codecs except VP6.

                Does anybody else have a leak running my code? Thank you.

                Edited by: 892895 on Oct 24, 2011 2:36 AM