android13/hardware/google/camera/common/hal/utils/zsl_buffer_manager.h

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