blob: 03112ecc2f6dd0ff76d5f2a946fa49fa44418dbd [file] [log] [blame]
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001/*
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#ifndef ANDROID_SERVERS_CAMERA3_BUFFER_UTILS_H
18#define ANDROID_SERVERS_CAMERA3_BUFFER_UTILS_H
19
20#include <unordered_map>
21#include <mutex>
22#include <set>
23
24#include <cutils/native_handle.h>
25
26#include <android/hardware/camera/device/3.2/ICameraDevice.h>
27
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -080028#include <device3/Camera3OutputInterface.h>
29
30namespace android {
31
32namespace camera3 {
33
34 struct BufferHasher {
35 size_t operator()(const buffer_handle_t& buf) const {
36 if (buf == nullptr)
37 return 0;
38
39 size_t result = 1;
40 result = 31 * result + buf->numFds;
41 for (int i = 0; i < buf->numFds; i++) {
42 result = 31 * result + buf->data[i];
43 }
44 return result;
45 }
46 };
47
48 struct BufferComparator {
49 bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const {
50 if (buf1->numFds == buf2->numFds) {
51 for (int i = 0; i < buf1->numFds; i++) {
52 if (buf1->data[i] != buf2->data[i]) {
53 return false;
54 }
55 }
56 return true;
57 }
58 return false;
59 }
60 };
61
62 // Per stream buffer native handle -> bufId map
63 typedef std::unordered_map<const buffer_handle_t, uint64_t,
64 BufferHasher, BufferComparator> BufferIdMap;
65
66 // streamId -> BufferIdMap
67 typedef std::unordered_map<int, BufferIdMap> BufferIdMaps;
68
69 // Map of inflight buffers sent along in capture requests.
70 // Key is composed by (frameNumber << 32 | streamId)
71 typedef std::unordered_map<uint64_t, buffer_handle_t*> InflightBufferMap;
72
73 // Map of inflight buffers dealt by requestStreamBuffers API
74 typedef std::unordered_map<uint64_t, std::pair<int32_t, buffer_handle_t*>> RequestedBufferMap;
75
76 // A struct containing all buffer tracking information like inflight buffers
77 // and buffer ID caches
78 class BufferRecords : public BufferRecordsInterface {
79
80 public:
81 BufferRecords() {}
82
83 BufferRecords(BufferRecords&& other) :
84 mBufferIdMaps(other.mBufferIdMaps),
85 mNextBufferId(other.mNextBufferId),
86 mInflightBufferMap(other.mInflightBufferMap),
87 mRequestedBufferMap(other.mRequestedBufferMap) {}
88
89 virtual ~BufferRecords() {}
90
91 // Helper methods to help moving buffer records
92 void takeInflightBufferMap(BufferRecords& other);
93 void takeRequestedBufferMap(BufferRecords& other);
94 void takeBufferCaches(BufferRecords& other, const std::vector<int32_t>& streams);
95
96 // method to extract buffer's unique ID
97 // return pair of (newlySeenBuffer?, bufferId)
98 virtual std::pair<bool, uint64_t> getBufferId(
99 const buffer_handle_t& buf, int streamId) override;
100
101 void tryCreateBufferCache(int streamId);
102
103 void removeInactiveBufferCaches(const std::set<int32_t>& activeStreams);
104
105 // Return the removed buffer ID if input cache is found.
106 // Otherwise return BUFFER_ID_NO_BUFFER
Shuzhen Wangcd5b1822021-09-07 11:52:48 -0700107 uint64_t removeOneBufferCache(int streamId, const native_handle_t* handle) override;
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -0800108
109 // Clear all caches for input stream, but do not remove the stream
110 // Removed buffers' ID are returned
111 std::vector<uint64_t> clearBufferCaches(int streamId);
112
113 bool isStreamCached(int streamId);
114
115 // Return true if the input caches match what we have; otherwise false
116 bool verifyBufferIds(int32_t streamId, std::vector<uint64_t>& inBufIds);
117
118 // Get a vector of (frameNumber, streamId) pair of currently inflight
119 // buffers
120 void getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out);
121
122 status_t pushInflightBuffer(int32_t frameNumber, int32_t streamId,
123 buffer_handle_t *buffer);
124
125 // Find a buffer_handle_t based on frame number and stream ID
126 virtual status_t popInflightBuffer(int32_t frameNumber, int32_t streamId,
127 /*out*/ buffer_handle_t **buffer) override;
128
129 // Pop inflight buffers based on pairs of (frameNumber,streamId)
130 void popInflightBuffers(const std::vector<std::pair<int32_t, int32_t>>& buffers);
131
132 // Get a vector of bufferId of currently inflight buffers
133 void getInflightRequestBufferKeys(std::vector<uint64_t>* out);
134
135 // Register a bufId (streamId, buffer_handle_t) to inflight request buffer
136 virtual status_t pushInflightRequestBuffer(
137 uint64_t bufferId, buffer_handle_t* buf, int32_t streamId) override;
138
139 // Find a buffer_handle_t based on bufferId
140 virtual status_t popInflightRequestBuffer(uint64_t bufferId,
141 /*out*/ buffer_handle_t** buffer,
142 /*optional out*/ int32_t* streamId = nullptr) override;
143
144 private:
145 std::mutex mBufferIdMapLock;
146 BufferIdMaps mBufferIdMaps;
147 uint64_t mNextBufferId = 1; // 0 means no buffer
148
149 std::mutex mInflightLock;
150 InflightBufferMap mInflightBufferMap;
151
152 std::mutex mRequestedBuffersLock;
153 RequestedBufferMap mRequestedBufferMap;
154 }; // class BufferRecords
155
156 static const uint64_t BUFFER_ID_NO_BUFFER = 0;
157
Emilian Peevf4816702020-04-03 15:44:51 -0700158 camera_buffer_status_t mapHidlBufferStatus(
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -0800159 hardware::camera::device::V3_2::BufferStatus status);
160} // namespace camera3
161
162} // namespace android
163
164#endif