mirror of
https://github.com/androidx/media.git
synced 2025-05-11 17:49:52 +08:00
Async queueing: avoid extra memory allocations
When copying CryptoInfo for asynchronous input buffer queueing, re-use the destination CryptoInfo's arrays to avoid re-allocating memory. PiperOrigin-RevId: 295706771
This commit is contained in:
parent
ab21f885d4
commit
3fb8ab2545
@ -15,11 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.decoder;
|
package com.google.android.exoplayer2.decoder;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compatibility wrapper for {@link android.media.MediaCodec.CryptoInfo}.
|
* Compatibility wrapper for {@link android.media.MediaCodec.CryptoInfo}.
|
||||||
@ -121,25 +119,6 @@ public final class CryptoInfo {
|
|||||||
return frameworkCryptoInfo;
|
return frameworkCryptoInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Performs a deep copy to {@code cryptoInfo}. */
|
|
||||||
public void copyTo(android.media.MediaCodec.CryptoInfo cryptoInfo) {
|
|
||||||
// Update cryptoInfo fields directly because CryptoInfo.set performs an unnecessary
|
|
||||||
// object allocation on Android N.
|
|
||||||
cryptoInfo.numSubSamples = numSubSamples;
|
|
||||||
cryptoInfo.numBytesOfClearData = copyOrNull(numBytesOfClearData);
|
|
||||||
cryptoInfo.numBytesOfEncryptedData = copyOrNull(numBytesOfEncryptedData);
|
|
||||||
cryptoInfo.key = copyOrNull(key);
|
|
||||||
cryptoInfo.iv = copyOrNull(iv);
|
|
||||||
cryptoInfo.mode = mode;
|
|
||||||
if (Util.SDK_INT >= 24) {
|
|
||||||
android.media.MediaCodec.CryptoInfo.Pattern pattern = patternHolder.pattern;
|
|
||||||
android.media.MediaCodec.CryptoInfo.Pattern patternCopy =
|
|
||||||
new android.media.MediaCodec.CryptoInfo.Pattern(
|
|
||||||
pattern.getEncryptBlocks(), pattern.getSkipBlocks());
|
|
||||||
cryptoInfo.setPattern(patternCopy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @deprecated Use {@link #getFrameworkCryptoInfo()}. */
|
/** @deprecated Use {@link #getFrameworkCryptoInfo()}. */
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public android.media.MediaCodec.CryptoInfo getFrameworkCryptoInfoV16() {
|
public android.media.MediaCodec.CryptoInfo getFrameworkCryptoInfoV16() {
|
||||||
@ -169,16 +148,6 @@ public final class CryptoInfo {
|
|||||||
numBytesOfClearData[0] += count;
|
numBytesOfClearData[0] += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static int[] copyOrNull(@Nullable int[] array) {
|
|
||||||
return array != null ? Arrays.copyOf(array, array.length) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static byte[] copyOrNull(@Nullable byte[] array) {
|
|
||||||
return array != null ? Arrays.copyOf(array, array.length) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(24)
|
@RequiresApi(24)
|
||||||
private static final class PatternHolderV24 {
|
private static final class PatternHolderV24 {
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import com.google.android.exoplayer2.decoder.CryptoInfo;
|
|||||||
import com.google.android.exoplayer2.util.ConditionVariable;
|
import com.google.android.exoplayer2.util.ConditionVariable;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
@ -110,7 +111,7 @@ class AsynchronousMediaCodecBufferEnqueuer implements MediaCodecInputBufferEnque
|
|||||||
maybeThrowException();
|
maybeThrowException();
|
||||||
MessageParams messageParams = getMessageParams();
|
MessageParams messageParams = getMessageParams();
|
||||||
messageParams.setQueueParams(index, offset, /* size= */ 0, presentationTimeUs, flags);
|
messageParams.setQueueParams(index, offset, /* size= */ 0, presentationTimeUs, flags);
|
||||||
info.copyTo(messageParams.cryptoInfo);
|
copy(info, messageParams.cryptoInfo);
|
||||||
Message message =
|
Message message =
|
||||||
Util.castNonNull(handler).obtainMessage(MSG_QUEUE_SECURE_INPUT_BUFFER, messageParams);
|
Util.castNonNull(handler).obtainMessage(MSG_QUEUE_SECURE_INPUT_BUFFER, messageParams);
|
||||||
message.sendToTarget();
|
message.sendToTarget();
|
||||||
@ -271,4 +272,65 @@ class AsynchronousMediaCodecBufferEnqueuer implements MediaCodecInputBufferEnque
|
|||||||
}
|
}
|
||||||
return labelBuilder.toString();
|
return labelBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Performs a deep copy of {@code cryptoInfo} to {@code frameworkCryptoInfo}. */
|
||||||
|
private static void copy(
|
||||||
|
CryptoInfo cryptoInfo, android.media.MediaCodec.CryptoInfo frameworkCryptoInfo) {
|
||||||
|
// Update frameworkCryptoInfo fields directly because CryptoInfo.set performs an unnecessary
|
||||||
|
// object allocation on Android N.
|
||||||
|
frameworkCryptoInfo.numSubSamples = cryptoInfo.numSubSamples;
|
||||||
|
frameworkCryptoInfo.numBytesOfClearData =
|
||||||
|
copy(cryptoInfo.numBytesOfClearData, frameworkCryptoInfo.numBytesOfClearData);
|
||||||
|
frameworkCryptoInfo.numBytesOfEncryptedData =
|
||||||
|
copy(cryptoInfo.numBytesOfEncryptedData, frameworkCryptoInfo.numBytesOfEncryptedData);
|
||||||
|
frameworkCryptoInfo.key = copy(cryptoInfo.key, frameworkCryptoInfo.key);
|
||||||
|
frameworkCryptoInfo.iv = copy(cryptoInfo.iv, frameworkCryptoInfo.iv);
|
||||||
|
frameworkCryptoInfo.mode = cryptoInfo.mode;
|
||||||
|
if (Util.SDK_INT >= 24) {
|
||||||
|
android.media.MediaCodec.CryptoInfo.Pattern pattern =
|
||||||
|
new android.media.MediaCodec.CryptoInfo.Pattern(
|
||||||
|
cryptoInfo.encryptedBlocks, cryptoInfo.clearBlocks);
|
||||||
|
frameworkCryptoInfo.setPattern(pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies {@code src}, reusing {@code dst} if it's at least as long as {@code src}.
|
||||||
|
*
|
||||||
|
* @param src The source array.
|
||||||
|
* @param dst The destination array, which will be reused if it's at least as long as {@code src}.
|
||||||
|
* @return The copy, which may be {@code dst} if it was reused.
|
||||||
|
*/
|
||||||
|
private static int[] copy(int[] src, int[] dst) {
|
||||||
|
if (src == null) {
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst == null || dst.length < src.length) {
|
||||||
|
return Arrays.copyOf(src, src.length);
|
||||||
|
} else {
|
||||||
|
System.arraycopy(src, 0, dst, 0, src.length);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies {@code src}, reusing {@code dst} if it's at least as long as {@code src}.
|
||||||
|
*
|
||||||
|
* @param src The source array.
|
||||||
|
* @param dst The destination array, which will be reused if it's at least as long as {@code src}.
|
||||||
|
* @return The copy, which may be {@code dst} if it was reused.
|
||||||
|
*/
|
||||||
|
private static byte[] copy(byte[] src, byte[] dst) {
|
||||||
|
if (src == null) {
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst == null || dst.length < src.length) {
|
||||||
|
return Arrays.copyOf(src, src.length);
|
||||||
|
} else {
|
||||||
|
System.arraycopy(src, 0, dst, 0, src.length);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user