Nick,
Here's a modified version of the VideoBuffer class. The "addFrame" method now takes a boolean which will "pause" the output frame. So, if you pass in "true" then the output will lag behind the input by a single frame. If you pass in "false" then the delay won't change.
So, whenever you want to "drop" a frame just pass "true" to the addFrame method.
Code:
import processing.video.*;
VideoBuffer vb;
Movie myMovie;
int c = 0;
void setup()
{
size(300,300, P3D);
myMovie = new Movie(this, "station.mov");
vb = new VideoBuffer(3000, 160, 120);
myMovie.loop();
}
void movieEvent(Movie m)
{
m.read();
c++;
if(c == 30)
{
c = 0;
}
// drop one frame every 30 frames.
vb.addFrame( m, (c == 0) );
}
void draw()
{
image( vb.getFrame(), 100, 100 );
image( myMovie, 0, 0 );
}
class VideoBuffer
{
PImage[] buffer;
int inputFrame = 0;
int outputFrame = 0;
int frameWidth = 0;
int frameHeight = 0;
/*
parameters:
frames - the number of frames in the buffer (fps * duration)
width - the width of the video
height - the height of the video
*/
VideoBuffer( int frames, int width, int height )
{
buffer = new PImage[frames];
for(int i = 0; i < frames; i++)
{
this.buffer[i] = new PImage(width, height);
}
this.inputFrame = 1;
this.outputFrame = 0;
this.frameWidth = width;
this.frameHeight = height;
}
// return the current "playback" frame.
PImage getFrame()
{
return this.buffer[this.outputFrame];
}
// Add a new frame to the buffer.
void addFrame( PImage frame, boolean pauseOutput )
{
// copy the new frame into the buffer.
System.arraycopy(frame.pixels, 0, this.buffer[this.inputFrame].pixels, 0, this.frameWidth * this.frameHeight);
// advance the input and output indexes
this.inputFrame++;
if(!pauseOutput)
{
this.outputFrame++;
}
// wrap the values..
if(this.inputFrame >= this.buffer.length)
{
this.inputFrame = 0;
}
if(this.outputFrame >= this.buffer.length)
{
this.outputFrame = 0;
}
}
}