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