package kaka.cakelight;
import java.io.*;
+import java.util.Optional;
-public class FrameGrabber {
+import static kaka.cakelight.Main.log;
+
+public class FrameGrabber implements Closeable {
private Configuration config;
private File file;
private int bytesPerFrame;
private FrameGrabber() {
}
- public static FrameGrabber from(Configuration config) {
+ public static FrameGrabber from(File videoDevice, Configuration config) {
FrameGrabber fg = new FrameGrabber();
fg.config = config;
- fg.file = new File(config.video.device);
+ fg.file = videoDevice;
fg.bytesPerFrame = config.video.width * config.video.height * config.video.bpp;
+ fg.prepare();
return fg;
}
- public boolean prepare() {
+ private boolean prepare() {
try {
fileStream = new FileInputStream(file);
return true;
} catch (FileNotFoundException e) {
+ // TODO: handle java.io.FileNotFoundException: /dev/video1 (Permission denied)
e.printStackTrace();
return false;
}
}
- public Frame grabFrame() {
+ /**
+ * Must be run in the same thread as {@link #prepare}.
+ */
+ public Optional<VideoFrame> grabFrame() {
try {
byte[] data = new byte[bytesPerFrame];
int count = fileStream.read(data);
- System.out.println("count = " + count);
- return Frame.of(data, config);
+ if (count != bytesPerFrame) {
+ log("Expected to read " + bytesPerFrame + " bytes per frame but read " + count);
+ }
+ return Optional.of(VideoFrame.of(data, config));
} catch (IOException e) {
e.printStackTrace();
}
- return null;
+ return Optional.empty();
}
- public void close() {
- try {
- fileStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
+ @Override
+ public void close() throws IOException {
+ fileStream.close();
}
}