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