enable better FPS skipping mechanism. For raspberry , optimal at 10 fps.

This commit is contained in:
2024-11-13 09:29:38 +07:00
parent 068316bb62
commit d2f924f5db
4 changed files with 81 additions and 51 deletions

View File

@@ -12,17 +12,26 @@ import org.bytedeco.javacv.FrameGrabber;
import org.tinylog.Logger;
public class GrabbingTask implements Runnable {
// for while loop control
private final AtomicBoolean isGrabbing;
// for grabbing frames
private final FrameGrabber grabber;
// Consumers
@Setter private Consumer<String> onMessageUpdate;
@Setter private Consumer<Frame> onHQFrameUpdate;
@Setter private Consumer<Frame> onLQFrameUpdate;
@Setter private Consumer<String> onHQBase64Update;
@Setter private Consumer<String> onLQBase64Update;
// status of capture fps
@Getter private int CaptureFPS = 0;
private final AtomicBoolean isGrabbing;
private final FrameGrabber grabber;
@Getter private final int lowquality_width = 640;
@Getter private final int lowquality_height = 360;
@Getter @Setter private int lowquality_width = 640;
@Getter @Setter private int lowquality_height = 360;
// for FPS calculation
private int intendedFps = 10;
private void updateMessage(String message) {
if (onMessageUpdate != null) {
@@ -62,10 +71,10 @@ public class GrabbingTask implements Runnable {
public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber) {
public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber, int fps) {
this.isGrabbing = isGrabbing;
this.grabber = grabber;
if (fps>0) intendedFps = fps;
}
@@ -73,39 +82,51 @@ public class GrabbingTask implements Runnable {
isGrabbing.set(false);
}
private void grabprocess() throws Exception{
grabber.flush();
Frame fr =grabber.grab();
private void processFrame(Frame fr){
if (fr!=null){
updateHQFrame(fr);
updateHQBase64(SomeCodes.FrameToBase64(fr));
Frame resized = SomeCodes.ResizeFrame(fr, lowquality_width, lowquality_height);
updateLQFrame(resized);
updateLQBase64(SomeCodes.FrameToBase64(resized));
} else updateMessage("Grabber returned null frame");
} else updateMessage("processFrame have null frame");
}
private void flush_grabber(){
try {
if (grabber!=null) grabber.flush();
} catch (FrameGrabber.Exception e) {
Logger.error("Error flushing grabber: "+e.getMessage());
}
}
@Override
public void run() {
isGrabbing.set(true);
Logger.info("Grabbing Task started");
double fps = grabber.getFrameRate();
Logger.info("Grabber framerate = {}", fps);
int skippedframes = (int)(fps / intendedFps);
//Logger.info("Grabber framerate = {}, intendedFps = {}, Skipping frames = {}", fps, intendedFps, skippedframes);
int framecount = 0;
flush_grabber();
long starttick = System.currentTimeMillis();
while (isGrabbing.get()) {
long elapsed = System.currentTimeMillis() - starttick;
starttick = System.currentTimeMillis();
//Logger.info("Elapsed time = {} ms", elapsed);
if (elapsed>0) CaptureFPS = (int) (1000 / elapsed);
try{
Thread.yield();
grabprocess();
Frame frame = grabber.grab();
if (framecount<Integer.MAX_VALUE) framecount++; else framecount = 0;
if (framecount % skippedframes == 0) processFrame(frame);
} catch (Exception e){
Logger.error("Error grabbing frame: "+e.getMessage());
}
long elapsed = System.currentTimeMillis() - starttick;
starttick = System.currentTimeMillis();
if (elapsed>0) {
int xx = (int) (1000 / elapsed);
if (xx<fps) CaptureFPS = xx;
}
//Logger.info("Elapsed time = {} ms, captureFPS = {}", elapsed, CaptureFPS);
}
Logger.info("Grabbing Task stopped");
}