Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a realtimeStreaming example #1659

Merged
merged 16 commits into from
Jun 11, 2021
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

* Add `FrameGrabber.grabAtFrameRate()` to simulate a device or stream when reading from files ([pull #1659](https://github.com/bytedeco/javacv/pull/1659))
* Update `FFmpegFrameGrabber` and `FFmpegFrameRecorder` with new `avcodec` API ([issue #1498](https://github.com/bytedeco/javacv/issues/1498))
* Add new `Similarity` sample with PSNR and MSSIM ([pull #1622](https://github.com/bytedeco/javacv/pull/1622))
* Avoid crash in `FFmpegFrameRecorder.stop()` by moving `av_write_trailer()` out of `flush()` ([issue #1616](https://github.com/bytedeco/javacv/issues/1616))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ public void testFFmpegFrameGrabber() {

int n = 0, m = 0;
Frame frame2;
while ((frame2 = grabber.grab()) != null) {
long startTime = System.nanoTime();
while ((frame2 = grabber.grabAtFrameRate()) != null) {
Frame clone2 = frame2.clone();
if (frame2.image != null) {
Frame frame = frames[n++];
Expand Down Expand Up @@ -127,6 +128,8 @@ public void testFFmpegFrameGrabber() {
}
clone2.close();
}
long stopTime = System.nanoTime();
assertEquals(n, (stopTime - startTime) * grabber.getFrameRate() / 1_000_000_000, 10.0);
assertEquals(frames.length, n);
assertEquals(null, grabber.grab());
grabber.restart();
Expand Down
26 changes: 25 additions & 1 deletion src/main/java/org/bytedeco/javacv/FrameGrabber.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
public abstract class FrameGrabber implements Closeable {

public static final List<String> list = new LinkedList<String>(Arrays.asList(new String[] {
"DC1394", "FlyCapture", "FlyCapture2", "OpenKinect", "OpenKinect2", "RealSense", "RealSense2", "PS3Eye", "VideoInput", "OpenCV", "FFmpeg", "IPCamera" }));
"DC1394", "FlyCapture", "FlyCapture2", "OpenKinect", "OpenKinect2", "RealSense", "RealSense2", "PS3Eye", "VideoInput", "OpenCV", "FFmpeg", "IPCamera" }));
public static void init() {
for (String name : list) {
try {
Expand Down Expand Up @@ -201,6 +201,7 @@ public static enum SampleMode {
protected int frameNumber = 0;
protected long timestamp = 0;
protected int maxDelay = -1;
protected long startTime = 0;

public int getVideoStream() {
return videoStream;
Expand Down Expand Up @@ -724,4 +725,27 @@ public void release() throws Exception {
public Array createArray(FrameGrabber[] frameGrabbers) {
return new Array(frameGrabbers);
}

/** Returns {@code frame = grab()} after {@code waitForTimestamp(frame)}. */
public Frame grabAtFrameRate() throws Exception, InterruptedException {
Frame frame = grab();
if (frame != null) {
waitForTimestamp(frame);
}
return frame;
}

/** Returns true if {@code Thread.sleep()} had to be called. */
public boolean waitForTimestamp(Frame frame) throws InterruptedException {
if (startTime == 0) {
startTime = System.nanoTime() / 1000 - frame.timestamp;
} else {
long delay = frame.timestamp - (System.nanoTime() / 1000 - startTime);
if (delay > 0) {
Thread.sleep(delay / 1000, (int)(delay % 1000) * 1000);
return true;
}
}
return false;
}
}