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