stagefright: reuse buffers instead of cloning

In buffer array mode, the buffer reference is kept in clients of
MediaCodec, so allocating new buffer for new input/output does not
work in that case.

Bug: 32577275
Bug: 32579231
Test: use screenrecord and investigate the output file.
Test: cts-tradefed run cts-dev -m CtsMediaTestCases -t android.media.cts.EncodeDecodeTest
Change-Id: I26d89f6b5735094062b8a2027bcab4754576d574
diff --git a/include/media/MediaCodecBuffer.h b/include/media/MediaCodecBuffer.h
index 05aaa14..501c00b 100644
--- a/include/media/MediaCodecBuffer.h
+++ b/include/media/MediaCodecBuffer.h
@@ -58,13 +58,13 @@
     sp<AMessage> meta();
     sp<AMessage> format();
 
-    virtual sp<MediaCodecBuffer> clone(const sp<AMessage> &format);
+    void setFormat(const sp<AMessage> &format);
 
 private:
     MediaCodecBuffer() = delete;
 
     const sp<AMessage> mMeta;
-    const sp<AMessage> mFormat;
+    sp<AMessage> mFormat;
     const sp<ABuffer> mBuffer;
     MediaBufferBase *mMediaBufferBase;
 };
diff --git a/media/libmedia/MediaCodecBuffer.cpp b/media/libmedia/MediaCodecBuffer.cpp
index 2af31d0..59d6164 100644
--- a/media/libmedia/MediaCodecBuffer.cpp
+++ b/media/libmedia/MediaCodecBuffer.cpp
@@ -80,8 +80,9 @@
     return mFormat;
 }
 
-sp<MediaCodecBuffer> MediaCodecBuffer::clone(const sp<AMessage> &format) {
-    return new MediaCodecBuffer(format, mBuffer);
+void MediaCodecBuffer::setFormat(const sp<AMessage> &format) {
+    mMeta->clear();
+    mFormat = format;
 }
 
 }  // namespace android
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 094f5cc..2f97fac 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -5552,7 +5552,8 @@
     notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
     notify->setInt32("buffer-id", info->mBufferID);
 
-    notify->setObject("buffer", info->mData->clone(mCodec->mInputFormat));
+    info->mData->setFormat(mCodec->mInputFormat);
+    notify->setObject("buffer", info->mData);
     info->mData.clear();
 
     sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
@@ -5912,7 +5913,7 @@
 
             sp<AMessage> reply =
                 new AMessage(kWhatOutputBufferDrained, mCodec);
-            sp<MediaCodecBuffer> buffer = info->mData->clone(mCodec->mOutputFormat);
+            sp<MediaCodecBuffer> buffer = info->mData;
 
             if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
                 // pretend that output format has changed on the first frame (we used to do this)
@@ -5926,6 +5927,7 @@
                 // data space) so that we can set it if and once the buffer is rendered.
                 mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
             }
+            buffer->setFormat(mCodec->mOutputFormat);
 
             if (mCodec->usingMetadataOnEncoderOutput()) {
                 native_handle_t *handle = NULL;
diff --git a/media/libstagefright/BufferImpl.cpp b/media/libstagefright/BufferImpl.cpp
index 81fe0fe..37a40ec 100644
--- a/media/libstagefright/BufferImpl.cpp
+++ b/media/libstagefright/BufferImpl.cpp
@@ -34,10 +34,6 @@
       mMemory(mem) {
 }
 
-sp<MediaCodecBuffer> SharedMemoryBuffer::clone(const sp<AMessage> &format) {
-    return new SharedMemoryBuffer(format, mMemory);
-}
-
 SecureBuffer::SecureBuffer(const sp<AMessage> &format, const void *ptr, size_t size)
     : MediaCodecBuffer(format, new ABuffer(nullptr, size)),
       mPointer(ptr) {
@@ -50,12 +46,6 @@
       mHandle(handle) {
 }
 
-sp<MediaCodecBuffer> SecureBuffer::clone(const sp<AMessage> &format) {
-    return (mHandle == nullptr)
-            ? new SecureBuffer(format, mPointer, capacity())
-            : new SecureBuffer(format, mHandle, capacity());
-}
-
 void *SecureBuffer::getDestinationPointer() {
     return (void *)(mHandle == nullptr ? mPointer : mHandle->handle());
 }
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e617b24..80860db 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2390,7 +2390,6 @@
     }
 
     mAvailPortBuffers[portIndex].clear();
-    mPortBufferArrays[portIndex].clear();
 }
 
 size_t MediaCodec::updateBuffers(
@@ -2414,8 +2413,7 @@
 
             if (portIndex == kPortIndexInput && mCrypto != NULL) {
                 info->mSecureData = buffer;
-                info->mData = new SharedMemoryBuffer(
-                        buffer->format(), info->mSharedEncryptedBuffer);
+                info->mData = mPortBufferArrays[portIndex][i];
             } else {
                 info->mData = buffer;
             }
diff --git a/media/libstagefright/include/SecureBuffer.h b/media/libstagefright/include/SecureBuffer.h
index ac7399a..cf7933a 100644
--- a/media/libstagefright/include/SecureBuffer.h
+++ b/media/libstagefright/include/SecureBuffer.h
@@ -42,8 +42,6 @@
     void *getDestinationPointer();
     ICrypto::DestinationType getDestinationType();
 
-    virtual sp<MediaCodecBuffer> clone(const sp<AMessage> &format) override;
-
 private:
     SecureBuffer() = delete;
 
diff --git a/media/libstagefright/include/SharedMemoryBuffer.h b/media/libstagefright/include/SharedMemoryBuffer.h
index c52e5c5..1d7f7a6 100644
--- a/media/libstagefright/include/SharedMemoryBuffer.h
+++ b/media/libstagefright/include/SharedMemoryBuffer.h
@@ -34,8 +34,6 @@
 
     virtual ~SharedMemoryBuffer() = default;
 
-    virtual sp<MediaCodecBuffer> clone(const sp<AMessage> &format) override;
-
 private:
     SharedMemoryBuffer() = delete;