Skip to content

Commit 003a6c0

Browse files
authored
[camerax] Wrap classes to implement resolution configuration for video capture (#4620)
Wraps classes to implement resolution configuration for video capture. No functionality changes. Part of flutter/flutter#120462.
1 parent 3ce497d commit 003a6c0

22 files changed

+2105
-46
lines changed

packages/camera/camera_android_camerax/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.5.0+14
2+
3+
* Wraps classes needed to implement resolution configuration for video recording.
4+
15
## 0.5.0+13
26

37
* Migrates `styleFrom` usage in examples off of deprecated `primary` and `onPrimary` parameters.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ public void setUp(
103103
binaryMessenger, new ResolutionStrategyHostApiImpl(instanceManager));
104104
GeneratedCameraXLibrary.AspectRatioStrategyHostApi.setup(
105105
binaryMessenger, new AspectRatioStrategyHostApiImpl(instanceManager));
106+
GeneratedCameraXLibrary.FallbackStrategyHostApi.setup(
107+
binaryMessenger, new FallbackStrategyHostApiImpl(instanceManager));
108+
GeneratedCameraXLibrary.QualitySelectorHostApi.setup(
109+
binaryMessenger, new QualitySelectorHostApiImpl(instanceManager));
106110
}
107111

108112
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugins.camerax;
6+
7+
import androidx.annotation.NonNull;
8+
import androidx.annotation.VisibleForTesting;
9+
import androidx.camera.video.FallbackStrategy;
10+
import androidx.camera.video.Quality;
11+
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.FallbackStrategyHostApi;
12+
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.VideoQualityConstraint;
13+
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.VideoResolutionFallbackRule;
14+
15+
/**
16+
* Host API implementation for {@link FallbackStrategy}.
17+
*
18+
* <p>This class may handle instantiating and adding native object instances that are attached to a
19+
* Dart instance or handle method calls on the associated native class or an instance of the class.
20+
*/
21+
public class FallbackStrategyHostApiImpl implements FallbackStrategyHostApi {
22+
private final InstanceManager instanceManager;
23+
24+
private final FallbackStrategyProxy proxy;
25+
26+
/** Proxy for constructors and static method of {@link FallbackStrategy}. */
27+
@VisibleForTesting
28+
public static class FallbackStrategyProxy {
29+
/** Creates an instance of {@link FallbackStrategy}. */
30+
public @NonNull FallbackStrategy create(
31+
@NonNull VideoQualityConstraint videoQualityConstraint,
32+
@NonNull VideoResolutionFallbackRule fallbackRule) {
33+
Quality videoQuality =
34+
QualitySelectorHostApiImpl.getQualityFromVideoQualityConstraint(videoQualityConstraint);
35+
36+
switch (fallbackRule) {
37+
case HIGHER_QUALITY_OR_LOWER_THAN:
38+
return FallbackStrategy.higherQualityOrLowerThan(videoQuality);
39+
case HIGHER_QUALITY_THAN:
40+
return FallbackStrategy.higherQualityThan(videoQuality);
41+
case LOWER_QUALITY_OR_HIGHER_THAN:
42+
return FallbackStrategy.lowerQualityOrHigherThan(videoQuality);
43+
case LOWER_QUALITY_THAN:
44+
return FallbackStrategy.lowerQualityThan(videoQuality);
45+
}
46+
throw new IllegalArgumentException(
47+
"Specified fallback rule " + fallbackRule + " unrecognized.");
48+
}
49+
}
50+
51+
/**
52+
* Constructs a {@link FallbackStrategyHostApiImpl}.
53+
*
54+
* @param instanceManager maintains instances stored to communicate with attached Dart objects
55+
*/
56+
public FallbackStrategyHostApiImpl(@NonNull InstanceManager instanceManager) {
57+
this(instanceManager, new FallbackStrategyProxy());
58+
}
59+
60+
/**
61+
* Constructs a {@link FallbackStrategyHostApiImpl}.
62+
*
63+
* @param instanceManager maintains instances stored to communicate with attached Dart objects
64+
* @param proxy proxy for constructors and static method of {@link FallbackStrategy}
65+
*/
66+
FallbackStrategyHostApiImpl(
67+
@NonNull InstanceManager instanceManager, @NonNull FallbackStrategyProxy proxy) {
68+
this.instanceManager = instanceManager;
69+
this.proxy = proxy;
70+
}
71+
72+
/**
73+
* Creates a {@link FallbackStrategy} instance with the video quality and fallback rule specified.
74+
*/
75+
@Override
76+
public void create(
77+
@NonNull Long identifier,
78+
@NonNull VideoQualityConstraint videoQualityConstraint,
79+
@NonNull VideoResolutionFallbackRule fallbackRule) {
80+
instanceManager.addDartCreatedInstance(
81+
proxy.create(videoQualityConstraint, fallbackRule), identifier);
82+
}
83+
}

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

Lines changed: 206 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,43 @@ private LiveDataSupportedType(final int index) {
104104
}
105105
}
106106

107+
/**
108+
* Video quality constraints that will be used by a QualitySelector to choose an appropriate video
109+
* resolution.
110+
*
111+
* <p>These are pre-defined quality constants that are universally used for video.
112+
*
113+
* <p>See https://developer.android.com/reference/androidx/camera/video/Quality.
114+
*/
115+
public enum VideoQualityConstraint {
116+
SD(0),
117+
HD(1),
118+
FHD(2),
119+
UHD(3),
120+
LOWEST(4),
121+
HIGHEST(5);
122+
123+
final int index;
124+
125+
private VideoQualityConstraint(final int index) {
126+
this.index = index;
127+
}
128+
}
129+
130+
/** Fallback rules for selecting video resolution. */
131+
public enum VideoResolutionFallbackRule {
132+
HIGHER_QUALITY_OR_LOWER_THAN(0),
133+
HIGHER_QUALITY_THAN(1),
134+
LOWER_QUALITY_OR_HIGHER_THAN(2),
135+
LOWER_QUALITY_THAN(3);
136+
137+
final int index;
138+
139+
private VideoResolutionFallbackRule(final int index) {
140+
this.index = index;
141+
}
142+
}
143+
107144
/** Generated class from Pigeon that represents data sent in messages. */
108145
public static final class ResolutionInfo {
109146
private @NonNull Long width;
@@ -1556,7 +1593,11 @@ public void create(@NonNull Long identifierArg, @NonNull Reply<Void> callback) {
15561593
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
15571594
public interface RecorderHostApi {
15581595

1559-
void create(@NonNull Long identifier, @Nullable Long aspectRatio, @Nullable Long bitRate);
1596+
void create(
1597+
@NonNull Long identifier,
1598+
@Nullable Long aspectRatio,
1599+
@Nullable Long bitRate,
1600+
@Nullable Long qualitySelectorId);
15601601

15611602
@NonNull
15621603
Long getAspectRatio(@NonNull Long identifier);
@@ -1587,11 +1628,13 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable RecorderHo
15871628
Number identifierArg = (Number) args.get(0);
15881629
Number aspectRatioArg = (Number) args.get(1);
15891630
Number bitRateArg = (Number) args.get(2);
1631+
Number qualitySelectorIdArg = (Number) args.get(3);
15901632
try {
15911633
api.create(
15921634
(identifierArg == null) ? null : identifierArg.longValue(),
15931635
(aspectRatioArg == null) ? null : aspectRatioArg.longValue(),
1594-
(bitRateArg == null) ? null : bitRateArg.longValue());
1636+
(bitRateArg == null) ? null : bitRateArg.longValue(),
1637+
(qualitySelectorIdArg == null) ? null : qualitySelectorIdArg.longValue());
15951638
wrapped.add(0, null);
15961639
} catch (Throwable exception) {
15971640
ArrayList<Object> wrappedError = wrapError(exception);
@@ -2937,4 +2980,165 @@ public void create(
29372980
channelReply -> callback.reply(null));
29382981
}
29392982
}
2983+
2984+
private static class QualitySelectorHostApiCodec extends StandardMessageCodec {
2985+
public static final QualitySelectorHostApiCodec INSTANCE = new QualitySelectorHostApiCodec();
2986+
2987+
private QualitySelectorHostApiCodec() {}
2988+
2989+
@Override
2990+
protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
2991+
switch (type) {
2992+
case (byte) 128:
2993+
return ResolutionInfo.fromList((ArrayList<Object>) readValue(buffer));
2994+
default:
2995+
return super.readValueOfType(type, buffer);
2996+
}
2997+
}
2998+
2999+
@Override
3000+
protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
3001+
if (value instanceof ResolutionInfo) {
3002+
stream.write(128);
3003+
writeValue(stream, ((ResolutionInfo) value).toList());
3004+
} else {
3005+
super.writeValue(stream, value);
3006+
}
3007+
}
3008+
}
3009+
3010+
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
3011+
public interface QualitySelectorHostApi {
3012+
3013+
void create(
3014+
@NonNull Long identifier,
3015+
@NonNull List<Long> videoQualityConstraintIndexList,
3016+
@Nullable Long fallbackStrategyId);
3017+
3018+
@NonNull
3019+
ResolutionInfo getResolution(
3020+
@NonNull Long cameraInfoId, @NonNull VideoQualityConstraint quality);
3021+
3022+
/** The codec used by QualitySelectorHostApi. */
3023+
static @NonNull MessageCodec<Object> getCodec() {
3024+
return QualitySelectorHostApiCodec.INSTANCE;
3025+
}
3026+
/**
3027+
* Sets up an instance of `QualitySelectorHostApi` to handle messages through the
3028+
* `binaryMessenger`.
3029+
*/
3030+
static void setup(
3031+
@NonNull BinaryMessenger binaryMessenger, @Nullable QualitySelectorHostApi api) {
3032+
{
3033+
BasicMessageChannel<Object> channel =
3034+
new BasicMessageChannel<>(
3035+
binaryMessenger, "dev.flutter.pigeon.QualitySelectorHostApi.create", getCodec());
3036+
if (api != null) {
3037+
channel.setMessageHandler(
3038+
(message, reply) -> {
3039+
ArrayList<Object> wrapped = new ArrayList<Object>();
3040+
ArrayList<Object> args = (ArrayList<Object>) message;
3041+
Number identifierArg = (Number) args.get(0);
3042+
List<Long> videoQualityConstraintIndexListArg = (List<Long>) args.get(1);
3043+
Number fallbackStrategyIdArg = (Number) args.get(2);
3044+
try {
3045+
api.create(
3046+
(identifierArg == null) ? null : identifierArg.longValue(),
3047+
videoQualityConstraintIndexListArg,
3048+
(fallbackStrategyIdArg == null) ? null : fallbackStrategyIdArg.longValue());
3049+
wrapped.add(0, null);
3050+
} catch (Throwable exception) {
3051+
ArrayList<Object> wrappedError = wrapError(exception);
3052+
wrapped = wrappedError;
3053+
}
3054+
reply.reply(wrapped);
3055+
});
3056+
} else {
3057+
channel.setMessageHandler(null);
3058+
}
3059+
}
3060+
{
3061+
BasicMessageChannel<Object> channel =
3062+
new BasicMessageChannel<>(
3063+
binaryMessenger,
3064+
"dev.flutter.pigeon.QualitySelectorHostApi.getResolution",
3065+
getCodec());
3066+
if (api != null) {
3067+
channel.setMessageHandler(
3068+
(message, reply) -> {
3069+
ArrayList<Object> wrapped = new ArrayList<Object>();
3070+
ArrayList<Object> args = (ArrayList<Object>) message;
3071+
Number cameraInfoIdArg = (Number) args.get(0);
3072+
VideoQualityConstraint qualityArg =
3073+
args.get(1) == null ? null : VideoQualityConstraint.values()[(int) args.get(1)];
3074+
try {
3075+
ResolutionInfo output =
3076+
api.getResolution(
3077+
(cameraInfoIdArg == null) ? null : cameraInfoIdArg.longValue(),
3078+
qualityArg);
3079+
wrapped.add(0, output);
3080+
} catch (Throwable exception) {
3081+
ArrayList<Object> wrappedError = wrapError(exception);
3082+
wrapped = wrappedError;
3083+
}
3084+
reply.reply(wrapped);
3085+
});
3086+
} else {
3087+
channel.setMessageHandler(null);
3088+
}
3089+
}
3090+
}
3091+
}
3092+
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
3093+
public interface FallbackStrategyHostApi {
3094+
3095+
void create(
3096+
@NonNull Long identifier,
3097+
@NonNull VideoQualityConstraint quality,
3098+
@NonNull VideoResolutionFallbackRule fallbackRule);
3099+
3100+
/** The codec used by FallbackStrategyHostApi. */
3101+
static @NonNull MessageCodec<Object> getCodec() {
3102+
return new StandardMessageCodec();
3103+
}
3104+
/**
3105+
* Sets up an instance of `FallbackStrategyHostApi` to handle messages through the
3106+
* `binaryMessenger`.
3107+
*/
3108+
static void setup(
3109+
@NonNull BinaryMessenger binaryMessenger, @Nullable FallbackStrategyHostApi api) {
3110+
{
3111+
BasicMessageChannel<Object> channel =
3112+
new BasicMessageChannel<>(
3113+
binaryMessenger, "dev.flutter.pigeon.FallbackStrategyHostApi.create", getCodec());
3114+
if (api != null) {
3115+
channel.setMessageHandler(
3116+
(message, reply) -> {
3117+
ArrayList<Object> wrapped = new ArrayList<Object>();
3118+
ArrayList<Object> args = (ArrayList<Object>) message;
3119+
Number identifierArg = (Number) args.get(0);
3120+
VideoQualityConstraint qualityArg =
3121+
args.get(1) == null ? null : VideoQualityConstraint.values()[(int) args.get(1)];
3122+
VideoResolutionFallbackRule fallbackRuleArg =
3123+
args.get(2) == null
3124+
? null
3125+
: VideoResolutionFallbackRule.values()[(int) args.get(2)];
3126+
try {
3127+
api.create(
3128+
(identifierArg == null) ? null : identifierArg.longValue(),
3129+
qualityArg,
3130+
fallbackRuleArg);
3131+
wrapped.add(0, null);
3132+
} catch (Throwable exception) {
3133+
ArrayList<Object> wrappedError = wrapError(exception);
3134+
wrapped = wrappedError;
3135+
}
3136+
reply.reply(wrapped);
3137+
});
3138+
} else {
3139+
channel.setMessageHandler(null);
3140+
}
3141+
}
3142+
}
3143+
}
29403144
}

0 commit comments

Comments
 (0)