CCodec: handle delay config update

Bug: 130223947
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
Test: manual test with software codecs changing delay randomly
Change-Id: Ia574522a44df22f9638bc4049d7418843a76b57b
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
index f5d9fee..461fbd5 100644
--- a/media/codec2/sfplugin/CCodecBuffers.h
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -134,7 +134,18 @@
      */
     virtual std::unique_ptr<InputBuffers> toArrayMode(size_t size) = 0;
 
+    /**
+     * Release the buffer obtained from requestNewBuffer(), and create a deep
+     * copy clone of the buffer.
+     *
+     * \return  the deep copy clone of the buffer; nullptr if cloning is not
+     *          possible.
+     */
+    sp<Codec2Buffer> cloneAndReleaseBuffer(const sp<MediaCodecBuffer> &buffer);
+
 protected:
+    virtual sp<Codec2Buffer> createNewBuffer() = 0;
+
     // Pool to obtain blocks for input buffers.
     std::shared_ptr<C2BlockPool> mPool;
 
@@ -346,6 +357,12 @@
      */
     size_t numClientBuffers() const;
 
+    /**
+     * Return the number of buffers that are sent to the component but not
+     * returned back yet.
+     */
+    size_t numComponentBuffers() const;
+
 private:
     friend class BuffersArrayImpl;
 
@@ -446,6 +463,16 @@
     void realloc(std::function<sp<Codec2Buffer>()> alloc);
 
     /**
+     * Grow the array to the new size. It is a programming error to supply
+     * smaller size as the new size.
+     *
+     * \param newSize[in] new size of the array.
+     * \param alloc[in]   the alllocation function for client buffers to fill
+     *                    the new empty slots.
+     */
+    void grow(size_t newSize, std::function<sp<Codec2Buffer>()> alloc);
+
+    /**
      * Return the number of buffers that are sent to the client but not released
      * yet.
      */
@@ -506,8 +533,12 @@
 
     size_t numClientBuffers() const final;
 
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
 private:
     BuffersArrayImpl mImpl;
+    std::function<sp<Codec2Buffer>()> mAllocate;
 };
 
 class LinearInputBuffers : public InputBuffers {
@@ -529,18 +560,18 @@
 
     void flush() override;
 
-    std::unique_ptr<InputBuffers> toArrayMode(size_t size) final;
+    std::unique_ptr<InputBuffers> toArrayMode(size_t size) override;
 
     size_t numClientBuffers() const final;
 
-    /**
-     * Allocate a client buffer with the given size. This method may be
-     * overridden to support different kind of linear buffers (e.g. encrypted).
-     */
-    virtual sp<Codec2Buffer> alloc(size_t size);
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
+    FlexBuffersImpl mImpl;
 
 private:
-    FlexBuffersImpl mImpl;
+    static sp<Codec2Buffer> Alloc(
+            const std::shared_ptr<C2BlockPool> &pool, const sp<AMessage> &format);
 };
 
 class EncryptedLinearInputBuffers : public LinearInputBuffers {
@@ -556,18 +587,28 @@
 
     ~EncryptedLinearInputBuffers() override = default;
 
-    sp<Codec2Buffer> alloc(size_t size) override;
+    std::unique_ptr<InputBuffers> toArrayMode(size_t size) override;
+
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
 
 private:
-    C2MemoryUsage mUsage;
-    sp<MemoryDealer> mDealer;
-    sp<ICrypto> mCrypto;
-    int32_t mHeapSeqNum;
     struct Entry {
         std::weak_ptr<C2LinearBlock> block;
         sp<IMemory> memory;
+        int32_t heapSeqNum;
     };
-    std::vector<Entry> mMemoryVector;
+
+    static sp<Codec2Buffer> Alloc(
+            const std::shared_ptr<C2BlockPool> &pool,
+            const sp<AMessage> &format,
+            C2MemoryUsage usage,
+            const std::shared_ptr<std::vector<Entry>> &memoryVector);
+
+    C2MemoryUsage mUsage;
+    sp<MemoryDealer> mDealer;
+    sp<ICrypto> mCrypto;
+    std::shared_ptr<std::vector<Entry>> mMemoryVector;
 };
 
 class GraphicMetadataInputBuffers : public InputBuffers {
@@ -591,6 +632,9 @@
 
     size_t numClientBuffers() const final;
 
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
 private:
     FlexBuffersImpl mImpl;
     std::shared_ptr<C2AllocatorStore> mStore;
@@ -619,6 +663,9 @@
 
     size_t numClientBuffers() const final;
 
+protected:
+    sp<Codec2Buffer> createNewBuffer() override;
+
 private:
     FlexBuffersImpl mImpl;
     std::shared_ptr<LocalBufferPool> mLocalBufferPool;
@@ -658,6 +705,11 @@
     size_t numClientBuffers() const final {
         return 0u;
     }
+
+protected:
+    sp<Codec2Buffer> createNewBuffer() override {
+        return nullptr;
+    }
 };
 
 class OutputBuffersArray : public OutputBuffers {
@@ -704,6 +756,8 @@
 
     void getArray(Vector<sp<MediaCodecBuffer>> *array) const final;
 
+    size_t numClientBuffers() const final;
+
     /**
      * Reallocate the array, filled with buffers with the same size as given
      * buffer.
@@ -712,10 +766,17 @@
      */
     void realloc(const std::shared_ptr<C2Buffer> &c2buffer);
 
-    size_t numClientBuffers() const final;
+    /**
+     * Grow the array to the new size. It is a programming error to supply
+     * smaller size as the new size.
+     *
+     * \param newSize[in] new size of the array.
+     */
+    void grow(size_t newSize);
 
 private:
     BuffersArrayImpl mImpl;
+    std::function<sp<Codec2Buffer>()> mAlloc;
 };
 
 class FlexOutputBuffers : public OutputBuffers {
@@ -755,12 +816,15 @@
     virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0;
 
     /**
-     * Return an appropriate Codec2Buffer object for the type of buffers, to be
-     * used as an empty array buffer.
+     * Return a function that allocates an appropriate Codec2Buffer object for
+     * the type of buffers, to be used as an empty array buffer. The function
+     * must not refer to this pointer, since it may be used after this object
+     * destructs.
      *
-     * \return  appropriate Codec2Buffer object which can copy() from C2Buffers.
+     * \return  a function that allocates appropriate Codec2Buffer object,
+     *          which can copy() from C2Buffers.
      */
-    virtual sp<Codec2Buffer> allocateArrayBuffer() = 0;
+    virtual std::function<sp<Codec2Buffer>()> getAlloc() = 0;
 
 private:
     FlexBuffersImpl mImpl;
@@ -776,7 +840,7 @@
 
     sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
 
-    sp<Codec2Buffer> allocateArrayBuffer() override;
+    std::function<sp<Codec2Buffer>()> getAlloc() override;
 };
 
 class GraphicOutputBuffers : public FlexOutputBuffers {
@@ -786,7 +850,7 @@
 
     sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
 
-    sp<Codec2Buffer> allocateArrayBuffer() override;
+    std::function<sp<Codec2Buffer>()> getAlloc() override;
 };
 
 class RawGraphicOutputBuffers : public FlexOutputBuffers {
@@ -797,7 +861,7 @@
 
     sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override;
 
-    sp<Codec2Buffer> allocateArrayBuffer() override;
+    std::function<sp<Codec2Buffer>()> getAlloc() override;
 
 private:
     std::shared_ptr<LocalBufferPool> mLocalBufferPool;