Commit 5f6b1973 by Oliver Woodman

Allow direct and indirect buffer replacement.

Also tweak ManifestFetcher.
parent ae6e082d
......@@ -174,7 +174,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
this.eventHandler = eventHandler;
this.eventListener = eventListener;
codecCounters = new CodecCounters();
sampleHolder = new SampleHolder(false);
sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DISABLED);
formatHolder = new MediaFormatHolder();
decodeOnlyPresentationTimestamps = new HashSet<Long>();
outputBufferInfo = new MediaCodec.BufferInfo();
......
......@@ -23,10 +23,19 @@ import java.nio.ByteBuffer;
public final class SampleHolder {
/**
* Whether a {@link SampleSource} is permitted to replace {@link #data} if its current value is
* null or of insufficient size to hold the sample.
* Disallows buffer replacement.
*/
public final boolean allowDataBufferReplacement;
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;
public final CryptoInfo cryptoInfo;
......@@ -57,12 +66,34 @@ public final class SampleHolder {
*/
public boolean decodeOnly;
private final int bufferReplacementMode;
/**
* @param allowDataBufferReplacement See {@link #allowDataBufferReplacement}.
* @param bufferReplacementMode Determines the behavior of {@link #replaceBuffer(int)}. One of
* {@link #BUFFER_REPLACEMENT_MODE_DISABLED}, {@link #BUFFER_REPLACEMENT_MODE_NORMAL} and
* {@link #BUFFER_REPLACEMENT_MODE_DIRECT}.
*/
public SampleHolder(boolean allowDataBufferReplacement) {
public SampleHolder(int bufferReplacementMode) {
this.cryptoInfo = new CryptoInfo();
this.allowDataBufferReplacement = allowDataBufferReplacement;
this.bufferReplacementMode = bufferReplacementMode;
}
/**
* Attempts to replace {@link #data} with a {@link ByteBuffer} of the specified capacity.
*
* @param capacity The capacity of the replacement buffer, in bytes.
* @return True if the buffer was replaced. False otherwise.
*/
public boolean replaceBuffer(int capacity) {
switch (bufferReplacementMode) {
case BUFFER_REPLACEMENT_MODE_NORMAL:
data = ByteBuffer.allocate(capacity);
return true;
case BUFFER_REPLACEMENT_MODE_DIRECT:
data = ByteBuffer.allocateDirect(capacity);
return true;
}
return false;
}
}
......@@ -22,7 +22,6 @@ import com.google.android.exoplayer.upstream.DataSpec;
import com.google.android.exoplayer.upstream.NonBlockingInputStream;
import com.google.android.exoplayer.util.Assertions;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.UUID;
......@@ -97,9 +96,8 @@ public class SingleSampleMediaChunk extends MediaChunk {
if (headerData != null) {
sampleSize += headerData.length;
}
if (holder.allowDataBufferReplacement &&
(holder.data == null || holder.data.capacity() < sampleSize)) {
holder.data = ByteBuffer.allocate(sampleSize);
if (holder.data == null || holder.data.capacity() < sampleSize) {
holder.replaceBuffer(sampleSize);
}
int bytesRead;
if (holder.data != null) {
......
......@@ -1069,21 +1069,20 @@ public final class FragmentedMp4Extractor implements Extractor {
if (out == null) {
return RESULT_NEED_SAMPLE_HOLDER;
}
ByteBuffer outputData = out.data;
out.timeUs = fragmentRun.getSamplePresentationTime(sampleIndex) * 1000L;
out.flags = 0;
if (fragmentRun.sampleIsSyncFrameTable[sampleIndex]) {
out.flags |= MediaExtractor.SAMPLE_FLAG_SYNC;
lastSyncSampleIndex = sampleIndex;
}
if (out.allowDataBufferReplacement && (out.data == null || out.data.capacity() < sampleSize)) {
outputData = ByteBuffer.allocate(sampleSize);
out.data = outputData;
if (out.data == null || out.data.capacity() < sampleSize) {
out.replaceBuffer(sampleSize);
}
if (fragmentRun.definesEncryptionData) {
readSampleEncryptionData(fragmentRun.sampleEncryptionData, out);
}
ByteBuffer outputData = out.data;
if (outputData == null) {
inputStream.skip(sampleSize);
out.size = 0;
......
......@@ -347,13 +347,11 @@ public final class WebmExtractor implements Extractor {
throw new IllegalStateException("Lacing mode " + lacing + " not supported");
}
ByteBuffer outputData = sampleHolder.data;
if (sampleHolder.allowDataBufferReplacement
&& (sampleHolder.data == null || sampleHolder.data.capacity() < sampleHolder.size)) {
outputData = ByteBuffer.allocate(sampleHolder.size);
sampleHolder.data = outputData;
if (sampleHolder.data == null || sampleHolder.data.capacity() < sampleHolder.size) {
sampleHolder.replaceBuffer(sampleHolder.size);
}
ByteBuffer outputData = sampleHolder.data;
if (outputData == null) {
reader.skipBytes(inputStream, sampleHolder.size);
sampleHolder.size = 0;
......
......@@ -55,7 +55,7 @@ public class SubtitleParserHelper implements Handler.Callback {
* Flushes the helper, canceling the current parsing operation, if there is one.
*/
public synchronized void flush() {
sampleHolder = new SampleHolder(true);
sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
parsing = false;
result = null;
error = null;
......
......@@ -24,8 +24,8 @@ import android.util.Pair;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.CancellationException;
/**
......@@ -282,10 +282,10 @@ public class ManifestFetcher<T> implements Loader.Callback {
@Override
public void load() throws IOException, InterruptedException {
String inputEncoding = null;
String inputEncoding;
InputStream inputStream = null;
try {
HttpURLConnection connection = configureHttpConnection(new URL(manifestUrl));
URLConnection connection = configureConnection(new URL(manifestUrl));
inputStream = connection.getInputStream();
inputEncoding = connection.getContentEncoding();
result = parser.parse(inputStream, inputEncoding, contentId,
......@@ -297,8 +297,8 @@ public class ManifestFetcher<T> implements Loader.Callback {
}
}
private HttpURLConnection configureHttpConnection(URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
private URLConnection configureConnection(URL url) throws IOException {
URLConnection connection = url.openConnection();
connection.setConnectTimeout(TIMEOUT_MILLIS);
connection.setReadTimeout(TIMEOUT_MILLIS);
connection.setDoOutput(false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment