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