summaryrefslogtreecommitdiff
path: root/chromium/media/capture/video/chromeos/camera_device_delegate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/capture/video/chromeos/camera_device_delegate.cc')
-rw-r--r--chromium/media/capture/video/chromeos/camera_device_delegate.cc166
1 files changed, 127 insertions, 39 deletions
diff --git a/chromium/media/capture/video/chromeos/camera_device_delegate.cc b/chromium/media/capture/video/chromeos/camera_device_delegate.cc
index 4664908380b..ab213906718 100644
--- a/chromium/media/capture/video/chromeos/camera_device_delegate.cc
+++ b/chromium/media/capture/video/chromeos/camera_device_delegate.cc
@@ -12,7 +12,7 @@
#include <vector>
#include "base/bind.h"
-#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
#include "base/no_destructor.h"
#include "base/numerics/ranges.h"
#include "base/posix/safe_strerror.h"
@@ -23,7 +23,6 @@
#include "media/capture/video/blob_utils.h"
#include "media/capture/video/chromeos/camera_3a_controller.h"
#include "media/capture/video/chromeos/camera_buffer_factory.h"
-#include "media/capture/video/chromeos/camera_device_context.h"
#include "media/capture/video/chromeos/camera_hal_delegate.h"
#include "media/capture/video/chromeos/camera_metadata_utils.h"
#include "media/capture/video/chromeos/request_manager.h"
@@ -48,6 +47,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>;
@@ -271,11 +271,13 @@ CameraDeviceDelegate::CameraDeviceDelegate(
VideoCaptureDeviceDescriptor device_descriptor,
scoped_refptr<CameraHalDelegate> camera_hal_delegate,
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner,
- CameraAppDeviceImpl* camera_app_device)
+ CameraAppDeviceImpl* camera_app_device,
+ ClientType client_type)
: device_descriptor_(device_descriptor),
camera_hal_delegate_(std::move(camera_hal_delegate)),
ipc_task_runner_(std::move(ipc_task_runner)),
- camera_app_device_(camera_app_device) {}
+ camera_app_device_(camera_app_device),
+ client_type_(client_type) {}
CameraDeviceDelegate::~CameraDeviceDelegate() = default;
@@ -289,6 +291,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;
@@ -509,29 +512,33 @@ void CameraDeviceDelegate::SetPhotoOptions(
is_set_awb_mode_ = false;
}
- bool is_resolution_specified = settings->has_width && settings->has_height;
- bool should_reconfigure_streams =
- is_resolution_specified && (current_blob_resolution_.IsEmpty() ||
- current_blob_resolution_.width() !=
- static_cast<int32_t>(settings->width) ||
- current_blob_resolution_.height() !=
- static_cast<int32_t>(settings->height));
- if (!request_manager_->HasStreamsConfiguredForTakePhoto() ||
- should_reconfigure_streams) {
- if (is_resolution_specified) {
- gfx::Size new_blob_resolution(static_cast<int32_t>(settings->width),
- static_cast<int32_t>(settings->height));
- request_manager_->StopPreview(
- base::BindOnce(&CameraDeviceDelegate::OnFlushed, GetWeakPtr(),
- std::move(new_blob_resolution)));
+ 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;
+ }
+
+ // If there is callback of SetPhotoOptions(), the streams might being
+ // reconfigured and we should notify them once the reconfiguration is done.
+ auto on_reconfigured_callback = base::BindOnce(
+ [](VideoCaptureDevice::SetPhotoOptionsCallback callback) {
+ std::move(callback).Run(true);
+ },
+ std::move(callback));
+ if (!on_reconfigured_callbacks_.empty()) {
+ on_reconfigured_callbacks_.push(std::move(on_reconfigured_callback));
+ } else {
+ if (MaybeReconfigureForPhotoStream(std::move(settings))) {
+ on_reconfigured_callbacks_.push(std::move(on_reconfigured_callback));
} else {
- request_manager_->StopPreview(base::BindOnce(
- &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), base::nullopt));
+ std::move(on_reconfigured_callback).Run();
}
- set_photo_option_callback_ = std::move(callback);
- } else {
- set_photo_option_callback_.Reset();
- std::move(callback).Run(true);
}
result_metadata_frame_number_for_photo_state_ = current_request_frame_number_;
}
@@ -546,6 +553,32 @@ base::WeakPtr<CameraDeviceDelegate> CameraDeviceDelegate::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
+bool CameraDeviceDelegate::MaybeReconfigureForPhotoStream(
+ mojom::PhotoSettingsPtr settings) {
+ bool is_resolution_specified = settings->has_width && settings->has_height;
+ bool should_reconfigure_streams =
+ (is_resolution_specified && (current_blob_resolution_.IsEmpty() ||
+ current_blob_resolution_.width() !=
+ static_cast<int32_t>(settings->width) ||
+ current_blob_resolution_.height() !=
+ static_cast<int32_t>(settings->height)));
+ if (!should_reconfigure_streams) {
+ return false;
+ }
+
+ if (is_resolution_specified) {
+ gfx::Size new_blob_resolution(static_cast<int32_t>(settings->width),
+ static_cast<int32_t>(settings->height));
+ request_manager_->StopPreview(
+ base::BindOnce(&CameraDeviceDelegate::OnFlushed, GetWeakPtr(),
+ std::move(new_blob_resolution)));
+ } else {
+ request_manager_->StopPreview(base::BindOnce(
+ &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), base::nullopt));
+ }
+ return true;
+}
+
void CameraDeviceDelegate::TakePhotoImpl() {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
@@ -559,15 +592,18 @@ void CameraDeviceDelegate::TakePhotoImpl() {
return;
}
- SetPhotoOptions(
- mojom::PhotoSettings::New(),
- base::BindOnce(
- [](base::WeakPtr<Camera3AController> controller,
- base::OnceClosure callback, bool result) {
- controller->Stabilize3AForStillCapture(std::move(callback));
- },
- camera_3a_controller_->GetWeakPtr(),
- std::move(construct_request_cb)));
+ // Trigger the reconfigure process if it not yet triggered.
+ if (on_reconfigured_callbacks_.empty()) {
+ request_manager_->StopPreview(base::BindOnce(
+ &CameraDeviceDelegate::OnFlushed, GetWeakPtr(), base::nullopt));
+ }
+ auto on_reconfigured_callback = base::BindOnce(
+ [](base::WeakPtr<Camera3AController> controller,
+ base::OnceClosure callback) {
+ controller->Stabilize3AForStillCapture(std::move(callback));
+ },
+ camera_3a_controller_->GetWeakPtr(), std::move(construct_request_cb));
+ on_reconfigured_callbacks_.push(std::move(on_reconfigured_callback));
}
void CameraDeviceDelegate::OnMojoConnectionError() {
@@ -680,7 +716,7 @@ void CameraDeviceDelegate::Initialize() {
device_context_, chrome_capture_params_.buffer_type,
std::make_unique<CameraBufferFactory>(),
base::BindRepeating(&RotateAndBlobify), ipc_task_runner_,
- camera_app_device_);
+ camera_app_device_, client_type_);
camera_3a_controller_ = std::make_unique<Camera3AController>(
static_metadata_, request_manager_.get(), ipc_task_runner_);
device_ops_->Initialize(
@@ -1068,8 +1104,9 @@ void CameraDeviceDelegate::OnGotFpsRange(
TakePhotoImpl();
}
- if (set_photo_option_callback_) {
- std::move(set_photo_option_callback_).Run(true);
+ while (!on_reconfigured_callbacks_.empty()) {
+ std::move(on_reconfigured_callbacks_.front()).Run();
+ on_reconfigured_callbacks_.pop();
}
}
@@ -1242,13 +1279,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.
@@ -1382,6 +1431,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));
}