1 /* 2 * Copyright 2014,2016 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 #pragma once 18 19 #include <memory> 20 #include <unordered_set> 21 22 #include <camera/CameraMetadata.h> 23 24 #include <gui/BufferItemConsumer.h> 25 #include <gui/Surface.h> 26 27 #include <utils/Condition.h> 28 #include <utils/Mutex.h> 29 #include <utils/StrongPointer.h> 30 #include <utils/Timers.h> 31 32 #include "Flags.h" 33 34 #if USE_NEW_STREAM_SPLITTER // trying to do this for each change would be a huge hassle. 35 36 #define SP_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__) 37 #define SP_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__) 38 #define SP_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__) 39 #define SP_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__) 40 41 namespace android { 42 43 class GraphicBuffer; 44 45 // Camera3StreamSplitter is an autonomous class that manages one input BufferQueue 46 // and multiple output BufferQueues. By using the buffer attach and detach logic 47 // in BufferQueue, it is able to present the illusion of a single split 48 // BufferQueue, where each buffer queued to the input is available to be 49 // acquired by each of the outputs, and is able to be dequeued by the input 50 // again only once all of the outputs have released it. 51 class Camera3StreamSplitter : public BufferItemConsumer::FrameAvailableListener { 52 public: 53 // Constructor 54 Camera3StreamSplitter(bool useHalBufManager = false); 55 56 // Connect to the stream splitter by creating buffer queue and connecting it 57 // with output surfaces. 58 status_t connect(const std::unordered_map<size_t, sp<Surface>> &surfaces, 59 uint64_t consumerUsage, uint64_t producerUsage, size_t halMaxBuffers, uint32_t width, 60 uint32_t height, android::PixelFormat format, sp<Surface>* consumer, 61 int64_t dynamicRangeProfile); 62 63 // addOutput adds an output BufferQueue to the splitter. The splitter 64 // connects to outputQueue as a CPU producer, and any buffers queued 65 // to the input will be queued to each output. If any output is abandoned 66 // by its consumer, the splitter will abandon its input queue (see onAbandoned). 67 // 68 // A return value other than NO_ERROR means that an error has occurred and 69 // outputQueue has not been added to the splitter. BAD_VALUE is returned if 70 // outputQueue is NULL. See Surface::connect for explanations 71 // of other error codes. 72 status_t addOutput(size_t surfaceId, const sp<Surface>& outputQueue); 73 74 //removeOutput will remove a BufferQueue that was previously added to 75 //the splitter outputs. Any pending buffers in the BufferQueue will get 76 //reclaimed. 77 status_t removeOutput(size_t surfaceId); 78 79 // Notification that the graphic buffer has been released to the input 80 // BufferQueue. The buffer should be reused by the camera device instead of 81 // queuing to the outputs. 82 status_t notifyBufferReleased(const sp<GraphicBuffer>& buffer); 83 84 // Attach a buffer to the specified outputs. This call reserves a buffer 85 // slot in the output queue. 86 status_t attachBufferToOutputs(ANativeWindowBuffer* anb, 87 const std::vector<size_t>& surface_ids); 88 89 // Get return value of onFrameAvailable to work around problem that 90 // onFrameAvailable is void. This function should be called by the producer 91 // right after calling queueBuffer(). 92 status_t getOnFrameAvailableResult(); 93 94 // Disconnect the buffer queue from output surfaces. 95 void disconnect(); 96 97 void setHalBufferManager(bool enabled); 98 99 status_t setTransform(size_t surfaceId, int transform); 100 private: 101 // From BufferItemConsumer::FrameAvailableListener 102 // 103 // During this callback, we store some tracking information, detach the 104 // buffer from the input, and attach it to each of the outputs. This call 105 // can block if there are too many outstanding buffers. If it blocks, it 106 // will resume when onBufferReleasedByOutput releases a buffer back to the 107 // input. 108 void onFrameAvailable(const BufferItem& item) override; 109 110 // From BufferItemConsumer::FrameAvailableListener 111 // 112 // Similar to onFrameAvailable, but buffer item is indeed replacing a buffer 113 // in the buffer queue. This can happen when buffer queue is in droppable 114 // mode. 115 void onFrameReplaced(const BufferItem& item) override; 116 117 // This is the implementation of the onBufferReleased callback from 118 // IProducerListener. It gets called from an OutputListener (see below), and 119 // 'from' is which producer interface from which the callback was received. 120 // 121 // During this callback, we detach the buffer from the output queue that 122 // generated the callback, update our state tracking to see if this is the 123 // last output releasing the buffer, and if so, release it to the input. 124 // If we release the buffer to the input, we allow a blocked 125 // onFrameAvailable call to proceed. 126 void onBufferReleasedByOutput(const sp<Surface>& from); 127 128 // Called by outputBufferLocked when a buffer in the async buffer queue got replaced. 129 void onBufferReplacedLocked(const sp<Surface>& from, size_t surfaceId); 130 131 // When this is called, the splitter disconnects from (i.e., abandons) its 132 // input queue and signals any waiting onFrameAvailable calls to wake up. 133 // It still processes callbacks from other outputs, but only detaches their 134 // buffers so they can continue operating until they run out of buffers to 135 // acquire. This must be called with mMutex locked. 136 void onAbandonedLocked(); 137 138 // Decrement the buffer's reference count. Once the reference count becomes 139 // 0, return the buffer back to the input BufferQueue. 140 void decrementBufRefCountLocked(uint64_t id, size_t surfaceId); 141 142 // Check for and handle any output surface dequeue errors. 143 void handleOutputDequeueStatusLocked(status_t res, const sp<GraphicBuffer>& buffer); 144 145 // Handles released output surface buffers. 146 void returnOutputBufferLocked(const sp<Fence>& fence, const sp<Surface>& from, size_t surfaceId, 147 const sp<GraphicBuffer>& buffer); 148 149 // This is a thin wrapper class that lets us determine which BufferQueue 150 // the IProducerListener::onBufferReleased callback is associated with. We 151 // create one of these per output BufferQueue, and then pass the producer 152 // into onBufferReleasedByOutput above. 153 class OutputListener : public SurfaceListener { 154 public: 155 OutputListener(wp<Camera3StreamSplitter> splitter, wp<Surface> output); 156 virtual ~OutputListener() = default; 157 158 // From SurfaceListener 159 void onBufferReleased() override; needsReleaseNotify()160 bool needsReleaseNotify() override { return true; }; onBuffersDiscarded(const std::vector<sp<GraphicBuffer>> &)161 void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>&) override {} onBufferDetached(int)162 void onBufferDetached(int /*slot*/) override {} 163 164 void onRemoteDied() override; 165 166 private: 167 wp<Camera3StreamSplitter> mSplitter; 168 wp<Surface> mOutput; 169 }; 170 171 class BufferTracker { 172 public: 173 BufferTracker(const sp<GraphicBuffer>& buffer, 174 const std::vector<size_t>& requestedSurfaces); 175 ~BufferTracker() = default; 176 getBuffer()177 const sp<GraphicBuffer>& getBuffer() const { return mBuffer; } getMergedFence()178 const sp<Fence>& getMergedFence() const { return mMergedFence; } 179 180 void mergeFence(const sp<Fence>& with); 181 182 // Returns the new value 183 // Only called while mMutex is held 184 size_t decrementReferenceCountLocked(size_t surfaceId); 185 requestedSurfaces()186 const std::vector<size_t> requestedSurfaces() const { return mRequestedSurfaces; } 187 188 private: 189 // Disallow copying 190 BufferTracker(const BufferTracker& other); 191 BufferTracker& operator=(const BufferTracker& other); 192 193 sp<GraphicBuffer> mBuffer; // One instance that holds this native handle 194 sp<Fence> mMergedFence; 195 196 // Request surfaces for a particular buffer. And when the buffer becomes 197 // available from the input queue, the registered surfaces are used to decide 198 // which output is the buffer sent to. 199 std::vector<size_t> mRequestedSurfaces; 200 size_t mReferenceCount; 201 }; 202 203 // Must be accessed through RefBase 204 virtual ~Camera3StreamSplitter(); 205 206 status_t addOutputLocked(size_t surfaceId, const sp<Surface>& outputQueue); 207 208 status_t removeOutputLocked(size_t surfaceId); 209 210 // Send a buffer to particular output, and increment the reference count 211 // of the buffer. If this output is abandoned, the buffer's reference count 212 // won't be incremented. 213 status_t outputBufferLocked(const sp<Surface>& output, const BufferItem& bufferItem, 214 size_t surfaceId); 215 216 // Get unique name for the buffer queue consumer 217 std::string getUniqueConsumerName(); 218 219 // Sum of max consumer buffers for all outputs 220 size_t mMaxConsumerBuffers = 0; 221 size_t mMaxHalBuffers = 0; 222 uint32_t mWidth = 0; 223 uint32_t mHeight = 0; 224 android::PixelFormat mFormat = android::PIXEL_FORMAT_NONE; 225 uint64_t mProducerUsage = 0; 226 int mDynamicRangeProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD; 227 228 // The attachBuffer call will happen on different thread according to mUseHalBufManager and have 229 // different timing constraint. 230 static const nsecs_t kNormalDequeueBufferTimeout = s2ns(1); // 1 sec 231 static const nsecs_t kHalBufMgrDequeueBufferTimeout = ms2ns(1); // 1 msec 232 233 Mutex mMutex; 234 235 sp<BufferItemConsumer> mBufferItemConsumer; 236 sp<Surface> mSurface; 237 238 //Map surface ids -> gbp outputs 239 std::unordered_map<int, sp<Surface>> mOutputSurfaces; 240 241 // Map surface ids -> transform 242 std::unordered_map<int, int> mOutputTransforms; 243 244 //Map surface ids -> consumer buffer count 245 std::unordered_map<int, size_t > mConsumerBufferCount; 246 247 // Map of GraphicBuffer IDs (GraphicBuffer::getId()) to buffer tracking 248 // objects (which are mostly for counting how many outputs have released the 249 // buffer, but also contain merged release fences). 250 std::unordered_map<uint64_t, std::unique_ptr<BufferTracker> > mBuffers; 251 252 struct SurfaceHash { operatorSurfaceHash253 std::size_t operator()(const sp<Surface>& producer) const { 254 return std::hash<Surface*>{}(producer.get()); 255 } 256 }; 257 258 struct BufferHash { operatorBufferHash259 std::size_t operator()(const sp<GraphicBuffer>& buffer) const { 260 return std::hash<GraphicBuffer*>{}(buffer.get()); 261 } 262 }; 263 264 std::unordered_map<sp<Surface>, sp<OutputListener>, SurfaceHash> mNotifiers; 265 266 typedef std::unordered_set<sp<GraphicBuffer>, BufferHash> HeldBuffers; 267 std::unordered_map<sp<Surface>, std::unique_ptr<HeldBuffers>, SurfaceHash> mHeldBuffers; 268 269 //A set of buffers that could potentially stay in some of the outputs after removal 270 //and therefore should be detached from the input queue. 271 std::unordered_set<uint64_t> mDetachedBuffers; 272 273 // Latest onFrameAvailable return value 274 std::atomic<status_t> mOnFrameAvailableRes{0}; 275 276 // Currently acquired input buffers 277 size_t mAcquiredInputBuffers; 278 279 std::string mConsumerName; 280 281 bool mUseHalBufManager; 282 }; 283 284 } // namespace android 285 286 #endif // USE_NEW_STREAM_SPLITTER 287