summaryrefslogtreecommitdiffstats
path: root/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java')
-rw-r--r--mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java209
1 files changed, 209 insertions, 0 deletions
diff --git a/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java
new file mode 100644
index 0000000000..254ecfdec8
--- /dev/null
+++ b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mozilla.thirdparty.com.google.android.exoplayer2.decoder;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.C;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
+
+/**
+ * Holds input for a decoder.
+ */
+public class DecoderInputBuffer extends Buffer {
+
+ /**
+ * The buffer replacement mode, which may disable replacement. One of {@link
+ * #BUFFER_REPLACEMENT_MODE_DISABLED}, {@link #BUFFER_REPLACEMENT_MODE_NORMAL} or {@link
+ * #BUFFER_REPLACEMENT_MODE_DIRECT}.
+ */
+ @Documented
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ BUFFER_REPLACEMENT_MODE_DISABLED,
+ BUFFER_REPLACEMENT_MODE_NORMAL,
+ BUFFER_REPLACEMENT_MODE_DIRECT
+ })
+ public @interface BufferReplacementMode {}
+ /**
+ * Disallows buffer replacement.
+ */
+ public static final int BUFFER_REPLACEMENT_MODE_DISABLED = 0;
+ /**
+ * Allows buffer replacement using {@link ByteBuffer#allocate(int)}.
+ */
+ public static final int BUFFER_REPLACEMENT_MODE_NORMAL = 1;
+ /**
+ * Allows buffer replacement using {@link ByteBuffer#allocateDirect(int)}.
+ */
+ public static final int BUFFER_REPLACEMENT_MODE_DIRECT = 2;
+
+ /**
+ * {@link CryptoInfo} for encrypted data.
+ */
+ public final CryptoInfo cryptoInfo;
+
+ /** The buffer's data, or {@code null} if no data has been set. */
+ @Nullable public ByteBuffer data;
+
+ // TODO: Remove this temporary signaling once end-of-stream propagation for clips using content
+ // protection is fixed. See [Internal: b/153326944] for details.
+ /**
+ * Whether the last attempt to read a sample into this buffer failed due to not yet having the DRM
+ * keys associated with the next sample.
+ */
+ public boolean waitingForKeys;
+
+ /**
+ * The time at which the sample should be presented.
+ */
+ public long timeUs;
+
+ /**
+ * Supplemental data related to the buffer, if {@link #hasSupplementalData()} returns true. If
+ * present, the buffer is populated with supplemental data from position 0 to its limit.
+ */
+ @Nullable public ByteBuffer supplementalData;
+
+ @BufferReplacementMode private final int bufferReplacementMode;
+
+ /**
+ * Creates a new instance for which {@link #isFlagsOnly()} will return true.
+ *
+ * @return A new flags only input buffer.
+ */
+ public static DecoderInputBuffer newFlagsOnlyInstance() {
+ return new DecoderInputBuffer(BUFFER_REPLACEMENT_MODE_DISABLED);
+ }
+
+ /**
+ * @param bufferReplacementMode Determines the behavior of {@link #ensureSpaceForWrite(int)}. One
+ * of {@link #BUFFER_REPLACEMENT_MODE_DISABLED}, {@link #BUFFER_REPLACEMENT_MODE_NORMAL} and
+ * {@link #BUFFER_REPLACEMENT_MODE_DIRECT}.
+ */
+ public DecoderInputBuffer(@BufferReplacementMode int bufferReplacementMode) {
+ this.cryptoInfo = new CryptoInfo();
+ this.bufferReplacementMode = bufferReplacementMode;
+ }
+
+ /**
+ * Clears {@link #supplementalData} and ensures that it's large enough to accommodate {@code
+ * length} bytes.
+ *
+ * @param length The length of the supplemental data that must be accommodated, in bytes.
+ */
+ @EnsuresNonNull("supplementalData")
+ public void resetSupplementalData(int length) {
+ if (supplementalData == null || supplementalData.capacity() < length) {
+ supplementalData = ByteBuffer.allocate(length);
+ } else {
+ supplementalData.clear();
+ }
+ }
+
+ /**
+ * Ensures that {@link #data} is large enough to accommodate a write of a given length at its
+ * current position.
+ *
+ * <p>If the capacity of {@link #data} is sufficient this method does nothing. If the capacity is
+ * insufficient then an attempt is made to replace {@link #data} with a new {@link ByteBuffer}
+ * whose capacity is sufficient. Data up to the current position is copied to the new buffer.
+ *
+ * @param length The length of the write that must be accommodated, in bytes.
+ * @throws IllegalStateException If there is insufficient capacity to accommodate the write and
+ * the buffer replacement mode of the holder is {@link #BUFFER_REPLACEMENT_MODE_DISABLED}.
+ */
+ @EnsuresNonNull("data")
+ public void ensureSpaceForWrite(int length) {
+ if (data == null) {
+ data = createReplacementByteBuffer(length);
+ return;
+ }
+ // Check whether the current buffer is sufficient.
+ int capacity = data.capacity();
+ int position = data.position();
+ int requiredCapacity = position + length;
+ if (capacity >= requiredCapacity) {
+ return;
+ }
+ // Instantiate a new buffer if possible.
+ ByteBuffer newData = createReplacementByteBuffer(requiredCapacity);
+ newData.order(data.order());
+ // Copy data up to the current position from the old buffer to the new one.
+ if (position > 0) {
+ data.flip();
+ newData.put(data);
+ }
+ // Set the new buffer.
+ data = newData;
+ }
+
+ /**
+ * Returns whether the buffer is only able to hold flags, meaning {@link #data} is null and
+ * its replacement mode is {@link #BUFFER_REPLACEMENT_MODE_DISABLED}.
+ */
+ public final boolean isFlagsOnly() {
+ return data == null && bufferReplacementMode == BUFFER_REPLACEMENT_MODE_DISABLED;
+ }
+
+ /**
+ * Returns whether the {@link C#BUFFER_FLAG_ENCRYPTED} flag is set.
+ */
+ public final boolean isEncrypted() {
+ return getFlag(C.BUFFER_FLAG_ENCRYPTED);
+ }
+
+ /**
+ * Flips {@link #data} and {@link #supplementalData} in preparation for being queued to a decoder.
+ *
+ * @see java.nio.Buffer#flip()
+ */
+ public final void flip() {
+ data.flip();
+ if (supplementalData != null) {
+ supplementalData.flip();
+ }
+ }
+
+ @Override
+ public void clear() {
+ super.clear();
+ if (data != null) {
+ data.clear();
+ }
+ if (supplementalData != null) {
+ supplementalData.clear();
+ }
+ waitingForKeys = false;
+ }
+
+ private ByteBuffer createReplacementByteBuffer(int requiredCapacity) {
+ if (bufferReplacementMode == BUFFER_REPLACEMENT_MODE_NORMAL) {
+ return ByteBuffer.allocate(requiredCapacity);
+ } else if (bufferReplacementMode == BUFFER_REPLACEMENT_MODE_DIRECT) {
+ return ByteBuffer.allocateDirect(requiredCapacity);
+ } else {
+ int currentCapacity = data == null ? 0 : data.capacity();
+ throw new IllegalStateException("Buffer too small (" + currentCapacity + " < "
+ + requiredCapacity + ")");
+ }
+ }
+
+}