-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[camera] Fix CamcorderProfile Usages #4423
Changes from 36 commits
6976152
49722e4
f40abe2
38d2310
09a2685
accaed0
a0441d9
2383bf3
09cbfa8
252a6fe
f8fd254
f238289
8532e97
724f891
b77b4fc
d6110ea
b7f7649
c77ff4e
162309b
e74767a
3fd589c
d3547d8
c8194fc
84a243a
95fac07
00a4e0d
d59ff1f
fb94483
e0f71bc
92e44c1
e54ec61
bf9e4f7
e10031d
ef23a8c
f59241c
4fff3f3
d2d58b3
25550d0
4cbe753
7304068
3f50377
5d6a93a
1e266e0
9acf444
2cf0c68
e779b26
e745349
d25fbac
979a37f
11cc4e1
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 |
|---|---|---|
|
|
@@ -4,12 +4,16 @@ | |
|
|
||
| package io.flutter.plugins.camera.features.resolution; | ||
|
|
||
| import android.annotation.TargetApi; | ||
| import android.hardware.camera2.CaptureRequest; | ||
| import android.media.CamcorderProfile; | ||
| import android.media.EncoderProfiles; | ||
| import android.os.Build; | ||
| import android.util.Size; | ||
| import androidx.annotation.VisibleForTesting; | ||
| import io.flutter.plugins.camera.CameraProperties; | ||
| import io.flutter.plugins.camera.features.CameraFeature; | ||
| import java.util.List; | ||
|
|
||
| /** | ||
| * Controls the resolutions configuration on the {@link android.hardware.camera2} API. | ||
|
|
@@ -22,6 +26,7 @@ public class ResolutionFeature extends CameraFeature<ResolutionPreset> { | |
| private Size captureSize; | ||
| private Size previewSize; | ||
| private CamcorderProfile recordingProfile; | ||
| private EncoderProfiles recordingProfileOn31; | ||
| private ResolutionPreset currentSetting; | ||
| private int cameraId; | ||
|
|
||
|
|
@@ -55,6 +60,10 @@ public CamcorderProfile getRecordingProfile() { | |
| return this.recordingProfile; | ||
| } | ||
|
|
||
| public EncoderProfiles getRecordingProfileOn31() { | ||
| return this.recordingProfileOn31; | ||
| } | ||
|
|
||
| /** | ||
| * Gets the optimal preview size based on the configured resolution. | ||
| * | ||
|
|
@@ -99,15 +108,25 @@ public void updateBuilder(CaptureRequest.Builder requestBuilder) { | |
| // No-op: when setting a resolution there is no need to update the request builder. | ||
| } | ||
|
|
||
| @SuppressWarnings("deprecation") | ||
camsim99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| @VisibleForTesting | ||
| static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset) { | ||
| static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset) | ||
| throws IndexOutOfBoundsException { | ||
| if (preset.ordinal() > ResolutionPreset.high.ordinal()) { | ||
| preset = ResolutionPreset.high; | ||
| } | ||
|
|
||
| CamcorderProfile profile = | ||
| getBestAvailableCamcorderProfileForResolutionPreset(cameraId, preset); | ||
| return new Size(profile.videoFrameWidth, profile.videoFrameHeight); | ||
| if (Build.VERSION.SDK_INT >= 31) { | ||
| EncoderProfiles profile = | ||
| getBestAvailableCamcorderProfileForResolutionPresetOn31(cameraId, preset); | ||
| List<EncoderProfiles.VideoProfile> videoProfiles = profile.getVideoProfiles(); | ||
| EncoderProfiles.VideoProfile defaultVideoProfile = videoProfiles.get(0); | ||
|
|
||
| return new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight()); | ||
| } else { | ||
| CamcorderProfile profile = | ||
| getBestAvailableCamcorderProfileForResolutionPreset(cameraId, preset); | ||
| return new Size(profile.videoFrameWidth, profile.videoFrameHeight); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -121,6 +140,7 @@ static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset) { | |
| * @return The best possible {@link android.media.CamcorderProfile} that matches the supplied | ||
| * {@link ResolutionPreset}. | ||
| */ | ||
| @SuppressWarnings("deprecation") | ||
| public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPreset( | ||
| int cameraId, ResolutionPreset preset) { | ||
| if (cameraId < 0) { | ||
|
|
@@ -164,13 +184,72 @@ public static CamcorderProfile getBestAvailableCamcorderProfileForResolutionPres | |
| } | ||
| } | ||
|
|
||
| private void configureResolution(ResolutionPreset resolutionPreset, int cameraId) { | ||
| @TargetApi(Build.VERSION_CODES.S) | ||
| public static EncoderProfiles getBestAvailableCamcorderProfileForResolutionPresetOn31( | ||
camsim99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
camsim99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| int cameraId, ResolutionPreset preset) { | ||
| if (cameraId < 0) { | ||
| throw new AssertionError( | ||
| "getBestAvailableCamcorderProfileForResolutionPreset can only be used with valid (>=0) camera identifiers."); | ||
| } | ||
|
|
||
| String cameraIdString = Integer.toString(cameraId); | ||
|
|
||
| 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.getAll(cameraIdString, CamcorderProfile.QUALITY_HIGH); | ||
| } | ||
| case ultraHigh: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_2160P)) { | ||
| return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_2160P); | ||
| } | ||
| case veryHigh: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_1080P)) { | ||
| return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_1080P); | ||
| } | ||
| case high: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_720P)) { | ||
| return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_720P); | ||
| } | ||
| case medium: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_480P)) { | ||
| return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_480P); | ||
| } | ||
| case low: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_QVGA)) { | ||
| return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_QVGA); | ||
| } | ||
| default: | ||
| if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_LOW)) { | ||
| return CamcorderProfile.getAll(cameraIdString, CamcorderProfile.QUALITY_LOW); | ||
| } | ||
|
|
||
| throw new IllegalArgumentException( | ||
| "No capture session available for current capture session."); | ||
| } | ||
| } | ||
|
|
||
| @SuppressWarnings("deprecation") | ||
|
||
| private void configureResolution(ResolutionPreset resolutionPreset, int cameraId) | ||
| throws IndexOutOfBoundsException { | ||
| if (!checkIsSupported()) { | ||
| return; | ||
| } | ||
| recordingProfile = | ||
| getBestAvailableCamcorderProfileForResolutionPreset(cameraId, resolutionPreset); | ||
| captureSize = new Size(recordingProfile.videoFrameWidth, recordingProfile.videoFrameHeight); | ||
|
|
||
| if (Build.VERSION.SDK_INT >= 31) { | ||
| recordingProfileOn31 = | ||
| getBestAvailableCamcorderProfileForResolutionPresetOn31(cameraId, resolutionPreset); | ||
| List<EncoderProfiles.VideoProfile> videoProfiles = recordingProfileOn31.getVideoProfiles(); | ||
|
|
||
| EncoderProfiles.VideoProfile defaultVideoProfile = videoProfiles.get(0); | ||
| captureSize = new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight()); | ||
| } else { | ||
| recordingProfile = | ||
| getBestAvailableCamcorderProfileForResolutionPreset(cameraId, resolutionPreset); | ||
| captureSize = new Size(recordingProfile.videoFrameWidth, recordingProfile.videoFrameHeight); | ||
| } | ||
|
|
||
| previewSize = computeBestPreviewSize(cameraId, resolutionPreset); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change, and the related changes to other plugins, shouldn't be part of this PR. We should land @blasten's PR first, and rebase this PR onto it so that it only contains
camerachanges.