diff options
16 files changed, 416 insertions, 232 deletions
diff --git a/common/hal/google_camera_hal/realtime_zsl_result_request_processor.cc b/common/hal/google_camera_hal/realtime_zsl_result_request_processor.cc index 498d681..0912351 100644 --- a/common/hal/google_camera_hal/realtime_zsl_result_request_processor.cc +++ b/common/hal/google_camera_hal/realtime_zsl_result_request_processor.cc @@ -121,9 +121,34 @@ void RealtimeZslResultRequestProcessor::ProcessResult( } // Return directly for frames with errors. - if (pending_error_frames_.find(result->frame_number) != - pending_error_frames_.end()) { - pending_error_frames_.erase(result->frame_number); + const auto& error_entry = pending_error_frames_.find(result->frame_number); + if (error_entry != pending_error_frames_.end()) { + // Also need to process pending buffers and metadata for the frame if exists. + const auto& entry = + pending_frame_number_to_requests_.find(result->frame_number); + if (entry != pending_frame_number_to_requests_.end()) { + // If the result is complete (buffers and all partial results arrived), send + // the callback directly. Otherwise wait until the missing pieces arrive. + if (!entry->second.capture_request->output_buffers.empty()) { + result->output_buffers = entry->second.capture_request->output_buffers; + result->input_buffers = entry->second.capture_request->input_buffers; + error_entry->second.capture_request->output_buffers = + result->output_buffers; + error_entry->second.capture_request->input_buffers = + result->input_buffers; + } + if (entry->second.capture_request->settings != nullptr) { + result->result_metadata = HalCameraMetadata::Clone( + entry->second.capture_request->settings.get()); + result->partial_result = entry->second.partial_results_received; + error_entry->second.partial_results_received++; + } + pending_frame_number_to_requests_.erase(result->frame_number); + } + if (!error_entry->second.capture_request->output_buffers.empty() && + error_entry->second.partial_results_received == partial_result_count_) { + pending_error_frames_.erase(result->frame_number); + } process_capture_result_(std::move(result)); return; } @@ -132,34 +157,53 @@ void RealtimeZslResultRequestProcessor::ProcessResult( // come together. if (pending_frame_number_to_requests_.find(result->frame_number) == pending_frame_number_to_requests_.end()) { - pending_frame_number_to_requests_[result->frame_number] = - std::make_unique<CaptureRequest>(); - pending_frame_number_to_requests_[result->frame_number]->frame_number = - result->frame_number; + pending_frame_number_to_requests_[result->frame_number] = { + .capture_request = std::make_unique<CaptureRequest>()}; + pending_frame_number_to_requests_[result->frame_number] + .capture_request->frame_number = result->frame_number; } // Fill in final result metadata - if (result->result_metadata != nullptr && - result->partial_result == partial_result_count_) { - pending_frame_number_to_requests_[result->frame_number]->settings = - HalCameraMetadata::Clone(result->result_metadata.get()); + if (result->result_metadata != nullptr) { + pending_frame_number_to_requests_[result->frame_number] + .partial_results_received++; + if (result->partial_result < partial_result_count_) { + // Early result, clone it + pending_frame_number_to_requests_[result->frame_number] + .capture_request->settings = + HalCameraMetadata::Clone(result->result_metadata.get()); + } else { + // Final result, early result may or may not exist + if (pending_frame_number_to_requests_[result->frame_number] + .capture_request->settings == nullptr) { + // No early result, i.e. partial results disabled. Clone final result + pending_frame_number_to_requests_[result->frame_number] + .capture_request->settings = + HalCameraMetadata::Clone(result->result_metadata.get()); + } else { + // Append final result to early result + pending_frame_number_to_requests_[result->frame_number] + .capture_request->settings->Append( + result->result_metadata->GetRawCameraMetadata()); + } + } } // Fill in output buffer if (!result->output_buffers.empty()) { - pending_frame_number_to_requests_[result->frame_number]->input_buffers = - result->input_buffers; - pending_frame_number_to_requests_[result->frame_number]->output_buffers = - result->output_buffers; + pending_frame_number_to_requests_[result->frame_number] + .capture_request->input_buffers = result->input_buffers; + pending_frame_number_to_requests_[result->frame_number] + .capture_request->output_buffers = result->output_buffers; } // Submit the request and remove the request from the cache when all data is collected. if (!pending_frame_number_to_requests_[result->frame_number] - ->output_buffers.empty() && - pending_frame_number_to_requests_[result->frame_number]->settings != - nullptr) { - res = - ProcessRequest(*pending_frame_number_to_requests_[result->frame_number]); + .capture_request->output_buffers.empty() && + pending_frame_number_to_requests_[result->frame_number] + .partial_results_received == partial_result_count_) { + res = ProcessRequest( + *pending_frame_number_to_requests_[result->frame_number].capture_request); pending_frame_number_to_requests_.erase(result->frame_number); if (res != OK) { ALOGE("%s: ProcessRequest fail", __FUNCTION__); @@ -265,7 +309,9 @@ void RealtimeZslResultRequestProcessor::Notify( if (message.type == MessageType::kError) { if (message.message.error.error_code == ErrorCode::kErrorRequest || message.message.error.error_code == ErrorCode::kErrorBuffer) { - pending_error_frames_.insert(message.message.error.frame_number); + pending_error_frames_.try_emplace( + message.message.error.frame_number, + RequestEntry{.capture_request = std::make_unique<CaptureRequest>()}); } } notify_(message); diff --git a/common/hal/google_camera_hal/realtime_zsl_result_request_processor.h b/common/hal/google_camera_hal/realtime_zsl_result_request_processor.h index 99fba95..61fad21 100644 --- a/common/hal/google_camera_hal/realtime_zsl_result_request_processor.h +++ b/common/hal/google_camera_hal/realtime_zsl_result_request_processor.h @@ -71,10 +71,20 @@ class RealtimeZslResultRequestProcessor : public RealtimeZslResultProcessor, // Protected by process_block_shared_lock_. std::unique_ptr<ProcessBlock> process_block_; - std::unordered_map<uint32_t, std::unique_ptr<CaptureRequest>> - pending_frame_number_to_requests_; - - std::unordered_set<uint32_t> pending_error_frames_; + // Simple wrapper struct to add partial result count to CaptureResult + struct RequestEntry { + std::unique_ptr<CaptureRequest> capture_request = nullptr; + uint32_t partial_results_received = 0; + }; + + // Results collected so far on a valid frame. Results are passed to the + // processor block once all items in the RequestEntry struct are complete - + // i.e. all buffers arrived an all partial results arrived. + std::unordered_map<uint32_t, RequestEntry> pending_frame_number_to_requests_; + // Results collected so far on a frame with an error. Each result item gets + // reported to the upper layer as it comes in, and once the RequestEntry + // struct is complete the entry is removed. + std::unordered_map<uint32_t, RequestEntry> pending_error_frames_; }; } // namespace google_camera_hal diff --git a/devices/EmulatedCamera/hwl/Android.bp b/devices/EmulatedCamera/hwl/Android.bp index cf276ec..fad5ef0 100644 --- a/devices/EmulatedCamera/hwl/Android.bp +++ b/devices/EmulatedCamera/hwl/Android.bp @@ -14,13 +14,8 @@ cc_defaults { "EmulatedLogicalRequestState.cpp", "EmulatedRequestProcessor.cpp", "EmulatedRequestState.cpp", - "EmulatedScene.cpp", - "EmulatedSensor.cpp", "EmulatedTorchState.cpp", - "JpegCompressor.cpp", - "utils/ExifUtils.cpp", - "utils/HWLUtils.cpp", - "utils/StreamConfigurationMap.cpp", + "GrallocSensorBuffer.cpp", ], cflags: [ "-Werror", @@ -56,6 +51,7 @@ cc_defaults { ], static_libs: [ "android.hardware.camera.common@1.0-helper", + "libgooglecamerahwl_sensor_impl", ], include_dirs: [ "system/media/private/camera/include", @@ -78,3 +74,52 @@ cc_library_shared { // Never installed to /vendor, only used inside an APEX. installable: false, } + +cc_library_static { + name: "libgooglecamerahwl_sensor_impl", + owner: "google", + proprietary: true, + host_supported: true, + + srcs: [ + "EmulatedScene.cpp", + "EmulatedSensor.cpp", + "JpegCompressor.cpp", + "utils/ExifUtils.cpp", + "utils/HWLUtils.cpp", + "utils/StreamConfigurationMap.cpp", + ], + + header_libs: [ + "libhardware_headers", + ], + + shared_libs: [ + "libcamera_metadata", + "libcutils", + "libexif", + "libjpeg", + "liblog", + "libyuv", + ], + + static_libs: [ + "android.hardware.graphics.common@1.1", + "android.hardware.graphics.common@1.2", + ], + + include_dirs: [ + "system/media/private/camera/include", + "hardware/google/camera/common/hal/common", + "hardware/google/camera/common/hal/hwl_interface", + "hardware/google/camera/common/hal/utils", + ], + + export_include_dirs: ["."], + + cflags: [ + "-Werror", + "-Wextra", + "-Wall", + ], +} diff --git a/devices/EmulatedCamera/hwl/Base.h b/devices/EmulatedCamera/hwl/Base.h index 883b61a..c6722a5 100644 --- a/devices/EmulatedCamera/hwl/Base.h +++ b/devices/EmulatedCamera/hwl/Base.h @@ -21,12 +21,11 @@ #include <memory> -#include "HandleImporter.h" +#include "android/hardware/graphics/common/1.1/types.h" #include "hwl_types.h" namespace android { -using android::hardware::camera::common::V1_0::helper::HandleImporter; using android::hardware::graphics::common::V1_1::PixelFormat; using google_camera_hal::HwlPipelineCallback; using google_camera_hal::StreamBuffer; @@ -55,7 +54,6 @@ struct SensorBuffer { PixelFormat format; android_dataspace_t dataSpace; StreamBuffer stream_buffer; - std::shared_ptr<HandleImporter> importer; HwlPipelineCallback callback; int acquire_fence_fd; bool is_input; @@ -66,7 +64,7 @@ struct SensorBuffer { YCbCrPlanes img_y_crcb; } plane; - SensorBuffer(std::shared_ptr<HandleImporter> handle_importer) + SensorBuffer() : width(0), height(0), frame_number(0), @@ -74,7 +72,6 @@ struct SensorBuffer { camera_id(0), format(PixelFormat::RGBA_8888), dataSpace(HAL_DATASPACE_UNKNOWN), - importer(handle_importer), acquire_fence_fd(-1), is_input(false), is_failed_request(false), @@ -83,59 +80,13 @@ struct SensorBuffer { SensorBuffer(const SensorBuffer&) = delete; SensorBuffer& operator=(const SensorBuffer&) = delete; + + virtual ~SensorBuffer() { + } }; typedef std::vector<std::unique_ptr<SensorBuffer>> Buffers; } // namespace android -using android::google_camera_hal::BufferStatus; -using android::google_camera_hal::ErrorCode; -using android::google_camera_hal::HwlPipelineResult; -using android::google_camera_hal::MessageType; -using android::google_camera_hal::NotifyMessage; - -template <> -struct std::default_delete<android::SensorBuffer> { - inline void operator()(android::SensorBuffer* buffer) const { - if (buffer != nullptr) { - if (buffer->stream_buffer.buffer != nullptr) { - buffer->importer->unlock(buffer->stream_buffer.buffer); - } - - if (buffer->acquire_fence_fd >= 0) { - buffer->importer->closeFence(buffer->acquire_fence_fd); - } - - if ((buffer->stream_buffer.status != BufferStatus::kOk) && - (buffer->callback.notify != nullptr) && (!buffer->is_failed_request)) { - NotifyMessage msg = { - .type = MessageType::kError, - .message.error = {.frame_number = buffer->frame_number, - .error_stream_id = buffer->stream_buffer.stream_id, - .error_code = ErrorCode::kErrorBuffer}}; - buffer->callback.notify(buffer->pipeline_id, msg); - } - - if (buffer->callback.process_pipeline_result != nullptr) { - auto result = std::make_unique<HwlPipelineResult>(); - result->camera_id = buffer->camera_id; - result->pipeline_id = buffer->pipeline_id; - result->frame_number = buffer->frame_number; - result->partial_result = 0; - - buffer->stream_buffer.acquire_fence = - buffer->stream_buffer.release_fence = nullptr; - if (buffer->is_input) { - result->input_buffers.push_back(buffer->stream_buffer); - } else { - result->output_buffers.push_back(buffer->stream_buffer); - } - buffer->callback.process_pipeline_result(std::move(result)); - } - delete buffer; - } - } -}; - #endif diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp index 558bb01..fb46544 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.cpp @@ -24,6 +24,8 @@ #include <log/log.h> #include <utils/Trace.h> +#include <memory> + #include "EmulatedSensor.h" #include "utils.h" #include "utils/HWLUtils.h" @@ -204,9 +206,11 @@ status_t EmulatedCameraDeviceSessionHwlImpl::InitializeRequestProcessor() { return ret; } - request_processor_ = std::make_unique<EmulatedRequestProcessor>( + request_processor_ = std::make_shared<EmulatedRequestProcessor>( camera_id_, emulated_sensor, session_callback_); + request_processor_->InitializeSensorQueue(request_processor_); + return request_processor_->Initialize( HalCameraMetadata::Clone(static_metadata_.get()), ClonePhysicalDeviceMap(physical_device_map_)); diff --git a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h index 52a4920..81631cf 100644 --- a/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h +++ b/devices/EmulatedCamera/hwl/EmulatedCameraDeviceSessionHWLImpl.h @@ -19,6 +19,7 @@ #include <camera_device_session_hwl.h> +#include <memory> #include <set> #include "EmulatedCameraDeviceHWLImpl.h" @@ -203,7 +204,7 @@ class EmulatedCameraDeviceSessionHwlImpl : public CameraDeviceSessionHwl { bool has_raw_stream_ = false; std::unique_ptr<HalCameraMetadata> static_metadata_; std::vector<EmulatedPipeline> pipelines_; - std::unique_ptr<EmulatedRequestProcessor> request_processor_; + std::shared_ptr<EmulatedRequestProcessor> request_processor_; std::unique_ptr<StreamConfigurationMap> stream_configuration_map_; PhysicalStreamConfigurationMap physical_stream_configuration_map_; PhysicalStreamConfigurationMap physical_stream_configuration_map_max_resolution_; diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp index 03c067d..05f3263 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.cpp @@ -26,9 +26,17 @@ #include <utils/Timers.h> #include <utils/Trace.h> +#include <memory> + +#include "GrallocSensorBuffer.h" + namespace android { +using ::android::frameworks::sensorservice::V1_0::ISensorManager; +using ::android::frameworks::sensorservice::V1_0::Result; using android::hardware::camera::common::V1_0::helper::HandleImporter; +using ::android::hardware::sensors::V1_0::SensorInfo; +using ::android::hardware::sensors::V1_0::SensorType; using google_camera_hal::ErrorCode; using google_camera_hal::HwlPipelineResult; using google_camera_hal::MessageType; @@ -56,6 +64,12 @@ EmulatedRequestProcessor::~EmulatedRequestProcessor() { ALOGE("%s: Failed during sensor shutdown %s (%d)", __FUNCTION__, strerror(-ret), ret); } + + if (sensor_event_queue_.get() != nullptr) { + sensor_event_queue_->disableSensor(sensor_handle_); + sensor_event_queue_.clear(); + sensor_event_queue_ = nullptr; + } } status_t EmulatedRequestProcessor::ProcessPipelineRequests( @@ -327,7 +341,7 @@ std::unique_ptr<SensorBuffer> EmulatedRequestProcessor::CreateSensorBuffer( uint32_t pipeline_id, HwlPipelineCallback callback, StreamBuffer stream_buffer, int32_t override_width, int32_t override_height) { - auto buffer = std::make_unique<SensorBuffer>(importer_); + auto buffer = std::make_unique<GrallocSensorBuffer>(importer_); auto stream = emulated_stream; // Make sure input stream formats are correctly mapped here @@ -455,6 +469,13 @@ void EmulatedRequestProcessor::RequestProcessorLoop() { if (ret == OK) { auto result = request_state_->InitializeLogicalResult(pipeline_id, frame_number); + // The screen rotation will be the same for all logical and physical devices + uint32_t screen_rotation = screen_rotation_; + for (auto it = logical_settings->begin(); + it != logical_settings->end(); it++) { + it->second.screen_rotation = screen_rotation; + } + sensor_->SetCurrentRequest( std::move(logical_settings), std::move(result), std::move(input_buffers), std::move(output_buffers)); @@ -511,4 +532,84 @@ status_t EmulatedRequestProcessor::GetDefaultRequest( return request_state_->GetDefaultRequest(type, default_settings); } +Return<void> EmulatedRequestProcessor::SensorHandler::onEvent(const Event& e) { + auto processor = processor_.lock(); + if (processor.get() == nullptr) { + return Void(); + } + + if (e.sensorType == SensorType::ACCELEROMETER) { + // Heuristic approach for deducing the screen + // rotation depending on the reported + // accelerometer readings. We switch + // the screen rotation when one of the + // x/y axis gets close enough to the earth + // acceleration. + const uint32_t earth_accel = 9; // Switch threshold [m/s^2] + uint32_t x_accel = e.u.vec3.x; + uint32_t y_accel = e.u.vec3.y; + if (x_accel == earth_accel) { + processor->screen_rotation_ = 270; + } else if (x_accel == -earth_accel) { + processor->screen_rotation_ = 90; + } else if (y_accel == -earth_accel) { + processor->screen_rotation_ = 180; + } else { + processor->screen_rotation_ = 0; + } + } else { + ALOGE("%s: unexpected event received type: %d", __func__, e.sensorType); + } + return Void(); +} + +void EmulatedRequestProcessor::InitializeSensorQueue( + std::weak_ptr<EmulatedRequestProcessor> processor) { + if (sensor_event_queue_.get() != nullptr) { + return; + } + + sp<ISensorManager> manager = ISensorManager::getService(); + if (manager == nullptr) { + ALOGE("%s: Cannot get ISensorManager", __func__); + } else { + bool sensor_found = false; + manager->getSensorList([&](const auto& list, auto result) { + if (result != Result::OK) { + ALOGE("%s: Failed to retrieve sensor list!", __func__); + } else { + for (const SensorInfo& it : list) { + if (it.type == SensorType::ACCELEROMETER) { + sensor_found = true; + sensor_handle_ = it.sensorHandle; + } + } + } + }); + if (sensor_found) { + manager->createEventQueue( + new SensorHandler(processor), [&](const auto& q, auto result) { + if (result != Result::OK) { + ALOGE("%s: Cannot create event queue", __func__); + return; + } + sensor_event_queue_ = q; + }); + + if (sensor_event_queue_.get() != nullptr) { + auto res = sensor_event_queue_->enableSensor( + sensor_handle_, + ns2us(EmulatedSensor::kSupportedFrameDurationRange[0]), + 0 /*maxBatchReportLatencyUs*/); + if (res.isOk()) { + } else { + ALOGE("%s: Failed to enable sensor", __func__); + } + } else { + ALOGE("%s: Failed to create event queue", __func__); + } + } + } +} + } // namespace android diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h index 4f47e89..f931e35 100644 --- a/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h +++ b/devices/EmulatedCamera/hwl/EmulatedRequestProcessor.h @@ -18,16 +18,26 @@ #define EMULATOR_CAMERA_HAL_HWL_REQUEST_PROCESSOR_H #include <condition_variable> +#include <memory> #include <mutex> #include <queue> #include <thread> #include "EmulatedLogicalRequestState.h" #include "EmulatedSensor.h" +#include "HandleImporter.h" +#include "android/frameworks/sensorservice/1.0/ISensorManager.h" +#include "android/frameworks/sensorservice/1.0/types.h" #include "hwl_types.h" namespace android { +using ::android::frameworks::sensorservice::V1_0::IEventQueue; +using ::android::frameworks::sensorservice::V1_0::IEventQueueCallback; +using ::android::hardware::Return; +using ::android::hardware::Void; +using android::hardware::camera::common::V1_0::helper::HandleImporter; +using ::android::hardware::sensors::V1_0::Event; using google_camera_hal::HalCameraMetadata; using google_camera_hal::HwlPipelineRequest; using google_camera_hal::HwlSessionCallback; @@ -62,10 +72,28 @@ class EmulatedRequestProcessor { status_t Initialize(std::unique_ptr<HalCameraMetadata> static_meta, PhysicalDeviceMapPtr physical_devices); + void InitializeSensorQueue(std::weak_ptr<EmulatedRequestProcessor> processor); void SetSessionCallback(const HwlSessionCallback& hwl_session_callback); private: + class SensorHandler : public IEventQueueCallback { + public: + SensorHandler(std::weak_ptr<EmulatedRequestProcessor> processor) + : processor_(processor) { + } + + // IEventQueueCallback interface + Return<void> onEvent(const Event& e) override; + + private: + std::weak_ptr<EmulatedRequestProcessor> processor_; + }; + + int32_t sensor_handle_; + sp<IEventQueue> sensor_event_queue_; + std::atomic_uint32_t screen_rotation_; + void RequestProcessorLoop(); std::thread request_thread_; diff --git a/devices/EmulatedCamera/hwl/EmulatedScene.cpp b/devices/EmulatedCamera/hwl/EmulatedScene.cpp index 965b3b5..800eacb 100644 --- a/devices/EmulatedCamera/hwl/EmulatedScene.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedScene.cpp @@ -29,11 +29,6 @@ namespace android { -using ::android::frameworks::sensorservice::V1_0::ISensorManager; -using ::android::frameworks::sensorservice::V1_0::Result; -using ::android::hardware::sensors::V1_0::SensorInfo; -using ::android::hardware::sensors::V1_0::SensorType; - // Define single-letter shortcuts for scene definition, for directly indexing // mCurrentColors #define G (EmulatedScene::GRASS * EmulatedScene::NUM_CHANNELS) @@ -89,8 +84,7 @@ const uint8_t EmulatedScene::kScene[EmulatedScene::kSceneWidth * EmulatedScene::EmulatedScene(int sensor_width_px, int sensor_height_px, float sensor_sensitivity, int sensor_orientation, bool is_front_facing) - : sensor_handle_(-1), - screen_rotation_(0), + : screen_rotation_(0), current_scene_(scene_rot0_), sensor_orientation_(sensor_orientation), is_front_facing_(is_front_facing), @@ -115,11 +109,6 @@ EmulatedScene::EmulatedScene(int sensor_width_px, int sensor_height_px, } EmulatedScene::~EmulatedScene() { - if (sensor_event_queue_.get() != nullptr) { - sensor_event_queue_->disableSensor(sensor_handle_); - sensor_event_queue_.clear(); - sensor_event_queue_ = nullptr; - } } void EmulatedScene::Initialize(int sensor_width_px, int sensor_height_px, @@ -140,37 +129,6 @@ void EmulatedScene::Initialize(int sensor_width_px, int sensor_height_px, } -Return<void> EmulatedScene::SensorHandler::onEvent(const Event& e) { - auto scene = scene_.promote(); - if (scene.get() == nullptr) { - return Void(); - } - - if (e.sensorType == SensorType::ACCELEROMETER) { - // Heuristic approach for deducing the screen - // rotation depending on the reported - // accelerometer readings. We switch - // the screen rotation when one of the - // x/y axis gets close enough to the earth - // acceleration. - const uint32_t earth_accel = 9; // Switch threshold [m/s^2] - uint32_t x_accel = e.u.vec3.x; - uint32_t y_accel = e.u.vec3.y; - if (x_accel == earth_accel) { - scene->screen_rotation_ = 270; - } else if (x_accel == -earth_accel) { - scene->screen_rotation_ = 90; - } else if (y_accel == -earth_accel) { - scene->screen_rotation_ = 180; - } else { - scene->screen_rotation_ = 0; - } - } else { - ALOGE("%s: unexpected event received type: %d", __func__, e.sensorType); - } - return Void(); -} - void EmulatedScene::SetColorFilterXYZ(float rX, float rY, float rZ, float grX, float grY, float grZ, float gbX, float gbY, float gbZ, float bX, float bY, float bZ) { @@ -197,6 +155,10 @@ int EmulatedScene::GetHour() const { return hour_; } +void EmulatedScene::SetScreenRotation(uint32_t screen_rotation) { + screen_rotation_ = screen_rotation; +} + void EmulatedScene::SetExposureDuration(float seconds) { exposure_duration_ = seconds; } @@ -389,24 +351,21 @@ void EmulatedScene::CalculateScene(nsecs_t time, int32_t handshake_divider) { handshake_y_ /= handshake_divider; } - if (sensor_event_queue_.get() != nullptr) { - int32_t sensor_orientation = is_front_facing_ ? -sensor_orientation_ : sensor_orientation_; - int32_t scene_rotation = ((screen_rotation_ + 360) + sensor_orientation) % 360; - switch (scene_rotation) { - case 90: - current_scene_ = scene_rot90_; - break; - case 180: - current_scene_ = scene_rot180_; - break; - case 270: - current_scene_ = scene_rot270_; - break; - default: - current_scene_ = scene_rot0_; - } - } else { - current_scene_ = scene_rot0_; + int32_t sensor_orientation = + is_front_facing_ ? -sensor_orientation_ : sensor_orientation_; + int32_t scene_rotation = ((screen_rotation_ + 360) + sensor_orientation) % 360; + switch (scene_rotation) { + case 90: + current_scene_ = scene_rot90_; + break; + case 180: + current_scene_ = scene_rot180_; + break; + case 270: + current_scene_ = scene_rot270_; + break; + default: + current_scene_ = scene_rot0_; } // Set starting pixel @@ -446,52 +405,6 @@ void EmulatedScene::InitiliazeSceneRotation(bool clock_wise) { } } -void EmulatedScene::InitializeSensorQueue() { - if (sensor_event_queue_.get() != nullptr) { - return; - } - - sp<ISensorManager> manager = ISensorManager::getService(); - if (manager == nullptr) { - ALOGE("%s: Cannot get ISensorManager", __func__); - } else { - bool sensor_found = false; - manager->getSensorList( - [&] (const auto& list, auto result) { - if (result != Result::OK) { - ALOGE("%s: Failed to retrieve sensor list!", __func__); - } else { - for (const SensorInfo& it : list) { - if (it.type == SensorType::ACCELEROMETER) { - sensor_found = true; - sensor_handle_ = it.sensorHandle; - } - } - }}); - if (sensor_found) { - manager->createEventQueue( - new SensorHandler(this), [&](const auto& q, auto result) { - if (result != Result::OK) { - ALOGE("%s: Cannot create event queue", __func__); - return; - } - sensor_event_queue_ = q; - }); - - if (sensor_event_queue_.get() != nullptr) { - auto res = sensor_event_queue_->enableSensor(sensor_handle_, - ns2us(EmulatedSensor::kSupportedFrameDurationRange[0]), 0/*maxBatchReportLatencyUs*/); - if (res.isOk()) { - } else { - ALOGE("%s: Failed to enable sensor", __func__); - } - } else { - ALOGE("%s: Failed to create event queue", __func__); - } - } - } -} - void EmulatedScene::SetReadoutPixel(int x, int y) { current_x_ = x; current_y_ = y; diff --git a/devices/EmulatedCamera/hwl/EmulatedScene.h b/devices/EmulatedCamera/hwl/EmulatedScene.h index 0334a58..0672422 100644 --- a/devices/EmulatedCamera/hwl/EmulatedScene.h +++ b/devices/EmulatedCamera/hwl/EmulatedScene.h @@ -26,27 +26,17 @@ #ifndef HW_EMULATOR_CAMERA2_SCENE_H #define HW_EMULATOR_CAMERA2_SCENE_H -#include "android/frameworks/sensorservice/1.0/ISensorManager.h" -#include "android/frameworks/sensorservice/1.0/types.h" #include "utils/Timers.h" namespace android { -using ::android::frameworks::sensorservice::V1_0::IEventQueue; -using ::android::frameworks::sensorservice::V1_0::IEventQueueCallback; -using ::android::hardware::sensors::V1_0::Event; -using ::android::hardware::Return; -using ::android::hardware::Void; - -class EmulatedScene : public RefBase { +class EmulatedScene { public: EmulatedScene(int sensor_width_px, int sensor_height_px, float sensor_sensitivity, int sensor_orientation, bool is_front_facing); ~EmulatedScene(); - void InitializeSensorQueue(); - void Initialize(int sensor_width_px, int sensor_height_px, float sensor_sensitivity); @@ -65,6 +55,8 @@ class EmulatedScene : public RefBase { // Get current hour int GetHour() const; + void SetScreenRotation(uint32_t screen_rotation); + // Set the duration of exposure for determining luminous exposure. // Must be called before calculateScene void SetExposureDuration(float seconds); @@ -99,27 +91,13 @@ class EmulatedScene : public RefBase { static const int kSceneHeight = 20; private: - class SensorHandler : public IEventQueueCallback { - public: - SensorHandler(wp<EmulatedScene> scene) : scene_(scene) { - } - - // IEventQueueCallback interface - Return<void> onEvent(const Event& e) override; - - private: - wp<EmulatedScene> scene_; - }; - void InitiliazeSceneRotation(bool clock_wise); - int32_t sensor_handle_; - sp<IEventQueue> sensor_event_queue_; - std::atomic_uint32_t screen_rotation_; uint8_t scene_rot0_[kSceneWidth*kSceneHeight]; uint8_t scene_rot90_[kSceneWidth*kSceneHeight]; uint8_t scene_rot180_[kSceneWidth*kSceneHeight]; uint8_t scene_rot270_[kSceneWidth*kSceneHeight]; + uint32_t screen_rotation_; uint8_t *current_scene_; int32_t sensor_orientation_; bool is_front_facing_; diff --git a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp index 1abd055..7d93ded 100644 --- a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp +++ b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp @@ -30,6 +30,7 @@ #include <cutils/properties.h> #include <inttypes.h> #include <libyuv.h> +#include <memory.h> #include <system/camera_metadata.h> #include <utils/Log.h> #include <utils/Trace.h> @@ -43,6 +44,7 @@ namespace android { +using android::google_camera_hal::ErrorCode; using google_camera_hal::HalCameraMetadata; using google_camera_hal::MessageType; using google_camera_hal::NotifyMessage; @@ -585,11 +587,10 @@ status_t EmulatedSensor::StartUp( } logical_camera_id_ = logical_camera_id; - scene_ = new EmulatedScene( + scene_ = std::make_unique<EmulatedScene>( device_chars->second.full_res_width, device_chars->second.full_res_height, kElectronsPerLuxSecond, device_chars->second.orientation, device_chars->second.is_front_facing); - scene_->InitializeSensorQueue(); jpeg_compressor_ = std::make_unique<JpegCompressor>(); auto res = run(LOG_TAG, ANDROID_PRIORITY_URGENT_DISPLAY); @@ -813,6 +814,7 @@ bool EmulatedSensor::threadLoop() { scene_->SetTestPattern(device_settings->second.test_pattern_mode == ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR); scene_->SetTestPatternData(device_settings->second.test_pattern_data); + scene_->SetScreenRotation(device_settings->second.screen_rotation); uint32_t handshake_divider = (device_settings->second.video_stab == @@ -1109,9 +1111,6 @@ bool EmulatedSensor::threadLoop() { ret = nanosleep(&t, &t); } while (ret != 0); } - nsecs_t end_real_time __unused = systemTime(); - ALOGVV("Frame cycle took %" PRIu64 " ms, target %" PRIu64 " ms", - ns2ms(end_real_time - start_real_time), ns2ms(frame_duration)); ReturnResults(callback, std::move(settings), std::move(next_result), reprocess_request); diff --git a/devices/EmulatedCamera/hwl/EmulatedSensor.h b/devices/EmulatedCamera/hwl/EmulatedSensor.h index 123016b..8c63ae4 100644 --- a/devices/EmulatedCamera/hwl/EmulatedSensor.h +++ b/devices/EmulatedCamera/hwl/EmulatedSensor.h @@ -77,11 +77,11 @@ #include <hwl_types.h> +#include <algorithm> #include <functional> #include "Base.h" #include "EmulatedScene.h" -#include "HandleImporter.h" #include "JpegCompressor.h" #include "utils/Mutex.h" #include "utils/StreamConfigurationMap.h" @@ -90,7 +90,6 @@ namespace android { -using android::hardware::camera::common::V1_0::helper::HandleImporter; using google_camera_hal::HwlPipelineCallback; using google_camera_hal::HwlPipelineResult; using google_camera_hal::StreamConfiguration; @@ -241,6 +240,7 @@ class EmulatedSensor : private Thread, public virtual RefBase { uint8_t sensor_pixel_mode = ANDROID_SENSOR_PIXEL_MODE_DEFAULT; uint8_t test_pattern_mode = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; uint32_t test_pattern_data[4] = {0, 0, 0, 0}; + uint32_t screen_rotation = 0; }; // Maps physical and logical camera ids to individual device settings @@ -349,7 +349,7 @@ class EmulatedSensor : private Thread, public virtual RefBase { std::map<uint32_t, SensorBinningFactorInfo> sensor_binning_factor_info_; - sp<EmulatedScene> scene_; + std::unique_ptr<EmulatedScene> scene_; static EmulatedScene::ColorChannels GetQuadBayerColor(uint32_t x, uint32_t y); diff --git a/devices/EmulatedCamera/hwl/GrallocSensorBuffer.cpp b/devices/EmulatedCamera/hwl/GrallocSensorBuffer.cpp new file mode 100644 index 0000000..173d4fc --- /dev/null +++ b/devices/EmulatedCamera/hwl/GrallocSensorBuffer.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2022 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. + */ + +#include "GrallocSensorBuffer.h" + +namespace android { + +GrallocSensorBuffer::~GrallocSensorBuffer() { + if (stream_buffer.buffer != nullptr) { + importer_->unlock(stream_buffer.buffer); + } + + if (acquire_fence_fd >= 0) { + importer_->closeFence(acquire_fence_fd); + } + + if ((stream_buffer.status != BufferStatus::kOk) && + (callback.notify != nullptr) && (!is_failed_request)) { + NotifyMessage msg = { + .type = MessageType::kError, + .message.error = {.frame_number = frame_number, + .error_stream_id = stream_buffer.stream_id, + .error_code = ErrorCode::kErrorBuffer}}; + callback.notify(pipeline_id, msg); + } + + if (callback.process_pipeline_result != nullptr) { + auto result = std::make_unique<HwlPipelineResult>(); + result->camera_id = camera_id; + result->pipeline_id = pipeline_id; + result->frame_number = frame_number; + result->partial_result = 0; + + stream_buffer.acquire_fence = stream_buffer.release_fence = nullptr; + if (is_input) { + result->input_buffers.push_back(stream_buffer); + } else { + result->output_buffers.push_back(stream_buffer); + } + callback.process_pipeline_result(std::move(result)); + } +} + +} // namespace android diff --git a/devices/EmulatedCamera/hwl/GrallocSensorBuffer.h b/devices/EmulatedCamera/hwl/GrallocSensorBuffer.h new file mode 100644 index 0000000..3fd9726 --- /dev/null +++ b/devices/EmulatedCamera/hwl/GrallocSensorBuffer.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2022 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 HW_EMULATOR_GRALLOC_SENSOR_BUFFER_H +#define HW_EMULATOR_GRALLOC_SENSOR_BUFFER_H + +#include <log/log.h> + +#include <memory> + +#include "Base.h" +#include "HandleImporter.h" + +namespace android { + +using android::google_camera_hal::BufferStatus; +using android::google_camera_hal::ErrorCode; +using android::google_camera_hal::HwlPipelineResult; +using android::google_camera_hal::MessageType; +using android::google_camera_hal::NotifyMessage; +using android::hardware::camera::common::V1_0::helper::HandleImporter; + +class GrallocSensorBuffer : public SensorBuffer { + public: + GrallocSensorBuffer(std::shared_ptr<HandleImporter> handle_importer) + : importer_(handle_importer) { + } + + GrallocSensorBuffer(const GrallocSensorBuffer&) = delete; + GrallocSensorBuffer& operator=(const GrallocSensorBuffer&) = delete; + + virtual ~GrallocSensorBuffer() override; + + private: + std::shared_ptr<HandleImporter> importer_; +}; + +} // namespace android + +#endif diff --git a/devices/EmulatedCamera/hwl/JpegCompressor.cpp b/devices/EmulatedCamera/hwl/JpegCompressor.cpp index 57530ad..c1ae8ea 100644 --- a/devices/EmulatedCamera/hwl/JpegCompressor.cpp +++ b/devices/EmulatedCamera/hwl/JpegCompressor.cpp @@ -260,7 +260,7 @@ size_t JpegCompressor::CompressYUV420Frame(YUV420Frame frame) { dmgr.buffer_size); }; - dmgr.empty_output_buffer = [](j_compress_ptr cinfo __unused) { + dmgr.empty_output_buffer = [](j_compress_ptr) { ALOGE("%s:%d Out of buffer", __FUNCTION__, __LINE__); return 0; }; diff --git a/devices/EmulatedCamera/hwl/JpegCompressor.h b/devices/EmulatedCamera/hwl/JpegCompressor.h index 1ebda72..f7379e7 100644 --- a/devices/EmulatedCamera/hwl/JpegCompressor.h +++ b/devices/EmulatedCamera/hwl/JpegCompressor.h @@ -25,7 +25,6 @@ #include <thread> #include "Base.h" -#include "HandleImporter.h" extern "C" { #include <jpeglib.h> @@ -35,7 +34,6 @@ extern "C" { namespace android { -using android::hardware::camera::common::V1_0::helper::HandleImporter; using google_camera_hal::BufferStatus; using google_camera_hal::HwlPipelineCallback; using google_camera_hal::HwlPipelineResult; |