Commit 6d07047d authored by Moja Hsu's avatar Moja Hsu Committed by Commit Bot

camera: Support whiteBalanceMode and colorTemperature

This CL adds whiteBalanceMode(continuous/manual) and colorTemperature
MediaTrackCapabilities.

Bug: b:148527288
Test: Test controls on krane and eve.

Change-Id: I823b7644f5494883161c5bd9567918114c038012
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2235145Reviewed-by: default avatarShik Chen <shik@chromium.org>
Reviewed-by: default avatarWei Lee <wtlee@chromium.org>
Commit-Queue: Hsu Wei-Cheng <mojahsu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807349}
parent a97c3a14
...@@ -379,6 +379,24 @@ void Camera3AController::SetAutoFocusModeForVideoRecording() { ...@@ -379,6 +379,24 @@ void Camera3AController::SetAutoFocusModeForVideoRecording() {
DVLOG(1) << "Setting AF mode to: " << af_mode_; DVLOG(1) << "Setting AF mode to: " << af_mode_;
} }
void Camera3AController::SetAutoWhiteBalanceMode(
cros::mojom::AndroidControlAwbMode mode) {
DCHECK(task_runner_->BelongsToCurrentThread());
if (!available_awb_modes_.count(mode)) {
LOG(WARNING) << "Don't support awb mode:" << mode;
return;
}
SetCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_LOCK,
cros::mojom::AndroidControlAwbLock::ANDROID_CONTROL_AWB_LOCK_OFF);
awb_mode_ = mode;
Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE,
base::checked_cast<uint8_t>(awb_mode_));
DVLOG(1) << "Setting AWB mode to: " << awb_mode_;
}
bool Camera3AController::IsPointOfInterestSupported() { bool Camera3AController::IsPointOfInterestSupported() {
return point_of_interest_supported_; return point_of_interest_supported_;
} }
...@@ -522,7 +540,7 @@ void Camera3AController::Set3AMode(cros::mojom::CameraMetadataTag tag, ...@@ -522,7 +540,7 @@ void Camera3AController::Set3AMode(cros::mojom::CameraMetadataTag tag,
tag == cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE || tag == cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE ||
tag == cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE); tag == cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE);
SetCaptureMetadata(tag, target_mode); SetRepeatingCaptureMetadata(tag, target_mode);
switch (tag) { switch (tag) {
case cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE: case cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE:
......
...@@ -42,6 +42,9 @@ class CAPTURE_EXPORT Camera3AController ...@@ -42,6 +42,9 @@ class CAPTURE_EXPORT Camera3AController
// Enable the auto-focus mode suitable for video recording. // Enable the auto-focus mode suitable for video recording.
void SetAutoFocusModeForVideoRecording(); void SetAutoFocusModeForVideoRecording();
// Set auto white balance mode.
void SetAutoWhiteBalanceMode(cros::mojom::AndroidControlAwbMode mode);
bool IsPointOfInterestSupported(); bool IsPointOfInterestSupported();
// Set point of interest. The coordinate system is based on the active // Set point of interest. The coordinate system is based on the active
......
...@@ -207,17 +207,17 @@ class Camera3AControllerTest : public ::testing::Test { ...@@ -207,17 +207,17 @@ class Camera3AControllerTest : public ::testing::Test {
AddResultMetadataObserver(_)) AddResultMetadataObserver(_))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, _)) cros::mojom::EntryType::TYPE_BYTE, 1, _))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, _)) cros::mojom::EntryType::TYPE_BYTE, 1, _))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, _)) cros::mojom::EntryType::TYPE_BYTE, 1, _))
.Times(1); .Times(1);
...@@ -249,7 +249,7 @@ TEST_F(Camera3AControllerTest, Stabilize3AForStillCaptureTest) { ...@@ -249,7 +249,7 @@ TEST_F(Camera3AControllerTest, Stabilize3AForStillCaptureTest) {
cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger_cancel)) cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger_cancel))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, af_mode)) cros::mojom::EntryType::TYPE_BYTE, 1, af_mode))
.Times(1); .Times(1);
...@@ -363,7 +363,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForStillCaptureTest) { ...@@ -363,7 +363,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForStillCaptureTest) {
cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger)) cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, af_mode)) cros::mojom::EntryType::TYPE_BYTE, 1, af_mode))
.Times(1); .Times(1);
...@@ -391,7 +391,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForStillCaptureTest) { ...@@ -391,7 +391,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForStillCaptureTest) {
cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger)) cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, af_mode)) cros::mojom::EntryType::TYPE_BYTE, 1, af_mode))
.Times(1); .Times(1);
...@@ -415,7 +415,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForStillCaptureTest) { ...@@ -415,7 +415,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForStillCaptureTest) {
cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger)) cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, af_mode)) cros::mojom::EntryType::TYPE_BYTE, 1, af_mode))
.Times(1); .Times(1);
...@@ -445,7 +445,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForVideoRecordingTest) { ...@@ -445,7 +445,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForVideoRecordingTest) {
cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger)) cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, af_mode)) cros::mojom::EntryType::TYPE_BYTE, 1, af_mode))
.Times(1); .Times(1);
...@@ -473,7 +473,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForVideoRecordingTest) { ...@@ -473,7 +473,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForVideoRecordingTest) {
cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger)) cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, af_mode)) cros::mojom::EntryType::TYPE_BYTE, 1, af_mode))
.Times(1); .Times(1);
...@@ -497,7 +497,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForVideoRecordingTest) { ...@@ -497,7 +497,7 @@ TEST_F(Camera3AControllerTest, SetAutoFocusModeForVideoRecordingTest) {
cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger)) cros::mojom::EntryType::TYPE_BYTE, 1, af_trigger))
.Times(1); .Times(1);
EXPECT_CALL(*mock_capture_metadata_dispatcher_, EXPECT_CALL(*mock_capture_metadata_dispatcher_,
SetCaptureMetadata( SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AF_MODE,
cros::mojom::EntryType::TYPE_BYTE, 1, af_mode)) cros::mojom::EntryType::TYPE_BYTE, 1, af_mode))
.Times(1); .Times(1);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/no_destructor.h"
#include "base/numerics/ranges.h" #include "base/numerics/ranges.h"
#include "base/posix/safe_strerror.h" #include "base/posix/safe_strerror.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
...@@ -46,6 +47,38 @@ constexpr char kTilt[] = "com.google.control.tilt"; ...@@ -46,6 +47,38 @@ constexpr char kTilt[] = "com.google.control.tilt";
constexpr char kTiltRange[] = "com.google.control.tiltRange"; constexpr char kTiltRange[] = "com.google.control.tiltRange";
constexpr char kZoom[] = "com.google.control.zoom"; constexpr char kZoom[] = "com.google.control.zoom";
constexpr char kZoomRange[] = "com.google.control.zoomRange"; constexpr char kZoomRange[] = "com.google.control.zoomRange";
constexpr int32_t kColorTemperatureStep = 100;
using AwbModeTemperatureMap = std::map<uint8_t, int32_t>;
const AwbModeTemperatureMap& GetAwbModeTemperatureMap() {
// https://source.android.com/devices/camera/camera3_3Amodes#auto-wb
static const base::NoDestructor<AwbModeTemperatureMap> kAwbModeTemperatureMap(
{
{static_cast<uint8_t>(cros::mojom::AndroidControlAwbMode::
ANDROID_CONTROL_AWB_MODE_INCANDESCENT),
2700},
{static_cast<uint8_t>(cros::mojom::AndroidControlAwbMode::
ANDROID_CONTROL_AWB_MODE_FLUORESCENT),
5000},
{static_cast<uint8_t>(cros::mojom::AndroidControlAwbMode::
ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT),
3000},
{static_cast<uint8_t>(cros::mojom::AndroidControlAwbMode::
ANDROID_CONTROL_AWB_MODE_DAYLIGHT),
5500},
{static_cast<uint8_t>(cros::mojom::AndroidControlAwbMode::
ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT),
6500},
{static_cast<uint8_t>(cros::mojom::AndroidControlAwbMode::
ANDROID_CONTROL_AWB_MODE_TWILIGHT),
15000},
{static_cast<uint8_t>(cros::mojom::AndroidControlAwbMode::
ANDROID_CONTROL_AWB_MODE_SHADE),
7500},
});
return *kAwbModeTemperatureMap;
}
std::pair<int32_t, int32_t> GetTargetFrameRateRange( std::pair<int32_t, int32_t> GetTargetFrameRateRange(
const cros::mojom::CameraMetadataPtr& static_metadata, const cros::mojom::CameraMetadataPtr& static_metadata,
...@@ -253,6 +286,7 @@ void CameraDeviceDelegate::AllocateAndStart( ...@@ -253,6 +286,7 @@ void CameraDeviceDelegate::AllocateAndStart(
result_metadata_frame_number_for_photo_state_ = 0; result_metadata_frame_number_for_photo_state_ = 0;
result_metadata_frame_number_ = 0; result_metadata_frame_number_ = 0;
is_set_awb_mode_ = false;
is_set_brightness_ = false; is_set_brightness_ = false;
is_set_contrast_ = false; is_set_contrast_ = false;
is_set_pan_ = false; is_set_pan_ = false;
...@@ -260,6 +294,7 @@ void CameraDeviceDelegate::AllocateAndStart( ...@@ -260,6 +294,7 @@ void CameraDeviceDelegate::AllocateAndStart(
is_set_sharpness_ = false; is_set_sharpness_ = false;
is_set_tilt_ = false; is_set_tilt_ = false;
is_set_zoom_ = false; is_set_zoom_ = false;
chrome_capture_params_ = params; chrome_capture_params_ = params;
device_context_ = device_context; device_context_ = device_context;
device_context_->SetState(CameraDeviceContext::State::kStarting); device_context_->SetState(CameraDeviceContext::State::kStarting);
...@@ -447,6 +482,33 @@ void CameraDeviceDelegate::SetPhotoOptions( ...@@ -447,6 +482,33 @@ void CameraDeviceDelegate::SetPhotoOptions(
set_vendor_int(kZoom, settings->has_zoom, settings->zoom, is_set_zoom_); set_vendor_int(kZoom, settings->has_zoom, settings->zoom, is_set_zoom_);
} }
if (settings->has_white_balance_mode &&
settings->white_balance_mode == mojom::MeteringMode::MANUAL &&
settings->has_color_temperature) {
const AwbModeTemperatureMap& map = GetAwbModeTemperatureMap();
cros::mojom::AndroidControlAwbMode awb_mode =
cros::mojom::AndroidControlAwbMode::ANDROID_CONTROL_AWB_MODE_AUTO;
auto awb_available_modes = GetMetadataEntryAsSpan<uint8_t>(
static_metadata_,
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_AVAILABLE_MODES);
int32_t min_diff = std::numeric_limits<int32_t>::max();
for (const auto& mode : awb_available_modes) {
auto it = map.find(mode);
// Find the nearest awb mode
int32_t diff = std::abs(settings->color_temperature - it->second);
if (diff < min_diff) {
awb_mode = static_cast<cros::mojom::AndroidControlAwbMode>(mode);
min_diff = diff;
}
}
camera_3a_controller_->SetAutoWhiteBalanceMode(awb_mode);
is_set_awb_mode_ = true;
} else if (is_set_awb_mode_) {
camera_3a_controller_->SetAutoWhiteBalanceMode(
cros::mojom::AndroidControlAwbMode::ANDROID_CONTROL_AWB_MODE_AUTO);
is_set_awb_mode_ = false;
}
bool is_resolution_specified = settings->has_width && settings->has_height; bool is_resolution_specified = settings->has_width && settings->has_height;
bool should_reconfigure_streams = bool should_reconfigure_streams =
is_resolution_specified && (current_blob_resolution_.IsEmpty() || is_resolution_specified && (current_blob_resolution_.IsEmpty() ||
...@@ -1180,6 +1242,14 @@ void CameraDeviceDelegate::OnResultMetadataAvailable( ...@@ -1180,6 +1242,14 @@ void CameraDeviceDelegate::OnResultMetadataAvailable(
gfx::Rect(rect[0], rect[1], rect[2], rect[3]); gfx::Rect(rect[0], rect[1], rect[2], rect[3]);
} }
result_metadata_.awb_mode.reset();
auto awb_mode = GetMetadataEntryAsSpan<uint8_t>(
result_metadata,
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_MODE);
if (awb_mode.size() == 1) {
result_metadata_.awb_mode = awb_mode[0];
}
result_metadata_frame_number_ = frame_number; result_metadata_frame_number_ = frame_number;
// We need to wait the new result metadata for new settings. // We need to wait the new result metadata for new settings.
if (result_metadata_frame_number_ > if (result_metadata_frame_number_ >
...@@ -1273,6 +1343,45 @@ void CameraDeviceDelegate::DoGetPhotoState( ...@@ -1273,6 +1343,45 @@ void CameraDeviceDelegate::DoGetPhotoState(
use_digital_zoom_ = false; use_digital_zoom_ = false;
} }
auto awb_available_modes = GetMetadataEntryAsSpan<uint8_t>(
static_metadata_,
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AWB_AVAILABLE_MODES);
// Only enable white balance control when there are more than 1 control modes.
if (awb_available_modes.size() > 1 && result_metadata_.awb_mode) {
photo_state->supported_white_balance_modes.push_back(
mojom::MeteringMode::MANUAL);
photo_state->supported_white_balance_modes.push_back(
mojom::MeteringMode::CONTINUOUS);
const AwbModeTemperatureMap& map = GetAwbModeTemperatureMap();
int32_t current_temperature = 0;
if (result_metadata_.awb_mode ==
static_cast<uint8_t>(
cros::mojom::AndroidControlAwbMode::ANDROID_CONTROL_AWB_MODE_AUTO))
photo_state->current_white_balance_mode = mojom::MeteringMode::CONTINUOUS;
else {
// Need to find current color temperature.
photo_state->current_white_balance_mode = mojom::MeteringMode::MANUAL;
current_temperature = map.at(result_metadata_.awb_mode.value());
}
int32_t min = std::numeric_limits<int32_t>::max();
int32_t max = std::numeric_limits<int32_t>::min();
for (const auto& mode : awb_available_modes) {
auto it = map.find(mode);
if (it == map.end())
continue;
if (it->second < min)
min = it->second;
else if (it->second > max)
max = it->second;
}
photo_state->color_temperature->min = min;
photo_state->color_temperature->max = max;
photo_state->color_temperature->step = kColorTemperatureStep;
photo_state->color_temperature->current = current_temperature;
}
std::move(callback).Run(std::move(photo_state)); std::move(callback).Run(std::move(photo_state));
} }
......
...@@ -42,6 +42,7 @@ struct ResultMetadata { ...@@ -42,6 +42,7 @@ struct ResultMetadata {
ResultMetadata(); ResultMetadata();
~ResultMetadata(); ~ResultMetadata();
base::Optional<uint8_t> awb_mode;
base::Optional<int32_t> brightness; base::Optional<int32_t> brightness;
base::Optional<int32_t> contrast; base::Optional<int32_t> contrast;
base::Optional<int32_t> pan; base::Optional<int32_t> pan;
...@@ -240,6 +241,7 @@ class CAPTURE_EXPORT CameraDeviceDelegate final ...@@ -240,6 +241,7 @@ class CAPTURE_EXPORT CameraDeviceDelegate final
CameraAppDeviceImpl* camera_app_device_; // Weak. CameraAppDeviceImpl* camera_app_device_; // Weak.
// States of SetPhotoOptions // States of SetPhotoOptions
bool is_set_awb_mode_;
bool is_set_brightness_; bool is_set_brightness_;
bool is_set_contrast_; bool is_set_contrast_;
bool is_set_pan_; bool is_set_pan_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment