4
4
5
5
package io .flutter .plugins .camera .features .resolution ;
6
6
7
+ import android .annotation .TargetApi ;
7
8
import android .hardware .camera2 .CaptureRequest ;
8
9
import android .media .CamcorderProfile ;
10
+ import android .media .EncoderProfiles ;
11
+ import android .os .Build ;
9
12
import android .util .Size ;
10
13
import androidx .annotation .VisibleForTesting ;
11
14
import io .flutter .plugins .camera .CameraProperties ;
12
15
import io .flutter .plugins .camera .features .CameraFeature ;
16
+ import java .util .List ;
13
17
14
18
/**
15
19
* Controls the resolutions configuration on the {@link android.hardware.camera2} API.
21
25
public class ResolutionFeature extends CameraFeature <ResolutionPreset > {
22
26
private Size captureSize ;
23
27
private Size previewSize ;
24
- private CamcorderProfile recordingProfile ;
28
+ private CamcorderProfile recordingProfileLegacy ;
29
+ private EncoderProfiles recordingProfile ;
25
30
private ResolutionPreset currentSetting ;
26
31
private int cameraId ;
27
32
@@ -51,7 +56,11 @@ public ResolutionFeature(
51
56
*
52
57
* @return Resolution information to configure the {@link android.hardware.camera2} API.
53
58
*/
54
- public CamcorderProfile getRecordingProfile () {
59
+ public CamcorderProfile getRecordingProfileLegacy () {
60
+ return this .recordingProfileLegacy ;
61
+ }
62
+
63
+ public EncoderProfiles getRecordingProfile () {
55
64
return this .recordingProfile ;
56
65
}
57
66
@@ -100,19 +109,29 @@ public void updateBuilder(CaptureRequest.Builder requestBuilder) {
100
109
}
101
110
102
111
@ VisibleForTesting
103
- static Size computeBestPreviewSize (int cameraId , ResolutionPreset preset ) {
112
+ static Size computeBestPreviewSize (int cameraId , ResolutionPreset preset )
113
+ throws IndexOutOfBoundsException {
104
114
if (preset .ordinal () > ResolutionPreset .high .ordinal ()) {
105
115
preset = ResolutionPreset .high ;
106
116
}
117
+ if (Build .VERSION .SDK_INT >= 31 ) {
118
+ EncoderProfiles profile =
119
+ getBestAvailableCamcorderProfileForResolutionPreset (cameraId , preset );
120
+ List <EncoderProfiles .VideoProfile > videoProfiles = profile .getVideoProfiles ();
121
+ EncoderProfiles .VideoProfile defaultVideoProfile = videoProfiles .get (0 );
107
122
108
- CamcorderProfile profile =
109
- getBestAvailableCamcorderProfileForResolutionPreset (cameraId , preset );
110
- return new Size (profile .videoFrameWidth , profile .videoFrameHeight );
123
+ return new Size (defaultVideoProfile .getWidth (), defaultVideoProfile .getHeight ());
124
+ } else {
125
+ @ SuppressWarnings ("deprecation" )
126
+ CamcorderProfile profile =
127
+ getBestAvailableCamcorderProfileForResolutionPresetLegacy (cameraId , preset );
128
+ return new Size (profile .videoFrameWidth , profile .videoFrameHeight );
129
+ }
111
130
}
112
131
113
132
/**
114
133
* Gets the best possible {@link android.media.CamcorderProfile} for the supplied {@link
115
- * ResolutionPreset}.
134
+ * ResolutionPreset}. Supports SDK < 31.
116
135
*
117
136
* @param cameraId Camera identifier which indicates the device's camera for which to select a
118
137
* {@link android.media.CamcorderProfile}.
@@ -121,7 +140,7 @@ static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset) {
121
140
* @return The best possible {@link android.media.CamcorderProfile} that matches the supplied
122
141
* {@link ResolutionPreset}.
123
142
*/
124
- public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPreset (
143
+ public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPresetLegacy (
125
144
int cameraId , ResolutionPreset preset ) {
126
145
if (cameraId < 0 ) {
127
146
throw new AssertionError (
@@ -164,13 +183,74 @@ public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPres
164
183
}
165
184
}
166
185
167
- private void configureResolution (ResolutionPreset resolutionPreset , int cameraId ) {
186
+ @ TargetApi (Build .VERSION_CODES .S )
187
+ public static EncoderProfiles getBestAvailableCamcorderProfileForResolutionPreset (
188
+ int cameraId , ResolutionPreset preset ) {
189
+ if (cameraId < 0 ) {
190
+ throw new AssertionError (
191
+ "getBestAvailableCamcorderProfileForResolutionPreset can only be used with valid (>=0) camera identifiers." );
192
+ }
193
+
194
+ String cameraIdString = Integer .toString (cameraId );
195
+
196
+ switch (preset ) {
197
+ // All of these cases deliberately fall through to get the best available profile.
198
+ case max :
199
+ if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_HIGH )) {
200
+ return CamcorderProfile .getAll (cameraIdString , CamcorderProfile .QUALITY_HIGH );
201
+ }
202
+ case ultraHigh :
203
+ if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_2160P )) {
204
+ return CamcorderProfile .getAll (cameraIdString , CamcorderProfile .QUALITY_2160P );
205
+ }
206
+ case veryHigh :
207
+ if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_1080P )) {
208
+ return CamcorderProfile .getAll (cameraIdString , CamcorderProfile .QUALITY_1080P );
209
+ }
210
+ case high :
211
+ if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_720P )) {
212
+ return CamcorderProfile .getAll (cameraIdString , CamcorderProfile .QUALITY_720P );
213
+ }
214
+ case medium :
215
+ if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_480P )) {
216
+ return CamcorderProfile .getAll (cameraIdString , CamcorderProfile .QUALITY_480P );
217
+ }
218
+ case low :
219
+ if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_QVGA )) {
220
+ return CamcorderProfile .getAll (cameraIdString , CamcorderProfile .QUALITY_QVGA );
221
+ }
222
+ default :
223
+ if (CamcorderProfile .hasProfile (cameraId , CamcorderProfile .QUALITY_LOW )) {
224
+ return CamcorderProfile .getAll (cameraIdString , CamcorderProfile .QUALITY_LOW );
225
+ }
226
+
227
+ throw new IllegalArgumentException (
228
+ "No capture session available for current capture session." );
229
+ }
230
+ }
231
+
232
+ private void configureResolution (ResolutionPreset resolutionPreset , int cameraId )
233
+ throws IndexOutOfBoundsException {
168
234
if (!checkIsSupported ()) {
169
235
return ;
170
236
}
171
- recordingProfile =
172
- getBestAvailableCamcorderProfileForResolutionPreset (cameraId , resolutionPreset );
173
- captureSize = new Size (recordingProfile .videoFrameWidth , recordingProfile .videoFrameHeight );
237
+
238
+ if (Build .VERSION .SDK_INT >= 31 ) {
239
+ recordingProfile =
240
+ getBestAvailableCamcorderProfileForResolutionPreset (cameraId , resolutionPreset );
241
+ List <EncoderProfiles .VideoProfile > videoProfiles = recordingProfile .getVideoProfiles ();
242
+
243
+ EncoderProfiles .VideoProfile defaultVideoProfile = videoProfiles .get (0 );
244
+ captureSize = new Size (defaultVideoProfile .getWidth (), defaultVideoProfile .getHeight ());
245
+ } else {
246
+ @ SuppressWarnings ("deprecation" )
247
+ CamcorderProfile camcorderProfile =
248
+ getBestAvailableCamcorderProfileForResolutionPresetLegacy (cameraId , resolutionPreset );
249
+ recordingProfileLegacy = camcorderProfile ;
250
+ captureSize =
251
+ new Size (recordingProfileLegacy .videoFrameWidth , recordingProfileLegacy .videoFrameHeight );
252
+ }
253
+
174
254
previewSize = computeBestPreviewSize (cameraId , resolutionPreset );
175
255
}
176
256
}
0 commit comments