Skip to content

Commit 86b3804

Browse files
committed
[camera_android_camerax] Adds support for video stabilization
- Implements getSupportedVideoStabilizationModes() and setVideoStabilizationMode() methods in AndroidCameraCameraX.
1 parent 09104b0 commit 86b3804

12 files changed

Lines changed: 628 additions & 30 deletions

File tree

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,4 @@ Hashir Shoaib <hashirshoaeb@gmail.com>
8181
Ricardo Dalarme <ricardodalarme@outlook.com>
8282
Andrei Kabylin <sys.int64@gmail.com>
8383
Ernesto Ramirez <neartox@outlook.com>
84+
Rui Craveiro <ruicraveiro@squarealfa.com>

packages/camera/camera_android_camerax/AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
# Name/Organization <email address>
55

66
Google Inc.
7+
Rui Craveiro <ruicraveiro@squarealfa.com>

packages/camera/camera_android_camerax/CHANGELOG.md

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.7.0
2+
3+
* Adds video stabilization.
4+
15
## 0.6.30
26

37
* Bump camerax_version from 1.5.2 to 1.5.3.
@@ -52,7 +56,8 @@
5256

5357
## 0.6.24+1
5458

55-
* Fixes crash in `DeviceOrientationManager` caused by `UnsupportedOperationException` when `getDisplay()` is called on a null or destroyed Activity during rotation.
59+
* Fixes crash in `DeviceOrientationManager` caused by `UnsupportedOperationException` when
60+
`getDisplay()` is called on a null or destroyed Activity during rotation.
5661

5762
## 0.6.24
5863

@@ -72,7 +77,8 @@
7277

7378
## 0.6.23+2
7479

75-
* Updates Java compatibility version to 17 and minimum supported SDK version to Flutter 3.35/Dart 3.9.
80+
* Updates Java compatibility version to 17 and minimum supported SDK version to Flutter 3.35/Dart
81+
3.9.
7682

7783
## 0.6.23+1
7884

@@ -81,7 +87,8 @@
8187
## 0.6.23
8288

8389
* Converts NV21-compatible streamed images to NV21 when requested. In doing so,
84-
this plugin should now be compatible with [google_ml_kit_flutter](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master).
90+
this plugin should now be compatible
91+
with [google_ml_kit_flutter](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master).
8592

8693
## 0.6.22
8794

@@ -258,8 +265,10 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
258265

259266
## 0.6.6
260267

261-
* Adds logic to support building a camera preview with Android `Surface`s not backed by a `SurfaceTexture`
262-
to which CameraX cannot not automatically apply the transformation required to achieve the correct rotation.
268+
* Adds logic to support building a camera preview with Android `Surface`s not backed by a
269+
`SurfaceTexture`
270+
to which CameraX cannot not automatically apply the transformation required to achieve the correct
271+
rotation.
263272
* Adds fix for incorrect camera preview rotation on naturally landscape-oriented devices.
264273
* Updates example app's minimum supported SDK version to Flutter 3.22/Dart 3.4.
265274

@@ -290,7 +299,8 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
290299

291300
## 0.6.5+1
292301

293-
* Updates `README.md` to reflect the fact that the `camera_android_camerax` camera plugin implementation
302+
* Updates `README.md` to reflect the fact that the `camera_android_camerax` camera plugin
303+
implementation
294304
is the endorsed Android implementation for `camera: ^0.11.0`.
295305

296306
## 0.6.5
@@ -299,22 +309,28 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
299309
recorded video finishes saving to a file.
300310
* Modifies `startVideoCapturing` to ensure that the method only returns when CameraX reports that
301311
video recording has started.
302-
* Adds empty implementation for `setDescriptionWhileRecording` and leaves a todo to add this feature.
312+
* Adds empty implementation for `setDescriptionWhileRecording` and leaves a todo to add this
313+
feature.
303314

304315
## 0.6.4+1
305316

306-
* Adds empty implementation for `prepareForVideoRecording` since this optimization is not used on Android.
317+
* Adds empty implementation for `prepareForVideoRecording` since this optimization is not used on
318+
Android.
307319

308320
## 0.6.4
309321

310-
* Prevents usage of unsupported concurrent `UseCase`s based on the capabiliites of the camera device.
322+
* Prevents usage of unsupported concurrent `UseCase`s based on the capabiliites of the camera
323+
device.
311324

312325
## 0.6.3
313326

314-
* Shortens default interval that internal Java `InstanceManager` uses to release garbage collected weak references to
327+
* Shortens default interval that internal Java `InstanceManager` uses to release garbage collected
328+
weak references to
315329
native objects.
316-
* Dynamically shortens interval that internal Java `InstanceManager` uses to release garbage collected weak references to
317-
native objects when an `ImageAnalysis.Analyzer` is set/removed to account for increased memory usage of analyzing
330+
* Dynamically shortens interval that internal Java `InstanceManager` uses to release garbage
331+
collected weak references to
332+
native objects when an `ImageAnalysis.Analyzer` is set/removed to account for increased memory
333+
usage of analyzing
318334
images that may cause a crash.
319335

320336
## 0.6.2
@@ -327,7 +343,8 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
327343

328344
## 0.6.1
329345

330-
* Modifies resolution selection logic to use an `AspectRatioStrategy` for all aspect ratios supported by CameraX.
346+
* Modifies resolution selection logic to use an `AspectRatioStrategy` for all aspect ratios
347+
supported by CameraX.
331348
* Adds `ResolutionFilter` to resolution selection logic to prioritize resolutions that match
332349
the defined `ResolutionPreset`s.
333350

@@ -346,7 +363,8 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
346363

347364
## 0.5.0+35
348365

349-
* Modifies `CameraInitializedEvent` that is sent when the camera is initialized to indicate that the initial focus
366+
* Modifies `CameraInitializedEvent` that is sent when the camera is initialized to indicate that the
367+
initial focus
350368
and exposure modes are auto and that developers may set focus and exposure points.
351369

352370
## 0.5.0+34
@@ -365,15 +383,18 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
365383

366384
## 0.5.0+31
367385

368-
* Wraps CameraX classes needed to set capture request options, which is needed to implement setting the exposure mode.
386+
* Wraps CameraX classes needed to set capture request options, which is needed to implement setting
387+
the exposure mode.
369388

370389
## 0.5.0+30
371390

372-
* Adds documentation to clarify how the plugin uses resolution presets as target resolutions for CameraX.
391+
* Adds documentation to clarify how the plugin uses resolution presets as target resolutions for
392+
CameraX.
373393

374394
## 0.5.0+29
375395

376-
* Modifies `buildPreview` to return `Texture` that maps to camera preview, building in the assumption
396+
* Modifies `buildPreview` to return `Texture` that maps to camera preview, building in the
397+
assumption
377398
that `createCamera` should have been called before building the preview. Fixes
378399
https://github.com/flutter/flutter/issues/140567.
379400

@@ -410,7 +431,8 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
410431

411432
## 0.5.0+21
412433

413-
* Changes fallback resolution strategies for camera use cases to look for a higher resolution if neither the desired
434+
* Changes fallback resolution strategies for camera use cases to look for a higher resolution if
435+
neither the desired
414436
resolution nor any lower resolutions are available.
415437

416438
## 0.5.0+20
@@ -436,7 +458,8 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
436458

437459
## 0.5.0+15
438460

439-
* Explicitly removes `READ_EXTERNAL_STORAGE` permission that may otherwise be implied from `WRITE_EXTERNAL_STORAGE`.
461+
* Explicitly removes `READ_EXTERNAL_STORAGE` permission that may otherwise be implied from
462+
`WRITE_EXTERNAL_STORAGE`.
440463

441464
## 0.5.0+14
442465

@@ -448,13 +471,15 @@ this plugin should now be compatible with [google_ml_kit_flutter](https://github
448471

449472
## 0.5.0+12
450473

451-
* Wraps classes needed to implement resolution configuration for image capture, image analysis, and preview.
474+
* Wraps classes needed to implement resolution configuration for image capture, image analysis, and
475+
preview.
452476
* Removes usages of deprecated APIs for resolution configuration.
453477
* Bumps CameraX version to 1.3.0-beta01.
454478

455479
## 0.5.0+11
456480

457-
* Fixes issue with image data not being emitted after relistening to stream returned by `onStreamedFrameAvailable`.
481+
* Fixes issue with image data not being emitted after relistening to stream returned by
482+
`onStreamedFrameAvailable`.
458483

459484
## 0.5.0+10
460485

packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraCharacteristicsProxyApi.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,10 @@ public CameraCharacteristics.Key<?> infoSupportedHardwareLevel() {
2828
public CameraCharacteristics.Key<?> sensorOrientation() {
2929
return CameraCharacteristics.SENSOR_ORIENTATION;
3030
}
31+
32+
@NonNull
33+
@Override
34+
public CameraCharacteristics.Key<?> controlAvailableVideoStabilizationModes() {
35+
return CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES;
36+
}
3137
}

packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXLibrary.g.kt

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2013 The Flutter Authors
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
4-
// Autogenerated from Pigeon (v26.1.5), do not edit directly.
4+
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
55
// See also: https://pub.dev/packages/pigeon
66
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
77

@@ -2181,7 +2181,7 @@ abstract class PigeonApiCameraInfo(
21812181
*/
21822182
abstract fun sensorRotationDegrees(pigeon_instance: androidx.camera.core.CameraInfo): Long
21832183

2184-
/** Returns the lens facing of this camera. */
2184+
/** Returns the lens direction of this camera. */
21852185
abstract fun lensFacing(pigeon_instance: androidx.camera.core.CameraInfo): LensFacing
21862186

21872187
/** Returns a ExposureState. */
@@ -6728,6 +6728,15 @@ abstract class PigeonApiCaptureRequest(
67286728
*/
67296729
abstract fun controlAELock(): android.hardware.camera2.CaptureRequest.Key<*>
67306730

6731+
/**
6732+
* Whether video stabilization is active.
6733+
*
6734+
* Value is int.
6735+
*
6736+
* This key is available on all devices.
6737+
*/
6738+
abstract fun controlVideoStabilizationMode(): android.hardware.camera2.CaptureRequest.Key<*>
6739+
67316740
companion object {
67326741
@Suppress("LocalVariableName")
67336742
fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiCaptureRequest?) {
@@ -6756,6 +6765,30 @@ abstract class PigeonApiCaptureRequest(
67566765
channel.setMessageHandler(null)
67576766
}
67586767
}
6768+
run {
6769+
val channel =
6770+
BasicMessageChannel<Any?>(
6771+
binaryMessenger,
6772+
"dev.flutter.pigeon.camera_android_camerax.CaptureRequest.controlVideoStabilizationMode",
6773+
codec)
6774+
if (api != null) {
6775+
channel.setMessageHandler { message, reply ->
6776+
val args = message as List<Any?>
6777+
val pigeon_identifierArg = args[0] as Long
6778+
val wrapped: List<Any?> =
6779+
try {
6780+
api.pigeonRegistrar.instanceManager.addDartCreatedInstance(
6781+
api.controlVideoStabilizationMode(), pigeon_identifierArg)
6782+
listOf(null)
6783+
} catch (exception: Throwable) {
6784+
CameraXLibraryPigeonUtils.wrapError(exception)
6785+
}
6786+
reply.reply(wrapped)
6787+
}
6788+
} else {
6789+
channel.setMessageHandler(null)
6790+
}
6791+
}
67596792
}
67606793
}
67616794

@@ -7226,6 +7259,17 @@ abstract class PigeonApiCameraCharacteristics(
72267259
*/
72277260
abstract fun sensorOrientation(): android.hardware.camera2.CameraCharacteristics.Key<*>
72287261

7262+
/**
7263+
* List of video stabilization modes for android.control.videoStabilizationMode that are supported
7264+
* by this camera device.
7265+
*
7266+
* Value is `ControlAvailableVideoStabilizationMode`.
7267+
*
7268+
* This key is available on all devices.
7269+
*/
7270+
abstract fun controlAvailableVideoStabilizationModes():
7271+
android.hardware.camera2.CameraCharacteristics.Key<*>
7272+
72297273
companion object {
72307274
@Suppress("LocalVariableName")
72317275
fun setUpMessageHandlers(
@@ -7281,6 +7325,30 @@ abstract class PigeonApiCameraCharacteristics(
72817325
channel.setMessageHandler(null)
72827326
}
72837327
}
7328+
run {
7329+
val channel =
7330+
BasicMessageChannel<Any?>(
7331+
binaryMessenger,
7332+
"dev.flutter.pigeon.camera_android_camerax.CameraCharacteristics.controlAvailableVideoStabilizationModes",
7333+
codec)
7334+
if (api != null) {
7335+
channel.setMessageHandler { message, reply ->
7336+
val args = message as List<Any?>
7337+
val pigeon_identifierArg = args[0] as Long
7338+
val wrapped: List<Any?> =
7339+
try {
7340+
api.pigeonRegistrar.instanceManager.addDartCreatedInstance(
7341+
api.controlAvailableVideoStabilizationModes(), pigeon_identifierArg)
7342+
listOf(null)
7343+
} catch (exception: Throwable) {
7344+
CameraXLibraryPigeonUtils.wrapError(exception)
7345+
}
7346+
reply.reply(wrapped)
7347+
}
7348+
} else {
7349+
channel.setMessageHandler(null)
7350+
}
7351+
}
72847352
}
72857353
}
72867354

packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CaptureRequestOptionsProxyApi.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,15 @@ public CaptureRequestOptions pigeon_defaultConstructor(
4242
continue;
4343
}
4444

45-
builder.setCaptureRequestOption(
46-
(CaptureRequest.Key<Object>) option.getKey(), option.getValue());
45+
// Because Pigeon isn't down-casting from Dart num to Java Int,
46+
// it needs to be done below.
47+
var key = option.getKey();
48+
var value = option.getValue();
49+
if (CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE == key) {
50+
value = ((Long) value).intValue();
51+
}
52+
53+
builder.setCaptureRequestOption((CaptureRequest.Key<Object>) key, value);
4754
}
4855

4956
return builder.build();

packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CaptureRequestProxyApi.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,10 @@ class CaptureRequestProxyApi extends PigeonApiCaptureRequest {
2222
public CaptureRequest.Key<?> controlAELock() {
2323
return CaptureRequest.CONTROL_AE_LOCK;
2424
}
25+
26+
@NonNull
27+
@Override
28+
public CaptureRequest.Key<?> controlVideoStabilizationMode() {
29+
return CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE;
30+
}
2531
}

0 commit comments

Comments
 (0)