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