looping video, sketch slowing down

edited March 2016 in Library Questions

Hello! I have a sketch-in-progress which reads in some items from a tsv file in order to display a video on loop and two alternate labels for it, in a randomised order. There are 16 videos. Each video is consecutively loaded into the same variable 'stimulus', via a function getTrial() which is called once in setup() and then once every time a choice of label is made via the keyPressed() function - so the user makes a choice, and the next movie is loaded in.

I thought that if I loaded the new video into the same variable, the old one would be cleared from memory, but after the first three or four videos, my sketch starts slowing down and gets slower and slower with each trial. I've also tried doing stimulus = null; before loading in the new video, but it doesn't seem to make a difference.

The sketch only slows down if the video is set to loop, but if I never pick a label the first video continues looping without slowing down.

Any ideas what is happening? I'm pasting in the whole sketch, in case the issue is something else. Maybe I should be calling stimulus.loop() somewhere else?

import processing.video.*;



Table stims;
int[] trialList;
int trials; 
int trialno; 
int currentTrial; 

int choice;
boolean choicemade; 

Movie stimulus;
String mov;
String target;
String distractor;
int veridical;

void setup () {
  size(512, 800);
  textAlign(CENTER);
  imageMode(CENTER);
  stims = loadTable("iconic_condition.txt", "header,tsv");
  trialno = 0;
  currentTrial = int(random(stims.getRowCount()));
  getTrial(currentTrial);
  choicemade = false;
}


void draw() {
  background(255);
  //draw stimulus and options
  fill(0);
  image(stimulus, width*0.5, height*0.25, 400*1.25, 400);
  text(mov+" veridical: "+veridical, width*0.5, height*0.25);
  text(target, width*0.25, height*0.5);
  text(distractor, width*0.75, height*0.5);

  //update trial info or exit
  if (choicemade) {
    if (trialno == 16) {
      exit();
    } else
      getTrial(currentTrial);
    choicemade = false;
  }
}




void keyReleased() {
  if (key == '1') {
    choicemade = true;
    choice = 1;
    println(trialno+"\t"+ mov + "\t" + target +"\t" + distractor +"\t" +  veridical + "\t" +choice );
    trialno += 1;
    stims.removeRow(currentTrial); //delete completed trial from table
    currentTrial = int(random(stims.getRowCount())); //pick new trial
    getTrial(currentTrial);
  } else if (key == '2' ) {
    choice = 2;
    println(trialno+"\t"+ mov + "\t" + target +"\t" + distractor +"\t" +  veridical + "\t" +choice );
    choicemade = true;
    trialno +=1;
    stims.removeRow(currentTrial); //delete completed trial from table
    currentTrial = int(random(stims.getRowCount())); //pick new trial
    getTrial(currentTrial);
  }
}

//gets variable values for current trial
void getTrial(int currentTrial) {
  if (trialno > 15) {
    exit();
  } else {
    //get all info for current trial:
    mov = stims.getString(currentTrial, "mov");
    stimulus = null; //this doesn't seem to make a difference
    stimulus = new Movie(this, "Stims/"+mov);
    stimulus.loop();
    target = stims.getString(currentTrial, "target");
    distractor = stims.getString(currentTrial, "distractor");
    veridical = stims.getInt(currentTrial, "ver"); //condition - 1 = veridical, 0 = fake
  }
}


//shuffling an int list
void shuff(int[] shufflebag) {
  int current;
  for (int i= 0; i < shufflebag.length; i++) {
    int selection = int(random(shufflebag.length)); //random index
    current = shufflebag[i]; // current index
    //swaps current and selected
    shufflebag[i] = shufflebag[selection]; // value @ selected index goes into current index
    shufflebag[selection] = current; //value of current index goes into selected index
  }
}


void movieEvent(Movie m) {
  m.read();
}

Answers

  • Answer ✓

    There's an undocumented (unfortunately it is so 8-}) method called dispose(). *-:)

  • edited March 2016

    Cool! Have searched around a bit for dispose() and it looks like it should do what I need.

    However I'm trying to call it using stimulus.dispose(); in exactly the place where I was previously calling stimulus = null; but it's giving me a null pointer exception :/

    Edit: Nevermind. Figured it out - needed to do

    if (stimulus != null ) {
    stimulus.dispose();
    }
    
  • Of course dispose() needs to be called before getting rid of its reference. /:)

  • edited March 2016

    Nevermind. Figured it out - needed to do

    That condition may masquerade the problem! #-o
    You really must make sure to dispose() a Movie instance before getting rid of it.

  • Wait, then I don't understand - I thought dispose() was gettting rid of it

  • edited March 2016
    • Normally in Java, an object exists as long as any variable or container got its reference.
    • Otherwise it becomes eligible to be garbage-collected. And in time it's disposed of completely.
    • However some objects grab hardware resources outside the control of Java.
    • Which is true for classes like Movie, Capture, Minim, etc.
    • In such cases, the hardware release needs to be dealt with prior of getting rid of the object.
    • Once the hardware part is completely yielded, the object is safe to be GCed by Java.
    • Thus getting rid of some object still bound to hardware resources causes memory leak! :-SS
Sign In or Register to comment.