diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2022-08-22 20:13:22 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2022-08-22 20:13:22 +0000 |
commit | abba82cd9d33f7a7d176f75228ef769697450264 (patch) | |
tree | 31f1a3a085a6d20e7eac8a1b9d05a00dbd627222 /media | |
parent | e4611ad6375773f2c60639bf0a9932a3daa85aae (diff) | |
parent | 4a114c2f9c573a28cb4f34e96ffed5b0bfe214fc (diff) | |
download | base-abba82cd9d33f7a7d176f75228ef769697450264.tar.gz |
Merge "RELAND MediaCodec: don't cache buffers until requested" into tm-qpr-dev
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/MediaCodec.java | 131 |
1 files changed, 90 insertions, 41 deletions
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 8756f1e2266d..c08f5a293e1d 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -45,6 +45,7 @@ import java.nio.ByteOrder; import java.nio.ReadOnlyBufferException; import java.util.ArrayList; import java.util.Arrays; +import java.util.BitSet; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -1803,7 +1804,7 @@ final public class MediaCodec { synchronized(mBufferLock) { switch (mBufferMode) { case BUFFER_MODE_LEGACY: - validateInputByteBuffer(mCachedInputBuffers, index); + validateInputByteBufferLocked(mCachedInputBuffers, index); break; case BUFFER_MODE_BLOCK: while (mQueueRequests.size() <= index) { @@ -1832,7 +1833,7 @@ final public class MediaCodec { synchronized(mBufferLock) { switch (mBufferMode) { case BUFFER_MODE_LEGACY: - validateOutputByteBuffer(mCachedOutputBuffers, index, info); + validateOutputByteBufferLocked(mCachedOutputBuffers, index, info); break; case BUFFER_MODE_BLOCK: while (mOutputFrames.size() <= index) { @@ -2320,10 +2321,6 @@ final public class MediaCodec { */ public final void start() { native_start(); - synchronized(mBufferLock) { - cacheBuffers(true /* input */); - cacheBuffers(false /* input */); - } } private native final void native_start(); @@ -2380,8 +2377,10 @@ final public class MediaCodec { */ public final void flush() { synchronized(mBufferLock) { - invalidateByteBuffers(mCachedInputBuffers); - invalidateByteBuffers(mCachedOutputBuffers); + invalidateByteBuffersLocked(mCachedInputBuffers); + invalidateByteBuffersLocked(mCachedOutputBuffers); + mValidInputIndices.clear(); + mValidOutputIndices.clear(); mDequeuedInputBuffers.clear(); mDequeuedOutputBuffers.clear(); } @@ -2665,14 +2664,14 @@ final public class MediaCodec { + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. " + "Please use getQueueRequest() to queue buffers"); } - invalidateByteBuffer(mCachedInputBuffers, index); + invalidateByteBufferLocked(mCachedInputBuffers, index, true /* input */); mDequeuedInputBuffers.remove(index); } try { native_queueInputBuffer( index, offset, size, presentationTimeUs, flags); } catch (CryptoException | IllegalStateException e) { - revalidateByteBuffer(mCachedInputBuffers, index); + revalidateByteBuffer(mCachedInputBuffers, index, true /* input */); throw e; } } @@ -2935,14 +2934,14 @@ final public class MediaCodec { + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. " + "Please use getQueueRequest() to queue buffers"); } - invalidateByteBuffer(mCachedInputBuffers, index); + invalidateByteBufferLocked(mCachedInputBuffers, index, true /* input */); mDequeuedInputBuffers.remove(index); } try { native_queueSecureInputBuffer( index, offset, info, presentationTimeUs, flags); } catch (CryptoException | IllegalStateException e) { - revalidateByteBuffer(mCachedInputBuffers, index); + revalidateByteBuffer(mCachedInputBuffers, index, true /* input */); throw e; } } @@ -2976,7 +2975,7 @@ final public class MediaCodec { int res = native_dequeueInputBuffer(timeoutUs); if (res >= 0) { synchronized(mBufferLock) { - validateInputByteBuffer(mCachedInputBuffers, res); + validateInputByteBufferLocked(mCachedInputBuffers, res); } } return res; @@ -3573,10 +3572,10 @@ final public class MediaCodec { int res = native_dequeueOutputBuffer(info, timeoutUs); synchronized (mBufferLock) { if (res == INFO_OUTPUT_BUFFERS_CHANGED) { - cacheBuffers(false /* input */); + cacheBuffersLocked(false /* input */); } else if (res >= 0) { - validateOutputByteBuffer(mCachedOutputBuffers, res, info); - if (mHasSurface) { + validateOutputByteBufferLocked(mCachedOutputBuffers, res, info); + if (mHasSurface || mCachedOutputBuffers == null) { mDequeuedOutputInfos.put(res, info.dup()); } } @@ -3670,9 +3669,9 @@ final public class MediaCodec { synchronized(mBufferLock) { switch (mBufferMode) { case BUFFER_MODE_LEGACY: - invalidateByteBuffer(mCachedOutputBuffers, index); + invalidateByteBufferLocked(mCachedOutputBuffers, index, false /* input */); mDequeuedOutputBuffers.remove(index); - if (mHasSurface) { + if (mHasSurface || mCachedOutputBuffers == null) { info = mDequeuedOutputInfos.remove(index); } break; @@ -3824,15 +3823,24 @@ final public class MediaCodec { private ByteBuffer[] mCachedInputBuffers; private ByteBuffer[] mCachedOutputBuffers; + private BitSet mValidInputIndices = new BitSet(); + private BitSet mValidOutputIndices = new BitSet(); + private final BufferMap mDequeuedInputBuffers = new BufferMap(); private final BufferMap mDequeuedOutputBuffers = new BufferMap(); private final Map<Integer, BufferInfo> mDequeuedOutputInfos = new HashMap<Integer, BufferInfo>(); final private Object mBufferLock; - private final void invalidateByteBuffer( - @Nullable ByteBuffer[] buffers, int index) { - if (buffers != null && index >= 0 && index < buffers.length) { + private void invalidateByteBufferLocked( + @Nullable ByteBuffer[] buffers, int index, boolean input) { + if (buffers == null) { + if (index < 0) { + throw new IllegalStateException("index is negative (" + index + ")"); + } + BitSet indices = input ? mValidInputIndices : mValidOutputIndices; + indices.clear(index); + } else if (index >= 0 && index < buffers.length) { ByteBuffer buffer = buffers[index]; if (buffer != null) { buffer.setAccessible(false); @@ -3840,9 +3848,14 @@ final public class MediaCodec { } } - private final void validateInputByteBuffer( + private void validateInputByteBufferLocked( @Nullable ByteBuffer[] buffers, int index) { - if (buffers != null && index >= 0 && index < buffers.length) { + if (buffers == null) { + if (index < 0) { + throw new IllegalStateException("index is negative (" + index + ")"); + } + mValidInputIndices.set(index); + } else if (index >= 0 && index < buffers.length) { ByteBuffer buffer = buffers[index]; if (buffer != null) { buffer.setAccessible(true); @@ -3851,10 +3864,16 @@ final public class MediaCodec { } } - private final void revalidateByteBuffer( - @Nullable ByteBuffer[] buffers, int index) { + private void revalidateByteBuffer( + @Nullable ByteBuffer[] buffers, int index, boolean input) { synchronized(mBufferLock) { - if (buffers != null && index >= 0 && index < buffers.length) { + if (buffers == null) { + if (index < 0) { + throw new IllegalStateException("index is negative (" + index + ")"); + } + BitSet indices = input ? mValidInputIndices : mValidOutputIndices; + indices.set(index); + } else if (index >= 0 && index < buffers.length) { ByteBuffer buffer = buffers[index]; if (buffer != null) { buffer.setAccessible(true); @@ -3863,9 +3882,14 @@ final public class MediaCodec { } } - private final void validateOutputByteBuffer( + private void validateOutputByteBufferLocked( @Nullable ByteBuffer[] buffers, int index, @NonNull BufferInfo info) { - if (buffers != null && index >= 0 && index < buffers.length) { + if (buffers == null) { + if (index < 0) { + throw new IllegalStateException("index is negative (" + index + ")"); + } + mValidOutputIndices.set(index); + } else if (index >= 0 && index < buffers.length) { ByteBuffer buffer = buffers[index]; if (buffer != null) { buffer.setAccessible(true); @@ -3874,7 +3898,7 @@ final public class MediaCodec { } } - private final void invalidateByteBuffers(@Nullable ByteBuffer[] buffers) { + private void invalidateByteBuffersLocked(@Nullable ByteBuffer[] buffers) { if (buffers != null) { for (ByteBuffer buffer: buffers) { if (buffer != null) { @@ -3884,27 +3908,29 @@ final public class MediaCodec { } } - private final void freeByteBuffer(@Nullable ByteBuffer buffer) { + private void freeByteBufferLocked(@Nullable ByteBuffer buffer) { if (buffer != null /* && buffer.isDirect() */) { // all of our ByteBuffers are direct java.nio.NioUtils.freeDirectBuffer(buffer); } } - private final void freeByteBuffers(@Nullable ByteBuffer[] buffers) { + private void freeByteBuffersLocked(@Nullable ByteBuffer[] buffers) { if (buffers != null) { for (ByteBuffer buffer: buffers) { - freeByteBuffer(buffer); + freeByteBufferLocked(buffer); } } } - private final void freeAllTrackedBuffers() { + private void freeAllTrackedBuffers() { synchronized(mBufferLock) { - freeByteBuffers(mCachedInputBuffers); - freeByteBuffers(mCachedOutputBuffers); + freeByteBuffersLocked(mCachedInputBuffers); + freeByteBuffersLocked(mCachedOutputBuffers); mCachedInputBuffers = null; mCachedOutputBuffers = null; + mValidInputIndices.clear(); + mValidOutputIndices.clear(); mDequeuedInputBuffers.clear(); mDequeuedOutputBuffers.clear(); mQueueRequests.clear(); @@ -3912,14 +3938,31 @@ final public class MediaCodec { } } - private final void cacheBuffers(boolean input) { + private void cacheBuffersLocked(boolean input) { ByteBuffer[] buffers = null; try { buffers = getBuffers(input); - invalidateByteBuffers(buffers); + invalidateByteBuffersLocked(buffers); } catch (IllegalStateException e) { // we don't get buffers in async mode } + if (buffers != null) { + BitSet indices = input ? mValidInputIndices : mValidOutputIndices; + for (int i = 0; i < buffers.length; ++i) { + ByteBuffer buffer = buffers[i]; + if (buffer == null || !indices.get(i)) { + continue; + } + buffer.setAccessible(true); + if (!input) { + BufferInfo info = mDequeuedOutputInfos.get(i); + if (info != null) { + buffer.limit(info.offset + info.size).position(info.offset); + } + } + } + indices.clear(); + } if (input) { mCachedInputBuffers = buffers; } else { @@ -3955,6 +3998,9 @@ final public class MediaCodec { + "objects and attach to QueueRequest objects."); } if (mCachedInputBuffers == null) { + cacheBuffersLocked(true /* input */); + } + if (mCachedInputBuffers == null) { throw new IllegalStateException(); } // FIXME: check codec status @@ -3993,6 +4039,9 @@ final public class MediaCodec { + "Please use getOutputFrame to get output frames."); } if (mCachedOutputBuffers == null) { + cacheBuffersLocked(false /* input */); + } + if (mCachedOutputBuffers == null) { throw new IllegalStateException(); } // FIXME: check codec status @@ -4030,7 +4079,7 @@ final public class MediaCodec { } ByteBuffer newBuffer = getBuffer(true /* input */, index); synchronized (mBufferLock) { - invalidateByteBuffer(mCachedInputBuffers, index); + invalidateByteBufferLocked(mCachedInputBuffers, index, true /* input */); mDequeuedInputBuffers.put(index, newBuffer); } return newBuffer; @@ -4067,7 +4116,7 @@ final public class MediaCodec { } Image newImage = getImage(true /* input */, index); synchronized (mBufferLock) { - invalidateByteBuffer(mCachedInputBuffers, index); + invalidateByteBufferLocked(mCachedInputBuffers, index, true /* input */); mDequeuedInputBuffers.put(index, newImage); } return newImage; @@ -4103,7 +4152,7 @@ final public class MediaCodec { } ByteBuffer newBuffer = getBuffer(false /* input */, index); synchronized (mBufferLock) { - invalidateByteBuffer(mCachedOutputBuffers, index); + invalidateByteBufferLocked(mCachedOutputBuffers, index, false /* input */); mDequeuedOutputBuffers.put(index, newBuffer); } return newBuffer; @@ -4138,7 +4187,7 @@ final public class MediaCodec { } Image newImage = getImage(false /* input */, index); synchronized (mBufferLock) { - invalidateByteBuffer(mCachedOutputBuffers, index); + invalidateByteBufferLocked(mCachedOutputBuffers, index, false /* input */); mDequeuedOutputBuffers.put(index, newImage); } return newImage; |