Skip to content

Commit

Permalink
camera: Support exposure time control
Browse files Browse the repository at this point in the history
This CL adds exposureMode(continuous/manual) and exposureTime
MediaTrackCapabilities.

Bug: b:148527288
Test: Test controls on built-in camera of krane and huddly go camera
Change-Id: I34efc4f7027f696591336939ac8aafcec7695844
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2275505
Reviewed-by: Shik Chen <shik@chromium.org>
Reviewed-by: Wei Lee <wtlee@chromium.org>
Commit-Queue: Hsu Wei-Cheng <mojahsu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820610}
  • Loading branch information
Moja Hsu authored and Commit Bot committed Oct 25, 2020
1 parent 769b5e9 commit 9be30fc
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 2 deletions.
30 changes: 30 additions & 0 deletions media/capture/video/chromeos/camera_3a_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,36 @@ void Camera3AController::SetAutoWhiteBalanceMode(
DVLOG(1) << "Setting AWB mode to: " << awb_mode_;
}

void Camera3AController::SetExposureTime(bool enable_auto,
int64_t exposure_time_nanoseconds) {
DCHECK(task_runner_->BelongsToCurrentThread());

if (enable_auto) {
if (!available_ae_modes_.count(
cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_ON)) {
LOG(WARNING) << "Don't support ANDROID_CONTROL_AE_MODE_ON";
return;
}
ae_mode_ = cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_ON;
capture_metadata_dispatcher_->UnsetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_SENSOR_EXPOSURE_TIME);
} else {
if (!available_ae_modes_.count(
cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_OFF)) {
LOG(WARNING) << "Don't support ANDROID_CONTROL_AE_MODE_OFF";
return;
}
ae_mode_ = cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_OFF;
SetRepeatingCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_SENSOR_EXPOSURE_TIME,
exposure_time_nanoseconds);
}

Set3AMode(cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE,
base::checked_cast<uint8_t>(ae_mode_));
DVLOG(1) << "Setting AE mode to: " << ae_mode_;
}

bool Camera3AController::IsPointOfInterestSupported() {
return point_of_interest_supported_;
}
Expand Down
5 changes: 5 additions & 0 deletions media/capture/video/chromeos/camera_3a_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ class CAPTURE_EXPORT Camera3AController
// Set auto white balance mode.
void SetAutoWhiteBalanceMode(cros::mojom::AndroidControlAwbMode mode);

// Set exposure time.
// |enable_auto| enables auto exposure mode. |exposure_time_nanoseconds| is
// only effective if |enable_auto| is set to false
void SetExposureTime(bool enable_auto, int64_t exposure_time_nanoseconds);

bool IsPointOfInterestSupported();

// Set point of interest. The coordinate system is based on the active
Expand Down
69 changes: 67 additions & 2 deletions media/capture/video/chromeos/camera_device_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ constexpr char kTiltRange[] = "com.google.control.tiltRange";
constexpr char kZoom[] = "com.google.control.zoom";
constexpr char kZoomRange[] = "com.google.control.zoomRange";
constexpr int32_t kColorTemperatureStep = 100;
constexpr int32_t kMicroToNano = 1000;

using AwbModeTemperatureMap = std::map<uint8_t, int32_t>;

Expand Down Expand Up @@ -289,6 +290,7 @@ void CameraDeviceDelegate::AllocateAndStart(
is_set_awb_mode_ = false;
is_set_brightness_ = false;
is_set_contrast_ = false;
is_set_exposure_time_ = false;
is_set_pan_ = false;
is_set_saturation_ = false;
is_set_sharpness_ = false;
Expand Down Expand Up @@ -509,6 +511,18 @@ void CameraDeviceDelegate::SetPhotoOptions(
is_set_awb_mode_ = false;
}

if (settings->has_exposure_mode &&
settings->exposure_mode == mojom::MeteringMode::MANUAL &&
settings->has_exposure_time) {
int64_t exposure_time_nanoseconds_ =
settings->exposure_time * 100 * kMicroToNano;
camera_3a_controller_->SetExposureTime(false, exposure_time_nanoseconds_);
is_set_exposure_time_ = true;
} else if (is_set_exposure_time_) {
camera_3a_controller_->SetExposureTime(true, 0);
is_set_exposure_time_ = false;
}

bool is_resolution_specified = settings->has_width && settings->has_height;
bool should_reconfigure_streams =
is_resolution_specified && (current_blob_resolution_.IsEmpty() ||
Expand Down Expand Up @@ -1242,13 +1256,25 @@ void CameraDeviceDelegate::OnResultMetadataAvailable(
gfx::Rect(rect[0], rect[1], rect[2], rect[3]);
}

result_metadata_.ae_mode.reset();
auto ae_mode = GetMetadataEntryAsSpan<uint8_t>(
result_metadata, cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_MODE);
if (ae_mode.size() == 1)
result_metadata_.ae_mode = ae_mode[0];

result_metadata_.exposure_time.reset();
auto exposure_time = GetMetadataEntryAsSpan<int64_t>(
result_metadata,
cros::mojom::CameraMetadataTag::ANDROID_SENSOR_EXPOSURE_TIME);
if (exposure_time.size() == 1)
result_metadata_.exposure_time = exposure_time[0];

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) {
if (awb_mode.size() == 1)
result_metadata_.awb_mode = awb_mode[0];
}

result_metadata_frame_number_ = frame_number;
// We need to wait the new result metadata for new settings.
Expand Down Expand Up @@ -1382,6 +1408,45 @@ void CameraDeviceDelegate::DoGetPhotoState(
photo_state->color_temperature->current = current_temperature;
}

auto ae_available_modes = GetMetadataEntryAsSpan<uint8_t>(
static_metadata_,
cros::mojom::CameraMetadataTag::ANDROID_CONTROL_AE_AVAILABLE_MODES);
bool support_manual_exposure_time = false;
if (ae_available_modes.size() > 1 && result_metadata_.ae_mode) {
support_manual_exposure_time = base::Contains(
ae_available_modes,
static_cast<uint8_t>(
cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_OFF));
}

auto exposure_time_range = GetMetadataEntryAsSpan<int64_t>(
static_metadata_,
cros::mojom::CameraMetadataTag::ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);

if (support_manual_exposure_time && exposure_time_range.size() == 2 &&
result_metadata_.exposure_time) {
photo_state->supported_exposure_modes.push_back(
mojom::MeteringMode::MANUAL);
photo_state->supported_exposure_modes.push_back(
mojom::MeteringMode::CONTINUOUS);
if (result_metadata_.ae_mode ==
static_cast<uint8_t>(
cros::mojom::AndroidControlAeMode::ANDROID_CONTROL_AE_MODE_OFF))
photo_state->current_exposure_mode = mojom::MeteringMode::MANUAL;
else
photo_state->current_exposure_mode = mojom::MeteringMode::CONTINUOUS;

// The unit of photo_state->exposure_time is 100 microseconds and from
// metadata is nanoseconds.
photo_state->exposure_time->min = std::ceil(
static_cast<float>(exposure_time_range[0]) / (100 * kMicroToNano));
photo_state->exposure_time->max =
exposure_time_range[1] / (100 * kMicroToNano);
photo_state->exposure_time->step = 1; // 100 microseconds
photo_state->exposure_time->current =
result_metadata_.exposure_time.value() / (100 * kMicroToNano);
}

std::move(callback).Run(std::move(photo_state));
}

Expand Down
3 changes: 3 additions & 0 deletions media/capture/video/chromeos/camera_device_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ struct ResultMetadata {
ResultMetadata();
~ResultMetadata();

base::Optional<uint8_t> ae_mode;
base::Optional<uint8_t> awb_mode;
base::Optional<int32_t> brightness;
base::Optional<int32_t> contrast;
base::Optional<int64_t> exposure_time;
base::Optional<int32_t> pan;
base::Optional<int32_t> saturation;
base::Optional<int32_t> sharpness;
Expand Down Expand Up @@ -244,6 +246,7 @@ class CAPTURE_EXPORT CameraDeviceDelegate final
bool is_set_awb_mode_;
bool is_set_brightness_;
bool is_set_contrast_;
bool is_set_exposure_time_;
bool is_set_pan_;
bool is_set_saturation_;
bool is_set_sharpness_;
Expand Down

0 comments on commit 9be30fc

Please sign in to comment.