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;