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