1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "GCH_DualIrRequestProcessor"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22 
23 #include "dual_ir_request_processor.h"
24 
25 namespace android {
26 namespace google_camera_hal {
27 
Create(CameraDeviceSessionHwl * device_session_hwl,uint32_t lead_ir_camera_id)28 std::unique_ptr<DualIrRequestProcessor> DualIrRequestProcessor::Create(
29     CameraDeviceSessionHwl* device_session_hwl, uint32_t lead_ir_camera_id) {
30   ATRACE_CALL();
31   if (device_session_hwl == nullptr) {
32     ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
33     return nullptr;
34   }
35 
36   // Check there are two physical cameras.
37   std::vector<uint32_t> camera_ids = device_session_hwl->GetPhysicalCameraIds();
38   if (camera_ids.size() != 2) {
39     ALOGE("%s: Only support two IR cameras but there are %zu cameras.",
40           __FUNCTION__, camera_ids.size());
41     return nullptr;
42   }
43 
44   // TODO(b/129017376): Figure out default IR camera ID from static metadata.
45   // Assume the first physical camera is the default for now.
46   auto request_processor = std::unique_ptr<DualIrRequestProcessor>(
47       new DualIrRequestProcessor(lead_ir_camera_id));
48   if (request_processor == nullptr) {
49     ALOGE("%s: Creating DualIrRequestProcessor failed.", __FUNCTION__);
50     return nullptr;
51   }
52 
53   return request_processor;
54 }
55 
DualIrRequestProcessor(uint32_t lead_camera_id)56 DualIrRequestProcessor::DualIrRequestProcessor(uint32_t lead_camera_id)
57     : kLeadCameraId(lead_camera_id) {
58 }
59 
ConfigureStreams(InternalStreamManager *,const StreamConfiguration & stream_config,StreamConfiguration * process_block_stream_config)60 status_t DualIrRequestProcessor::ConfigureStreams(
61     InternalStreamManager* /*internal_stream_manager*/,
62     const StreamConfiguration& stream_config,
63     StreamConfiguration* process_block_stream_config) {
64   ATRACE_CALL();
65   if (process_block_stream_config == nullptr) {
66     ALOGE("%s: process_block_stream_config is nullptr", __FUNCTION__);
67     return BAD_VALUE;
68   }
69 
70   process_block_stream_config->streams = stream_config.streams;
71   process_block_stream_config->operation_mode = stream_config.operation_mode;
72   process_block_stream_config->session_params =
73       HalCameraMetadata::Clone(stream_config.session_params.get());
74   process_block_stream_config->stream_config_counter =
75       stream_config.stream_config_counter;
76   process_block_stream_config->log_id = stream_config.log_id;
77 
78   for (auto& stream : process_block_stream_config->streams) {
79     // Assign all logical streams to the lead camera.
80     if (!stream.is_physical_camera_stream) {
81       stream.is_physical_camera_stream = true;
82       stream.physical_camera_id = kLeadCameraId;
83     }
84 
85     stream_physical_camera_ids_[stream.id] = stream.physical_camera_id;
86   }
87 
88   return OK;
89 }
90 
SetProcessBlock(std::unique_ptr<ProcessBlock> process_block)91 status_t DualIrRequestProcessor::SetProcessBlock(
92     std::unique_ptr<ProcessBlock> process_block) {
93   ATRACE_CALL();
94   if (process_block == nullptr) {
95     ALOGE("%s: process_block is nullptr", __FUNCTION__);
96     return BAD_VALUE;
97   }
98 
99   std::lock_guard<std::mutex> lock(process_block_lock_);
100   if (process_block_ != nullptr) {
101     ALOGE("%s: Already configured.", __FUNCTION__);
102     return ALREADY_EXISTS;
103   }
104 
105   process_block_ = std::move(process_block);
106   return OK;
107 }
108 
ProcessRequest(const CaptureRequest & request)109 status_t DualIrRequestProcessor::ProcessRequest(const CaptureRequest& request) {
110   ATRACE_CALL();
111   std::lock_guard<std::mutex> lock(process_block_lock_);
112   if (process_block_ == nullptr) {
113     ALOGE("%s: Not configured yet.", __FUNCTION__);
114     return NO_INIT;
115   }
116 
117   uint32_t frame_number = request.frame_number;
118 
119   // Create one physical request for each physical camera.
120   // Map from camera_id to the camera's request.
121   std::map<uint32_t, CaptureRequest> requests;
122 
123   for (auto& buffer : request.output_buffers) {
124     uint32_t camera_id = stream_physical_camera_ids_[buffer.stream_id];
125     CaptureRequest* physical_request = nullptr;
126 
127     auto request_iter = requests.find(camera_id);
128     if (request_iter == requests.end()) {
129       physical_request = &requests[camera_id];
130       physical_request->frame_number = frame_number;
131       // TODO: Combine physical camera settings?
132       physical_request->settings =
133           HalCameraMetadata::Clone(request.settings.get());
134     } else {
135       physical_request = &request_iter->second;
136     }
137     physical_request->output_buffers.push_back(buffer);
138   }
139 
140   // Construct block requests.
141   std::vector<ProcessBlockRequest> block_requests;
142   for (auto& [camera_id, physical_request] : requests) {
143     ProcessBlockRequest block_request = {
144         .request_id = camera_id,
145         .request = std::move(physical_request),
146     };
147 
148     block_requests.push_back(std::move(block_request));
149   }
150 
151   return process_block_->ProcessRequests(block_requests, request);
152 }
153 
Flush()154 status_t DualIrRequestProcessor::Flush() {
155   ATRACE_CALL();
156   std::lock_guard<std::mutex> lock(process_block_lock_);
157   if (process_block_ == nullptr) {
158     return OK;
159   }
160 
161   return process_block_->Flush();
162 }
163 
164 }  // namespace google_camera_hal
165 }  // namespace android