- make timer of VideoRecorderAppState actually throttle fps if actual fps is greater than target fps, threaded file writing
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8709 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
f6e3a3eab2
commit
11b5a1395d
@ -14,6 +14,12 @@ import java.awt.image.BufferedImage;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -28,9 +34,20 @@ public class VideoRecorderAppState extends AbstractAppState {
|
|||||||
private MjpegFileWriter writer;
|
private MjpegFileWriter writer;
|
||||||
private File file;
|
private File file;
|
||||||
private Application app;
|
private Application app;
|
||||||
|
private ExecutorService executor;
|
||||||
|
private Future fut;
|
||||||
|
|
||||||
public VideoRecorderAppState(File file) {
|
public VideoRecorderAppState(File file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
|
||||||
|
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread th = new Thread(r);
|
||||||
|
th.setName("jME Video processing Thread");
|
||||||
|
th.setDaemon(true);
|
||||||
|
return th;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
@ -99,19 +116,39 @@ public class VideoRecorderAppState extends AbstractAppState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void postFrame(FrameBuffer out) {
|
public void postFrame(FrameBuffer out) {
|
||||||
|
try {
|
||||||
|
if (fut != null) {
|
||||||
|
fut.get();
|
||||||
|
}
|
||||||
|
fut = null;
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
} catch (ExecutionException ex) {
|
||||||
|
}
|
||||||
byteBuffer.clear();
|
byteBuffer.clear();
|
||||||
renderManager.getRenderer().readFrameBuffer(out, byteBuffer);
|
renderManager.getRenderer().readFrameBuffer(out, byteBuffer);
|
||||||
synchronized (rawFrame) {
|
fut = executor.submit(new Callable<Void>() {
|
||||||
Screenshots.convertScreenShot(byteBuffer, rawFrame);
|
|
||||||
try {
|
public Void call() throws Exception {
|
||||||
writer.addImage(rawFrame);
|
Screenshots.convertScreenShot(byteBuffer, rawFrame);
|
||||||
} catch (Exception ex) {
|
try {
|
||||||
Logger.getLogger(VideoRecorderAppState.class.getName()).log(Level.SEVERE, "Error writing frame: {0}", ex);
|
writer.addImage(rawFrame);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.getLogger(VideoRecorderAppState.class.getName()).log(Level.SEVERE, "Error writing frame: {0}", ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
|
try {
|
||||||
|
if (fut != null) {
|
||||||
|
fut.get();
|
||||||
|
fut = null;
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
} catch (ExecutionException ex) {
|
||||||
|
}
|
||||||
app.setTimer(new NanoTimer());
|
app.setTimer(new NanoTimer());
|
||||||
try {
|
try {
|
||||||
writer.finishAVI();
|
writer.finishAVI();
|
||||||
@ -125,6 +162,7 @@ public class VideoRecorderAppState extends AbstractAppState {
|
|||||||
|
|
||||||
private float framerate;
|
private float framerate;
|
||||||
private int ticks;
|
private int ticks;
|
||||||
|
private long lastTime = 0;
|
||||||
|
|
||||||
public IsoTimer(float framerate) {
|
public IsoTimer(float framerate) {
|
||||||
this.framerate = framerate;
|
this.framerate = framerate;
|
||||||
@ -132,7 +170,7 @@ public class VideoRecorderAppState extends AbstractAppState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long getTime() {
|
public long getTime() {
|
||||||
return (long) (this.ticks * (1.0f / this.framerate));
|
return (long) (this.ticks * (1.0f / this.framerate) * 1000f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getResolution() {
|
public long getResolution() {
|
||||||
@ -148,6 +186,15 @@ public class VideoRecorderAppState extends AbstractAppState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
public void update() {
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
long difference = time - lastTime;
|
||||||
|
lastTime = time;
|
||||||
|
if (difference < (1.0f / this.framerate) * 1000.0f) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(difference);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
this.ticks++;
|
this.ticks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user