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