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