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