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(¤t_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