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_CameraDeviceSession"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "camera_device_session.h"
21
22 #include <inttypes.h>
23 #include <log/log.h>
24 #include <system/graphics-base-v1.0.h>
25 #include <utils/Trace.h>
26
27 #include <optional>
28
29 #include "basic_capture_session.h"
30 #include "capture_session_utils.h"
31 #include "hal_types.h"
32 #include "hal_utils.h"
33 #include "libgooglecamerahal_flags.h"
34 #include "stream_buffer_cache_manager.h"
35 #include "system/camera_metadata.h"
36 #include "ui/GraphicBufferMapper.h"
37 #include "utils.h"
38 #include "vendor_tag_defs.h"
39 #include "vendor_tag_types.h"
40 #include "vendor_tags.h"
41 #include "zsl_snapshot_capture_session.h"
42
43 namespace android {
44 namespace google_camera_hal {
45
46 constexpr char kMeasureBufferAllocationProp[] =
47 "persist.vendor.camera.measure_buffer_allocation";
48
49 static constexpr int64_t kNsPerSec = 1000000000;
50 static constexpr int64_t kAllocationThreshold = 33000000; // 33ms
51
52 std::vector<CaptureSessionEntryFuncs>
53 CameraDeviceSession::kCaptureSessionEntries = {
54 {.IsStreamConfigurationSupported =
55 BasicCaptureSession::IsStreamConfigurationSupported,
56 .CreateSession = BasicCaptureSession::Create}};
57
58 std::vector<WrapperCaptureSessionEntryFuncs>
59 CameraDeviceSession::kWrapperCaptureSessionEntries = {
60 {.IsStreamConfigurationSupported =
61 ZslSnapshotCaptureSession::IsStreamConfigurationSupported,
62 .CreateSession = ZslSnapshotCaptureSession::Create}};
63
Create(std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl,std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries,CameraBufferAllocatorHwl * camera_allocator_hwl)64 std::unique_ptr<CameraDeviceSession> CameraDeviceSession::Create(
65 std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl,
66 std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries,
67 CameraBufferAllocatorHwl* camera_allocator_hwl) {
68 ATRACE_CALL();
69 if (device_session_hwl == nullptr) {
70 ALOGE("%s: device_session_hwl is nullptr", __FUNCTION__);
71 return nullptr;
72 }
73
74 uint32_t camera_id = device_session_hwl->GetCameraId();
75 std::vector<uint32_t> physical_camera_ids =
76 device_session_hwl->GetPhysicalCameraIds();
77
78 auto session = std::unique_ptr<CameraDeviceSession>(new CameraDeviceSession());
79 if (session == nullptr) {
80 ALOGE("%s: Creating CameraDeviceSession failed.", __FUNCTION__);
81 return nullptr;
82 }
83
84 status_t res =
85 session->Initialize(std::move(device_session_hwl), camera_allocator_hwl,
86 external_session_factory_entries);
87 if (res != OK) {
88 ALOGE("%s: Initializing CameraDeviceSession failed: %s (%d).", __FUNCTION__,
89 strerror(-res), res);
90 return nullptr;
91 }
92
93 // Construct a string of physical camera IDs.
94 std::string physical_camera_ids_string;
95 if (physical_camera_ids.size() > 0) {
96 physical_camera_ids_string += ": ";
97
98 for (auto& id : physical_camera_ids) {
99 physical_camera_ids_string += std::to_string(id) + " ";
100 }
101 }
102
103 ALOGI(
104 "%s: Created a device session for camera %d with %zu physical cameras%s",
105 __FUNCTION__, camera_id, physical_camera_ids.size(),
106 physical_camera_ids_string.c_str());
107
108 return session;
109 }
110
UpdatePendingRequest(CaptureResult * result)111 status_t CameraDeviceSession::UpdatePendingRequest(CaptureResult* result) {
112 std::lock_guard<std::mutex> lock(request_record_lock_);
113 if (result == nullptr) {
114 ALOGE("%s: result is nullptr.", __FUNCTION__);
115 return BAD_VALUE;
116 }
117
118 if (result->output_buffers.empty()) {
119 // Nothing to do if the result doesn't contain any output buffers.
120 return OK;
121 }
122 bool frame_has_hal_buffer_managed_buffer = false;
123 for (const auto& buffer : result->output_buffers) {
124 if (hal_buffer_managed_stream_ids_.find(buffer.stream_id) !=
125 hal_buffer_managed_stream_ids_.end()) {
126 frame_has_hal_buffer_managed_buffer = true;
127 break;
128 }
129 }
130
131 // There's no HAL buffer managed buffer in the frame, we don't need to track
132 // it through pending_request_streams_.
133 if (!frame_has_hal_buffer_managed_buffer) {
134 return OK;
135 }
136
137 // Update inflight request records and notify SBC for flushing if needed
138 uint32_t frame_number = result->frame_number;
139
140 if (pending_request_streams_.find(frame_number) ==
141 pending_request_streams_.end()) {
142 ALOGE("%s: Can't find frame %u in result holder.", __FUNCTION__,
143 frame_number);
144 return UNKNOWN_ERROR;
145 }
146
147 // Remove streams from pending request streams for buffers in the result.
148 auto& streams = pending_request_streams_.at(frame_number);
149 for (auto& stream_buffer : result->output_buffers) {
150 int32_t stream_id = stream_buffer.stream_id;
151 if (streams.find(stream_id) == streams.end()) {
152 // If stream_id belongs to a stream group, the HWL may choose to output
153 // buffers to a different stream in the same group.
154 if (grouped_stream_id_map_.count(stream_id) == 1) {
155 int32_t stream_id_for_group = grouped_stream_id_map_.at(stream_id);
156 if (streams.find(stream_id_for_group) != streams.end()) {
157 streams.erase(stream_id_for_group);
158 } else {
159 ALOGE(
160 "%s: Can't find stream_id_for_group %d for stream %d in frame %u "
161 "result holder. It may have been returned or have not been "
162 "requested.",
163 __FUNCTION__, stream_id_for_group, stream_id, frame_number);
164 }
165 } else {
166 ALOGE(
167 "%s: Can't find stream %d in frame %u result holder. It may"
168 " have been returned or have not been requested.",
169 __FUNCTION__, stream_id, frame_number);
170 }
171 // Ignore this buffer and continue handling other buffers in the
172 // result.
173 } else {
174 streams.erase(stream_id);
175 }
176 }
177
178 if (streams.empty()) {
179 pending_request_streams_.erase(frame_number);
180 }
181
182 if (pending_request_streams_.empty()) {
183 status_t res = stream_buffer_cache_manager_->NotifyFlushingAll();
184 if (res != OK) {
185 ALOGE("%s: Failed to notify SBC manager to flush all streams.",
186 __FUNCTION__);
187 }
188 ALOGI(
189 "%s: [sbc] All inflight requests/streams cleared. Notified SBC for "
190 "flushing.",
191 __FUNCTION__);
192 }
193 return OK;
194 }
195
ProcessCaptureResult(std::unique_ptr<CaptureResult> result)196 void CameraDeviceSession::ProcessCaptureResult(
197 std::unique_ptr<CaptureResult> result) {
198 if (TryHandleCaptureResult(result)) return;
199
200 // Update pending request tracker with returned buffers.
201 std::vector<StreamBuffer> buffers;
202 buffers.insert(buffers.end(), result->output_buffers.begin(),
203 result->output_buffers.end());
204
205 if (result->result_metadata) {
206 std::lock_guard<std::mutex> lock(request_record_lock_);
207 pending_results_.erase(result->frame_number);
208 }
209
210 {
211 std::shared_lock lock(session_callback_lock_);
212 session_callback_.process_capture_result(std::move(result));
213 }
214
215 TrackReturnedBuffers(buffers);
216 }
217
ProcessBatchCaptureResult(std::vector<std::unique_ptr<CaptureResult>> results)218 void CameraDeviceSession::ProcessBatchCaptureResult(
219 std::vector<std::unique_ptr<CaptureResult>> results) {
220 std::vector<std::unique_ptr<CaptureResult>> results_to_callback;
221 results_to_callback.reserve(results.size());
222 std::vector<StreamBuffer> buffers;
223 for (auto& result : results) {
224 if (TryHandleCaptureResult(result)) continue;
225
226 // Update pending request tracker with returned buffers.
227 buffers.insert(buffers.end(), result->output_buffers.begin(),
228 result->output_buffers.end());
229
230 if (result->result_metadata) {
231 std::lock_guard<std::mutex> lock(request_record_lock_);
232 pending_results_.erase(result->frame_number);
233 }
234
235 results_to_callback.push_back(std::move(result));
236 }
237
238 {
239 std::shared_lock lock(session_callback_lock_);
240 session_callback_.process_batch_capture_result(
241 std::move(results_to_callback));
242 }
243
244 TrackReturnedBuffers(buffers);
245 }
246
Notify(const NotifyMessage & result)247 void CameraDeviceSession::Notify(const NotifyMessage& result) {
248 if (ShouldSendNotifyMessage(result)) {
249 std::shared_lock lock(session_callback_lock_);
250 session_callback_.notify(result);
251 }
252 }
253
NotifyBatch(const std::vector<NotifyMessage> & results)254 void CameraDeviceSession::NotifyBatch(const std::vector<NotifyMessage>& results) {
255 std::vector<NotifyMessage> callback_results;
256 callback_results.reserve(results.size());
257
258 for (const NotifyMessage& result : results) {
259 if (ShouldSendNotifyMessage(result)) {
260 callback_results.push_back(result);
261 }
262 }
263 if (!callback_results.empty()) {
264 std::shared_lock lock(session_callback_lock_);
265 session_callback_.notify_batch(callback_results);
266 }
267 }
268
InitializeCallbacks()269 void CameraDeviceSession::InitializeCallbacks() {
270 std::lock_guard lock(session_callback_lock_);
271
272 // Initialize callback to
273 session_callback_.process_capture_result =
274 ProcessCaptureResultFunc([](std::unique_ptr<CaptureResult> /*result*/) {
275 ALOGW("%s: No session callback was set.", __FUNCTION__);
276 });
277
278 session_callback_.notify = NotifyFunc([](const NotifyMessage& /*message*/) {
279 ALOGW("%s: No session callback was set.", __FUNCTION__);
280 });
281
282 session_callback_.request_stream_buffers = RequestStreamBuffersFunc(
283 [](const std::vector<BufferRequest>& /*hal_buffer_requests*/,
284 std::vector<BufferReturn>* /*hal_buffer_returns*/) {
285 ALOGW("%s: No session callback was set.", __FUNCTION__);
286 return google_camera_hal::BufferRequestStatus::kFailedUnknown;
287 });
288
289 session_callback_.return_stream_buffers = ReturnStreamBuffersFunc(
290 [](const std::vector<StreamBuffer>& /*return_hal_buffers*/) {
291 ALOGW("%s: No session callback was set.", __FUNCTION__);
292 return google_camera_hal::BufferRequestStatus::kFailedUnknown;
293 });
294
295 camera_device_session_callback_.process_capture_result =
296 ProcessCaptureResultFunc([this](std::unique_ptr<CaptureResult> result) {
297 ProcessCaptureResult(std::move(result));
298 });
299
300 camera_device_session_callback_.process_batch_capture_result =
301 ProcessBatchCaptureResultFunc(
302 [this](std::vector<std::unique_ptr<CaptureResult>> results) {
303 ProcessBatchCaptureResult(std::move(results));
304 });
305
306 camera_device_session_callback_.notify =
307 NotifyFunc([this](const NotifyMessage& message) { Notify(message); });
308
309 camera_device_session_callback_.notify_batch =
310 NotifyBatchFunc([this](const std::vector<NotifyMessage>& messages) {
311 NotifyBatch(messages);
312 });
313
314 hwl_session_callback_.request_stream_buffers = HwlRequestBuffersFunc(
315 [this](int32_t stream_id, uint32_t num_buffers,
316 std::vector<StreamBuffer>* buffers, uint32_t frame_number) {
317 return RequestBuffersFromStreamBufferCacheManager(
318 stream_id, num_buffers, buffers, frame_number);
319 });
320
321 hwl_session_callback_.return_stream_buffers =
322 HwlReturnBuffersFunc([this](const std::vector<StreamBuffer>& buffers) {
323 return ReturnStreamBuffers(buffers);
324 });
325
326 device_session_hwl_->SetSessionCallback(hwl_session_callback_);
327 }
328
InitializeBufferManagement(HalCameraMetadata * characteristics)329 status_t CameraDeviceSession::InitializeBufferManagement(
330 HalCameraMetadata* characteristics) {
331 ATRACE_CALL();
332
333 if (characteristics == nullptr) {
334 ALOGE("%s: characteristics cannot be nullptr.", __FUNCTION__);
335 return BAD_VALUE;
336 }
337
338 camera_metadata_ro_entry entry = {};
339 status_t res = characteristics->Get(
340 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
341 if (res == OK && entry.count > 0) {
342 buffer_management_used_ =
343 (entry.data.u8[0] ==
344 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
345 session_buffer_management_supported_ =
346 (entry.data.u8[0] ==
347 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE);
348 }
349
350 return OK;
351 }
352
Initialize(std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl,CameraBufferAllocatorHwl * camera_allocator_hwl,std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries)353 status_t CameraDeviceSession::Initialize(
354 std::unique_ptr<CameraDeviceSessionHwl> device_session_hwl,
355 CameraBufferAllocatorHwl* camera_allocator_hwl,
356 std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries) {
357 ATRACE_CALL();
358 if (device_session_hwl == nullptr) {
359 ALOGE("%s: device_session_hwl cannot be nullptr.", __FUNCTION__);
360 return BAD_VALUE;
361 }
362 measure_buffer_allocation_time_ =
363 property_get_bool(kMeasureBufferAllocationProp, false);
364 ALOGI("%s: measure buffer allocation time: %d ", __FUNCTION__,
365 measure_buffer_allocation_time_);
366
367 camera_id_ = device_session_hwl->GetCameraId();
368 device_session_hwl_ = std::move(device_session_hwl);
369 camera_allocator_hwl_ = camera_allocator_hwl;
370
371 GraphicBufferMapper::preloadHal();
372 InitializeCallbacks();
373
374 std::unique_ptr<google_camera_hal::HalCameraMetadata> characteristics;
375 status_t res = device_session_hwl_->GetCameraCharacteristics(&characteristics);
376 if (res != OK) {
377 ALOGE("%s: Get camera characteristics failed: %s(%d)", __FUNCTION__,
378 strerror(-res), res);
379 return res;
380 }
381
382 res = utils::GetStreamUseCases(
383 characteristics.get(),
384 &camera_id_to_stream_use_cases_[device_session_hwl_->GetCameraId()]);
385 if (res != OK) {
386 ALOGE("%s: Initializing stream use case failed: %s(%d) for camera id %u",
387 __FUNCTION__, strerror(-res), res, device_session_hwl_->GetCameraId());
388 return res;
389 }
390
391 res = utils::GetPhysicalCameraStreamUseCases(device_session_hwl_.get(),
392 &camera_id_to_stream_use_cases_);
393 if (res != OK) {
394 ALOGE(
395 "%s: Initializing physical stream use cases failed: %s(%d) for camera "
396 "id %u",
397 __FUNCTION__, strerror(-res), res, device_session_hwl_->GetCameraId());
398 return res;
399 }
400 res = InitializeBufferManagement(characteristics.get());
401 if (res != OK) {
402 ALOGE("%s: Initialize buffer management failed: %s(%d)", __FUNCTION__,
403 strerror(-res), res);
404 return res;
405 }
406
407 res = LoadExternalCaptureSession(external_session_factory_entries);
408 if (res != OK) {
409 ALOGE("%s: Loading external capture sessions failed: %s(%d)", __FUNCTION__,
410 strerror(-res), res);
411 return res;
412 }
413
414 InitializeZoomRatioMapper(characteristics.get());
415
416 return OK;
417 }
418
GetMaxResDimension(const HalCameraMetadata * characteristics,Dimension & max_res_dimension)419 status_t GetMaxResDimension(const HalCameraMetadata* characteristics,
420 Dimension& max_res_dimension) {
421 Rect active_array_maximum_resolution_size;
422 status_t max_res_status = utils::GetSensorActiveArraySize(
423 characteristics, &active_array_maximum_resolution_size,
424 /*maximum_resolution*/ true);
425 if (max_res_status == OK) {
426 max_res_dimension = {active_array_maximum_resolution_size.right -
427 active_array_maximum_resolution_size.left + 1,
428 active_array_maximum_resolution_size.bottom -
429 active_array_maximum_resolution_size.top + 1};
430 }
431 return max_res_status;
432 }
433
InitializeZoomRatioMapper(HalCameraMetadata * characteristics)434 void CameraDeviceSession::InitializeZoomRatioMapper(
435 HalCameraMetadata* characteristics) {
436 if (characteristics == nullptr) {
437 ALOGE("%s: characteristics cannot be nullptr.", __FUNCTION__);
438 return;
439 }
440
441 Rect active_array_size;
442 status_t res =
443 utils::GetSensorActiveArraySize(characteristics, &active_array_size,
444 /*maximum_resolution*/ false);
445 if (res != OK) {
446 ALOGE("%s: Failed to get the active array size: %s(%d)", __FUNCTION__,
447 strerror(-res), res);
448 return;
449 }
450
451 ZoomRatioMapper::InitParams params;
452 params.camera_id = camera_id_;
453 params.active_array_dimension = {
454 active_array_size.right - active_array_size.left + 1,
455 active_array_size.bottom - active_array_size.top + 1};
456
457 // Populate max-res dimension only if the logical camera have max-res resolution
458 (void)GetMaxResDimension(characteristics,
459 params.active_array_maximum_resolution_dimension);
460
461 std::vector<uint32_t> physical_camera_ids =
462 device_session_hwl_->GetPhysicalCameraIds();
463 for (uint32_t id : physical_camera_ids) {
464 std::unique_ptr<google_camera_hal::HalCameraMetadata>
465 physical_cam_characteristics;
466 res = device_session_hwl_->GetPhysicalCameraCharacteristics(
467 id, &physical_cam_characteristics);
468 if (res != OK) {
469 ALOGE("%s: Get camera: %u characteristics failed: %s(%d)", __FUNCTION__,
470 id, strerror(-res), res);
471 return;
472 }
473
474 res = utils::GetSensorActiveArraySize(physical_cam_characteristics.get(),
475 &active_array_size,
476 /*maximum_resolution*/ false);
477 if (res != OK) {
478 ALOGE("%s: Failed to get cam: %u, active array size: %s(%d)",
479 __FUNCTION__, id, strerror(-res), res);
480 return;
481 }
482 Dimension active_array_dimension = {
483 active_array_size.right - active_array_size.left + 1,
484 active_array_size.bottom - active_array_size.top + 1};
485 params.physical_cam_active_array_dimension.emplace(id,
486 active_array_dimension);
487 Dimension max_res_dimension;
488 if (GetMaxResDimension(physical_cam_characteristics.get(),
489 max_res_dimension) == OK) {
490 params.physical_cam_active_array_maximum_resolution_dimension.emplace(
491 id, max_res_dimension);
492 }
493 }
494
495 res = utils::GetZoomRatioRange(characteristics, ¶ms.zoom_ratio_range);
496 if (res != OK) {
497 ALOGW("%s: Failed to get the zoom ratio range: %s(%d)", __FUNCTION__,
498 strerror(-res), res);
499 return;
500 }
501
502 params.zoom_ratio_mapper_hwl = device_session_hwl_->GetZoomRatioMapperHwl();
503
504 zoom_ratio_mapper_.Initialize(¶ms);
505 }
506
DeriveGroupedStreamIdMap()507 void CameraDeviceSession::DeriveGroupedStreamIdMap() {
508 // Group stream ids by stream group id
509 std::unordered_map<int32_t, std::vector<int32_t>> group_to_streams_map;
510 for (const auto& [stream_id, stream] : configured_streams_map_) {
511 if (stream.stream_type == StreamType::kOutput && stream.group_id != -1) {
512 group_to_streams_map[stream.group_id].push_back(stream_id);
513 }
514 }
515
516 // For each stream group, map all the streams' ids to one id
517 for (const auto& [group_id, stream_ids] : group_to_streams_map) {
518 for (size_t i = 1; i < stream_ids.size(); i++) {
519 grouped_stream_id_map_[stream_ids[i]] = stream_ids[0];
520 }
521 }
522 }
523
LoadExternalCaptureSession(std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries)524 status_t CameraDeviceSession::LoadExternalCaptureSession(
525 std::vector<GetCaptureSessionFactoryFunc> external_session_factory_entries) {
526 ATRACE_CALL();
527
528 if (external_capture_session_entries_.size() > 0) {
529 ALOGI("%s: External capture session libraries already loaded; skip.",
530 __FUNCTION__);
531 return OK;
532 }
533
534 for (const auto& external_session_factory_t :
535 external_session_factory_entries) {
536 ExternalCaptureSessionFactory* external_session =
537 external_session_factory_t();
538 if (!external_session) {
539 ALOGE("%s: External session may be incomplete", __FUNCTION__);
540 continue;
541 }
542
543 external_capture_session_entries_.push_back(external_session);
544 }
545
546 return OK;
547 }
548
~CameraDeviceSession()549 CameraDeviceSession::~CameraDeviceSession() {
550 UnregisterThermalCallback();
551
552 capture_session_ = nullptr;
553 device_session_hwl_ = nullptr;
554
555 for (auto external_session : external_capture_session_entries_) {
556 delete external_session;
557 }
558 external_capture_session_entries_.clear();
559
560 FreeImportedBufferHandles();
561 }
562
UnregisterThermalCallback()563 void CameraDeviceSession::UnregisterThermalCallback() {
564 std::shared_lock lock(session_callback_lock_);
565 if (thermal_callback_.unregister_thermal_changed_callback != nullptr) {
566 thermal_callback_.unregister_thermal_changed_callback();
567 }
568 }
569
SetSessionCallback(const CameraDeviceSessionCallback & session_callback,const ThermalCallback & thermal_callback)570 void CameraDeviceSession::SetSessionCallback(
571 const CameraDeviceSessionCallback& session_callback,
572 const ThermalCallback& thermal_callback) {
573 ATRACE_CALL();
574 std::lock_guard lock(session_callback_lock_);
575 session_callback_ = session_callback;
576 thermal_callback_ = thermal_callback;
577
578 status_t res = thermal_callback_.register_thermal_changed_callback(
579 NotifyThrottlingFunc([this](const Temperature& temperature) {
580 NotifyThrottling(temperature);
581 }),
582 /*filter_type=*/false,
583 /*type=*/TemperatureType::kUnknown);
584 if (res != OK) {
585 ALOGW("%s: Registering thermal callback failed: %s(%d)", __FUNCTION__,
586 strerror(-res), res);
587 }
588 }
589
NotifyThrottling(const Temperature & temperature)590 void CameraDeviceSession::NotifyThrottling(const Temperature& temperature) {
591 switch (temperature.throttling_status) {
592 case ThrottlingSeverity::kNone:
593 case ThrottlingSeverity::kLight:
594 case ThrottlingSeverity::kModerate:
595 ALOGI("%s: temperature type: %d, severity: %u, value: %f", __FUNCTION__,
596 temperature.type, temperature.throttling_status, temperature.value);
597 return;
598 case ThrottlingSeverity::kSevere:
599 case ThrottlingSeverity::kCritical:
600 case ThrottlingSeverity::kEmergency:
601 case ThrottlingSeverity::kShutdown:
602 ALOGW("%s: temperature type: %d, severity: %u, value: %f", __FUNCTION__,
603 temperature.type, temperature.throttling_status, temperature.value);
604 {
605 std::lock_guard<std::mutex> lock(session_lock_);
606 thermal_throttling_ = true;
607 }
608 return;
609 default:
610 ALOGE("%s: Unknown throttling status %u for type %d", __FUNCTION__,
611 temperature.throttling_status, temperature.type);
612 return;
613 }
614 }
615
ConstructDefaultRequestSettings(RequestTemplate type,std::unique_ptr<HalCameraMetadata> * default_settings)616 status_t CameraDeviceSession::ConstructDefaultRequestSettings(
617 RequestTemplate type, std::unique_ptr<HalCameraMetadata>* default_settings) {
618 ATRACE_CALL();
619 status_t res = device_session_hwl_->ConstructDefaultRequestSettings(
620 type, default_settings);
621 if (res != OK) {
622 ALOGE("%s: Construct default settings for type %d failed: %s(%d)",
623 __FUNCTION__, type, strerror(-res), res);
624 return res;
625 }
626
627 return hal_vendor_tag_utils::ModifyDefaultRequestSettings(
628 type, default_settings->get());
629 }
630
ConfigureStreams(const StreamConfiguration & stream_config,bool v2,ConfigureStreamsReturn * configured_streams)631 status_t CameraDeviceSession::ConfigureStreams(
632 const StreamConfiguration& stream_config, bool v2,
633 ConfigureStreamsReturn* configured_streams) {
634 ATRACE_CALL();
635 bool set_realtime_thread = false;
636 int32_t schedule_policy;
637 struct sched_param schedule_param = {0};
638 if (configured_streams == nullptr) {
639 ALOGE("%s: configured_streams output is nullptr", __FUNCTION__);
640 return BAD_VALUE;
641 }
642 std::vector<HalStream>& hal_config = configured_streams->hal_streams;
643 if (utils::SupportRealtimeThread()) {
644 bool get_thread_schedule = false;
645 if (pthread_getschedparam(pthread_self(), &schedule_policy,
646 &schedule_param) == 0) {
647 get_thread_schedule = true;
648 } else {
649 ALOGE("%s: pthread_getschedparam fail", __FUNCTION__);
650 }
651
652 if (get_thread_schedule) {
653 status_t res = utils::SetRealtimeThread(pthread_self());
654 if (res != OK) {
655 ALOGE("%s: SetRealtimeThread fail", __FUNCTION__);
656 } else {
657 set_realtime_thread = true;
658 }
659 }
660 }
661
662 std::lock_guard<std::mutex> lock(session_lock_);
663
664 std::lock_guard lock_capture_session(capture_session_lock_);
665 if (capture_session_ != nullptr) {
666 ATRACE_NAME("CameraDeviceSession::DestroyOldSession");
667 capture_session_ = nullptr;
668 }
669
670 pending_requests_tracker_ = nullptr;
671
672 if (!configured_streams_map_.empty()) {
673 CleanupStaleStreamsLocked(stream_config.streams);
674 }
675 hal_buffer_managed_stream_ids_.clear();
676
677 hal_utils::DumpStreamConfiguration(stream_config, "App stream configuration");
678
679 multi_res_reprocess_ = stream_config.multi_resolution_input_image;
680
681 // TODO: We would ideally want this to be a part of CreateCaptureSession,
682 // which internally calls IsStreamCombinationSupported. However this
683 // IsStreamCombinationSupported doesn't match the
684 // CameraDevice::IsStreamCombination. We should look at unifying the two for a
685 // potentially cleaner code-base.
686 if (!utils::IsStreamUseCaseSupported(stream_config, camera_id_,
687 camera_id_to_stream_use_cases_)) {
688 return BAD_VALUE;
689 }
690 device_session_hwl_->setConfigureStreamsV2(v2);
691 bool multi_resolution_stream_used = false;
692 for (const auto& stream : stream_config.streams) {
693 if (stream.group_id != -1) {
694 multi_resolution_stream_used = true;
695 break;
696 }
697 }
698
699 // Check if the feature combination in the given StreamConfiguration is
700 // supported by current device.
701 // This is from the requirement that Feature Combination Query API should
702 // provide consistent output with the CreateCaptureSession result. b/401442279
703 if (!device_session_hwl_->IsFeatureCombinationSupported(stream_config)) {
704 ALOGE("%s: IsFeatureCombinationSupported returns false", __FUNCTION__);
705 return BAD_VALUE;
706 }
707
708 capture_session_ = CreateCaptureSession(
709 stream_config, kWrapperCaptureSessionEntries,
710 external_capture_session_entries_, kCaptureSessionEntries,
711 hwl_session_callback_, camera_allocator_hwl_, device_session_hwl_.get(),
712 &hal_config, camera_device_session_callback_.process_capture_result,
713 camera_device_session_callback_.notify,
714 camera_device_session_callback_.process_batch_capture_result,
715 camera_device_session_callback_.notify_batch);
716
717 if (capture_session_ == nullptr) {
718 ALOGE("%s: Cannot find a capture session compatible with stream config",
719 __FUNCTION__);
720 if (set_realtime_thread) {
721 utils::UpdateThreadSched(pthread_self(), schedule_policy, &schedule_param);
722 }
723 return BAD_VALUE;
724 }
725 // Backup the streams received from frameworks into configured_streams_map_,
726 // and we can find out specific streams through stream id in output_buffers.
727 for (auto& stream : stream_config.streams) {
728 configured_streams_map_[stream.id] = stream;
729 }
730 if (session_buffer_management_supported_ && v2) {
731 std::set<int32_t> hal_buffer_managed_stream_ids =
732 device_session_hwl_->GetHalBufferManagedStreams(stream_config);
733 hal_buffer_managed_stream_ids_ = hal_buffer_managed_stream_ids;
734 for (auto& hal_stream : hal_config) {
735 if (hal_buffer_managed_stream_ids.find(hal_stream.id) !=
736 hal_buffer_managed_stream_ids.end()) {
737 hal_stream.is_hal_buffer_managed = true;
738 }
739 }
740 } else if (buffer_management_used_ || multi_resolution_stream_used) {
741 // No session specific hal buffer manager supported, all streams are
742 // hal buffer managed. In the case of multi resolution streams we also
743 // are mandated to use hal buffer manager (VTS asserts for this)
744 for (auto& hal_stream : hal_config) {
745 if (configured_streams_map_.find(hal_stream.id) ==
746 configured_streams_map_.end()) {
747 ALOGE("%s: HalStream id %d not found in configured streams map",
748 __FUNCTION__, hal_stream.id);
749 return UNKNOWN_ERROR;
750 }
751 if (configured_streams_map_[hal_stream.id].stream_type ==
752 StreamType::kInput) {
753 continue;
754 }
755 hal_stream.is_hal_buffer_managed = true;
756 hal_buffer_managed_stream_ids_.insert(hal_stream.id);
757 }
758 }
759
760 stream_buffer_cache_manager_ =
761 StreamBufferCacheManager::Create(hal_buffer_managed_stream_ids_);
762 if (stream_buffer_cache_manager_ == nullptr) {
763 ALOGE("%s: Failed to create stream buffer cache manager.", __FUNCTION__);
764 if (set_realtime_thread) {
765 utils::UpdateThreadSched(pthread_self(), schedule_policy, &schedule_param);
766 }
767 return UNKNOWN_ERROR;
768 }
769 if (hal_buffer_managed_stream_ids_.size() != 0) {
770 status_t res =
771 RegisterStreamsIntoCacheManagerLocked(stream_config, hal_config);
772 if (res != OK) {
773 ALOGE("%s: Failed to register streams into stream buffer cache manager.",
774 __FUNCTION__);
775 if (set_realtime_thread) {
776 utils::UpdateThreadSched(pthread_self(), schedule_policy,
777 &schedule_param);
778 }
779 return res;
780 }
781 }
782
783 // (b/129561652): Framework assumes HalStream is sorted.
784 std::sort(hal_config.begin(), hal_config.end(),
785 [](const HalStream& a, const HalStream& b) { return a.id < b.id; });
786
787 // Derives all stream ids within a group to a representative stream id
788 DeriveGroupedStreamIdMap();
789
790 // If buffer management is support, create a pending request tracker for
791 // capture request throttling.
792 pending_requests_tracker_ = PendingRequestsTracker::Create(
793 hal_config, grouped_stream_id_map_, hal_buffer_managed_stream_ids_);
794 if (pending_requests_tracker_ == nullptr) {
795 ALOGE("%s: Cannot create a pending request tracker.", __FUNCTION__);
796 if (set_realtime_thread) {
797 utils::UpdateThreadSched(pthread_self(), schedule_policy, &schedule_param);
798 }
799 return UNKNOWN_ERROR;
800 }
801
802 {
803 std::lock_guard<std::mutex> request_lock(request_record_lock_);
804 pending_request_streams_.clear();
805 error_notified_requests_.clear();
806 placeholder_buffer_observed_.clear();
807 pending_results_.clear();
808 ignore_shutters_.clear();
809 }
810
811 has_valid_settings_ = false;
812 thermal_throttling_ = false;
813 thermal_throttling_notified_ = false;
814 last_request_settings_ = nullptr;
815 last_timestamp_ns_for_trace_ = 0;
816
817 if (set_realtime_thread) {
818 utils::UpdateThreadSched(pthread_self(), schedule_policy, &schedule_param);
819 }
820 return OK;
821 }
822
UpdateBufferHandlesLocked(std::vector<StreamBuffer> * buffers,bool update_hal_buffer_managed_streams)823 status_t CameraDeviceSession::UpdateBufferHandlesLocked(
824 std::vector<StreamBuffer>* buffers, bool update_hal_buffer_managed_streams) {
825 ATRACE_CALL();
826 if (buffers == nullptr) {
827 ALOGE("%s: buffers cannot be nullptr", __FUNCTION__);
828 return BAD_VALUE;
829 }
830
831 for (auto& buffer : *buffers) {
832 bool is_hal_buffer_managed =
833 hal_buffer_managed_stream_ids_.find(buffer.stream_id) !=
834 hal_buffer_managed_stream_ids_.end();
835 // Skip the update if import_hal_buffer_managed_streams doesn't match the
836 // stream ids hal buffer manager behavior.
837 bool skip = (!is_hal_buffer_managed && update_hal_buffer_managed_streams) ||
838 (!update_hal_buffer_managed_streams && is_hal_buffer_managed);
839 if (skip) {
840 continue;
841 }
842 // Get the buffer handle from buffer handle map.
843 BufferCache buffer_cache = {buffer.stream_id, buffer.buffer_id};
844 auto buffer_handle_it = imported_buffer_handle_map_.find(buffer_cache);
845 if (buffer_handle_it == imported_buffer_handle_map_.end()) {
846 ALOGE("%s: Cannot find buffer handle for stream %u, buffer %" PRIu64,
847 __FUNCTION__, buffer.stream_id, buffer.buffer_id);
848 return NAME_NOT_FOUND;
849 }
850
851 buffer.buffer = buffer_handle_it->second;
852 }
853
854 return OK;
855 }
856
CreateCaptureRequestLocked(const CaptureRequest & request,CaptureRequest * updated_request)857 status_t CameraDeviceSession::CreateCaptureRequestLocked(
858 const CaptureRequest& request, CaptureRequest* updated_request) {
859 ATRACE_CALL();
860 if (updated_request == nullptr) {
861 return BAD_VALUE;
862 }
863
864 if (request.settings != nullptr) {
865 last_request_settings_ = HalCameraMetadata::Clone(request.settings.get());
866 }
867
868 updated_request->frame_number = request.frame_number;
869 updated_request->settings = HalCameraMetadata::Clone(request.settings.get());
870 updated_request->input_buffers = request.input_buffers;
871 updated_request->input_buffer_metadata.clear();
872 updated_request->output_buffers = request.output_buffers;
873 std::vector<uint32_t> physical_camera_ids =
874 device_session_hwl_->GetPhysicalCameraIds();
875 for (auto& [camid, physical_setting] : request.physical_camera_settings) {
876 if (std::find(physical_camera_ids.begin(), physical_camera_ids.end(),
877 camid) == physical_camera_ids.end()) {
878 ALOGE("%s: Pyhsical camera id %d in request had not registered",
879 __FUNCTION__, camid);
880 return BAD_VALUE;
881 }
882 updated_request->physical_camera_settings[camid] =
883 HalCameraMetadata::Clone(physical_setting.get());
884 }
885 updated_request->input_width = request.input_width;
886 updated_request->input_height = request.input_height;
887
888 // Returns -1 if kThermalThrottling is not defined, skip following process.
889 if (get_camera_metadata_tag_type(VendorTagIds::kThermalThrottling) != -1) {
890 // Create settings to set thermal throttling key if needed.
891 if (thermal_throttling_ && !thermal_throttling_notified_ &&
892 updated_request->settings == nullptr) {
893 updated_request->settings =
894 HalCameraMetadata::Clone(last_request_settings_.get());
895 thermal_throttling_notified_ = true;
896 }
897
898 if (updated_request->settings != nullptr) {
899 status_t res = updated_request->settings->Set(
900 VendorTagIds::kThermalThrottling, &thermal_throttling_,
901 /*data_count=*/1);
902 if (res != OK) {
903 ALOGE("%s: Setting thermal throttling key failed: %s(%d)", __FUNCTION__,
904 strerror(-res), res);
905 return res;
906 }
907 }
908 }
909
910 AppendOutputIntentToSettingsLocked(request, updated_request);
911
912 {
913 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
914
915 status_t res = UpdateBufferHandlesLocked(&updated_request->input_buffers);
916 if (res != OK) {
917 ALOGE("%s: Updating input buffer handles failed: %s(%d)", __FUNCTION__,
918 strerror(-res), res);
919 return res;
920 }
921
922 res = UpdateBufferHandlesLocked(&updated_request->output_buffers);
923 if (res != OK) {
924 ALOGE("%s: Updating output buffer handles failed: %s(%d)", __FUNCTION__,
925 strerror(-res), res);
926 return res;
927 }
928 }
929
930 zoom_ratio_mapper_.UpdateCaptureRequest(updated_request);
931
932 return OK;
933 }
934
ImportBufferHandleLocked(const StreamBuffer & buffer)935 status_t CameraDeviceSession::ImportBufferHandleLocked(
936 const StreamBuffer& buffer) {
937 ATRACE_CALL();
938 buffer_handle_t imported_buffer_handle;
939
940 status_t status = GraphicBufferMapper::get().importBufferNoValidate(
941 buffer.buffer, &imported_buffer_handle);
942 if (status != OK) {
943 ALOGE("%s: Importing buffer failed: %s", __FUNCTION__,
944 ::android::statusToString(status).c_str());
945 return UNKNOWN_ERROR;
946 }
947
948 BufferCache buffer_cache = {buffer.stream_id, buffer.buffer_id};
949 return AddImportedBufferHandlesLocked(buffer_cache, imported_buffer_handle);
950 }
951
ImportBufferHandles(const std::vector<StreamBuffer> & buffers)952 status_t CameraDeviceSession::ImportBufferHandles(
953 const std::vector<StreamBuffer>& buffers) {
954 ATRACE_CALL();
955 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
956
957 // Import buffers that are new to HAL.
958 for (auto& buffer : buffers) {
959 bool is_hal_buffer_managed =
960 hal_buffer_managed_stream_ids_.find(buffer.stream_id) !=
961 hal_buffer_managed_stream_ids_.end();
962 // Skip the update if import_hal_buffer_managed_streams doesn't match the
963 // stream ids hal buffer manager behavior.
964 if (is_hal_buffer_managed) {
965 ALOGV(
966 "%s: Buffer management is enabled. Skip importing buffer for stream "
967 "id"
968 " %d in request ",
969 __FUNCTION__, buffer.stream_id);
970 continue;
971 }
972 if (!IsBufferImportedLocked(buffer.stream_id, buffer.buffer_id)) {
973 status_t res = ImportBufferHandleLocked(buffer);
974
975 if (res != OK) {
976 ALOGE("%s: Importing buffer %" PRIu64 " from stream %d failed: %s(%d)",
977 __FUNCTION__, buffer.buffer_id, buffer.stream_id, strerror(-res),
978 res);
979 return res;
980 }
981 }
982 }
983
984 return OK;
985 }
986
ImportRequestBufferHandles(const CaptureRequest & request)987 status_t CameraDeviceSession::ImportRequestBufferHandles(
988 const CaptureRequest& request) {
989 ATRACE_CALL();
990
991 status_t res = ImportBufferHandles(request.input_buffers);
992 if (res != OK) {
993 ALOGE("%s: Importing input buffer handles failed: %s(%d)", __FUNCTION__,
994 strerror(-res), res);
995 return res;
996 }
997
998 res = ImportBufferHandles(request.output_buffers);
999 if (res != OK) {
1000 ALOGE("%s: Importing output buffer handles failed: %s(%d)", __FUNCTION__,
1001 strerror(-res), res);
1002 return res;
1003 }
1004
1005 return OK;
1006 }
1007
NotifyErrorMessage(uint32_t frame_number,int32_t stream_id,ErrorCode error_code)1008 void CameraDeviceSession::NotifyErrorMessage(uint32_t frame_number,
1009 int32_t stream_id,
1010 ErrorCode error_code) {
1011 ALOGI("%s: [sbc] Request %d with stream (%d), return error code (%d)",
1012 __FUNCTION__, frame_number, stream_id, error_code);
1013
1014 if ((error_code == ErrorCode::kErrorResult ||
1015 error_code == ErrorCode::kErrorRequest) &&
1016 stream_id != kInvalidStreamId) {
1017 ALOGW("%s: [sbc] Request %d reset setream id again", __FUNCTION__,
1018 frame_number);
1019 stream_id = kInvalidStreamId;
1020 }
1021 NotifyMessage message = {.type = MessageType::kError,
1022 .message.error = {.frame_number = frame_number,
1023 .error_stream_id = stream_id,
1024 .error_code = error_code}};
1025
1026 std::shared_lock lock(session_callback_lock_);
1027 session_callback_.notify(message);
1028 }
1029
TryHandlePlaceholderResult(CaptureResult * result,bool * result_handled)1030 status_t CameraDeviceSession::TryHandlePlaceholderResult(CaptureResult* result,
1031 bool* result_handled) {
1032 if (result == nullptr || result_handled == nullptr) {
1033 ALOGE("%s: result or result_handled is nullptr.", __FUNCTION__);
1034 return BAD_VALUE;
1035 }
1036
1037 uint32_t frame_number = result->frame_number;
1038 *result_handled = false;
1039 bool need_to_handle_result = false;
1040 bool need_to_notify_error_result = false;
1041 {
1042 std::lock_guard<std::mutex> lock(request_record_lock_);
1043 if (error_notified_requests_.find(frame_number) ==
1044 error_notified_requests_.end()) {
1045 for (auto& stream_buffer : result->output_buffers) {
1046 if (placeholder_buffer_observed_.find(stream_buffer.buffer) !=
1047 placeholder_buffer_observed_.end()) {
1048 error_notified_requests_.insert(frame_number);
1049 if (pending_results_.find(frame_number) != pending_results_.end()) {
1050 need_to_notify_error_result = true;
1051 pending_results_.erase(frame_number);
1052 if (ignore_shutters_.find(frame_number) == ignore_shutters_.end()) {
1053 ignore_shutters_.insert(frame_number);
1054 }
1055 }
1056 need_to_handle_result = true;
1057 break;
1058 }
1059 }
1060 } else {
1061 need_to_handle_result = true;
1062 }
1063 }
1064
1065 if (need_to_notify_error_result) {
1066 NotifyErrorMessage(frame_number, kInvalidStreamId, ErrorCode::kErrorResult);
1067 }
1068
1069 if (need_to_handle_result) {
1070 for (auto& stream_buffer : result->output_buffers) {
1071 bool is_placeholder_buffer = false;
1072 if (hal_buffer_managed_stream_ids_.find(stream_buffer.stream_id) ==
1073 hal_buffer_managed_stream_ids_.end()) {
1074 // No need to handle non HAL buffer managed streams here
1075 continue;
1076 }
1077 {
1078 std::lock_guard<std::mutex> lock(request_record_lock_);
1079 is_placeholder_buffer =
1080 (placeholder_buffer_observed_.find(stream_buffer.buffer) !=
1081 placeholder_buffer_observed_.end());
1082 }
1083
1084 uint64_t buffer_id =
1085 (is_placeholder_buffer ? /*Use invalid for placeholder*/ 0
1086 : stream_buffer.buffer_id);
1087 // To avoid publishing duplicated error buffer message, only publish
1088 // it here when getting normal buffer status from HWL
1089 if (stream_buffer.status == BufferStatus::kOk) {
1090 NotifyErrorMessage(frame_number, stream_buffer.stream_id,
1091 ErrorCode::kErrorBuffer);
1092 }
1093 NotifyBufferError(frame_number, stream_buffer.stream_id, buffer_id);
1094 }
1095
1096 std::vector<StreamBuffer> buffers;
1097 buffers.insert(buffers.end(), result->output_buffers.begin(),
1098 result->output_buffers.end());
1099
1100 if (!buffers.empty()) {
1101 if (pending_requests_tracker_->TrackReturnedResultBuffers(buffers) != OK) {
1102 ALOGE("%s: Tracking requested quota buffers failed", __FUNCTION__);
1103 }
1104 std::vector<StreamBuffer> acquired_buffers;
1105 {
1106 std::lock_guard<std::mutex> lock(request_record_lock_);
1107 for (auto& buffer : buffers) {
1108 if (hal_buffer_managed_stream_ids_.find(buffer.stream_id) ==
1109 hal_buffer_managed_stream_ids_.end()) {
1110 // non HAL buffer managed stream buffers are not tracked by pending
1111 // requests tracker
1112 continue;
1113 }
1114 if (placeholder_buffer_observed_.find(buffer.buffer) ==
1115 placeholder_buffer_observed_.end()) {
1116 acquired_buffers.push_back(buffer);
1117 }
1118 }
1119 }
1120
1121 if (pending_requests_tracker_->TrackReturnedAcquiredBuffers(
1122 acquired_buffers) != OK) {
1123 ALOGE("%s: Tracking requested acquired buffers failed", __FUNCTION__);
1124 }
1125 }
1126 }
1127
1128 *result_handled = need_to_handle_result;
1129 return OK;
1130 }
1131
NotifyBufferError(const CaptureRequest & request)1132 void CameraDeviceSession::NotifyBufferError(const CaptureRequest& request) {
1133 ALOGI("%s: [sbc] Return Buffer Error Status for frame %d", __FUNCTION__,
1134 request.frame_number);
1135
1136 auto result = std::make_unique<CaptureResult>(CaptureResult({}));
1137 result->frame_number = request.frame_number;
1138 for (auto& stream_buffer : request.output_buffers) {
1139 StreamBuffer buffer;
1140 buffer.stream_id = stream_buffer.stream_id;
1141 buffer.status = BufferStatus::kError;
1142 result->output_buffers.push_back(buffer);
1143 }
1144 for (auto& stream_buffer : request.input_buffers) {
1145 result->input_buffers.push_back(stream_buffer);
1146 }
1147 result->partial_result = 1;
1148
1149 std::shared_lock lock(session_callback_lock_);
1150 session_callback_.process_capture_result(std::move(result));
1151 }
1152
NotifyBufferError(uint32_t frame_number,int32_t stream_id,uint64_t buffer_id)1153 void CameraDeviceSession::NotifyBufferError(uint32_t frame_number,
1154 int32_t stream_id,
1155 uint64_t buffer_id) {
1156 ALOGI("%s: [sbc] Return Buffer Error Status for frame %d stream %d",
1157 __FUNCTION__, frame_number, stream_id);
1158
1159 auto result = std::make_unique<CaptureResult>(CaptureResult({}));
1160 result->frame_number = frame_number;
1161 StreamBuffer stream_buffer;
1162 stream_buffer.buffer_id = buffer_id;
1163 stream_buffer.stream_id = stream_id;
1164 stream_buffer.status = BufferStatus::kError;
1165 result->output_buffers.push_back(stream_buffer);
1166 result->partial_result = 1;
1167
1168 std::shared_lock lock(session_callback_lock_);
1169 session_callback_.process_capture_result(std::move(result));
1170 }
1171
HandleSBCInactiveStreams(const CaptureRequest & request,bool * all_active)1172 status_t CameraDeviceSession::HandleSBCInactiveStreams(
1173 const CaptureRequest& request, bool* all_active) {
1174 if (all_active == nullptr) {
1175 ALOGE("%s: all_active is nullptr", __FUNCTION__);
1176 return BAD_VALUE;
1177 }
1178
1179 *all_active = true;
1180 for (auto& stream_buffer : request.output_buffers) {
1181 bool is_hal_buffer_managed =
1182 hal_buffer_managed_stream_ids_.find(stream_buffer.stream_id) !=
1183 hal_buffer_managed_stream_ids_.end();
1184 if (!is_hal_buffer_managed) {
1185 continue;
1186 }
1187 bool is_active = true;
1188 status_t res = stream_buffer_cache_manager_->IsStreamActive(
1189 stream_buffer.stream_id, &is_active);
1190 if (res != OK) {
1191 ALOGE("%s: Failed to check if stream is active, error status: %s(%d)",
1192 __FUNCTION__, strerror(-res), res);
1193 return UNKNOWN_ERROR;
1194 }
1195 if (!is_active) {
1196 ALOGI("%s: Stream %d is not active when submitting frame %d request.",
1197 __FUNCTION__, stream_buffer.stream_id, request.frame_number);
1198 *all_active = false;
1199 break;
1200 }
1201 }
1202 if (*all_active == false) {
1203 NotifyErrorMessage(request.frame_number, kInvalidStreamId,
1204 ErrorCode::kErrorRequest);
1205 NotifyBufferError(request);
1206 }
1207
1208 return OK;
1209 }
1210
CheckRequestForStreamBufferCacheManager(const CaptureRequest & request,bool * need_to_process)1211 void CameraDeviceSession::CheckRequestForStreamBufferCacheManager(
1212 const CaptureRequest& request, bool* need_to_process) {
1213 ATRACE_CALL();
1214
1215 // If any stream in the stream buffer cache manager has been labeld as inactive,
1216 // return ERROR_REQUEST immediately. No need to send the request to HWL.
1217 status_t res = HandleSBCInactiveStreams(request, need_to_process);
1218 if (res != OK) {
1219 ALOGE("%s: Failed to check if streams are active.", __FUNCTION__);
1220 return;
1221 }
1222
1223 // Note: This function should only be called if buffer_management_used_
1224 // is true.
1225 if (pending_request_streams_.empty()) {
1226 pending_requests_tracker_->OnBufferCacheFlushed();
1227 }
1228
1229 // Add streams into pending_request_streams_
1230 uint32_t frame_number = request.frame_number;
1231 if (*need_to_process) {
1232 std::lock_guard<std::mutex> lock(request_record_lock_);
1233 pending_results_.insert(frame_number);
1234 for (auto& stream_buffer : request.output_buffers) {
1235 bool is_hal_buffer_managed =
1236 hal_buffer_managed_stream_ids_.find(stream_buffer.stream_id) !=
1237 hal_buffer_managed_stream_ids_.end();
1238 if (!is_hal_buffer_managed) {
1239 // pending_request_streams_ tracks only hal buffer managed streams.
1240 continue;
1241 }
1242 if (grouped_stream_id_map_.count(stream_buffer.stream_id) == 1) {
1243 pending_request_streams_[frame_number].insert(
1244 grouped_stream_id_map_.at(stream_buffer.stream_id));
1245 } else {
1246 pending_request_streams_[frame_number].insert(stream_buffer.stream_id);
1247 }
1248 }
1249 }
1250 }
1251
ValidateRequestLocked(const CaptureRequest & request)1252 status_t CameraDeviceSession::ValidateRequestLocked(
1253 const CaptureRequest& request) {
1254 // First request must have valid settings.
1255 if (!has_valid_settings_) {
1256 if (request.settings == nullptr ||
1257 request.settings->GetCameraMetadataSize() == 0) {
1258 ALOGE("%s: First request must have valid settings", __FUNCTION__);
1259 return BAD_VALUE;
1260 }
1261
1262 has_valid_settings_ = true;
1263 }
1264
1265 if (request.output_buffers.empty()) {
1266 ALOGE("%s: there is no output buffer.", __FUNCTION__);
1267 return BAD_VALUE;
1268 }
1269
1270 // Check all output streams are configured.
1271 for (auto& buffer : request.input_buffers) {
1272 if (configured_streams_map_.find(buffer.stream_id) ==
1273 configured_streams_map_.end()) {
1274 ALOGE("%s: input stream %d is not configured.", __FUNCTION__,
1275 buffer.stream_id);
1276 return BAD_VALUE;
1277 }
1278 const Stream& input_stream = configured_streams_map_.at(buffer.stream_id);
1279 if (!multi_res_reprocess_ && (request.input_width != input_stream.width ||
1280 request.input_height != input_stream.height)) {
1281 ALOGE("%s: Invalid input size [%d, %d], expected [%d, %d]", __FUNCTION__,
1282 request.input_width, request.input_height, input_stream.width,
1283 input_stream.height);
1284 return BAD_VALUE;
1285 }
1286 }
1287 if (request.input_buffers.size() > 0) {
1288 if (multi_res_reprocess_ &&
1289 (request.input_width == 0 || request.input_height == 0)) {
1290 ALOGE(
1291 "%s: Session is a multi-res input session, but has invalid input "
1292 "size [%d, %d]",
1293 __FUNCTION__, request.input_width, request.input_height);
1294 return BAD_VALUE;
1295 }
1296 }
1297
1298 for (auto& buffer : request.output_buffers) {
1299 if (configured_streams_map_.find(buffer.stream_id) ==
1300 configured_streams_map_.end()) {
1301 ALOGE("%s: output stream %d is not configured.", __FUNCTION__,
1302 buffer.stream_id);
1303 return BAD_VALUE;
1304 }
1305 }
1306
1307 return OK;
1308 }
1309
ProcessCaptureRequest(const std::vector<CaptureRequest> & requests,uint32_t * num_processed_requests)1310 status_t CameraDeviceSession::ProcessCaptureRequest(
1311 const std::vector<CaptureRequest>& requests,
1312 uint32_t* num_processed_requests) {
1313 ATRACE_CALL();
1314 std::lock_guard<std::mutex> lock(session_lock_);
1315 if (num_processed_requests == nullptr) {
1316 return BAD_VALUE;
1317 }
1318
1319 if (requests.empty()) {
1320 ALOGE("%s: requests is empty.", __FUNCTION__);
1321 return BAD_VALUE;
1322 }
1323
1324 status_t res;
1325 *num_processed_requests = 0;
1326
1327 for (auto& request : requests) {
1328 if (ATRACE_ENABLED()) {
1329 ATRACE_INT("request_frame_number", request.frame_number);
1330 }
1331
1332 res = ValidateRequestLocked(request);
1333 if (res != OK) {
1334 ALOGE("%s: Request %d is not valid.", __FUNCTION__, request.frame_number);
1335 return res;
1336 }
1337
1338 res = ImportRequestBufferHandles(request);
1339 if (res != OK) {
1340 ALOGE("%s: Importing request buffer handles failed: %s(%d)", __FUNCTION__,
1341 strerror(-res), res);
1342 return res;
1343 }
1344
1345 CaptureRequest updated_request;
1346 res = CreateCaptureRequestLocked(request, &updated_request);
1347 if (res != OK) {
1348 ALOGE("%s: Updating buffer handles failed for frame %u", __FUNCTION__,
1349 request.frame_number);
1350 return res;
1351 }
1352
1353 bool need_to_process = true;
1354 // If a processCaptureRequest() call is made during flushing,
1355 // notify CAMERA3_MSG_ERROR_REQUEST directly.
1356 if (is_flushing_) {
1357 NotifyErrorMessage(request.frame_number, kInvalidStreamId,
1358 ErrorCode::kErrorRequest);
1359 NotifyBufferError(request);
1360 need_to_process = false;
1361 } else if (hal_buffer_managed_stream_ids_.size() != 0) {
1362 CheckRequestForStreamBufferCacheManager(updated_request, &need_to_process);
1363 }
1364
1365 if (need_to_process) {
1366 // For HAL buffer managed streams, framework does not throttle requests
1367 // with stream's max buffers. We need to throttle on our own.
1368 std::vector<int32_t> first_requested_stream_ids;
1369
1370 res = pending_requests_tracker_->WaitAndTrackRequestBuffers(
1371 updated_request, &first_requested_stream_ids);
1372 if (res != OK) {
1373 ALOGE("%s: Waiting until capture ready failed: %s(%d)", __FUNCTION__,
1374 strerror(-res), res);
1375 return res;
1376 }
1377
1378 for (auto& stream_id : first_requested_stream_ids) {
1379 ALOGI("%s: [sbc] Stream %d 1st req arrived, notify SBC Manager.",
1380 __FUNCTION__, stream_id);
1381 res = stream_buffer_cache_manager_->NotifyProviderReadiness(stream_id);
1382 if (res != OK) {
1383 ALOGE("%s: Notifying provider readiness failed: %s(%d)", __FUNCTION__,
1384 strerror(-res), res);
1385 return res;
1386 }
1387 }
1388
1389 // Check the flush status again to prevent flush being called while we are
1390 // waiting for the request buffers(request throttling).
1391 if (is_flushing_) {
1392 std::vector<StreamBuffer> buffers = updated_request.output_buffers;
1393 {
1394 std::lock_guard<std::mutex> request_lock(request_record_lock_);
1395 pending_request_streams_.erase(updated_request.frame_number);
1396 pending_results_.erase(updated_request.frame_number);
1397 }
1398 NotifyErrorMessage(updated_request.frame_number, kInvalidStreamId,
1399 ErrorCode::kErrorRequest);
1400 NotifyBufferError(updated_request);
1401 if (pending_requests_tracker_->TrackReturnedResultBuffers(buffers) !=
1402 OK) {
1403 ALOGE("%s: Tracking requested quota buffers failed", __FUNCTION__);
1404 }
1405 } else {
1406 std::shared_lock session_lock(capture_session_lock_);
1407 if (capture_session_ == nullptr) {
1408 ALOGE("%s: Capture session wasn't created.", __FUNCTION__);
1409 return NO_INIT;
1410 }
1411
1412 res = capture_session_->ProcessRequest(updated_request);
1413 if (res != OK) {
1414 ALOGE("%s: Submitting request to HWL session failed: %s (%d)",
1415 __FUNCTION__, strerror(-res), res);
1416 return res;
1417 }
1418 }
1419 }
1420
1421 (*num_processed_requests)++;
1422 }
1423
1424 return OK;
1425 }
1426
IsBufferImportedLocked(int32_t stream_id,uint32_t buffer_id)1427 bool CameraDeviceSession::IsBufferImportedLocked(int32_t stream_id,
1428 uint32_t buffer_id) {
1429 BufferCache buffer_cache = {stream_id, buffer_id};
1430 return imported_buffer_handle_map_.find(buffer_cache) !=
1431 imported_buffer_handle_map_.end();
1432 }
1433
AddImportedBufferHandlesLocked(const BufferCache & buffer_cache,buffer_handle_t buffer_handle)1434 status_t CameraDeviceSession::AddImportedBufferHandlesLocked(
1435 const BufferCache& buffer_cache, buffer_handle_t buffer_handle) {
1436 ATRACE_CALL();
1437 auto buffer_handle_it = imported_buffer_handle_map_.find(buffer_cache);
1438 if (buffer_handle_it == imported_buffer_handle_map_.end()) {
1439 // Add a new buffer cache if it doesn't exist.
1440 imported_buffer_handle_map_.emplace(buffer_cache, buffer_handle);
1441 } else if (buffer_handle_it->second != buffer_handle) {
1442 ALOGE(
1443 "%s: Cached buffer handle %p doesn't match %p for stream %u buffer "
1444 "%" PRIu64,
1445 __FUNCTION__, buffer_handle_it->second, buffer_handle,
1446 buffer_cache.stream_id, buffer_cache.buffer_id);
1447 return BAD_VALUE;
1448 }
1449
1450 return OK;
1451 }
1452
RemoveBufferCache(const std::vector<BufferCache> & buffer_caches)1453 void CameraDeviceSession::RemoveBufferCache(
1454 const std::vector<BufferCache>& buffer_caches) {
1455 ATRACE_CALL();
1456 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
1457
1458 for (auto& buffer_cache : buffer_caches) {
1459 auto buffer_handle_it = imported_buffer_handle_map_.find(buffer_cache);
1460 if (buffer_handle_it == imported_buffer_handle_map_.end()) {
1461 ALOGW("%s: Could not find buffer cache for stream %u buffer %" PRIu64,
1462 __FUNCTION__, buffer_cache.stream_id, buffer_cache.buffer_id);
1463 continue;
1464 }
1465
1466 device_session_hwl_->RemoveCachedBuffers(buffer_handle_it->second);
1467
1468 status_t res =
1469 GraphicBufferMapper::get().freeBuffer(buffer_handle_it->second);
1470 if (res != OK) {
1471 ALOGE("%s: Freeing imported buffer failed: %s", __FUNCTION__,
1472 ::android::statusToString(res).c_str());
1473 }
1474
1475 imported_buffer_handle_map_.erase(buffer_handle_it);
1476 }
1477 }
1478
FreeBufferHandlesLocked(int32_t stream_id)1479 void CameraDeviceSession::FreeBufferHandlesLocked(int32_t stream_id) {
1480 for (auto buffer_handle_it = imported_buffer_handle_map_.begin();
1481 buffer_handle_it != imported_buffer_handle_map_.end();) {
1482 if (buffer_handle_it->first.stream_id == stream_id) {
1483 status_t res =
1484 GraphicBufferMapper::get().freeBuffer(buffer_handle_it->second);
1485 if (res != OK) {
1486 ALOGE("%s: Freeing imported buffer failed: %s", __FUNCTION__,
1487 ::android::statusToString(res).c_str());
1488 }
1489 buffer_handle_it = imported_buffer_handle_map_.erase(buffer_handle_it);
1490 } else {
1491 buffer_handle_it++;
1492 }
1493 }
1494 }
1495
FreeImportedBufferHandles()1496 void CameraDeviceSession::FreeImportedBufferHandles() {
1497 ATRACE_CALL();
1498 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
1499
1500 auto& mapper = GraphicBufferMapper::get();
1501 for (auto buffer_handle_it : imported_buffer_handle_map_) {
1502 status_t status = mapper.freeBuffer(buffer_handle_it.second);
1503 if (status != OK) {
1504 ALOGE("%s: Freeing imported buffer failed: %s", __FUNCTION__,
1505 ::android::statusToString(status).c_str());
1506 }
1507 }
1508
1509 imported_buffer_handle_map_.clear();
1510 }
1511
CleanupStaleStreamsLocked(const std::vector<Stream> & new_streams)1512 void CameraDeviceSession::CleanupStaleStreamsLocked(
1513 const std::vector<Stream>& new_streams) {
1514 for (auto stream_it = configured_streams_map_.begin();
1515 stream_it != configured_streams_map_.end();) {
1516 int32_t stream_id = stream_it->first;
1517 bool found = false;
1518 for (const Stream& stream : new_streams) {
1519 if (stream.id == stream_id) {
1520 found = true;
1521 break;
1522 }
1523 }
1524 if (!found) {
1525 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
1526 stream_it = configured_streams_map_.erase(stream_it);
1527 FreeBufferHandlesLocked(stream_id);
1528 } else {
1529 stream_it++;
1530 }
1531 }
1532 }
1533
Flush()1534 status_t CameraDeviceSession::Flush() {
1535 ATRACE_CALL();
1536 std::shared_lock lock(capture_session_lock_);
1537 if (capture_session_ == nullptr) {
1538 return OK;
1539 }
1540
1541 is_flushing_ = true;
1542 status_t res = capture_session_->Flush();
1543 stream_buffer_cache_manager_->NotifyFlushingAll();
1544 is_flushing_ = false;
1545
1546 return res;
1547 }
1548
RepeatingRequestEnd(int32_t frame_number,const std::vector<int32_t> & stream_ids)1549 void CameraDeviceSession::RepeatingRequestEnd(
1550 int32_t frame_number, const std::vector<int32_t>& stream_ids) {
1551 ATRACE_CALL();
1552 std::shared_lock lock(capture_session_lock_);
1553 if (capture_session_ != nullptr) {
1554 capture_session_->RepeatingRequestEnd(frame_number, stream_ids);
1555 }
1556 }
1557
AppendOutputIntentToSettingsLocked(const CaptureRequest & request,CaptureRequest * updated_request)1558 void CameraDeviceSession::AppendOutputIntentToSettingsLocked(
1559 const CaptureRequest& request, CaptureRequest* updated_request) {
1560 if (updated_request == nullptr || updated_request->settings == nullptr) {
1561 // The frameworks may have no settings and just do nothing here.
1562 return;
1563 }
1564
1565 bool has_video = false;
1566 bool has_snapshot = false;
1567 bool has_zsl = false;
1568
1569 // From request output_buffers to find stream id and then find the stream.
1570 for (auto& buffer : request.output_buffers) {
1571 auto stream = configured_streams_map_.find(buffer.stream_id);
1572 if (stream != configured_streams_map_.end()) {
1573 if (utils::IsVideoStream(stream->second)) {
1574 has_video = true;
1575 } else if (utils::IsJPEGSnapshotStream(stream->second)) {
1576 has_snapshot = true;
1577 }
1578 }
1579 }
1580
1581 for (auto& buffer : request.input_buffers) {
1582 auto stream = configured_streams_map_.find(buffer.stream_id);
1583 if (stream != configured_streams_map_.end()) {
1584 if ((stream->second.usage & GRALLOC_USAGE_HW_CAMERA_ZSL) != 0) {
1585 has_zsl = true;
1586 break;
1587 }
1588 }
1589 }
1590
1591 uint8_t output_intent = static_cast<uint8_t>(OutputIntent::kPreview);
1592
1593 if (has_video && has_snapshot) {
1594 output_intent = static_cast<uint8_t>(OutputIntent::kVideoSnapshot);
1595 } else if (has_snapshot) {
1596 output_intent = static_cast<uint8_t>(OutputIntent::kSnapshot);
1597 } else if (has_video) {
1598 output_intent = static_cast<uint8_t>(OutputIntent::kVideo);
1599 } else if (has_zsl) {
1600 output_intent = static_cast<uint8_t>(OutputIntent::kZsl);
1601 }
1602
1603 // Used to indicate the possible start and end of video recording in traces
1604 if (has_video && !prev_output_intent_has_video_) {
1605 ATRACE_NAME("Start Video Streaming");
1606 } else if (prev_output_intent_has_video_ && !has_video) {
1607 ATRACE_NAME("Stop Video Streaming");
1608 }
1609
1610 prev_output_intent_has_video_ = has_video;
1611
1612 status_t res = updated_request->settings->Set(VendorTagIds::kOutputIntent,
1613 &output_intent,
1614 /*data_count=*/1);
1615 if (res != OK) {
1616 ALOGE("%s: Failed to set vendor tag OutputIntent: %s(%d).", __FUNCTION__,
1617 strerror(-res), res);
1618 }
1619 }
1620
IsReconfigurationRequired(const HalCameraMetadata * old_session,const HalCameraMetadata * new_session,bool * reconfiguration_required)1621 status_t CameraDeviceSession::IsReconfigurationRequired(
1622 const HalCameraMetadata* old_session, const HalCameraMetadata* new_session,
1623 bool* reconfiguration_required) {
1624 if (old_session == nullptr || new_session == nullptr ||
1625 reconfiguration_required == nullptr) {
1626 ALOGE(
1627 "%s: old_session or new_session or reconfiguration_required is "
1628 "nullptr.",
1629 __FUNCTION__);
1630 return BAD_VALUE;
1631 }
1632
1633 return device_session_hwl_->IsReconfigurationRequired(
1634 old_session, new_session, reconfiguration_required);
1635 }
1636
UpdateRequestedBufferHandles(std::vector<StreamBuffer> * buffers)1637 status_t CameraDeviceSession::UpdateRequestedBufferHandles(
1638 std::vector<StreamBuffer>* buffers) {
1639 if (buffers == nullptr) {
1640 ALOGE("%s: buffer is nullptr.", __FUNCTION__);
1641 return BAD_VALUE;
1642 }
1643
1644 std::lock_guard<std::mutex> lock(imported_buffer_handle_map_lock_);
1645
1646 status_t res;
1647 for (auto& buffer : *buffers) {
1648 // If buffer handle is not nullptr, we need to add the new buffer handle
1649 // to buffer cache.
1650 if (buffer.buffer != nullptr) {
1651 BufferCache buffer_cache = {buffer.stream_id, buffer.buffer_id};
1652 res = AddImportedBufferHandlesLocked(buffer_cache, buffer.buffer);
1653 if (res != OK) {
1654 ALOGE("%s: Adding imported buffer handle failed: %s(%d)", __FUNCTION__,
1655 strerror(-res), res);
1656 return res;
1657 }
1658 }
1659 }
1660
1661 res = UpdateBufferHandlesLocked(buffers,
1662 /*update_hal_buffer_managed_streams=*/true);
1663 if (res != OK) {
1664 ALOGE("%s: Updating output buffer handles failed: %s(%d)", __FUNCTION__,
1665 strerror(-res), res);
1666 return res;
1667 }
1668
1669 return OK;
1670 }
1671
RegisterStreamsIntoCacheManagerLocked(const StreamConfiguration & stream_config,const std::vector<HalStream> & hal_streams)1672 status_t CameraDeviceSession::RegisterStreamsIntoCacheManagerLocked(
1673 const StreamConfiguration& stream_config,
1674 const std::vector<HalStream>& hal_streams) {
1675 ATRACE_CALL();
1676
1677 std::optional<uint32_t> hfr_batch_size;
1678 camera_metadata_ro_entry entry;
1679 if (stream_config.operation_mode ==
1680 StreamConfigurationMode::kConstrainedHighSpeed &&
1681 stream_config.session_params != nullptr &&
1682 stream_config.session_params->Get(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1683 &entry) == OK) {
1684 uint32_t max_fps = entry.data.i32[1];
1685 if (max_fps % 30 != 0) {
1686 ALOGE("%s: max_fps(%u) must be multiple of 30", __FUNCTION__, max_fps);
1687 return BAD_VALUE;
1688 }
1689 hfr_batch_size = max_fps / 30;
1690 }
1691
1692 for (auto& stream : stream_config.streams) {
1693 uint64_t producer_usage = 0;
1694 uint64_t consumer_usage = 0;
1695 int32_t stream_id = -1;
1696 android_pixel_format_t stream_format = stream.format;
1697 for (auto& hal_stream : hal_streams) {
1698 if (hal_stream.id == stream.id) {
1699 producer_usage = hal_stream.producer_usage;
1700 consumer_usage = hal_stream.consumer_usage;
1701 stream_id = hal_stream.id;
1702 if (stream_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
1703 stream_format = hal_stream.override_format;
1704 }
1705 }
1706 }
1707 if (stream_id == -1) {
1708 ALOGE("%s: Could not fine framework stream in hal configured stream list",
1709 __FUNCTION__);
1710 return UNKNOWN_ERROR;
1711 }
1712 // Input stream buffers are always allocated by the camera service, not by
1713 // request_stream_buffers() callback from the HAL.
1714 if (stream.stream_type != StreamType::kOutput) {
1715 continue;
1716 }
1717
1718 // The stream is not HAL buffer managed, so no need to register with SBC.
1719 if (hal_buffer_managed_stream_ids_.find(stream_id) ==
1720 hal_buffer_managed_stream_ids_.end()) {
1721 continue;
1722 }
1723 StreamBufferRequestFunc session_request_func = StreamBufferRequestFunc(
1724 [this, stream_id](uint32_t num_buffer,
1725 std::vector<StreamBuffer>* buffers,
1726 StreamBufferRequestError* status) -> status_t {
1727 ATRACE_NAME("StreamBufferRequestFunc");
1728 if (buffers == nullptr) {
1729 ALOGE("%s: buffers is nullptr.", __FUNCTION__);
1730 return BAD_VALUE;
1731 }
1732
1733 if (num_buffer == 0) {
1734 ALOGE("%s: num_buffer is 0", __FUNCTION__);
1735 return BAD_VALUE;
1736 }
1737
1738 if (status == nullptr) {
1739 ALOGE("%s: status is nullptr.", __FUNCTION__);
1740 return BAD_VALUE;
1741 }
1742
1743 return RequestStreamBuffers(stream_id, num_buffer, buffers, status);
1744 });
1745
1746 StreamBufferReturnFunc session_return_func = StreamBufferReturnFunc(
1747 [this](const std::vector<StreamBuffer>& buffers) -> status_t {
1748 ReturnStreamBuffers(buffers);
1749
1750 for (auto& stream_buffer : buffers) {
1751 ALOGI("%s: [sbc] Flushed buf[%p] bid[%" PRIu64 "] strm[%d] frm[xx]",
1752 __FUNCTION__, stream_buffer.buffer, stream_buffer.buffer_id,
1753 stream_buffer.stream_id);
1754 }
1755
1756 return OK;
1757 });
1758
1759 const uint32_t num_buffers_to_cache =
1760 libgooglecamerahal::flags::batched_request_buffers() &&
1761 hfr_batch_size.has_value() && utils::IsVideoStream(stream)
1762 ? *hfr_batch_size
1763 : 1;
1764
1765 StreamBufferCacheRegInfo reg_info = {
1766 .request_func = session_request_func,
1767 .return_func = session_return_func,
1768 .stream_id = stream_id,
1769 .width = stream.width,
1770 .height = stream.height,
1771 .format = stream_format,
1772 .producer_flags = producer_usage,
1773 .consumer_flags = consumer_usage,
1774 .num_buffers_to_cache = num_buffers_to_cache};
1775
1776 status_t res = stream_buffer_cache_manager_->RegisterStream(reg_info);
1777 if (res != OK) {
1778 ALOGE(
1779 "%s: Failed to register stream into stream buffer cache manager, "
1780 "error status: %s(%d)",
1781 __FUNCTION__, strerror(-res), res);
1782 return UNKNOWN_ERROR;
1783 }
1784 ALOGI("%s: [sbc] Registered stream %d into SBC manager.", __FUNCTION__,
1785 stream.id);
1786 }
1787
1788 return OK;
1789 }
1790
RequestBuffersFromStreamBufferCacheManager(int32_t stream_id,uint32_t num_buffers,std::vector<StreamBuffer> * buffers,uint32_t frame_number)1791 status_t CameraDeviceSession::RequestBuffersFromStreamBufferCacheManager(
1792 int32_t stream_id, uint32_t num_buffers, std::vector<StreamBuffer>* buffers,
1793 uint32_t frame_number) {
1794 if (num_buffers != 1) {
1795 ALOGE(
1796 "%s: Only one buffer per request can be handled now. num_buffers = %d",
1797 __FUNCTION__, num_buffers);
1798 // TODO(b/127988765): handle multiple buffers from multiple streams if
1799 // HWL needs this feature.
1800 return BAD_VALUE;
1801 }
1802
1803 StreamBufferRequestResult buffer_request_result;
1804
1805 status_t res = this->stream_buffer_cache_manager_->GetStreamBuffer(
1806 stream_id, &buffer_request_result);
1807 if (res != OK) {
1808 ALOGE(
1809 "%s: Failed to get stream buffer from SBC manager, error status: "
1810 "%s(%d).",
1811 __FUNCTION__, strerror(-res), res);
1812 return UNKNOWN_ERROR;
1813 }
1814
1815 // This function fulfills requests from lower HAL level. It is hard for some
1816 // implementation of lower HAL level to handle the case of a request failure.
1817 // In case a framework buffer can not be delivered to the lower level, a
1818 // placeholder buffer will be returned by the stream buffer cache manager. The
1819 // client at lower level can use that placeholder buffer as a normal buffer
1820 // for writing and so forth. But that buffer will not be returned to the
1821 // framework. This avoids the troublesome for lower level to handle such
1822 // situation. An ERROR_REQUEST needs to be returned to the framework according
1823 // to
1824 // ::android::hardware::camera::device::V3_5::StreamBufferRequestError.
1825 if (buffer_request_result.is_placeholder_buffer) {
1826 ALOGI("%s: [sbc] Placeholder buffer returned for stream: %d, frame: %d",
1827 __FUNCTION__, stream_id, frame_number);
1828 {
1829 std::lock_guard<std::mutex> lock(request_record_lock_);
1830 placeholder_buffer_observed_.insert(buffer_request_result.buffer.buffer);
1831 }
1832 }
1833
1834 ALOGV("%s: [sbc] => HWL Acquired buf[%p] buf_id[%" PRIu64
1835 "] strm[%d] frm[%u] placeholder[%d]",
1836 __FUNCTION__, buffer_request_result.buffer.buffer,
1837 buffer_request_result.buffer.buffer_id, stream_id, frame_number,
1838 buffer_request_result.is_placeholder_buffer);
1839
1840 buffers->push_back(buffer_request_result.buffer);
1841 return OK;
1842 }
1843
RequestStreamBuffers(int32_t stream_id,uint32_t num_buffers,std::vector<StreamBuffer> * buffers,StreamBufferRequestError * request_status)1844 status_t CameraDeviceSession::RequestStreamBuffers(
1845 int32_t stream_id, uint32_t num_buffers, std::vector<StreamBuffer>* buffers,
1846 StreamBufferRequestError* request_status) {
1847 if (buffers == nullptr) {
1848 ALOGE("%s: buffers is nullptr", __FUNCTION__);
1849 return BAD_VALUE;
1850 }
1851
1852 if (num_buffers == 0) {
1853 ALOGE("%s: num_buffers is 0", __FUNCTION__);
1854 return BAD_VALUE;
1855 }
1856
1857 if (request_status == nullptr) {
1858 ALOGE("%s: request_status is nullptr", __FUNCTION__);
1859 return BAD_VALUE;
1860 }
1861
1862 *request_status = StreamBufferRequestError::kOk;
1863 status_t res = pending_requests_tracker_->WaitAndTrackAcquiredBuffers(
1864 stream_id, num_buffers);
1865 if (res != OK) {
1866 ALOGW("%s: Waiting until available buffer failed: %s(%d)", __FUNCTION__,
1867 strerror(-res), res);
1868 *request_status = StreamBufferRequestError::kNoBufferAvailable;
1869 return res;
1870 }
1871
1872 std::vector<BufferReturn> buffer_returns;
1873 std::vector<BufferRequest> buffer_requests = {{
1874 .stream_id = stream_id,
1875 .num_buffers_requested = num_buffers,
1876 }};
1877
1878 BufferRequestStatus status = BufferRequestStatus::kOk;
1879 {
1880 int64_t start_timestamp;
1881 std::shared_lock lock(session_callback_lock_);
1882 if (measure_buffer_allocation_time_) {
1883 struct timespec start_time;
1884 if (clock_gettime(CLOCK_BOOTTIME, &start_time)) {
1885 ALOGE("%s: Getting start_time failed.", __FUNCTION__);
1886 } else {
1887 start_timestamp = start_time.tv_sec * kNsPerSec + start_time.tv_nsec;
1888 }
1889 }
1890 status = session_callback_.request_stream_buffers(buffer_requests,
1891 &buffer_returns);
1892 if (measure_buffer_allocation_time_) {
1893 int64_t end_timestamp;
1894 struct timespec end_time;
1895 if (clock_gettime(CLOCK_BOOTTIME, &end_time)) {
1896 ALOGE("%s: Getting end_time failed.", __FUNCTION__);
1897 } else {
1898 end_timestamp = end_time.tv_sec * kNsPerSec + end_time.tv_nsec;
1899 int64_t elapsed_timestamp = end_timestamp - start_timestamp;
1900 if (elapsed_timestamp > kAllocationThreshold) {
1901 ALOGW("%s: buffer allocation time: %" PRIu64 " ms", __FUNCTION__,
1902 elapsed_timestamp / 1000000);
1903 }
1904 }
1905 }
1906 }
1907
1908 // need this information when status is not kOk
1909 if (buffer_returns.size() > 0) {
1910 *request_status = buffer_returns[0].val.error;
1911 }
1912
1913 if (status != BufferRequestStatus::kOk || buffer_returns.size() != 1) {
1914 ALOGW(
1915 "%s: Requesting stream buffer failed. (buffer_returns has %zu "
1916 "entries; status is %s(%d)).",
1917 __FUNCTION__, buffer_returns.size(), strerror(-res), status);
1918 for (auto& buffer_return : buffer_returns) {
1919 ALOGI("%s: stream %d, buffer request error %d", __FUNCTION__,
1920 buffer_return.stream_id, buffer_return.val.error);
1921 }
1922 pending_requests_tracker_->TrackBufferAcquisitionFailure(stream_id,
1923 num_buffers);
1924 pending_requests_tracker_->DumpStatus();
1925 // TODO(b/129362905): Return partial buffers.
1926 return UNKNOWN_ERROR;
1927 }
1928
1929 *buffers = buffer_returns[0].val.buffers;
1930
1931 res = UpdateRequestedBufferHandles(buffers);
1932 if (res != OK) {
1933 ALOGE("%s: Updating requested buffer handles failed: %s(%d).", __FUNCTION__,
1934 strerror(-res), res);
1935 // TODO(b/129362905): Return partial buffers.
1936 return res;
1937 }
1938
1939 ALOGV("%s: [sbc] => CDS Acquired buf[%p] buf_id[%" PRIu64 "] strm[%d]",
1940 __FUNCTION__, buffers->at(0).buffer, buffers->at(0).buffer_id,
1941 stream_id);
1942
1943 return OK;
1944 }
1945
ReturnStreamBuffers(const std::vector<StreamBuffer> & buffers)1946 void CameraDeviceSession::ReturnStreamBuffers(
1947 const std::vector<StreamBuffer>& buffers) {
1948 {
1949 std::shared_lock lock(session_callback_lock_);
1950 session_callback_.return_stream_buffers(buffers);
1951 }
1952
1953 for (auto& stream_buffer : buffers) {
1954 ALOGV("%s: [sbc] <= Return extra buf[%p], bid[%" PRIu64 "], strm[%d]",
1955 __FUNCTION__, stream_buffer.buffer, stream_buffer.buffer_id,
1956 stream_buffer.stream_id);
1957 }
1958
1959 if (pending_requests_tracker_->TrackReturnedAcquiredBuffers(buffers) != OK) {
1960 ALOGE("%s: Tracking requested buffers failed.", __FUNCTION__);
1961 }
1962 }
1963
1964 std::unique_ptr<google::camera_common::Profiler>
GetProfiler(uint32_t camera_id,int option)1965 CameraDeviceSession::GetProfiler(uint32_t camera_id, int option) {
1966 return device_session_hwl_->GetProfiler(camera_id, option);
1967 }
1968
TryHandleCaptureResult(std::unique_ptr<CaptureResult> & result)1969 bool CameraDeviceSession::TryHandleCaptureResult(
1970 std::unique_ptr<CaptureResult>& result) {
1971 if (result == nullptr) {
1972 ALOGE("%s: result is nullptr", __FUNCTION__);
1973 return true;
1974 }
1975 zoom_ratio_mapper_.UpdateCaptureResult(result.get());
1976
1977 status_t res = UpdatePendingRequest(result.get());
1978 if (res != OK) {
1979 ALOGE("%s: Updating inflight requests/streams failed: %s(%d)", __FUNCTION__,
1980 strerror(-res), res);
1981 return true;
1982 }
1983
1984 for (auto& stream_buffer : result->output_buffers) {
1985 ALOGV("%s: [sbc] <= Return result output buf[%p], bid[%" PRIu64
1986 "], strm[%d], frm[%u]",
1987 __FUNCTION__, stream_buffer.buffer, stream_buffer.buffer_id,
1988 stream_buffer.stream_id, result->frame_number);
1989 }
1990 for (auto& stream_buffer : result->input_buffers) {
1991 ALOGV("%s: [sbc] <= Return result input buf[%p], bid[%" PRIu64
1992 "], strm[%d], frm[%u]",
1993 __FUNCTION__, stream_buffer.buffer, stream_buffer.buffer_id,
1994 stream_buffer.stream_id, result->frame_number);
1995 }
1996
1997 // If there is placeholder buffer or a placeholder buffer has been observed of
1998 // this frame, handle the capture result specifically.
1999 bool result_handled = false;
2000 res = TryHandlePlaceholderResult(result.get(), &result_handled);
2001 if (res != OK) {
2002 ALOGE("%s: Failed to handle placeholder result.", __FUNCTION__);
2003 return true;
2004 }
2005 return result_handled;
2006 }
2007
TrackReturnedBuffers(const std::vector<StreamBuffer> & buffers)2008 void CameraDeviceSession::TrackReturnedBuffers(
2009 const std::vector<StreamBuffer>& buffers) {
2010 if (!buffers.empty()) {
2011 if (pending_requests_tracker_->TrackReturnedAcquiredBuffers(buffers) != OK) {
2012 ALOGE("%s: Tracking requested acquired buffers failed", __FUNCTION__);
2013 }
2014 if (pending_requests_tracker_->TrackReturnedResultBuffers(buffers) != OK) {
2015 ALOGE("%s: Tracking requested quota buffers failed", __FUNCTION__);
2016 }
2017 }
2018 }
2019
ShouldSendNotifyMessage(const NotifyMessage & result)2020 bool CameraDeviceSession::ShouldSendNotifyMessage(const NotifyMessage& result) {
2021 {
2022 uint32_t frame_number = 0;
2023 if (result.type == MessageType::kError) {
2024 frame_number = result.message.error.frame_number;
2025 } else if (result.type == MessageType::kShutter) {
2026 frame_number = result.message.shutter.frame_number;
2027 }
2028 std::lock_guard<std::mutex> lock(request_record_lock_);
2029 // Strip out results for frame number that has been notified
2030 // ErrorCode::kErrorResult and ErrorCode::kErrorBuffer
2031 if ((error_notified_requests_.find(frame_number) !=
2032 error_notified_requests_.end()) &&
2033 (result.type != MessageType::kShutter)) {
2034 return false;
2035 }
2036
2037 if (result.type == MessageType::kError &&
2038 result.message.error.error_code == ErrorCode::kErrorResult) {
2039 pending_results_.erase(frame_number);
2040
2041 if (ignore_shutters_.find(frame_number) == ignore_shutters_.end()) {
2042 ignore_shutters_.insert(frame_number);
2043 }
2044 }
2045
2046 if (result.type == MessageType::kShutter) {
2047 if (ignore_shutters_.find(frame_number) != ignore_shutters_.end()) {
2048 ignore_shutters_.erase(frame_number);
2049 return false;
2050 }
2051 }
2052 }
2053
2054 if (ATRACE_ENABLED() && result.type == MessageType::kShutter) {
2055 int64_t timestamp_ns_diff = 0;
2056 int64_t current_timestamp_ns = result.message.shutter.timestamp_ns;
2057 if (last_timestamp_ns_for_trace_ != 0) {
2058 timestamp_ns_diff = current_timestamp_ns - last_timestamp_ns_for_trace_;
2059 }
2060
2061 last_timestamp_ns_for_trace_ = current_timestamp_ns;
2062
2063 ATRACE_INT64("sensor_timestamp_diff", timestamp_ns_diff);
2064 ATRACE_INT("timestamp_frame_number", result.message.shutter.frame_number);
2065 }
2066
2067 return true;
2068 }
2069
2070 } // namespace google_camera_hal
2071 } // namespace android
2072