blob: c246b3743343c8427a3b407f2b4ab9e68d0c59b8 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/capture/video/chromeos/reprocess_manager.h"
#include <functional>
#include <utility>
#include "media/capture/video/chromeos/camera_metadata_utils.h"
namespace media {
namespace {
void OnStillCaptureDone(media::mojom::ImageCapture::TakePhotoCallback callback,
int status,
mojom::BlobPtr blob) {
std::move(callback).Run(std::move(blob));
}
} // namespace
ReprocessTask::ReprocessTask() = default;
ReprocessTask::ReprocessTask(ReprocessTask&& other)
: effect(other.effect),
callback(std::move(other.callback)),
extra_metadata(std::move(other.extra_metadata)) {}
ReprocessTask::~ReprocessTask() = default;
// static
int ReprocessManager::GetReprocessReturnCode(
cros::mojom::Effect effect,
const cros::mojom::CameraMetadataPtr* metadata) {
if (effect == cros::mojom::Effect::PORTRAIT_MODE) {
auto* portrait_mode_segmentation_result = GetMetadataEntry(
*metadata, static_cast<cros::mojom::CameraMetadataTag>(
kPortraitModeSegmentationResultVendorKey));
CHECK(portrait_mode_segmentation_result);
return static_cast<int>((*portrait_mode_segmentation_result)->data[0]);
}
return kReprocessSuccess;
}
ReprocessManager::ReprocessManager(UpdateStaticMetadataCallback callback)
: sequenced_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
{base::TaskPriority::USER_VISIBLE})),
impl(new ReprocessManager::ReprocessManagerImpl(std::move(callback))) {}
ReprocessManager::~ReprocessManager() {
sequenced_task_runner_->DeleteSoon(FROM_HERE, std::move(impl));
}
void ReprocessManager::SetReprocessOption(
const std::string& device_id,
cros::mojom::Effect effect,
cros::mojom::CrosImageCapture::SetReprocessOptionCallback
reprocess_result_callback) {
sequenced_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&ReprocessManager::ReprocessManagerImpl::SetReprocessOption,
base::Unretained(impl.get()), device_id, effect,
std::move(reprocess_result_callback)));
}
void ReprocessManager::ConsumeReprocessOptions(
const std::string& device_id,
media::mojom::ImageCapture::TakePhotoCallback take_photo_callback,
base::OnceCallback<void(ReprocessTaskQueue)> consumption_callback) {
sequenced_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&ReprocessManager::ReprocessManagerImpl::ConsumeReprocessOptions,
base::Unretained(impl.get()), device_id,
std::move(take_photo_callback), std::move(consumption_callback)));
}
void ReprocessManager::FlushReprocessOptions(const std::string& device_id) {
sequenced_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&ReprocessManager::ReprocessManagerImpl::FlushReprocessOptions,
base::Unretained(impl.get()), device_id));
}
void ReprocessManager::GetStaticMetadata(const std::string& device_id,
GetStaticMetadataCallback callback) {
sequenced_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&ReprocessManager::ReprocessManagerImpl::GetStaticMetadata,
base::Unretained(impl.get()), device_id,
std::move(callback)));
}
void ReprocessManager::UpdateStaticMetadata(
const std::string& device_id,
const cros::mojom::CameraMetadataPtr& metadata) {
sequenced_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&ReprocessManager::ReprocessManagerImpl::UpdateStaticMetadata,
base::Unretained(impl.get()), device_id, metadata.Clone()));
}
ReprocessManager::ReprocessManagerImpl::ReprocessManagerImpl(
UpdateStaticMetadataCallback callback)
: update_static_metadata_callback_(std::move(callback)) {}
ReprocessManager::ReprocessManagerImpl::~ReprocessManagerImpl() = default;
void ReprocessManager::ReprocessManagerImpl::SetReprocessOption(
const std::string& device_id,
cros::mojom::Effect effect,
cros::mojom::CrosImageCapture::SetReprocessOptionCallback
reprocess_result_callback) {
ReprocessTask task;
task.effect = effect;
task.callback = std::move(reprocess_result_callback);
if (effect == cros::mojom::Effect::PORTRAIT_MODE) {
std::vector<uint8_t> portrait_mode_value(sizeof(int32_t));
*reinterpret_cast<int32_t*>(portrait_mode_value.data()) = 1;
cros::mojom::CameraMetadataEntryPtr e =
cros::mojom::CameraMetadataEntry::New();
e->tag =
static_cast<cros::mojom::CameraMetadataTag>(kPortraitModeVendorKey);
e->type = cros::mojom::EntryType::TYPE_INT32;
e->count = 1;
e->data = std::move(portrait_mode_value);
task.extra_metadata.push_back(std::move(e));
}
reprocess_task_queue_map_[device_id].push(std::move(task));
}
void ReprocessManager::ReprocessManagerImpl::ConsumeReprocessOptions(
const std::string& device_id,
media::mojom::ImageCapture::TakePhotoCallback take_photo_callback,
base::OnceCallback<void(ReprocessTaskQueue)> consumption_callback) {
ReprocessTaskQueue result_task_queue;
ReprocessTask still_capture_task;
still_capture_task.effect = cros::mojom::Effect::NO_EFFECT;
still_capture_task.callback =
base::BindOnce(&OnStillCaptureDone, std::move(take_photo_callback));
result_task_queue.push(std::move(still_capture_task));
auto& task_queue = reprocess_task_queue_map_[device_id];
while (!task_queue.empty()) {
result_task_queue.push(std::move(task_queue.front()));
task_queue.pop();
}
std::move(consumption_callback).Run(std::move(result_task_queue));
}
void ReprocessManager::ReprocessManagerImpl::FlushReprocessOptions(
const std::string& device_id) {
auto empty_queue = ReprocessTaskQueue();
reprocess_task_queue_map_[device_id].swap(empty_queue);
}
void ReprocessManager::ReprocessManagerImpl::GetStaticMetadata(
const std::string& device_id,
GetStaticMetadataCallback callback) {
if (static_metadata_map_[device_id]) {
std::move(callback).Run(static_metadata_map_[device_id].Clone());
} else {
get_static_metadata_callback_queue_map_[device_id].push(
std::move(callback));
update_static_metadata_callback_.Run(device_id);
}
}
void ReprocessManager::ReprocessManagerImpl::UpdateStaticMetadata(
const std::string& device_id,
cros::mojom::CameraMetadataPtr metadata) {
static_metadata_map_[device_id] = std::move(metadata);
auto& callback_queue = get_static_metadata_callback_queue_map_[device_id];
while (!callback_queue.empty()) {
std::move(callback_queue.front())
.Run(static_metadata_map_[device_id].Clone());
callback_queue.pop();
}
}
} // namespace media