• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <device3/Camera3OutputInterface.h>
29 
30 namespace android {
31 
32 namespace camera3 {
33 
34     struct BufferHasher {
operatorBufferHasher35         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 {
operatorBufferComparator49         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:
BufferRecords()81         BufferRecords() {}
82 
BufferRecords(BufferRecords && other)83         BufferRecords(BufferRecords&& other) :
84                 mBufferIdMaps(other.mBufferIdMaps),
85                 mNextBufferId(other.mNextBufferId),
86                 mInflightBufferMap(other.mInflightBufferMap),
87                 mRequestedBufferMap(other.mRequestedBufferMap) {}
88 
~BufferRecords()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
107         uint64_t removeOneBufferCache(int streamId, const native_handle_t* handle);
108 
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 
158     camera_buffer_status_t mapHidlBufferStatus(
159             hardware::camera::device::V3_2::BufferStatus status);
160 } // namespace camera3
161 
162 } // namespace android
163 
164 #endif
165