blob: 8035648176b57c10c396cdd3aed80320a1e60360 [file] [log] [blame]
/*
* Copyright 2018 The Chromium OS 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 "hal_adapter/reprocess_effect/reprocess_effect_manager.h"
#include <utility>
#include <vector>
#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/logging.h>
#include <hardware/gralloc.h>
#include "cros-camera/common.h"
#include "hal_adapter/reprocess_effect/portrait_mode_effect.h"
#include "hal_adapter/vendor_tags.h"
namespace cros {
ReprocessEffectManager::ReprocessEffectManager()
: max_vendor_tag_(VENDOR_GOOGLE_START),
buffer_manager_(CameraBufferManager::GetInstance()) {}
int32_t ReprocessEffectManager::Initialize() {
VLOGF_ENTER();
portrait_mode_ = std::make_unique<PortraitModeEffect>();
std::vector<VendorTagInfo> request_vendor_tags;
std::vector<VendorTagInfo> result_vendor_tags;
if (portrait_mode_->InitializeAndGetVendorTags(&request_vendor_tags,
&result_vendor_tags) != 0) {
LOGF(ERROR) << "Failed to initialize portrait mode effect";
return -ENODEV;
}
if (!request_vendor_tags.empty() || !result_vendor_tags.empty()) {
uint32_t request_vendor_tag_start = max_vendor_tag_;
for (const auto& it : request_vendor_tags) {
vendor_tag_effect_info_map_.emplace(
max_vendor_tag_, VendorTagEffectInfo(it, portrait_mode_.get()));
max_vendor_tag_++;
}
uint32_t result_vendor_tag_start = max_vendor_tag_;
for (const auto& it : result_vendor_tags) {
vendor_tag_effect_info_map_.emplace(max_vendor_tag_,
VendorTagEffectInfo(it, nullptr));
max_vendor_tag_++;
}
if (portrait_mode_->SetVendorTags(
request_vendor_tag_start,
result_vendor_tag_start - request_vendor_tag_start,
result_vendor_tag_start,
max_vendor_tag_ - result_vendor_tag_start) != 0) {
LOGF(ERROR) << "Failed to set portrait mode effect vendor tags";
return -ENODEV;
}
}
return 0;
}
int32_t ReprocessEffectManager::GetAllVendorTags(
std::unordered_map<uint32_t, VendorTagInfo>* vendor_tag_map) {
if (!vendor_tag_map) {
return -EINVAL;
}
for (const auto& it : vendor_tag_effect_info_map_) {
vendor_tag_map->emplace(it.first, it.second.vendor_tag_info);
}
return 0;
}
bool ReprocessEffectManager::HasReprocessEffectVendorTag(
const camera_metadata_t& settings) {
VLOGF_ENTER();
for (uint32_t tag = VENDOR_GOOGLE_START; tag < max_vendor_tag_; tag++) {
camera_metadata_ro_entry_t entry;
if (find_camera_metadata_ro_entry(&settings, tag, &entry) == 0) {
DCHECK(vendor_tag_effect_info_map_.find(tag) !=
vendor_tag_effect_info_map_.end());
if (!vendor_tag_effect_info_map_.at(tag).effect) {
LOGF(WARNING) << "Received result vendor tag 0x" << std::hex << tag
<< " in request";
continue;
}
return true;
}
}
return false;
}
int32_t ReprocessEffectManager::ReprocessRequest(
const camera_metadata_t& settings,
ScopedYUVBufferHandle* input_buffer,
uint32_t width,
uint32_t height,
android::CameraMetadata* result_metadata,
ScopedYUVBufferHandle* output_buffer) {
VLOGF_ENTER();
if (!input_buffer || !*input_buffer || !output_buffer || !*output_buffer) {
return -EINVAL;
}
uint32_t orientation = 0;
camera_metadata_ro_entry_t entry;
if (find_camera_metadata_ro_entry(&settings, ANDROID_JPEG_ORIENTATION,
&entry) == 0) {
orientation = entry.data.i32[0];
}
// TODO(hywu): enable cascading effects
for (uint32_t tag = VENDOR_GOOGLE_START; tag < max_vendor_tag_; tag++) {
if (find_camera_metadata_ro_entry(&settings, tag, &entry) == 0) {
DCHECK(vendor_tag_effect_info_map_.find(tag) !=
vendor_tag_effect_info_map_.end());
if (!vendor_tag_effect_info_map_.at(tag).effect) {
LOGF(WARNING) << "Received result vendor tag 0x" << std::hex << tag
<< " in request";
continue;
}
int result = 0;
uint32_t v4l2_format =
buffer_manager_->GetV4L2PixelFormat(*output_buffer->GetHandle());
result = vendor_tag_effect_info_map_.at(tag).effect->ReprocessRequest(
settings, input_buffer, width, height, orientation, v4l2_format,
result_metadata, output_buffer);
if (result != 0) {
LOGF(ERROR) << "Failed to handle reprocess request on vendor tag 0x"
<< std::hex << tag;
}
return result;
}
}
return -ENOENT;
}
} // namespace cros