forked from flutter/flutter
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[camerax] Implement Image Streaming (flutter#3454)
Implements image streaming with all required image data, see [here](flutter#113792). Fixes flutter#120463. Fixes flutter#113792 along the way. Special shoutout to @reidbaker for pair programming on this!
- Loading branch information
Showing
44 changed files
with
3,812 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
...roid_camerax/android/src/main/java/io/flutter/plugins/camerax/AnalyzerFlutterApiImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package io.flutter.plugins.camerax; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.VisibleForTesting; | ||
import androidx.camera.core.ImageAnalysis; | ||
import androidx.camera.core.ImageProxy; | ||
import io.flutter.plugin.common.BinaryMessenger; | ||
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.AnalyzerFlutterApi; | ||
import java.util.Objects; | ||
|
||
/** | ||
* Flutter API implementation for {@link ImageAnalysis.Analyzer}. | ||
* | ||
* <p>This class may handle adding native instances that are attached to a Dart instance or passing | ||
* arguments of callbacks methods to a Dart instance. | ||
*/ | ||
public class AnalyzerFlutterApiImpl { | ||
private final BinaryMessenger binaryMessenger; | ||
private final InstanceManager instanceManager; | ||
private AnalyzerFlutterApi api; | ||
|
||
/** | ||
* Constructs a {@link AnalyzerFlutterApiImpl}. | ||
* | ||
* @param binaryMessenger used to communicate with Dart over asynchronous messages | ||
* @param instanceManager maintains instances stored to communicate with attached Dart objects | ||
*/ | ||
public AnalyzerFlutterApiImpl( | ||
@NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) { | ||
this.binaryMessenger = binaryMessenger; | ||
this.instanceManager = instanceManager; | ||
api = new AnalyzerFlutterApi(binaryMessenger); | ||
} | ||
|
||
/** | ||
* Stores the {@link ImageAnalysis.Analyzer} instance and notifies Dart to create and store a new | ||
* {@code Analyzer} instance that is attached to this one. If {@code instance} has already been | ||
* added, this method does nothing. | ||
*/ | ||
public void create( | ||
@NonNull ImageAnalysis.Analyzer instance, @NonNull AnalyzerFlutterApi.Reply<Void> callback) { | ||
if (!instanceManager.containsInstance(instance)) { | ||
api.create(instanceManager.addHostCreatedInstance(instance), callback); | ||
} | ||
} | ||
|
||
/** | ||
* Sends a message to Dart to call {@code Analyzer.analyze} on the Dart object representing | ||
* `instance`. | ||
*/ | ||
public void analyze( | ||
@NonNull ImageAnalysis.Analyzer analyzerInstance, | ||
@NonNull ImageProxy imageProxyInstance, | ||
@NonNull AnalyzerFlutterApi.Reply<Void> callback) { | ||
api.analyze( | ||
Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(analyzerInstance)), | ||
Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(imageProxyInstance)), | ||
callback); | ||
} | ||
|
||
/** | ||
* Sets the Flutter API used to send messages to Dart. | ||
* | ||
* <p>This is only visible for testing. | ||
*/ | ||
@VisibleForTesting | ||
void setApi(@NonNull AnalyzerFlutterApi api) { | ||
this.api = api; | ||
} | ||
} |
119 changes: 119 additions & 0 deletions
119
...android_camerax/android/src/main/java/io/flutter/plugins/camerax/AnalyzerHostApiImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package io.flutter.plugins.camerax; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.VisibleForTesting; | ||
import androidx.camera.core.ImageAnalysis; | ||
import androidx.camera.core.ImageProxy; | ||
import io.flutter.plugin.common.BinaryMessenger; | ||
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.AnalyzerHostApi; | ||
|
||
/** | ||
* Host API implementation for {@link ImageAnalysis.Analyzer}. | ||
* | ||
* <p>This class may handle instantiating and adding native object instances that are attached to a | ||
* Dart instance or handle method calls on the associated native class or an instance of the class. | ||
*/ | ||
public class AnalyzerHostApiImpl implements AnalyzerHostApi { | ||
private final BinaryMessenger binaryMessenger; | ||
private final InstanceManager instanceManager; | ||
private final AnalyzerProxy proxy; | ||
|
||
/** Proxy for constructors and static method of {@link ImageAnalysis.Analyzer}. */ | ||
@VisibleForTesting | ||
public static class AnalyzerProxy { | ||
|
||
/** Creates an instance of {@link AnalyzerImpl}. */ | ||
@NonNull | ||
public AnalyzerImpl create( | ||
@NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) { | ||
return new AnalyzerImpl(binaryMessenger, instanceManager); | ||
} | ||
} | ||
|
||
/** | ||
* Implementation of {@link ImageAnalysis.Analyzer} that passes arguments of callback methods to | ||
* Dart. | ||
*/ | ||
public static class AnalyzerImpl implements ImageAnalysis.Analyzer { | ||
private BinaryMessenger binaryMessenger; | ||
private InstanceManager instanceManager; | ||
private AnalyzerFlutterApiImpl api; | ||
|
||
@VisibleForTesting @NonNull public ImageProxyFlutterApiImpl imageProxyApi; | ||
|
||
/** | ||
* Constructs an instance of {@link ImageAnalysis.Analyzer} that passes arguments of callbacks | ||
* methods to Dart. | ||
*/ | ||
public AnalyzerImpl( | ||
@NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) { | ||
super(); | ||
this.binaryMessenger = binaryMessenger; | ||
this.instanceManager = instanceManager; | ||
api = new AnalyzerFlutterApiImpl(binaryMessenger, instanceManager); | ||
imageProxyApi = new ImageProxyFlutterApiImpl(binaryMessenger, instanceManager); | ||
} | ||
|
||
@Override | ||
public void analyze(@NonNull ImageProxy imageProxy) { | ||
Long imageFormat = Long.valueOf(imageProxy.getFormat()); | ||
Long imageHeight = Long.valueOf(imageProxy.getHeight()); | ||
Long imageWidth = Long.valueOf(imageProxy.getWidth()); | ||
imageProxyApi.create(imageProxy, imageFormat, imageHeight, imageWidth, reply -> {}); | ||
|
||
api.analyze(this, imageProxy, reply -> {}); | ||
} | ||
|
||
/** | ||
* Flutter API used to send messages back to Dart. | ||
* | ||
* <p>This is only visible for testing. | ||
*/ | ||
@VisibleForTesting | ||
void setApi(@NonNull AnalyzerFlutterApiImpl api) { | ||
this.api = api; | ||
} | ||
} | ||
|
||
/** | ||
* Constructs a {@link AnalyzerHostApiImpl}. | ||
* | ||
* @param binaryMessenger used to communicate with Dart over asynchronous messages | ||
* @param instanceManager maintains instances stored to communicate with attached Dart objects | ||
*/ | ||
public AnalyzerHostApiImpl( | ||
@NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) { | ||
this(binaryMessenger, instanceManager, new AnalyzerProxy()); | ||
} | ||
|
||
/** | ||
* Constructs a {@link AnalyzerHostApiImpl}. | ||
* | ||
* @param binaryMessenger used to communicate with Dart over asynchronous messages | ||
* @param instanceManager maintains instances stored to communicate with attached Dart objects | ||
* @param proxy proxy for constructors and static method of {@link ImageAnalysis.Analyzer} | ||
*/ | ||
@VisibleForTesting | ||
AnalyzerHostApiImpl( | ||
@NonNull BinaryMessenger binaryMessenger, | ||
@NonNull InstanceManager instanceManager, | ||
@NonNull AnalyzerProxy proxy) { | ||
this.binaryMessenger = binaryMessenger; | ||
this.instanceManager = instanceManager; | ||
this.proxy = proxy; | ||
} | ||
|
||
/** | ||
* Creates an {@link AnalyzerProxy} that represents an {@link ImageAnalysis.Analyzer} instance | ||
* with the specified identifier. | ||
*/ | ||
@Override | ||
public void create(@NonNull Long identifier) { | ||
instanceManager.addDartCreatedInstance( | ||
proxy.create(binaryMessenger, instanceManager), identifier); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.