-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[camera] android-rework part 3: Android exposure related features #3797
[camera] android-rework part 3: Android exposure related features #3797
Conversation
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
@googlebot I consent. |
Co-authored-by: Andrew Coutts <[email protected]>
Co-authored-by: Andrew Coutts <[email protected]>
7a37b86
to
461309a
Compare
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.
Initial pass comments below; I haven't reviewed the tests yet.
default: | ||
requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); | ||
break; | ||
} |
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.
Is there a reason to write this as a switch rather than just: requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, currentSetting = ExposureMode.locked);
?
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.
No, no particular reason. I have adjusted the code.
} | ||
|
||
/** | ||
* Return the minimum exposure offset double value. |
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.
Returns
s/double value/value/
No need to document things in comments that are expressly indicated by the types in the function signature.
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.
Done.
} | ||
|
||
/** | ||
* Return the max exposure offset double value. |
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.
Same.
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.
Done.
|
||
/** | ||
* Returns the exposure offset step size. This is the smallest amount which the exposure offset | ||
* can be changed. |
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 second sentence seems misleading; it implies that this value is a just minimum delta in exposure offset changes, rather than a multiplier.
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.
Fixed.
* This represents the exposure offset value. It holds the minimum and maximum values, as well as | ||
* the current setting value. | ||
*/ | ||
public class ExposureOffsetValue { |
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.
Why are min/max and current value the same object? That seems surprising since they are fundamentally different kinds of values.
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.
You are correct. The ExposureOffsetValue
is currently used to return all values at once to the Camera
class. However it would make much more sense if the Camera
class could just call the ExposureOffsetFeature.getMinExposureOffset
or ExposureOffsetFeature.getMaxExposureOffset
methods when it needs to returns these values to the Dart side.
If have removed the ExposureOffsetValue
and replaced it with a simple double and made the getMinExposureOffset
and getMaxExposureOffset
public.
public MeteringRectangle getMeteringRectangleForPoint(Size maxBoundaries, double x, double y) { | ||
assert (x >= 0 && x <= 1); | ||
assert (y >= 0 && y <= 1); | ||
if (maxBoundaries == null) |
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.
Add braces, per Google Java style.
https://google.github.io/styleguide/javaguide.html#s4.1-braces
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.
Done.
// Interpolate the target coordinate | ||
int targetX = (int) Math.round(x * ((double) (maxBoundaries.getWidth() - 1))); | ||
int targetY = (int) Math.round(y * ((double) (maxBoundaries.getHeight() - 1))); | ||
// Determine the dimensions of the metering triangle (10th of the viewport) |
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.
Where is 1/10th coming from? Is this arbitrarily chosen? A standard? Other? A comment would be helpful.
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.
Added explanation in the method API documentation.
|
||
/** | ||
* Holds the current region boundaries. When this is created, you must provide a | ||
* CaptureRequestBuilder for which we can read the distortion correction settings from. |
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.
Who are "you" and "we"?
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.
I have merged the RegionBoundariesFeature
class with the CameraRegions
class which makes this file obsolete. I made sure to include the feedback you provided in the new structure as well.
The RegionBoundariesFeature
in fact was used as a factory to create an instance of the CameraRegions
class. The actual implementation didn't represent a "Camera Feature" and was mis-used as a feature and consumed by other feature classes.
super(cameraProperties); | ||
|
||
// No distortion correction support | ||
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.P |
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.
Why not just make this check internal to supportsDistortionCorrection? Assuming false is always going to be the fallback, presumably.
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 is to silence the linter, since the else
construct contains code that is only available on API level P
and higher.
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.
Ah, I missed that this was a <
check; usually it's the opposite. I think it would be clearer to flip the bodies and use
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && supportsDistortionCorrection()) {
// the distortion correction code
} else {
// the fallback code
}
private boolean supportsDistortionCorrection() { | ||
int[] availableDistortionCorrectionModes = | ||
cameraProperties.getDistortionCorrectionAvailableModes(); | ||
if (availableDistortionCorrectionModes == null) availableDistortionCorrectionModes = new int[0]; |
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.
Braces.
S.a |
@stuartmorgan thank you for the review. I have processed your feedback and would appreciate it if you could have another look. |
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.
Just a few small things left, otherwise looks good.
super(cameraProperties); | ||
|
||
// No distortion correction support | ||
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.P |
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.
Ah, I missed that this was a <
check; usually it's the opposite. I think it would be clearer to flip the bodies and use
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && supportsDistortionCorrection()) {
// the distortion correction code
} else {
// the fallback code
}
} | ||
|
||
/** | ||
* Return the minimum exposure offset double value. | ||
* Returns the minimum exposure offset value, in counts of {@link #getExposureOffsetStepSize}. |
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.
The return value is multiplied by stepSize
, so this seems wrong.
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.
I was strongly influenced by the documentation from the Android Camera2 API when I documented this method.
Here this mention:
Maximum and minimum exposure compensation values for android.control.aeExposureCompensation, in counts of android.control.aeCompensationStep, that are supported by this camera device.
I am not saying this would be necessarily correct or the best, just wanted to quickly verify with you before I update it.
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.
I don't follow. You're pointing to the documentation for the exposure range, which is line 64 here. This method doesn't return that, it returns that multiplied by the step size (line 67). If you take step counts, and multiply by step sizes, you don't have step counts any more. You have the actual exposure value.
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.
Yes you are right, I completely read the Android documentation wrong.
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.
Fixed
Range<Integer> range = cameraProperties.getControlAutoExposureCompensationRange(); | ||
double minStepped = range == null ? 0 : range.getLower(); | ||
double stepSize = getExposureOffsetStepSize(); | ||
return minStepped * stepSize; | ||
} | ||
|
||
/** | ||
* Return the max exposure offset double value. | ||
* Returns the maximum exposure offset value, in counts of {@link #getExposureOffsetStepSize}. |
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.
Same.
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.
Fixed
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.
LGTM
Something seems to have gone wrong with the Windows re-run; it either didn't schedule, or didn't update the status here. Maybe something related to the jobs changing right around the time I restarted it? I'm just going to land this, as the Windows test isn't relevant to the change. |
* master: (131 commits) [in_app_purchase] fix "autoConsume" param in "buyConsumable" (flutter#3957) [video_player_web] fix: set autoplay to false during initialization (flutter#3985) [multiple_web] Adapt web PlatformView widgets to work slotted. (flutter#3964) [url_launcher] Add iOS unit and UI tests (flutter#3987) [image_picker] Change storage location for camera captures to internal cache on Android, to comply with new Google Play storage requirements. (flutter#3956) [script/tool] Use 'dart pub' instead of deprecated 'pub' (flutter#3991) [video_player] Add iOS unit and UI tests (flutter#3986) Add pubspec convention checks (flutter#3984) Enable pubspec dependency sorting lint (flutter#3983) [image_picker] Migrate maven repo from jcenter to mavenCentral (flutter#3915) [video_player] Update README.md (flutter#3975) [script/tool] speed up the pub get portion of the analyze command (flutter#3982) Revert commit e742a7b (flutter#3976) Added support to request list of purchases (flutter#3944) [google_maps_flutter] Add iOS unit and UI tests (flutter#3978) Added Windows to the description (flutter#3936) use 'flutter pub get' for both dart and flutter packages (flutter#3973) [camera] android-rework part 3: Android exposure related features (flutter#3797) Remove exoplayer workaround from everything but video_player (flutter#3980) Allow reverts when checking versions (flutter#3981) ...
…utter#3797) Adds exposure related features containing the implementation to handle auto exposure, exposure lock, exposure offset and exposure point via the Android Camera2 API. This is the third PR in a series of pull-requests which will gradually introduce changes from PR flutter#3651, making it easier to review the code (as discussed with @stuartmorgan).
Adds exposure related features containing the implementation to handle auto exposure, exposure lock, exposure offset and exposure point via the Android Camera2 API.
This is the third PR in a series of pull-requests which will gradually introduce changes from PR #3651, making it easier to review the code (as discussed with @stuartmorgan).
If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.
Pre-launch Checklist
[shared_preferences]
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.