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