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