Add support for dynamic shared output surfaces

The Camera API needs to support the dynamic attach/detach of extra
output surfaces to a given camera stream.

Bug: 63912484
Change-Id: I18809aea31f78fb9e125bd18b58951ade4fad3c5
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 3b8839e..704f88f 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -51,22 +51,25 @@
 
     // Connect to the stream splitter by creating buffer queue and connecting it
     // with output surfaces.
-    status_t connect(const std::vector<sp<Surface> >& surfaces,
-            uint64_t consumerUsage, size_t halMaxBuffers,
-            sp<Surface>* consumer);
+    status_t connect(const std::unordered_map<size_t, sp<Surface>> &surfaces,
+            uint64_t consumerUsage, uint64_t producerUsage, size_t halMaxBuffers, uint32_t width,
+            uint32_t height, android::PixelFormat format, sp<Surface>* consumer);
 
     // addOutput adds an output BufferQueue to the splitter. The splitter
     // connects to outputQueue as a CPU producer, and any buffers queued
-    // to the input will be queued to each output. It is assumed that all of the
-    // outputs are added before any buffers are queued on the input. If any
-    // output is abandoned by its consumer, the splitter will abandon its input
-    // queue (see onAbandoned).
+    // to the input will be queued to each output. If any  output is abandoned
+    // by its consumer, the splitter will abandon its input queue (see onAbandoned).
     //
     // A return value other than NO_ERROR means that an error has occurred and
     // outputQueue has not been added to the splitter. BAD_VALUE is returned if
     // outputQueue is NULL. See IGraphicBufferProducer::connect for explanations
     // of other error codes.
-    status_t addOutput(const sp<Surface>& outputQueue);
+    status_t addOutput(size_t surfaceId, const sp<Surface>& outputQueue);
+
+    //removeOutput will remove a BufferQueue that was previously added to
+    //the splitter outputs. Any pending buffers in the BufferQueue will get
+    //reclaimed.
+    status_t removeOutput(size_t surfaceId);
 
     // Notification that the graphic buffer has been released to the input
     // BufferQueue. The buffer should be reused by the camera device instead of
@@ -120,7 +123,7 @@
     // This is the implementation of onBufferReleasedByOutput without the mutex locked.
     // It could either be called from onBufferReleasedByOutput or from
     // onFrameAvailable when a buffer in the async buffer queue is overwritten.
-    void onBufferReleasedByOutputLocked(const sp<IGraphicBufferProducer>& from);
+    void onBufferReleasedByOutputLocked(const sp<IGraphicBufferProducer>& from, size_t surfaceId);
 
     // When this is called, the splitter disconnects from (i.e., abandons) its
     // input queue and signals any waiting onFrameAvailable calls to wake up.
@@ -131,7 +134,7 @@
 
     // Decrement the buffer's reference count. Once the reference count becomes
     // 0, return the buffer back to the input BufferQueue.
-    void decrementBufRefCountLocked(uint64_t id, const sp<IGraphicBufferProducer>& from);
+    void decrementBufRefCountLocked(uint64_t id, size_t surfaceId);
 
     // This is a thin wrapper class that lets us determine which BufferQueue
     // the IProducerListener::onBufferReleased callback is associated with. We
@@ -168,7 +171,7 @@
 
         // Returns the new value
         // Only called while mMutex is held
-        size_t decrementReferenceCountLocked();
+        size_t decrementReferenceCountLocked(size_t surfaceId);
 
         const std::vector<size_t> requestedSurfaces() const { return mRequestedSurfaces; }
 
@@ -191,13 +194,15 @@
     // Must be accessed through RefBase
     virtual ~Camera3StreamSplitter();
 
-    status_t addOutputLocked(const sp<Surface>& outputQueue);
+    status_t addOutputLocked(size_t surfaceId, const sp<Surface>& outputQueue);
+
+    status_t removeOutputLocked(size_t surfaceId);
 
     // Send a buffer to particular output, and increment the reference count
     // of the buffer. If this output is abandoned, the buffer's reference count
     // won't be incremented.
     status_t outputBufferLocked(const sp<IGraphicBufferProducer>& output,
-            const BufferItem& bufferItem);
+            const BufferItem& bufferItem, size_t surfaceId);
 
     // Get unique name for the buffer queue consumer
     String8 getUniqueConsumerName();
@@ -205,14 +210,14 @@
     // Helper function to get the BufferQueue slot where a particular buffer is attached to.
     int getSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
             const sp<GraphicBuffer>& gb);
-    // Helper function to remove the buffer from the BufferQueue slot
-    status_t removeSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
-            const sp<GraphicBuffer>& gb);
-
 
     // Sum of max consumer buffers for all outputs
     size_t mMaxConsumerBuffers = 0;
     size_t mMaxHalBuffers = 0;
+    uint32_t mWidth = 0;
+    uint32_t mHeight = 0;
+    android::PixelFormat mFormat = android::PIXEL_FORMAT_NONE;
+    uint64_t mProducerUsage = 0;
 
     static const nsecs_t kDequeueBufferTimeout   = s2ns(1); // 1 sec
 
@@ -223,7 +228,15 @@
     sp<BufferItemConsumer> mBufferItemConsumer;
     sp<Surface> mSurface;
 
-    std::vector<sp<IGraphicBufferProducer> > mOutputs;
+    //Map graphic buffer ids -> buffer items
+    std::unordered_map<uint64_t, BufferItem> mInputSlots;
+
+    //Map surface ids -> gbp outputs
+    std::unordered_map<int, sp<IGraphicBufferProducer> > mOutputs;
+
+    //Map surface ids -> consumer buffer count
+    std::unordered_map<int, size_t > mConsumerBufferCount;
+
     // Map of GraphicBuffer IDs (GraphicBuffer::getId()) to buffer tracking
     // objects (which are mostly for counting how many outputs have released the
     // buffer, but also contain merged release fences).