196 lines
7.0 KiB
C++
196 lines
7.0 KiB
C++
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_BUFFER_MANAGER_H
|
|
#define HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_BUFFER_MANAGER_H
|
|
|
|
#include <utils/Errors.h>
|
|
#include <deque>
|
|
#include <functional>
|
|
#include <list>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
#include "gralloc_buffer_allocator.h"
|
|
#include "hal_buffer_allocator.h"
|
|
|
|
#include "hal_types.h"
|
|
|
|
namespace android {
|
|
namespace google_camera_hal {
|
|
|
|
// ZslBufferManager creates and manages ZSL buffers.
|
|
class ZslBufferManager {
|
|
public:
|
|
// allocator will be used to allocate buffers. If allocator is nullptr,
|
|
// GrallocBufferAllocator will be used to allocate buffers.
|
|
ZslBufferManager(IHalBufferAllocator* allocator = nullptr,
|
|
int partial_result_count = 1);
|
|
virtual ~ZslBufferManager();
|
|
|
|
// Defines a ZSL buffer.
|
|
struct ZslBuffer {
|
|
// Original frame number of this ZSL buffer captured by HAL.
|
|
uint32_t frame_number = 0;
|
|
// Buffer
|
|
StreamBuffer buffer;
|
|
// Original result metadata of this ZSL buffer captured by HAL.
|
|
std::unique_ptr<HalCameraMetadata> metadata;
|
|
// Last partial result received
|
|
int partial_result = 0;
|
|
};
|
|
|
|
// Allocate buffers. This can only be called once.
|
|
// The second call will return ALREADY_EXISTS.
|
|
status_t AllocateBuffers(const HalBufferDescriptor& buffer_descriptor);
|
|
|
|
// Get an empty buffer for capture. The caller can modify the buffer data
|
|
// but the buffer is owned by ZslBufferManager and
|
|
// must not be freed by the caller.
|
|
buffer_handle_t GetEmptyBuffer();
|
|
|
|
// Return an empty buffer that was previously obtained by GetEmptyBuffer().
|
|
status_t ReturnEmptyBuffer(buffer_handle_t buffer);
|
|
|
|
// Return the buffer part of a filled buffer
|
|
// that was previously obtained by GetEmptyBuffer().
|
|
status_t ReturnFilledBuffer(uint32_t frame_number, const StreamBuffer& buffer);
|
|
|
|
// Return the metadata part of a filled buffer
|
|
// that was previously obtained by GetEmptyBuffer().
|
|
// ZSL buffer manager will make a copy of metadata.
|
|
// The caller still owns metadata.
|
|
status_t ReturnMetadata(uint32_t frame_number,
|
|
const HalCameraMetadata* metadata, int partial_result);
|
|
|
|
// Get a number of the most recent ZSL buffers.
|
|
// If numBuffers is larger than available ZSL buffers,
|
|
// zslBuffers will contain all available ZSL buffers,
|
|
// i.e. zslBuffers.size() may be smaller than numBuffers.
|
|
// The buffer and metadata are owned by ZslBufferManager and
|
|
// must not be freed by the caller.
|
|
// minBuffers is the minimum number of buffers the
|
|
// zsl buffer manager should return. If this can not be satisfied
|
|
// (i.e. not enough ZSL buffers exist),
|
|
// this GetMostRecentZslBuffers returns an empty vector.
|
|
void GetMostRecentZslBuffers(std::vector<ZslBuffer>* zsl_buffers,
|
|
uint32_t num_buffers, uint32_t min_buffers);
|
|
|
|
// Return a ZSL buffer that was previously obtained by
|
|
// GetMostRecentZslBuffers().
|
|
void ReturnZslBuffer(ZslBuffer zsl_buffer);
|
|
|
|
// Return a vector of ZSL buffers that were previously obtained by
|
|
// GetMostRecentZslBuffers().
|
|
void ReturnZslBuffers(std::vector<ZslBuffer> zsl_buffers);
|
|
|
|
// Check ZslBuffers are allocated or not.
|
|
bool IsBufferAllocated() {
|
|
return allocated_;
|
|
};
|
|
|
|
// Check pending_zsl_buffers_ is empty or not.
|
|
bool IsPendingBufferEmpty();
|
|
|
|
// Add buffer map to pending_zsl_buffers_
|
|
void AddPendingBuffers(const std::vector<ZslBuffer>& buffers);
|
|
|
|
// Clean buffer map from pending_zsl_buffers_
|
|
status_t CleanPendingBuffers(std::vector<ZslBuffer>* buffers);
|
|
|
|
private:
|
|
static const uint32_t kMaxPartialZslBuffers = 100;
|
|
|
|
// Max timestamp difference of the ZSL buffer and current time. Used
|
|
// to discard old ZSL buffers.
|
|
static const int64_t kMaxBufferTimestampDiff = 1000000000; // 1 second
|
|
|
|
// Maximum number of unused buffers. When the number of unused buffers >
|
|
// kMaxUnusedBuffers, it will try to free excessive buffers.
|
|
static const uint32_t kMaxUnusedBuffers = 2;
|
|
|
|
// Maximum number of frames with enough unused buffers. When the number of
|
|
// counter > kMaxIdelBufferFrameCounter, it will try to free excessive
|
|
// buffers.
|
|
static const uint32_t kMaxIdelBufferFrameCounter = 300;
|
|
|
|
const bool kMemoryProfilingEnabled;
|
|
|
|
// Remove the oldest metadata.
|
|
status_t RemoveOldestMetadataLocked();
|
|
|
|
// Get current BOOT_TIME timestamp in nanoseconds
|
|
status_t GetCurrentTimestampNs(int64_t* current_timestamp);
|
|
|
|
// Allocate a number of buffers. Must be protected by zsl_buffers_lock_.
|
|
status_t AllocateBuffersLocked(uint32_t buffer_number);
|
|
|
|
// Get an empty buffer. Must be protected by zsl_buffers_lock_.
|
|
buffer_handle_t GetEmptyBufferLocked();
|
|
|
|
// Try to free unused buffers. Must be protected by zsl_buffers_lock_.
|
|
void FreeUnusedBuffersLocked();
|
|
|
|
bool allocated_ = false;
|
|
std::mutex zsl_buffers_lock_;
|
|
|
|
// Buffer manager for allocating the buffers. Protected by mZslBuffersLock.
|
|
std::unique_ptr<IHalBufferAllocator> internal_buffer_allocator_;
|
|
|
|
// external buffer allocator
|
|
IHalBufferAllocator* buffer_allocator_ = nullptr;
|
|
|
|
// Empty ZSL buffer queue. Protected by mZslBuffersLock.
|
|
std::deque<buffer_handle_t> empty_zsl_buffers_;
|
|
|
|
// Filled ZSL buffers. Map from frameNumber to ZslBuffer.
|
|
// Ordered from the oldest to the newest buffers.
|
|
// Protected by mZslBuffersLock.
|
|
std::map<uint32_t, ZslBuffer> filled_zsl_buffers_;
|
|
|
|
// Partially filled ZSL buffers. Either the metadata or
|
|
// the buffer is returned. Once the metadata and the buffer are both ready,
|
|
// the ZslBuffer will be moved to the filled_zsl_buffers_.
|
|
// Map from frameNumber to ZslBuffer. Ordered from the oldest to the newest
|
|
// buffers. filled_zsl_buffers_ protected by zsl_buffers_lock_.
|
|
std::map<uint32_t, ZslBuffer> partially_filled_zsl_buffers_;
|
|
|
|
// Store all allocated buffers return from GrallocBufferAllocator
|
|
std::vector<buffer_handle_t> buffers_;
|
|
|
|
std::mutex pending_zsl_buffers_mutex;
|
|
|
|
// Map from buffer handle to ZSL buffer. Protected by pending_zsl_buffers_mutex.
|
|
std::unordered_map<buffer_handle_t, ZslBuffer> pending_zsl_buffers_;
|
|
|
|
// Store the buffer descriptor when call AllocateBuffers()
|
|
// Use it for AllocateExtraBuffers()
|
|
HalBufferDescriptor buffer_descriptor_;
|
|
|
|
// Count the number when there are enough unused buffers.
|
|
uint32_t idle_buffer_frame_counter_ = 0;
|
|
|
|
// Partial result count reported by camera HAL
|
|
int partial_result_count_ = 1;
|
|
};
|
|
|
|
} // namespace google_camera_hal
|
|
} // namespace android
|
|
|
|
#endif // HARDWARE_GOOGLE_CAMERA_HAL_UTILS_ZSL_BUFFER_MANAGER_H
|