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