From 6f4ef00754a1ac28ab0b005e8aa80f63a42fb642 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Wed, 28 Aug 2019 16:24:49 +0200 Subject: [PATCH] Improve Frames documentation --- docs/_posts/2018-12-20-frame-processing.md | 42 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/docs/_posts/2018-12-20-frame-processing.md b/docs/_posts/2018-12-20-frame-processing.md index 08a7d02d..864f441e 100644 --- a/docs/_posts/2018-12-20-frame-processing.md +++ b/docs/_posts/2018-12-20-frame-processing.md @@ -18,7 +18,7 @@ a QR code detector, the cameraView.addFrameProcessor(new FrameProcessor() { @Override @WorkerThread - public void process(Frame frame) { + public void process(@NonNull Frame frame) { byte[] data = frame.getData(); int rotation = frame.getRotation(); long time = frame.getTime(); @@ -33,9 +33,45 @@ For your convenience, the `FrameProcessor` method is run in a background thread in a synchronous fashion. Once the process method returns, internally we will re-use the `Frame` instance and apply new data to it. So: -- you can do your job synchronously in the `process()` method +- you can do your job synchronously in the `process()` method. This is **recommended**. - if you must hold the `Frame` instance longer, use `frame = frame.freeze()` to get a frozen instance - that will not be affected + that will not be affected. This is **discouraged** because it requires copying the whole array. + +### Process synchronously + +Processing synchronously, for the duration of the `process()` method, is the recommended way of using +processors, because it solves different issues: + +- avoids the need of calling `frame = frame.freeze()` which is a very expensive operation +- the engine will **automatically drop frames** if the `process()` method is busy, so you'll only receive frames that you can handle +- we have already allocated a thread for you, so there's no need to create another + +Some frame consumers might have a built-in asynchronous behavior. +But you can still block the `process()` thread until the consumer has returned. + +```java +@Override +@WorkerThread +public void process(@NonNull Frame frame) { + + // EXAMPLE 1: + // Firebase and Google APIs will often return a Task. + // You can use Tasks.await() to complete the task on the current thread. + Tasks.await(firebaseDetector.detectInImage(firebaseImage)); + + // EXAMPLE 2: + // For other async consumers, you can use, for example, a CountDownLatch. + + // Step 1: create the latch. + final CountDownLatch latch = new CountDownLatch(1); + + // Step 2: launch async processing here... + // When processing completes or fails, call latch.countDown(); + + // Step 3: after launching, block the current thread. + latch.await(); +} +``` ### Related APIs