Snap for 7901677 from a1d5a41dce57f5aa647d98ec26db92a0ba27df21 to sc-platform-release
Change-Id: I2d071f1d1a2751af9d2be9a07ffa77caafe36a31
diff --git a/common/hal/google_camera_hal/realtime_zsl_request_processor.cc b/common/hal/google_camera_hal/realtime_zsl_request_processor.cc
index 1250496..c5db47d 100644
--- a/common/hal/google_camera_hal/realtime_zsl_request_processor.cc
+++ b/common/hal/google_camera_hal/realtime_zsl_request_processor.cc
@@ -195,8 +195,7 @@
// checked the size is supported in capture session.
if (pixel_format_ == android_pixel_format_t::HAL_PIXEL_FORMAT_YCBCR_420_888) {
for (const auto& stream : stream_config.streams) {
- if (utils::IsJPEGSnapshotStream(stream) ||
- utils::IsYUVSnapshotStream(stream)) {
+ if (utils::IsSoftwareDenoiseEligibleSnapshotStream(stream)) {
if (SelectWidthAndHeight(stream.width, stream.height,
*device_session_hwl_, active_array_width_,
active_array_height_) != OK) {
diff --git a/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc b/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
index 077a880..fa25403 100644
--- a/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
+++ b/common/hal/google_camera_hal/zsl_snapshot_capture_session.cc
@@ -163,28 +163,28 @@
return false;
}
- bool has_jpeg_stream = false;
+ bool has_eligible_snapshot_stream = false;
bool has_preview_stream = false;
- bool has_yuv_stream = false;
for (const auto& stream : stream_config.streams) {
if (stream.is_physical_camera_stream) {
ALOGE("%s: support logical camera only", __FUNCTION__);
return false;
}
- if (utils::IsJPEGSnapshotStream(stream)) {
- has_jpeg_stream = true;
+ if (utils::IsJPEGSnapshotStream(stream) ||
+ utils::IsYUVSnapshotStream(stream)) {
+ if (utils::IsSoftwareDenoiseEligibleSnapshotStream(stream)) {
+ has_eligible_snapshot_stream = true;
+ }
} else if (utils::IsPreviewStream(stream)) {
has_preview_stream = true;
- } else if (utils::IsYUVSnapshotStream(stream)) {
- has_yuv_stream = true;
} else {
ALOGE("%s: only support preview + (snapshot and/or YUV) streams",
__FUNCTION__);
return false;
}
}
- if (!has_jpeg_stream && !has_yuv_stream) {
- ALOGE("%s: no JPEG or YUV stream", __FUNCTION__);
+ if (!has_eligible_snapshot_stream) {
+ ALOGE("%s: no eligible JPEG or YUV stream", __FUNCTION__);
return false;
}
@@ -231,12 +231,16 @@
}
ZslSnapshotCaptureSession::~ZslSnapshotCaptureSession() {
+ auto release_thread = std::thread([this]() {
+ ATRACE_NAME("Release snapshot request processor");
+ snapshot_request_processor_ = nullptr;
+ });
if (camera_device_session_hwl_ != nullptr) {
camera_device_session_hwl_->DestroyPipelines();
}
// Need to explicitly release SnapshotProcessBlock by releasing
// SnapshotRequestProcessor before the lib handle is released.
- snapshot_request_processor_ = nullptr;
+ release_thread.join();
dlclose(snapshot_process_block_lib_handle_);
}
@@ -609,8 +613,8 @@
if (res == OK) {
partial_result_count_ = partial_result_entry.data.i32[0];
}
- result_dispatcher_ = ResultDispatcher::Create(partial_result_count_,
- process_capture_result, notify);
+ result_dispatcher_ = ZslResultDispatcher::Create(
+ partial_result_count_, process_capture_result, notify);
if (result_dispatcher_ == nullptr) {
ALOGE("%s: Cannot create result dispatcher.", __FUNCTION__);
return UNKNOWN_ERROR;
@@ -677,7 +681,15 @@
status_t ZslSnapshotCaptureSession::ProcessRequest(const CaptureRequest& request) {
ATRACE_CALL();
- status_t res = result_dispatcher_->AddPendingRequest(request);
+ bool is_zsl_request = false;
+ camera_metadata_ro_entry entry;
+ if (request.settings != nullptr) {
+ if (request.settings->Get(ANDROID_CONTROL_ENABLE_ZSL, &entry) == OK &&
+ *entry.data.u8 == ANDROID_CONTROL_ENABLE_ZSL_TRUE) {
+ is_zsl_request = true;
+ }
+ }
+ status_t res = result_dispatcher_->AddPendingRequest(request, is_zsl_request);
if (res != OK) {
ALOGE("%s: frame(%d) fail to AddPendingRequest", __FUNCTION__,
request.frame_number);
diff --git a/common/hal/google_camera_hal/zsl_snapshot_capture_session.h b/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
index dab4515..74b3cc3 100644
--- a/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
+++ b/common/hal/google_camera_hal/zsl_snapshot_capture_session.h
@@ -27,10 +27,10 @@
#include "realtime_zsl_request_processor.h"
#include "realtime_zsl_result_processor.h"
#include "request_processor.h"
-#include "result_dispatcher.h"
#include "result_processor.h"
#include "snapshot_request_processor.h"
#include "snapshot_result_processor.h"
+#include "zsl_result_dispatcher.h"
namespace android {
namespace google_camera_hal {
@@ -157,7 +157,7 @@
int32_t additional_stream_id_ = -1;
- std::unique_ptr<ResultDispatcher> result_dispatcher_;
+ std::unique_ptr<ZslResultDispatcher> result_dispatcher_;
std::mutex callback_lock_;
// The following callbacks must be protected by callback_lock_.
diff --git a/common/hal/hidl_service/Android.bp b/common/hal/hidl_service/Android.bp
index 29f7203..f10d6ef 100644
--- a/common/hal/hidl_service/Android.bp
+++ b/common/hal/hidl_service/Android.bp
@@ -46,21 +46,22 @@
},
}
-sh_binary_host {
+// Exported for use in vendor/google/services/LyricCameraHAL/src/
+python_binary_host {
name: "camera_hal_version_script",
- src: "version_script.sh",
- filename_from_src: true,
+ main: "version_script.py",
+ srcs: ["version_script.py"],
}
cc_genrule {
- name: "hidl_camera_build_version",
- tools: [":camera_hal_version_script"],
- cmd: "$(location :camera_hal_version_script) $(in) $(out)",
- vendor: true,
- srcs: [
- "hidl_camera_build_version.inl",
- ],
- out: ["hidl_camera_build_version.h"],
+ name: "hidl_camera_build_version",
+ tool_files: ["version_script.py"],
+ cmd: "python3 $(location version_script.py) $(in) $(out)",
+ vendor: true,
+ srcs: [
+ "hidl_camera_build_version.inl",
+ ],
+ out: ["hidl_camera_build_version.h"],
}
cc_defaults {
diff --git a/common/hal/hidl_service/version_script.py b/common/hal/hidl_service/version_script.py
new file mode 100644
index 0000000..a5bb167
--- /dev/null
+++ b/common/hal/hidl_service/version_script.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+#
+# See: go/camera-sideline#versions for more context
+#
+# This script generates the apex manifest version number (which is also used for
+# the outer aab/jar object's version available to PackageManager).
+#
+# That version is limited to INT_MAX
+# Strategy:
+# if(local eng build)
+# version = 2147480000
+# else
+# version = brach specific code + padding + numeric part of build number
+#
+# 2147480000 is chosen as being a value that can install over any expected build
+# server build number that is still a little smaller than INT_MAX to leave room
+# for maneuvering
+
+import os
+import re
+import sys
+
+BRANCH_SPECIFIC_VERSION_IDENTIFIER = 2 # sc-qpr1-dev
+DEFAULT_ENG_BUILD_NUMBER = 2147480000
+DEFAULT_BAD_BUILD_NUMBER = DEFAULT_ENG_BUILD_NUMBER - 1
+
+
+def tame_box(numeric_build_number):
+ # Box the regex extracted value to a min and a max, just in case. Should not
+ # be needed ever.
+ if numeric_build_number < 1:
+ numeric_build_number = 1
+ if numeric_build_number > DEFAULT_ENG_BUILD_NUMBER:
+ numeric_build_number = DEFAULT_BAD_BUILD_NUMBER
+ return numeric_build_number
+
+
+def get_version(input_path, output_path):
+
+ soong_build_number = DEFAULT_BAD_BUILD_NUMBER
+ numeric_build_number = DEFAULT_BAD_BUILD_NUMBER
+
+ # Extract the Android Build ID from the build products
+ out_dir = os.getenv('OUT_DIR')
+ with open('%s/soong/build_number.txt' % out_dir, 'r') as file:
+ soong_build_number = file.read().replace('\n', '')
+
+ # Eng builds all have a default very high version number to permit for local
+ # builds to ovewrite whatever else is installed on the OS.
+ if soong_build_number.startswith('eng.'): # eng.bills.20210901.235403
+ numeric_build_number = DEFAULT_ENG_BUILD_NUMBER
+ else:
+ # We only want the numeric part of the Android Build ID
+ match = re.search(r'([0-9]+)', soong_build_number)
+ if match:
+ numeric_build_number = int(match.group(0))
+ else:
+ numeric_build_number = DEFAULT_BAD_BUILD_NUMBER
+
+ # Tame the inputs into a reasonable box, just in case
+ numeric_build_number = tame_box(numeric_build_number)
+ # print('numeric_build_number: %s' % str(numeric_build_number))
+
+ # With the numeric build number as a starting point, let's augment it with
+ # the BRANCH_SPECIFIC_VERSION_IDENTIFIER to differentiate build products from
+ # this branch according to: go/camera-sideline#versions
+ branched_build_number = numeric_build_number
+ if numeric_build_number == DEFAULT_ENG_BUILD_NUMBER:
+ # High default eng numbers can't really be multiplied so we add our branch
+ # specific number instead
+ branched_build_number = numeric_build_number + BRANCH_SPECIFIC_VERSION_IDENTIFIER
+ else:
+ # Two cases to consider:
+ # 1. A "regular" Android Build ID like: 7699287
+ # 2. A pending Android Build ID like: P25748464
+
+ # "It's just string concatenation"
+ string_build_number = '%s%s' % (BRANCH_SPECIFIC_VERSION_IDENTIFIER,
+ str(numeric_build_number).zfill(8))
+ # Ints in python3 are long
+ branched_build_number = int(string_build_number)
+ # Tame the result into a reasonable box, just in case
+ branched_build_number = tame_box(branched_build_number)
+
+ # print('soong_build_number: %s' % soong_build_number)
+ # print('branched_build_number: %s' % str(branched_build_number))
+
+ # Bash version:
+ # cat $1 | \
+ # sed -E "s/\{BUILD_NUMBER\}/$numeric_build_number/g" | \
+ # sed -E "s/\{BUILD_ID\}/$soong_build_number/g" > $2
+ try:
+ if os.path.exists(input_path):
+ input_fh = open(input_path, 'r')
+ contents = input_fh.readlines()
+ # print('Read: %s' % input_path)
+ new_contents = []
+ input_fh.close()
+ for line in contents:
+ line = line.replace('{BUILD_ID}', soong_build_number)
+ line = line.replace('{BUILD_NUMBER}', str(branched_build_number))
+ new_contents.append(line)
+ # print(new_contents)
+ output_fh = open(output_path, 'w')
+ output_fh.write(''.join(new_contents))
+ output_fh.close()
+ # print('Wrote: %s' % output_path)
+ except IOError:
+ print(f'error occurred trying to read the file {input_path}')
+ return 1
+
+ return 0
+
+
+def main():
+ return get_version(*sys.argv[1:])
+
+
+if __name__ == '__main__':
+ sys.exit(main())
+
diff --git a/common/hal/hidl_service/version_script.sh b/common/hal/hidl_service/version_script.sh
deleted file mode 100755
index 2ab4e2b..0000000
--- a/common/hal/hidl_service/version_script.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-#
-# This script generates the apex manifest version number (which is also used for
-# the outer aab/jar object's version available to PackageManager).
-#
-# That version is limited to INT_MAX
-# Strategy:
-# if(local eng build)
-# version = 2147480000
-# else
-# version = numeric part of build number
-#
-# 2147480000 is chosen as being a value that can install over any expected build
-# server build number that is still a little smaller than INT_MAX to leave room
-# for maneuvering
-
-default_eng_build_number=2147480000
-
-build_number=$(cat $OUT_DIR/soong/build_number.txt)
-if [[ "$build_number" == "eng."* ]]; then
- numeric_build_number=$default_eng_build_number
-else
- numeric_build_number=$(cat $OUT_DIR/soong/build_number.txt | tr -d -c 0-9)
- if [[ -z "$numeric_build_number" ]]; then
- numeric_build_number=$default_eng_build_number
- fi
- if ((numeric_build_number < 1)); then
- numeric_build_number=1
- fi
- if ((numeric_build_number >= default_eng_build_number)); then
- numeric_build_number=$((default_eng_build_number-1))
- fi
-fi
-
-cat $1 | sed -E "s/\{BUILD_NUMBER\}/$numeric_build_number/g" | sed -E "s/\{BUILD_ID\}/$build_number/g" > $2
-
diff --git a/common/hal/utils/Android.bp b/common/hal/utils/Android.bp
index 6b2dc58..635a798 100644
--- a/common/hal/utils/Android.bp
+++ b/common/hal/utils/Android.bp
@@ -47,6 +47,7 @@
"vendor_tag_utils.cc",
"zoom_ratio_mapper.cc",
"zsl_buffer_manager.cc",
+ "zsl_result_dispatcher.cc",
],
shared_libs: [
"lib_profiler",
diff --git a/common/hal/utils/result_dispatcher.cc b/common/hal/utils/result_dispatcher.cc
index 6443e8f..6c8b2de 100644
--- a/common/hal/utils/result_dispatcher.cc
+++ b/common/hal/utils/result_dispatcher.cc
@@ -273,11 +273,13 @@
uint32_t frame_number = error.frame_number;
// No need to deliver the shutter message on an error
if (error.error_code == ErrorCode::kErrorDevice ||
- error.error_code == ErrorCode::kErrorResult) {
+ error.error_code == ErrorCode::kErrorResult ||
+ error.error_code == ErrorCode::kErrorRequest) {
pending_shutters_.erase(frame_number);
}
// No need to deliver the result metadata on a result metadata error
- if (error.error_code == ErrorCode::kErrorResult) {
+ if (error.error_code == ErrorCode::kErrorResult ||
+ error.error_code == ErrorCode::kErrorRequest) {
pending_final_metadata_.erase(frame_number);
}
diff --git a/common/hal/utils/result_dispatcher.h b/common/hal/utils/result_dispatcher.h
index 74f4b4a..5acc90a 100644
--- a/common/hal/utils/result_dispatcher.h
+++ b/common/hal/utils/result_dispatcher.h
@@ -65,7 +65,6 @@
// Remove a pending request.
void RemovePendingRequest(uint32_t frame_number);
- protected:
ResultDispatcher(uint32_t partial_result_count,
ProcessCaptureResultFunc process_capture_result,
NotifyFunc notify);
diff --git a/common/hal/utils/utils.cc b/common/hal/utils/utils.cc
index 54b382a..7a41889 100644
--- a/common/hal/utils/utils.cc
+++ b/common/hal/utils/utils.cc
@@ -15,16 +15,16 @@
*/
//#define LOG_NDEBUG 0
+#include <cstdint>
#define LOG_TAG "GCH_Utils"
-#include "utils.h"
-
#include <cutils/properties.h>
#include <dirent.h>
#include <dlfcn.h>
#include <hardware/gralloc.h>
#include <sys/stat.h>
+#include "utils.h"
#include "vendor_tag_defs.h"
namespace android {
@@ -34,6 +34,8 @@
constexpr char kRealtimeThreadSetProp[] =
"persist.vendor.camera.realtimethread";
+constexpr uint32_t kMinSupportedSoftwareDenoiseDimension = 1000;
+
bool IsDepthStream(const Stream& stream) {
if (stream.stream_type == StreamType::kOutput &&
stream.data_space == HAL_DATASPACE_DEPTH &&
@@ -121,6 +123,15 @@
return false;
}
+bool IsSoftwareDenoiseEligibleSnapshotStream(const Stream& stream) {
+ if (utils::IsYUVSnapshotStream(stream) ||
+ utils::IsJPEGSnapshotStream(stream)) {
+ return stream.width >= kMinSupportedSoftwareDenoiseDimension ||
+ stream.height >= kMinSupportedSoftwareDenoiseDimension;
+ }
+ return false;
+}
+
status_t GetSensorPhysicalSize(const HalCameraMetadata* characteristics,
float* width, float* height) {
if (characteristics == nullptr || width == nullptr || height == nullptr) {
diff --git a/common/hal/utils/utils.h b/common/hal/utils/utils.h
index 4412908..a43e614 100644
--- a/common/hal/utils/utils.h
+++ b/common/hal/utils/utils.h
@@ -36,6 +36,7 @@
bool IsYUVSnapshotStream(const Stream& stream);
bool IsDepthStream(const Stream& stream);
bool IsOutputZslStream(const Stream& stream);
+bool IsSoftwareDenoiseEligibleSnapshotStream(const Stream& stream);
bool HasCapability(const HalCameraMetadata* metadata, uint8_t capability);
diff --git a/common/hal/utils/zsl_result_dispatcher.cc b/common/hal/utils/zsl_result_dispatcher.cc
new file mode 100644
index 0000000..3b5baa4
--- /dev/null
+++ b/common/hal/utils/zsl_result_dispatcher.cc
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "GCH_ZslResultDispatcher"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+#include <log/log.h>
+#include <utils/Trace.h>
+
+#include <inttypes.h>
+
+#include "utils.h"
+#include "zsl_result_dispatcher.h"
+
+namespace android {
+namespace google_camera_hal {
+
+std::unique_ptr<ZslResultDispatcher> ZslResultDispatcher::Create(
+ uint32_t partial_result_count,
+ ProcessCaptureResultFunc process_capture_result, NotifyFunc notify) {
+ ATRACE_CALL();
+ auto dispatcher = std::unique_ptr<ZslResultDispatcher>(
+ new ZslResultDispatcher(process_capture_result, notify));
+ if (dispatcher == nullptr) {
+ ALOGE("%s: Creating ZslResultDispatcher failed.", __FUNCTION__);
+ return nullptr;
+ }
+
+ status_t res = dispatcher->Initialize(partial_result_count);
+ if (res != OK) {
+ ALOGE("%s: Initialize failed.", __FUNCTION__);
+ return nullptr;
+ }
+
+ return dispatcher;
+}
+
+ZslResultDispatcher::ZslResultDispatcher(
+ ProcessCaptureResultFunc process_capture_result, NotifyFunc notify)
+ : device_session_process_capture_result_(process_capture_result),
+ device_session_notify_(notify) {
+}
+
+status_t ZslResultDispatcher::Initialize(uint32_t partial_result_count) {
+ ATRACE_CALL();
+ process_capture_result_ =
+ ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
+ ProcessCaptureResult(std::move(result));
+ });
+ notify_ = NotifyFunc(
+ [this](const NotifyMessage& message) { NotifyHalMessage(message); });
+
+ normal_result_dispatcher_ =
+ std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
+ partial_result_count, process_capture_result_, notify_));
+ if (normal_result_dispatcher_ == nullptr) {
+ ALOGE("%s: Creating normal_result_dispatcher_ failed.", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ zsl_result_dispatcher_ =
+ std::unique_ptr<ResultDispatcher>(new ResultDispatcher(
+ partial_result_count, process_capture_result_, notify_));
+ if (zsl_result_dispatcher_ == nullptr) {
+ ALOGE("%s: Creating zsl_result_dispatcher_ failed.", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ return OK;
+}
+
+void ZslResultDispatcher::ProcessCaptureResult(
+ std::unique_ptr<CaptureResult> result) {
+ std::lock_guard<std::mutex> lock(process_capture_result_lock_);
+ device_session_process_capture_result_(std::move(result));
+}
+
+bool ZslResultDispatcher::IsZslFrame(uint32_t frame_number) {
+ std::lock_guard<std::mutex> lock(zsl_frames_lock_);
+ if (zsl_frames_.empty()) {
+ return false;
+ }
+ if (std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number) ==
+ zsl_frames_.end()) {
+ return false;
+ }
+ return true;
+}
+
+void ZslResultDispatcher::NotifyHalMessage(const NotifyMessage& message) {
+ std::lock_guard<std::mutex> lock(result_lock_);
+ device_session_notify_(message);
+}
+
+status_t ZslResultDispatcher::AddPendingRequest(
+ const CaptureRequest& pending_request, bool is_zsl_request) {
+ ATRACE_CALL();
+ if (is_zsl_request) {
+ uint32_t frame_number = pending_request.frame_number;
+ {
+ std::lock_guard<std::mutex> lock(zsl_frames_lock_);
+ zsl_frames_.push_back(frame_number);
+ }
+
+ status_t res = zsl_result_dispatcher_->AddPendingRequest(pending_request);
+ if (res != OK) {
+ std::lock_guard<std::mutex> lock(zsl_frames_lock_);
+ zsl_frames_.erase(
+ std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
+ }
+ return res;
+ } else {
+ return normal_result_dispatcher_->AddPendingRequest(pending_request);
+ }
+}
+
+status_t ZslResultDispatcher::AddResult(std::unique_ptr<CaptureResult> result) {
+ ATRACE_CALL();
+ if (result == nullptr) {
+ ALOGE("%s: result is nullptr", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ uint32_t frame_number = result->frame_number;
+ bool is_zsl_request = IsZslFrame(frame_number);
+ if (is_zsl_request) {
+ return zsl_result_dispatcher_->AddResult(std::move(result));
+ } else {
+ return normal_result_dispatcher_->AddResult(std::move(result));
+ }
+}
+
+status_t ZslResultDispatcher::AddShutter(uint32_t frame_number,
+ int64_t timestamp_ns) {
+ ATRACE_CALL();
+ bool is_zsl_request = IsZslFrame(frame_number);
+ if (is_zsl_request) {
+ return zsl_result_dispatcher_->AddShutter(frame_number, timestamp_ns);
+ } else {
+ return normal_result_dispatcher_->AddShutter(frame_number, timestamp_ns);
+ }
+}
+
+status_t ZslResultDispatcher::AddError(const ErrorMessage& error) {
+ ATRACE_CALL();
+ uint32_t frame_number = error.frame_number;
+ bool is_zsl_request = IsZslFrame(frame_number);
+ if (is_zsl_request) {
+ return zsl_result_dispatcher_->AddError(error);
+ } else {
+ return normal_result_dispatcher_->AddError(error);
+ }
+}
+
+void ZslResultDispatcher::RemovePendingRequest(uint32_t frame_number) {
+ ATRACE_CALL();
+ bool is_zsl_request = IsZslFrame(frame_number);
+ if (is_zsl_request) {
+ zsl_result_dispatcher_->RemovePendingRequest(frame_number);
+ std::lock_guard<std::mutex> lock(zsl_frames_lock_);
+ zsl_frames_.erase(
+ std::find(zsl_frames_.begin(), zsl_frames_.end(), frame_number));
+ } else {
+ normal_result_dispatcher_->RemovePendingRequest(frame_number);
+ }
+}
+
+} // namespace google_camera_hal
+} // namespace android
diff --git a/common/hal/utils/zsl_result_dispatcher.h b/common/hal/utils/zsl_result_dispatcher.h
new file mode 100644
index 0000000..6297b6b
--- /dev/null
+++ b/common/hal/utils/zsl_result_dispatcher.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_RESULT_DISPATCHER_H_
+#define HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_RESULT_DISPATCHER_H_
+
+#include <map>
+#include <thread>
+
+#include "hal_types.h"
+#include "result_dispatcher.h"
+
+namespace android {
+namespace google_camera_hal {
+
+// ZslResultDispatcher dispatches capture results of zsl requests and none-zsl
+// requests in the order of frame numbers, including result metadata, shutters,
+// and stream buffers.
+//
+// The client can add results and shutters via AddResult() and AddShutter() in
+// any order. ZslResultDispatcher will invoke ProcessCaptureResultFunc and
+// NotifyFunc to notify result metadata, shutters, and stream buffers in the
+// in the order of increasing frame numbers.
+class ZslResultDispatcher {
+ public:
+ // Create a ZslResultDispatcher.
+ // partial_result_count is the partial result count.
+ // process_capture_result is the function to notify capture results.
+ // notify is the function to notify shutter messages.
+ // Treat ZSL requests and normal requests separately.
+ // For ZSL requests, it returns zsl shutter and zsl results in order
+ // and is not blocked by normal shutter and results.
+ static std::unique_ptr<ZslResultDispatcher> Create(
+ uint32_t partial_result_count,
+ ProcessCaptureResultFunc process_capture_result, NotifyFunc notify);
+
+ virtual ~ZslResultDispatcher() = default;
+
+ // Add a pending request. This tells ZslResultDispatcher to watch for
+ // the shutter, result metadata, and stream buffers for this request,
+ // that will be added later via AddResult() and AddShutter().
+ // Treat the request as zsl request if is_zsl_request is true
+ status_t AddPendingRequest(const CaptureRequest& pending_request,
+ bool is_zsl_request);
+
+ // Add a ready result. If the result doesn't belong to a pending request that
+ // was previously added via AddPendingRequest(), an error will be returned.
+ status_t AddResult(std::unique_ptr<CaptureResult> result);
+
+ // Add a shutter for a frame number. If the frame number doesn't belong to a
+ // pending request that was previously added via AddPendingRequest(), an error
+ // will be returned.
+ status_t AddShutter(uint32_t frame_number, int64_t timestamp_ns);
+
+ // Add an error notification for a frame number. When this is called, we no
+ // longer wait for a shutter message or result metadata for the given frame.
+ status_t AddError(const ErrorMessage& error);
+
+ // Remove a pending request.
+ void RemovePendingRequest(uint32_t frame_number);
+
+ protected:
+ ZslResultDispatcher(ProcessCaptureResultFunc process_capture_result,
+ NotifyFunc notify);
+
+ private:
+ status_t Initialize(uint32_t partial_result_count);
+
+ // Invoked when receiving a result from ResultDispatcher class.
+ void ProcessCaptureResult(std::unique_ptr<CaptureResult> result);
+
+ // Invoked when receiving a message from ResultDispatcher.
+ void NotifyHalMessage(const NotifyMessage& message);
+
+ // Return true if this frame is zsl request.
+ bool IsZslFrame(uint32_t frame_number);
+
+ std::unique_ptr<ResultDispatcher> normal_result_dispatcher_;
+ std::unique_ptr<ResultDispatcher> zsl_result_dispatcher_;
+
+ std::mutex process_capture_result_lock_;
+ // The following callbacks must be protected by process_capture_result_lock_.
+ // Pass this callback function to ResultDispatcher class
+ ProcessCaptureResultFunc process_capture_result_;
+
+ std::mutex result_lock_;
+ // The following callbacks must be protected by result_lock_.
+ // Pass this callback function to ResultDispatcher class
+ NotifyFunc notify_;
+
+ // Record the callback function for framework callback
+ ProcessCaptureResultFunc device_session_process_capture_result_;
+ NotifyFunc device_session_notify_;
+
+ std::mutex zsl_frames_lock_;
+ // Store the frame number of zsl requests
+ // Protected by zsl_frames_lock_.
+ std::vector<uint32_t> zsl_frames_;
+};
+
+} // namespace google_camera_hal
+} // namespace android
+
+#endif // HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_RESULT_DISPATCHER_H_
diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
index a1e553a..e7c62f9 100644
--- a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
@@ -969,8 +969,11 @@
}
if (zoom_ratio_supported_) {
result->result_metadata->Set(ANDROID_CONTROL_ZOOM_RATIO, &zoom_ratio_, 1);
- result->result_metadata->Set(ANDROID_SCALER_CROP_REGION,
- scaler_crop_region_default_,
+ int32_t* chosen_crop_region = scaler_crop_region_default_;
+ if (sensor_pixel_mode_ == ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) {
+ chosen_crop_region = scaler_crop_region_max_resolution_;
+ }
+ result->result_metadata->Set(ANDROID_SCALER_CROP_REGION, chosen_crop_region,
ARRAY_SIZE(scaler_crop_region_default_));
}
if (report_extended_scene_mode_) {
@@ -2285,6 +2288,23 @@
return BAD_VALUE;
}
+ if (SupportsCapability(
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR)) {
+ ret = static_metadata_->Get(
+ ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, &entry);
+ if ((ret == OK) && (entry.count == 4)) {
+ scaler_crop_region_max_resolution_[0] = entry.data.i32[0];
+ scaler_crop_region_max_resolution_[1] = entry.data.i32[1];
+ scaler_crop_region_max_resolution_[2] = entry.data.i32[2];
+ scaler_crop_region_max_resolution_[3] = entry.data.i32[3];
+ } else {
+ ALOGE(
+ "%s: Sensor pixel array size maximum resolution is not available!",
+ __FUNCTION__);
+ return BAD_VALUE;
+ }
+ }
+
if (available_requests_.find(ANDROID_SCALER_CROP_REGION) ==
available_requests_.end()) {
ALOGE(
diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.h b/devices/EmulatedCamera/hwl/EmulatedRequestState.h
index 1591422..1987bfa 100644
--- a/devices/EmulatedCamera/hwl/EmulatedRequestState.h
+++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.h
@@ -262,6 +262,7 @@
bool report_rotate_and_crop_ = false;
uint8_t rotate_and_crop_ = ANDROID_SCALER_ROTATE_AND_CROP_NONE;
int32_t scaler_crop_region_default_[4] = {0, 0, 0, 0};
+ int32_t scaler_crop_region_max_resolution_[4] = {0, 0, 0, 0};
std::set<uint8_t> available_rotate_crop_modes_;
// android.statistics.*