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 
77   for (auto& stream : process_block_stream_config->streams) {
78     // Assign all logical streams to the lead camera.
79     if (!stream.is_physical_camera_stream) {
80       stream.is_physical_camera_stream = true;
81       stream.physical_camera_id = kLeadCameraId;
82     }
83 
84     stream_physical_camera_ids_[stream.id] = stream.physical_camera_id;
85   }
86 
87   return OK;
88 }
89 
SetProcessBlock(std::unique_ptr<ProcessBlock> process_block)90 status_t DualIrRequestProcessor::SetProcessBlock(
91     std::unique_ptr<ProcessBlock> process_block) {
92   ATRACE_CALL();
93   if (process_block == nullptr) {
94     ALOGE("%s: process_block is nullptr", __FUNCTION__);
95     return BAD_VALUE;
96   }
97 
98   std::lock_guard<std::mutex> lock(process_block_lock_);
99   if (process_block_ != nullptr) {
100     ALOGE("%s: Already configured.", __FUNCTION__);
101     return ALREADY_EXISTS;
102   }
103 
104   process_block_ = std::move(process_block);
105   return OK;
106 }
107 
ProcessRequest(const CaptureRequest & request)108 status_t DualIrRequestProcessor::ProcessRequest(const CaptureRequest& request) {
109   ATRACE_CALL();
110   std::lock_guard<std::mutex> lock(process_block_lock_);
111   if (process_block_ == nullptr) {
112     ALOGE("%s: Not configured yet.", __FUNCTION__);
113     return NO_INIT;
114   }
115 
116   uint32_t frame_number = request.frame_number;
117 
118   // Create one physical request for each physical camera.
119   // Map from camera_id to the camera's request.
120   std::map<uint32_t, CaptureRequest> requests;
121 
122   for (auto& buffer : request.output_buffers) {
123     uint32_t camera_id = stream_physical_camera_ids_[buffer.stream_id];
124     CaptureRequest* physical_request = nullptr;
125 
126     auto request_iter = requests.find(camera_id);
127     if (request_iter == requests.end()) {
128       physical_request = &requests[camera_id];
129       physical_request->frame_number = frame_number;
130       // TODO: Combine physical camera settings?
131       physical_request->settings =
132           HalCameraMetadata::Clone(request.settings.get());
133     } else {
134       physical_request = &request_iter->second;
135     }
136     physical_request->output_buffers.push_back(buffer);
137   }
138 
139   // Construct block requests.
140   std::vector<ProcessBlockRequest> block_requests;
141   for (auto& [camera_id, physical_request] : requests) {
142     ProcessBlockRequest block_request = {
143         .request_id = camera_id,
144         .request = std::move(physical_request),
145     };
146 
147     block_requests.push_back(std::move(block_request));
148   }
149 
150   return process_block_->ProcessRequests(block_requests, request);
151 }
152 
Flush()153 status_t DualIrRequestProcessor::Flush() {
154   ATRACE_CALL();
155   std::lock_guard<std::mutex> lock(process_block_lock_);
156   if (process_block_ == nullptr) {
157     return OK;
158   }
159 
160   return process_block_->Flush();
161 }
162 
163 }  // namespace google_camera_hal
164 }  // namespace android