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_ZslBufferManager"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <cutils/properties.h>
21 #include <log/log.h>
22 #include <utils/Trace.h>
23 
24 #include <time.h>
25 
26 #include "zsl_buffer_manager.h"
27 
28 namespace android {
29 namespace google_camera_hal {
30 
ZslBufferManager(IHalBufferAllocator * allocator,int partial_result_count)31 ZslBufferManager::ZslBufferManager(IHalBufferAllocator* allocator,
32                                    int partial_result_count)
33     : kMemoryProfilingEnabled(
34           property_get_bool("persist.vendor.camera.hal.memoryprofile", false)),
35       buffer_allocator_(allocator),
36       partial_result_count_(partial_result_count) {
37 }
38 
~ZslBufferManager()39 ZslBufferManager::~ZslBufferManager() {
40   ATRACE_CALL();
41   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
42   if (buffer_allocator_ != nullptr) {
43     buffer_allocator_->FreeBuffers(&buffers_);
44   }
45 }
46 
AllocateBuffers(const HalBufferDescriptor & buffer_descriptor)47 status_t ZslBufferManager::AllocateBuffers(
48     const HalBufferDescriptor& buffer_descriptor) {
49   ATRACE_CALL();
50   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
51 
52   if (allocated_) {
53     ALOGE("%s: Buffer is already allocated.", __FUNCTION__);
54     return ALREADY_EXISTS;
55   }
56 
57   // Create a buffer allocator if the client doesn't specify one.
58   if (buffer_allocator_ == nullptr) {
59     // Create a buffer manager.
60     internal_buffer_allocator_ = GrallocBufferAllocator::Create();
61     if (internal_buffer_allocator_ == nullptr) {
62       ALOGE("%s: Creating a buffer manager failed.", __FUNCTION__);
63       return NO_MEMORY;
64     }
65 
66     buffer_allocator_ = internal_buffer_allocator_.get();
67   }
68 
69   uint32_t num_buffers = buffer_descriptor.immediate_num_buffers;
70   buffer_descriptor_ = buffer_descriptor;
71   status_t res = AllocateBuffersLocked(num_buffers);
72   if (res != OK) {
73     ALOGE("%s: Allocating %d buffers failed.", __FUNCTION__, num_buffers);
74     return res;
75   }
76 
77   allocated_ = true;
78   return OK;
79 }
80 
AllocateBuffersLocked(uint32_t buffer_number)81 status_t ZslBufferManager::AllocateBuffersLocked(uint32_t buffer_number) {
82   if (buffer_number + buffers_.size() > buffer_descriptor_.max_num_buffers) {
83     ALOGE("%s: allocate %d + exist %zu > max buffer number %d", __FUNCTION__,
84           buffer_number, buffers_.size(), buffer_descriptor_.max_num_buffers);
85     return NO_MEMORY;
86   }
87 
88   HalBufferDescriptor buffer_descriptor = buffer_descriptor_;
89   buffer_descriptor.immediate_num_buffers = buffer_number;
90   std::vector<buffer_handle_t> buffers;
91   status_t res = buffer_allocator_->AllocateBuffers(buffer_descriptor, &buffers);
92   if (res != OK) {
93     ALOGE("%s: AllocateBuffers fail.", __FUNCTION__);
94     return res;
95   }
96 
97   for (auto& buffer : buffers) {
98     if (buffer != kInvalidBufferHandle) {
99       buffers_.push_back(buffer);
100       empty_zsl_buffers_.push_back(buffer);
101     }
102   }
103 
104   if (buffers.size() != buffer_number) {
105     ALOGE("%s: allocate buffer failed. request %u, get %zu", __FUNCTION__,
106           buffer_number, buffers.size());
107     return NO_MEMORY;
108   }
109 
110   if (kMemoryProfilingEnabled) {
111     ALOGI(
112         "%s: Allocated %u buffers, res %ux%u, format %d, overall allocated "
113         "%zu buffers",
114         __FUNCTION__, buffer_number, buffer_descriptor_.width,
115         buffer_descriptor_.height, buffer_descriptor_.format, buffers_.size());
116   }
117 
118   return OK;
119 }
120 
GetEmptyBuffer()121 buffer_handle_t ZslBufferManager::GetEmptyBuffer() {
122   ATRACE_CALL();
123   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
124   if (!allocated_) {
125     ALOGE("%s: Buffers are not allocated.", __FUNCTION__);
126     return kInvalidBufferHandle;
127   }
128 
129   buffer_handle_t buffer = GetEmptyBufferLocked();
130   if (buffer == kInvalidBufferHandle) {
131     // Try to allocate one more buffer if there is no empty buffer.
132     status_t res = AllocateBuffersLocked(/*buffer_number=*/1);
133     if (res != OK) {
134       ALOGE("%s: Allocating one more buffer failed: %s(%d)", __FUNCTION__,
135             strerror(-res), res);
136       return kInvalidBufferHandle;
137     }
138 
139     buffer = GetEmptyBufferLocked();
140   }
141 
142   return buffer;
143 }
144 
GetEmptyBufferLocked()145 buffer_handle_t ZslBufferManager::GetEmptyBufferLocked() {
146   ATRACE_CALL();
147   buffer_handle_t buffer = kInvalidBufferHandle;
148 
149   // Get an empty buffer from empty ZSL buffer queue.
150   // If empty ZSL buffer queue is empty,
151   // Get the oldest buffer from filled ZSL buffer queue.
152   // If filled ZSL buffer queue is empty,
153   // Get the oldest buffer from the partially filled ZSL buffer queue.
154   if (empty_zsl_buffers_.size() > 0) {
155     buffer = empty_zsl_buffers_[0];
156     empty_zsl_buffers_.pop_front();
157   } else if (filled_zsl_buffers_.size() > 0) {
158     auto buffer_iter = filled_zsl_buffers_.begin();
159     buffer = buffer_iter->second.buffer.buffer;
160     filled_zsl_buffers_.erase(buffer_iter);
161   } else if (partially_filled_zsl_buffers_.size() > 0) {
162     auto buffer_iter = partially_filled_zsl_buffers_.begin();
163     while (buffer_iter != partially_filled_zsl_buffers_.end()) {
164       if (buffer_iter->second.partial_result == partial_result_count_) {
165         if (buffer_iter->second.buffer.buffer != kInvalidBufferHandle) {
166           ALOGE("%s: Invalid: both are ready in partial zsl queue.",
167                 __FUNCTION__);
168           // TODO: clean up resources in this invalid situation.
169           return kInvalidBufferHandle;
170         }
171         ALOGI(
172             "%s: Remove metadata-only buffer in partially filled zsl "
173             "buffer queue. Releasing the metadata resource.",
174             __FUNCTION__);
175       } else if (buffer_iter->second.buffer.buffer == kInvalidBufferHandle &&
176                  buffer_iter->second.partial_result == 0) {
177         ALOGE(
178             "%s: Invalid: both buffer and metadata are empty in partial "
179             "zsl queue.",
180             __FUNCTION__);
181         // TODO: clean up resources in this invalid situation.
182         return kInvalidBufferHandle;
183       } else {
184         ALOGI(
185             "%s: Get buffer-only empty buffer from partially filled zsl "
186             "buffer queue.",
187             __FUNCTION__);
188         buffer = buffer_iter->second.buffer.buffer;
189       }
190 
191       // remove whatever visited
192       buffer_iter = partially_filled_zsl_buffers_.erase(buffer_iter);
193 
194       if (buffer != kInvalidBufferHandle) {
195         break;
196       }
197     }
198 
199     if (buffer_iter == partially_filled_zsl_buffers_.end()) {
200       ALOGE("%s: No empty buffer available.", __FUNCTION__);
201     }
202   } else {
203     ALOGW("%s: No empty buffer available.", __FUNCTION__);
204   }
205 
206   return buffer;
207 }
208 
FreeUnusedBuffersLocked()209 void ZslBufferManager::FreeUnusedBuffersLocked() {
210   ATRACE_CALL();
211   if (empty_zsl_buffers_.size() <= kMaxUnusedBuffers ||
212       buffers_.size() <= buffer_descriptor_.immediate_num_buffers) {
213     idle_buffer_frame_counter_ = 0;
214     return;
215   }
216 
217   idle_buffer_frame_counter_++;
218   if (idle_buffer_frame_counter_ <= kMaxIdelBufferFrameCounter) {
219     return;
220   }
221 
222   std::vector<buffer_handle_t> unused_buffers;
223 
224   // When there are at least kMaxUnusedBuffers unused buffers, try to reduce
225   // the number of buffers to buffer_descriptor_.immediate_num_buffers.
226   while (buffers_.size() > buffer_descriptor_.immediate_num_buffers &&
227          empty_zsl_buffers_.size() > 0) {
228     buffer_handle_t buffer = empty_zsl_buffers_.back();
229     unused_buffers.push_back(buffer);
230     empty_zsl_buffers_.pop_back();
231     buffers_.erase(std::find(buffers_.begin(), buffers_.end(), buffer));
232   }
233 
234   if (kMemoryProfilingEnabled) {
235     ALOGI(
236         "%s: Freeing %zu buffers, res %ux%u, format %d, overall allocated "
237         "%zu buffers",
238         __FUNCTION__, unused_buffers.size(), buffer_descriptor_.width,
239         buffer_descriptor_.height, buffer_descriptor_.format, buffers_.size());
240   }
241 
242   buffer_allocator_->FreeBuffers(&unused_buffers);
243 }
244 
ReturnEmptyBuffer(buffer_handle_t buffer)245 status_t ZslBufferManager::ReturnEmptyBuffer(buffer_handle_t buffer) {
246   ATRACE_CALL();
247   if (buffer == kInvalidBufferHandle) {
248     ALOGE("%s: buffer is nullptr.", __FUNCTION__);
249     return BAD_VALUE;
250   }
251 
252   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
253   // Check whether the returned buffer is freed or not
254   auto exist_buffer = std::find(buffers_.begin(), buffers_.end(), buffer);
255   if (exist_buffer == buffers_.end()) {
256     ALOGE("%s: Buffer %p is invalid", __FUNCTION__, buffer);
257     return BAD_VALUE;
258   }
259 
260   auto empty_buffer = std::find(std::begin(empty_zsl_buffers_),
261                                 std::end(empty_zsl_buffers_), buffer);
262   if (empty_buffer != std::end(empty_zsl_buffers_)) {
263     ALOGE("%s: Buffer %p was already returned.", __FUNCTION__, buffer);
264     return ALREADY_EXISTS;
265   }
266 
267   empty_zsl_buffers_.push_back(buffer);
268   FreeUnusedBuffersLocked();
269   return OK;
270 }
271 
ReturnFilledBuffer(uint32_t frame_number,const StreamBuffer & buffer)272 status_t ZslBufferManager::ReturnFilledBuffer(uint32_t frame_number,
273                                               const StreamBuffer& buffer) {
274   ATRACE_CALL();
275   ZslBuffer zsl_buffer = {};
276   zsl_buffer.frame_number = frame_number;
277   zsl_buffer.buffer = buffer;
278 
279   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
280   if (partially_filled_zsl_buffers_.empty() ||
281       partially_filled_zsl_buffers_.find(frame_number) ==
282           partially_filled_zsl_buffers_.end()) {
283     // not able to distinguish these two cases through the current status
284     // of the partial buffer
285     ALOGV(
286         "%s: no entry for frame[%u] in ZslBufferManager. Not created or "
287         "has been removed",
288         __FUNCTION__, frame_number);
289 
290     zsl_buffer.metadata = nullptr;
291     partially_filled_zsl_buffers_[frame_number] = std::move(zsl_buffer);
292   } else if (partially_filled_zsl_buffers_[frame_number].buffer.buffer ==
293              kInvalidBufferHandle) {
294     partially_filled_zsl_buffers_[frame_number].buffer = buffer;
295     if (partially_filled_zsl_buffers_[frame_number].partial_result ==
296         partial_result_count_) {
297       ALOGV(
298           "%s: both buffer and metadata for frame[%u] are ready. Move to "
299           "filled_zsl_buffers_.",
300           __FUNCTION__, frame_number);
301       filled_zsl_buffers_[frame_number] =
302           std::move(partially_filled_zsl_buffers_[frame_number]);
303       partially_filled_zsl_buffers_.erase(frame_number);
304     }
305   } else {
306     ALOGE(
307         "%s: the buffer for frame[%u] already returned or the metadata is "
308         "missing.",
309         __FUNCTION__, frame_number);
310     return INVALID_OPERATION;
311   }
312 
313   return OK;
314 }
315 
ReturnMetadata(uint32_t frame_number,const HalCameraMetadata * metadata,int partial_result)316 status_t ZslBufferManager::ReturnMetadata(uint32_t frame_number,
317                                           const HalCameraMetadata* metadata,
318                                           int partial_result) {
319   ATRACE_CALL();
320   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
321 
322   ZslBuffer zsl_buffer = {};
323   zsl_buffer.frame_number = frame_number;
324   zsl_buffer.partial_result = partial_result;
325 
326   auto partially_filled_buffer_it =
327       partially_filled_zsl_buffers_.find(frame_number);
328   if (partially_filled_buffer_it == partially_filled_zsl_buffers_.end()) {
329     // not able to distinguish these two cases through the current status of
330     // the partial buffer
331     ALOGV(
332         "%s: no entry for frame[%u] in ZslBufferManager. Not created or "
333         "has been removed",
334         __FUNCTION__, frame_number);
335 
336     zsl_buffer.buffer = {};
337     zsl_buffer.metadata = HalCameraMetadata::Clone(metadata);
338     if (zsl_buffer.metadata == nullptr) {
339       ALOGE("%s: Failed to Clone camera metadata.", __FUNCTION__);
340       return NO_MEMORY;
341     }
342     partially_filled_zsl_buffers_[frame_number] = std::move(zsl_buffer);
343   } else if (partial_result < partial_result_count_) {
344     partially_filled_buffer_it->second.partial_result = partial_result;
345     // Need to wait for more partial results
346     if (partially_filled_buffer_it->second.metadata == nullptr) {
347       // This is the first partial result, clone to create an entry
348       partially_filled_buffer_it->second.metadata =
349           HalCameraMetadata::Clone(metadata);
350       if (partially_filled_buffer_it->second.metadata == nullptr) {
351         ALOGE("%s: Failed to Clone camera metadata.", __FUNCTION__);
352         return NO_MEMORY;
353       }
354     } else {
355       // Append to previously received partial results
356       partially_filled_buffer_it->second.metadata->Append(
357           metadata->GetRawCameraMetadata());
358     }
359   } else {
360     zsl_buffer.buffer = partially_filled_buffer_it->second.buffer;
361     partially_filled_buffer_it->second.partial_result = partial_result;
362     if (partially_filled_buffer_it->second.metadata == nullptr) {
363       // This will happen if partial_result_count_ == 1
364       partially_filled_buffer_it->second.metadata =
365           HalCameraMetadata::Clone(metadata);
366     } else {
367       // This is the last partial result, append it to the others
368       partially_filled_buffer_it->second.metadata->Append(
369           metadata->GetRawCameraMetadata());
370     }
371     if (partially_filled_buffer_it->second.buffer.buffer !=
372         kInvalidBufferHandle) {
373       ALOGV(
374           "%s: both buffer and metadata for frame[%u] are ready. Move to "
375           "filled_zsl_buffers_.",
376           __FUNCTION__, frame_number);
377       filled_zsl_buffers_[frame_number] =
378           std::move(partially_filled_buffer_it->second);
379       partially_filled_zsl_buffers_.erase(frame_number);
380     }
381   }
382 
383   if (partially_filled_zsl_buffers_.size() > kMaxPartialZslBuffers) {
384     // Remove the oldest one if it exceeds the maximum number of partial ZSL
385     // buffers.
386     partially_filled_zsl_buffers_.erase(partially_filled_zsl_buffers_.begin());
387   }
388 
389   return OK;
390 }
391 
GetCurrentTimestampNs(int64_t * current_timestamp)392 status_t ZslBufferManager::GetCurrentTimestampNs(int64_t* current_timestamp) {
393   if (current_timestamp == nullptr) {
394     ALOGE("%s: current_timestamp is nullptr", __FUNCTION__);
395     return BAD_VALUE;
396   }
397 
398   struct timespec ts;
399   if (clock_gettime(CLOCK_BOOTTIME, &ts)) {
400     ALOGE("%s: Getting boot time failed.", __FUNCTION__);
401     return UNKNOWN_ERROR;
402   }
403 
404   static const int64_t kNsPerSec = 1000000000;
405   *current_timestamp = ts.tv_sec * kNsPerSec + ts.tv_nsec;
406   return OK;
407 }
408 
GetMostRecentZslBuffers(std::vector<ZslBuffer> * zsl_buffers,uint32_t num_buffers,uint32_t min_buffers)409 void ZslBufferManager::GetMostRecentZslBuffers(
410     std::vector<ZslBuffer>* zsl_buffers, uint32_t num_buffers,
411     uint32_t min_buffers) {
412   ATRACE_CALL();
413   if (zsl_buffers == nullptr) {
414     return;
415   }
416 
417   int64_t current_timestamp;
418   status_t res = GetCurrentTimestampNs(&current_timestamp);
419   if (res != OK) {
420     ALOGE("%s: Getting current timestamp failed: %s(%d)", __FUNCTION__,
421           strerror(-res), res);
422     return;
423   }
424 
425   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
426   if (filled_zsl_buffers_.size() < min_buffers) {
427     ALOGD("%s: Requested min_buffers = %u, ZslBufferManager only has %zu",
428           __FUNCTION__, min_buffers, filled_zsl_buffers_.size());
429     ALOGD("%s: Not enough ZSL buffers to get, returns empty zsl_buffers.",
430           __FUNCTION__);
431     return;
432   }
433 
434   num_buffers =
435       std::min(static_cast<uint32_t>(filled_zsl_buffers_.size()), num_buffers);
436   auto zsl_buffer_iter = filled_zsl_buffers_.begin();
437 
438   // Skip the older ones.
439   for (uint32_t i = 0; i < filled_zsl_buffers_.size() - num_buffers; i++) {
440     zsl_buffer_iter++;
441   }
442 
443   // Fallback to realtime pipeline capture if there are any flash-fired frame
444   // in zsl buffers with AE_MODE_ON_AUTO_FLASH.
445   camera_metadata_ro_entry entry = {};
446   res = zsl_buffer_iter->second.metadata->Get(ANDROID_CONTROL_AE_MODE, &entry);
447   if (res == OK && entry.data.u8[0] == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH) {
448     for (auto search_iter = filled_zsl_buffers_.begin();
449          search_iter != filled_zsl_buffers_.end(); search_iter++) {
450       res = search_iter->second.metadata->Get(ANDROID_FLASH_STATE, &entry);
451       if (res == OK && entry.count == 1) {
452         if (entry.data.u8[0] == ANDROID_FLASH_STATE_FIRED) {
453           ALOGD("%s: Returns empty zsl_buffers due to flash fired",
454                 __FUNCTION__);
455           return;
456         }
457       }
458     }
459   }
460 
461   for (uint32_t i = 0; i < num_buffers; i++) {
462     camera_metadata_ro_entry entry = {};
463     int64_t buffer_timestamp;
464     res =
465         zsl_buffer_iter->second.metadata->Get(ANDROID_SENSOR_TIMESTAMP, &entry);
466     if (res != OK || entry.count != 1) {
467       ALOGW("%s: Getting sensor timestamp failed: %s(%d)", __FUNCTION__,
468             strerror(-res), res);
469       return;
470     }
471 
472     buffer_timestamp = entry.data.i64[0];
473     // Only include recent buffers.
474     if (current_timestamp - buffer_timestamp < kMaxBufferTimestampDiff) {
475       zsl_buffers->push_back(std::move(zsl_buffer_iter->second));
476       zsl_buffer_iter = filled_zsl_buffers_.erase(zsl_buffer_iter);
477     } else {
478       zsl_buffer_iter++;
479     }
480   }
481 }
482 
ReturnZslBuffer(ZslBuffer zsl_buffer)483 void ZslBufferManager::ReturnZslBuffer(ZslBuffer zsl_buffer) {
484   ATRACE_CALL();
485   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
486   filled_zsl_buffers_[zsl_buffer.frame_number] = std::move(zsl_buffer);
487 }
488 
ReturnZslBuffers(std::vector<ZslBuffer> zsl_buffers)489 void ZslBufferManager::ReturnZslBuffers(std::vector<ZslBuffer> zsl_buffers) {
490   ATRACE_CALL();
491   for (auto& zsl_buffer : zsl_buffers) {
492     ReturnZslBuffer(std::move(zsl_buffer));
493   }
494 }
495 
IsPendingBufferEmpty()496 bool ZslBufferManager::IsPendingBufferEmpty() {
497   std::lock_guard<std::mutex> lock(pending_zsl_buffers_mutex);
498   bool empty = (pending_zsl_buffers_.size() == 0);
499   if (!empty) {
500     ALOGW("%s: Pending buffer is not empty:%zu.", __FUNCTION__,
501           pending_zsl_buffers_.size());
502     return false;
503   }
504 
505   return true;
506 }
507 
AddPendingBuffers(const std::vector<ZslBuffer> & buffers)508 void ZslBufferManager::AddPendingBuffers(const std::vector<ZslBuffer>& buffers) {
509   ATRACE_CALL();
510   std::lock_guard<std::mutex> lock(pending_zsl_buffers_mutex);
511   for (auto& buffer : buffers) {
512     ZslBuffer zsl_buffer = {
513         .frame_number = buffer.frame_number,
514         .buffer = buffer.buffer,
515         .metadata = HalCameraMetadata::Clone(buffer.metadata.get()),
516     };
517 
518     pending_zsl_buffers_.emplace(buffer.buffer.buffer, std::move(zsl_buffer));
519   }
520 }
521 
CleanPendingBuffers(std::vector<ZslBuffer> * buffers)522 status_t ZslBufferManager::CleanPendingBuffers(std::vector<ZslBuffer>* buffers) {
523   ATRACE_CALL();
524   if (buffers == nullptr) {
525     ALOGE("%s: buffers is nullptr", __FUNCTION__);
526     return BAD_VALUE;
527   }
528 
529   std::lock_guard<std::mutex> lock(pending_zsl_buffers_mutex);
530   if (pending_zsl_buffers_.empty()) {
531     ALOGE("%s: There is no empty buffer.", __FUNCTION__);
532     return BAD_VALUE;
533   }
534 
535   for (auto zsl_buffer_iter = pending_zsl_buffers_.begin();
536        zsl_buffer_iter != pending_zsl_buffers_.end(); zsl_buffer_iter++) {
537     buffers->push_back(std::move(zsl_buffer_iter->second));
538   }
539 
540   pending_zsl_buffers_.clear();
541   return OK;
542 }
543 
544 }  // namespace google_camera_hal
545 }  // namespace android
546