• 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_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     idle_buffer_frame_counter_ = 0;
211     return;
212   }
213 
214   idle_buffer_frame_counter_++;
215   if (idle_buffer_frame_counter_ <= kMaxIdelBufferFrameCounter) {
216     return;
217   }
218 
219   std::vector<buffer_handle_t> unused_buffers;
220 
221   // When there are at least kMaxUnusedBuffers unused buffers, try to reduce
222   // the number of buffers to buffer_descriptor_.immediate_num_buffers.
223   while (buffers_.size() > buffer_descriptor_.immediate_num_buffers &&
224          empty_zsl_buffers_.size() > 0) {
225     buffer_handle_t buffer = empty_zsl_buffers_.back();
226     unused_buffers.push_back(buffer);
227     empty_zsl_buffers_.pop_back();
228     buffers_.erase(std::find(buffers_.begin(), buffers_.end(), buffer));
229   }
230 
231   if (kMemoryProfilingEnabled) {
232     ALOGI(
233         "%s: Freeing %zu buffers, res %ux%u, format %d, overall allocated "
234         "%zu buffers",
235         __FUNCTION__, unused_buffers.size(), buffer_descriptor_.width,
236         buffer_descriptor_.height, buffer_descriptor_.format, buffers_.size());
237   }
238 
239   buffer_allocator_->FreeBuffers(&unused_buffers);
240 }
241 
ReturnEmptyBuffer(buffer_handle_t buffer)242 status_t ZslBufferManager::ReturnEmptyBuffer(buffer_handle_t buffer) {
243   ATRACE_CALL();
244   if (buffer == kInvalidBufferHandle) {
245     ALOGE("%s: buffer is nullptr.", __FUNCTION__);
246     return BAD_VALUE;
247   }
248 
249   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
250   // Check whether the returned buffer is freed or not
251   auto exist_buffer = std::find(buffers_.begin(), buffers_.end(), buffer);
252   if (exist_buffer == buffers_.end()) {
253     ALOGE("%s: Buffer %p is invalid", __FUNCTION__, buffer);
254     return BAD_VALUE;
255   }
256 
257   auto empty_buffer = std::find(std::begin(empty_zsl_buffers_),
258                                 std::end(empty_zsl_buffers_), buffer);
259   if (empty_buffer != std::end(empty_zsl_buffers_)) {
260     ALOGE("%s: Buffer %p was already returned.", __FUNCTION__, buffer);
261     return ALREADY_EXISTS;
262   }
263 
264   empty_zsl_buffers_.push_back(buffer);
265   FreeUnusedBuffersLocked();
266   return OK;
267 }
268 
ReturnFilledBuffer(uint32_t frame_number,const StreamBuffer & buffer)269 status_t ZslBufferManager::ReturnFilledBuffer(uint32_t frame_number,
270                                               const StreamBuffer& buffer) {
271   ATRACE_CALL();
272   ZslBuffer zsl_buffer = {};
273   zsl_buffer.frame_number = frame_number;
274   zsl_buffer.buffer = buffer;
275 
276   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
277   if (partially_filled_zsl_buffers_.empty() ||
278       partially_filled_zsl_buffers_.find(frame_number) ==
279           partially_filled_zsl_buffers_.end()) {
280     // not able to distinguish these two cases through the current status
281     // of the partial buffer
282     ALOGV(
283         "%s: no entry for frame[%u] in ZslBufferManager. Not created or "
284         "has been removed",
285         __FUNCTION__, frame_number);
286 
287     zsl_buffer.metadata = nullptr;
288     partially_filled_zsl_buffers_[frame_number] = std::move(zsl_buffer);
289   } else if (partially_filled_zsl_buffers_[frame_number].buffer.buffer ==
290                  kInvalidBufferHandle &&
291              partially_filled_zsl_buffers_[frame_number].metadata != nullptr) {
292     ALOGV(
293         "%s: both buffer and metadata for frame[%u] are ready. Move to "
294         "filled_zsl_buffers_.",
295         __FUNCTION__, frame_number);
296 
297     zsl_buffer.metadata =
298         std::move(partially_filled_zsl_buffers_[frame_number].metadata);
299     filled_zsl_buffers_[frame_number] = std::move(zsl_buffer);
300     partially_filled_zsl_buffers_.erase(frame_number);
301   } else {
302     ALOGE(
303         "%s: the buffer for frame[%u] already returned or the metadata is "
304         "missing.",
305         __FUNCTION__, frame_number);
306     return INVALID_OPERATION;
307   }
308 
309   return OK;
310 }
311 
ReturnMetadata(uint32_t frame_number,const HalCameraMetadata * metadata)312 status_t ZslBufferManager::ReturnMetadata(uint32_t frame_number,
313                                           const HalCameraMetadata* metadata) {
314   ATRACE_CALL();
315   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
316 
317   ZslBuffer zsl_buffer = {};
318   zsl_buffer.frame_number = frame_number;
319   zsl_buffer.metadata = HalCameraMetadata::Clone(metadata);
320   if (zsl_buffer.metadata == nullptr) {
321     ALOGE("%s: Failed to Clone camera metadata.", __FUNCTION__);
322     return NO_MEMORY;
323   }
324 
325   if (partially_filled_zsl_buffers_.empty() ||
326       partially_filled_zsl_buffers_.find(frame_number) ==
327           partially_filled_zsl_buffers_.end()) {
328     // not able to distinguish these two cases through the current status of
329     // the partial buffer
330     ALOGV(
331         "%s: no entry for frame[%u] in ZslBufferManager. Not created or "
332         "has been removed",
333         __FUNCTION__, frame_number);
334 
335     zsl_buffer.buffer = {};
336     partially_filled_zsl_buffers_[frame_number] = std::move(zsl_buffer);
337   } else if (partially_filled_zsl_buffers_[frame_number].metadata == nullptr &&
338              partially_filled_zsl_buffers_[frame_number].buffer.buffer !=
339                  kInvalidBufferHandle) {
340     ALOGV(
341         "%s: both buffer and metadata for frame[%u] are ready. Move to "
342         "filled_zsl_buffers_.",
343         __FUNCTION__, frame_number);
344 
345     zsl_buffer.buffer = partially_filled_zsl_buffers_[frame_number].buffer;
346     filled_zsl_buffers_[frame_number] = std::move(zsl_buffer);
347     partially_filled_zsl_buffers_.erase(frame_number);
348   } else {
349     ALOGE(
350         "%s: the metadata for frame[%u] already returned or the buffer is "
351         "missing.",
352         __FUNCTION__, frame_number);
353     return INVALID_OPERATION;
354   }
355 
356   if (partially_filled_zsl_buffers_.size() > kMaxPartialZslBuffers) {
357     // Remove the oldest one if it exceeds the maximum number of partial ZSL
358     // buffers.
359     partially_filled_zsl_buffers_.erase(partially_filled_zsl_buffers_.begin());
360   }
361 
362   return OK;
363 }
364 
GetCurrentTimestampNs(int64_t * current_timestamp)365 status_t ZslBufferManager::GetCurrentTimestampNs(int64_t* current_timestamp) {
366   if (current_timestamp == nullptr) {
367     ALOGE("%s: current_timestamp is nullptr", __FUNCTION__);
368     return BAD_VALUE;
369   }
370 
371   struct timespec ts;
372   if (clock_gettime(CLOCK_BOOTTIME, &ts)) {
373     ALOGE("%s: Getting boot time failed.", __FUNCTION__);
374     return UNKNOWN_ERROR;
375   }
376 
377   static const int64_t kNsPerSec = 1000000000;
378   *current_timestamp = ts.tv_sec * kNsPerSec + ts.tv_nsec;
379   return OK;
380 }
381 
GetMostRecentZslBuffers(std::vector<ZslBuffer> * zsl_buffers,uint32_t num_buffers,uint32_t min_buffers)382 void ZslBufferManager::GetMostRecentZslBuffers(
383     std::vector<ZslBuffer>* zsl_buffers, uint32_t num_buffers,
384     uint32_t min_buffers) {
385   ATRACE_CALL();
386   if (zsl_buffers == nullptr) {
387     return;
388   }
389 
390   int64_t current_timestamp;
391   status_t res = GetCurrentTimestampNs(&current_timestamp);
392   if (res != OK) {
393     ALOGE("%s: Getting current timestamp failed: %s(%d)", __FUNCTION__,
394           strerror(-res), res);
395     return;
396   }
397 
398   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
399   if (filled_zsl_buffers_.size() < min_buffers) {
400     ALOGD("%s: Requested min_buffers = %u, ZslBufferManager only has %zu",
401           __FUNCTION__, min_buffers, filled_zsl_buffers_.size());
402     ALOGD("%s: Not enough ZSL buffers to get, returns empty zsl_buffers.",
403           __FUNCTION__);
404     return;
405   }
406 
407   num_buffers =
408       std::min(static_cast<uint32_t>(filled_zsl_buffers_.size()), num_buffers);
409   auto zsl_buffer_iter = filled_zsl_buffers_.begin();
410 
411   // Skip the older ones.
412   for (uint32_t i = 0; i < filled_zsl_buffers_.size() - num_buffers; i++) {
413     zsl_buffer_iter++;
414   }
415 
416   // Fallback to realtime pipeline capture if there are any flash-fired frame
417   // in zsl buffers with AE_MODE_ON_AUTO_FLASH.
418   camera_metadata_ro_entry entry = {};
419   res = zsl_buffer_iter->second.metadata->Get(ANDROID_CONTROL_AE_MODE, &entry);
420   if (res == OK && entry.data.u8[0] == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH) {
421     for (auto search_iter = filled_zsl_buffers_.begin();
422          search_iter != filled_zsl_buffers_.end(); search_iter++) {
423       res = search_iter->second.metadata->Get(ANDROID_FLASH_STATE, &entry);
424       if (res == OK && entry.count == 1) {
425         if (entry.data.u8[0] == ANDROID_FLASH_STATE_FIRED) {
426           ALOGD("%s: Returns empty zsl_buffers due to flash fired",
427                 __FUNCTION__);
428           return;
429         }
430       }
431     }
432   }
433 
434   for (uint32_t i = 0; i < num_buffers; i++) {
435     camera_metadata_ro_entry entry = {};
436     int64_t buffer_timestamp;
437     res =
438         zsl_buffer_iter->second.metadata->Get(ANDROID_SENSOR_TIMESTAMP, &entry);
439     if (res != OK || entry.count != 1) {
440       ALOGW("%s: Getting sensor timestamp failed: %s(%d)", __FUNCTION__,
441             strerror(-res), res);
442       return;
443     }
444 
445     buffer_timestamp = entry.data.i64[0];
446     // Only include recent buffers.
447     if (current_timestamp - buffer_timestamp < kMaxBufferTimestampDiff) {
448       zsl_buffers->push_back(std::move(zsl_buffer_iter->second));
449     }
450 
451     zsl_buffer_iter = filled_zsl_buffers_.erase(zsl_buffer_iter);
452   }
453 }
454 
ReturnZslBuffer(ZslBuffer zsl_buffer)455 void ZslBufferManager::ReturnZslBuffer(ZslBuffer zsl_buffer) {
456   ATRACE_CALL();
457   std::unique_lock<std::mutex> lock(zsl_buffers_lock_);
458   filled_zsl_buffers_[zsl_buffer.frame_number] = std::move(zsl_buffer);
459 }
460 
ReturnZslBuffers(std::vector<ZslBuffer> zsl_buffers)461 void ZslBufferManager::ReturnZslBuffers(std::vector<ZslBuffer> zsl_buffers) {
462   ATRACE_CALL();
463   for (auto& zsl_buffer : zsl_buffers) {
464     ReturnZslBuffer(std::move(zsl_buffer));
465   }
466 }
467 
IsPendingBufferEmpty()468 bool ZslBufferManager::IsPendingBufferEmpty() {
469   std::lock_guard<std::mutex> lock(pending_zsl_buffers_mutex);
470   bool empty = (pending_zsl_buffers_.size() == 0);
471   if (!empty) {
472     ALOGW("%s: Pending buffer is not empty:%zu.", __FUNCTION__,
473           pending_zsl_buffers_.size());
474     return false;
475   }
476 
477   return true;
478 }
479 
AddPendingBuffers(const std::vector<ZslBuffer> & buffers)480 void ZslBufferManager::AddPendingBuffers(const std::vector<ZslBuffer>& buffers) {
481   ATRACE_CALL();
482   std::lock_guard<std::mutex> lock(pending_zsl_buffers_mutex);
483   for (auto& buffer : buffers) {
484     ZslBuffer zsl_buffer = {
485         .frame_number = buffer.frame_number,
486         .buffer = buffer.buffer,
487         .metadata = HalCameraMetadata::Clone(buffer.metadata.get()),
488     };
489 
490     pending_zsl_buffers_.emplace(buffer.buffer.buffer, std::move(zsl_buffer));
491   }
492 }
493 
CleanPendingBuffers(std::vector<ZslBuffer> * buffers)494 status_t ZslBufferManager::CleanPendingBuffers(std::vector<ZslBuffer>* buffers) {
495   ATRACE_CALL();
496   if (buffers == nullptr) {
497     ALOGE("%s: buffers is nullptr", __FUNCTION__);
498     return BAD_VALUE;
499   }
500 
501   std::lock_guard<std::mutex> lock(pending_zsl_buffers_mutex);
502   if (pending_zsl_buffers_.empty()) {
503     ALOGE("%s: There is no empty buffer.", __FUNCTION__);
504     return BAD_VALUE;
505   }
506 
507   for (auto zsl_buffer_iter = pending_zsl_buffers_.begin();
508        zsl_buffer_iter != pending_zsl_buffers_.end(); zsl_buffer_iter++) {
509     buffers->push_back(std::move(zsl_buffer_iter->second));
510   }
511 
512   pending_zsl_buffers_.clear();
513   return OK;
514 }
515 
516 }  // namespace google_camera_hal
517 }  // namespace android
518