-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[camera] android-rework part 5: Android FPS range, resolution and sensor orientation features #3799
Changes from 6 commits
2b7aa9b
f780742
76bc5bd
0bbed99
1ba738d
de4e70f
728346a
c014fe3
84f5e73
f763f77
4a7c73a
a890919
55a6702
cd53321
35831d3
a9f3142
551800e
68cbc56
1b137c2
6514a00
7f0180e
24af367
8313dd0
a39c2e1
3eecfe9
7299b1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| // 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.camera.features.fpsrange; | ||
|
|
||
| import android.hardware.camera2.CaptureRequest; | ||
| import android.util.Log; | ||
| import android.util.Range; | ||
| import io.flutter.plugins.camera.CameraProperties; | ||
| import io.flutter.plugins.camera.features.CameraFeature; | ||
|
|
||
| public class FpsRangeFeature extends CameraFeature<Range<Integer>> { | ||
| private Range<Integer> currentSetting; | ||
|
|
||
| public FpsRangeFeature(CameraProperties cameraProperties) { | ||
| super(cameraProperties); | ||
|
|
||
| Log.i("Camera", "getAvailableFpsRange"); | ||
|
|
||
| try { | ||
| Range<Integer>[] ranges = cameraProperties.getControlAutoExposureAvailableTargetFpsRanges(); | ||
|
|
||
| if (ranges != null) { | ||
| for (Range<Integer> range : ranges) { | ||
| int upper = range.getUpper(); | ||
| if (upper >= 10) { | ||
| if (currentSetting == null || upper > currentSetting.getUpper()) { | ||
| currentSetting = range; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } catch (Exception e) { | ||
| // TODO: maybe just send a dart error back | ||
| // pictureCaptureRequest.error("cameraAccess", e.getMessage(), null); | ||
|
||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public String getDebugName() { | ||
| return "FpsRangeFeature"; | ||
| } | ||
|
|
||
| @Override | ||
| public Range<Integer> getValue() { | ||
| return currentSetting; | ||
| } | ||
|
|
||
| @Override | ||
| public void setValue(Range<Integer> value) { | ||
| this.currentSetting = value; | ||
| } | ||
|
|
||
| // Always supported | ||
| @Override | ||
| public boolean checkIsSupported() { | ||
| return true; | ||
| } | ||
|
|
||
| @Override | ||
| public void updateBuilder(CaptureRequest.Builder requestBuilder) { | ||
| if (!checkIsSupported()) { | ||
| return; | ||
| } | ||
|
|
||
| requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, currentSetting); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| // 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.camera.features.resolution; | ||
|
|
||
| import android.hardware.camera2.CaptureRequest; | ||
| import android.media.CamcorderProfile; | ||
| import android.util.Size; | ||
| import io.flutter.plugins.camera.CameraProperties; | ||
| import io.flutter.plugins.camera.features.CameraFeature; | ||
|
|
||
| public class ResolutionFeature extends CameraFeature<ResolutionPreset> { | ||
| private final Size captureSize; | ||
| private final Size previewSize; | ||
| private final CamcorderProfile recordingProfile; | ||
| private ResolutionPreset currentSetting; | ||
|
|
||
| public ResolutionFeature( | ||
| CameraProperties cameraProperties, ResolutionPreset initialSetting, String cameraName) { | ||
| super(cameraProperties); | ||
| setValue(initialSetting); | ||
|
|
||
| // Resolution configuration | ||
| recordingProfile = | ||
| getBestAvailableCamcorderProfileForResolutionPreset(cameraName, initialSetting); | ||
| captureSize = new Size(recordingProfile.videoFrameWidth, recordingProfile.videoFrameHeight); | ||
|
|
||
| previewSize = computeBestPreviewSize(cameraName, initialSetting); | ||
| } | ||
|
|
||
| public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPreset( | ||
| String cameraName, ResolutionPreset preset) { | ||
| int cameraId = Integer.parseInt(cameraName); | ||
|
||
| switch (preset) { | ||
| // All of these cases deliberately fall through to get the best available profile. | ||
| case max: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_HIGH)) { | ||
| return CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_HIGH); | ||
| } | ||
| case ultraHigh: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_2160P)) { | ||
| return CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_2160P); | ||
| } | ||
| case veryHigh: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_1080P)) { | ||
| return CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_1080P); | ||
| } | ||
| case high: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_720P)) { | ||
| return CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_720P); | ||
| } | ||
| case medium: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_480P)) { | ||
| return CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_480P); | ||
| } | ||
| case low: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_QVGA)) { | ||
| return CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_QVGA); | ||
| } | ||
| default: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_LOW)) { | ||
| return CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_LOW); | ||
| } else { | ||
| throw new IllegalArgumentException( | ||
| "No capture session available for current capture session."); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static Size computeBestPreviewSize(String cameraName, ResolutionPreset preset) { | ||
| if (preset.ordinal() > ResolutionPreset.high.ordinal()) { | ||
mvanbeusekom marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| preset = ResolutionPreset.high; | ||
| } | ||
|
|
||
| CamcorderProfile profile = | ||
| getBestAvailableCamcorderProfileForResolutionPreset(cameraName, preset); | ||
| return new Size(profile.videoFrameWidth, profile.videoFrameHeight); | ||
| } | ||
|
|
||
| @Override | ||
| public String getDebugName() { | ||
| return "ResolutionFeature"; | ||
| } | ||
|
|
||
| @Override | ||
| public ResolutionPreset getValue() { | ||
| return currentSetting; | ||
| } | ||
|
|
||
| @Override | ||
| public void setValue(ResolutionPreset value) { | ||
| this.currentSetting = value; | ||
| } | ||
|
|
||
| // Always supported | ||
mvanbeusekom marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| @Override | ||
| public boolean checkIsSupported() { | ||
| return true; | ||
| } | ||
|
|
||
| @Override | ||
| public void updateBuilder(CaptureRequest.Builder requestBuilder) { | ||
| // No-op: when setting a resolution there is no need to update the request builder. | ||
| } | ||
|
|
||
| public CamcorderProfile getRecordingProfile() { | ||
| return this.recordingProfile; | ||
| } | ||
|
|
||
| public Size getPreviewSize() { | ||
| return this.previewSize; | ||
| } | ||
|
|
||
| public Size getCaptureSize() { | ||
| return this.captureSize; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // 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.camera.features.resolution; | ||
|
|
||
| // Mirrors camera.dart | ||
| public enum ResolutionPreset { | ||
| low, | ||
| medium, | ||
| high, | ||
| veryHigh, | ||
| ultraHigh, | ||
| max, | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.