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