Remove DecoderInputBuffer.size

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=122146105
This commit is contained in:
olly 2016-05-12 04:38:03 -07:00 committed by Oliver Woodman
parent f9f95d638b
commit 68d39b5159
17 changed files with 106 additions and 84 deletions

View file

@ -77,18 +77,14 @@ import java.util.List;
if (reset) {
decoder.flush();
}
ByteBuffer data = inputBuffer.data;
outputBuffer.timestampUs = inputBuffer.timeUs;
data.limit(data.position());
data.position(data.position() - inputBuffer.size);
outputBuffer.init(maxOutputBufferSize);
decoder.setData(data);
int result = decoder.decodeSample(outputBuffer.data);
decoder.setData(inputBuffer.data);
ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, maxOutputBufferSize);
int result = decoder.decodeSample(outputData);
if (result < 0) {
return new FlacDecoderException("Frame decoding failed");
}
outputBuffer.data.position(0);
outputBuffer.data.limit(result);
outputData.position(0);
outputData.limit(result);
return null;
}

View file

@ -149,34 +149,31 @@ import java.util.List;
opusReset(nativeDecoderContext);
// When seeking to 0, skip number of samples as specified in opus header. When seeking to
// any other time, skip number of samples as specified by seek preroll.
skipSamples =
(inputBuffer.timeUs == 0) ? headerSkipSamples : headerSeekPreRollSamples;
skipSamples = (inputBuffer.timeUs == 0) ? headerSkipSamples : headerSeekPreRollSamples;
}
outputBuffer.timestampUs = inputBuffer.timeUs;
inputBuffer.data.position(inputBuffer.data.position() - inputBuffer.size);
int requiredOutputBufferSize =
opusGetRequiredOutputBufferSize(inputBuffer.data, inputBuffer.size, SAMPLE_RATE);
if (requiredOutputBufferSize < 0) {
ByteBuffer inputData = inputBuffer.data;
int inputSize = inputData.limit();
int outputSize = opusGetRequiredOutputBufferSize(inputData, inputSize, SAMPLE_RATE);
if (outputSize < 0) {
return new OpusDecoderException("Error when computing required output buffer size.");
}
outputBuffer.init(requiredOutputBufferSize);
int result = opusDecode(nativeDecoderContext, inputBuffer.data, inputBuffer.size,
outputBuffer.data, outputBuffer.data.capacity());
ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, outputSize);
int result = opusDecode(nativeDecoderContext, inputData, inputSize, outputData, outputSize);
if (result < 0) {
return new OpusDecoderException("Decode error: " + opusGetErrorMessage(result));
}
outputBuffer.data.position(0);
outputBuffer.data.limit(result);
outputData.position(0);
outputData.limit(result);
if (skipSamples > 0) {
int bytesPerSample = channelCount * 2;
int skipBytes = skipSamples * bytesPerSample;
if (result <= skipBytes) {
skipSamples -= result / bytesPerSample;
outputBuffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
outputBuffer.data.position(result);
outputData.position(result);
} else {
skipSamples = 0;
outputBuffer.data.position(skipBytes);
outputData.position(skipBytes);
}
}
return null;

View file

@ -108,7 +108,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
previousWidth = -1;
previousHeight = -1;
formatHolder = new FormatHolder();
outputMode = VpxDecoder.OUTPUT_MODE_UNKNOWN;
outputMode = VpxDecoder.OUTPUT_MODE_NONE;
}
/**
@ -281,6 +281,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
if (inputBuffer.isEndOfStream()) {
inputStreamEnded = true;
}
inputBuffer.flip();
decoder.queueInputBuffer(inputBuffer);
inputBuffer = null;
return true;
@ -377,7 +378,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
}
this.surface = surface;
outputBufferRenderer = null;
outputMode = (surface != null) ? VpxDecoder.OUTPUT_MODE_RGB : VpxDecoder.OUTPUT_MODE_UNKNOWN;
outputMode = (surface != null) ? VpxDecoder.OUTPUT_MODE_RGB : VpxDecoder.OUTPUT_MODE_NONE;
if (decoder != null) {
decoder.setOutputMode(outputMode);
}
@ -390,8 +391,8 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
}
this.outputBufferRenderer = outputBufferRenderer;
surface = null;
outputMode = (outputBufferRenderer != null)
? VpxDecoder.OUTPUT_MODE_YUV : VpxDecoder.OUTPUT_MODE_UNKNOWN;
outputMode = (outputBufferRenderer != null) ? VpxDecoder.OUTPUT_MODE_YUV
: VpxDecoder.OUTPUT_MODE_NONE;
if (decoder != null) {
decoder.setOutputMode(outputMode);
}

View file

@ -27,7 +27,7 @@ import java.nio.ByteBuffer;
/* package */ final class VpxDecoder extends
SimpleDecoder<DecoderInputBuffer, VpxOutputBuffer, VpxDecoderException> {
public static final int OUTPUT_MODE_UNKNOWN = -1;
public static final int OUTPUT_MODE_NONE = -1;
public static final int OUTPUT_MODE_YUV = 0;
public static final int OUTPUT_MODE_RGB = 1;
@ -77,8 +77,8 @@ import java.nio.ByteBuffer;
/**
* Sets the output mode for frames rendered by the decoder.
*
* @param outputMode The output mode to use, which must be one of the {@code OUTPUT_MODE_*}
* constants in {@link VpxDecoder}.
* @param outputMode The output mode. One of {@link #OUTPUT_MODE_NONE}, {@link #OUTPUT_MODE_RGB}
* and {@link #OUTPUT_MODE_YUV}.
*/
public void setOutputMode(int outputMode) {
this.outputMode = outputMode;
@ -102,12 +102,12 @@ import java.nio.ByteBuffer;
@Override
protected VpxDecoderException decode(DecoderInputBuffer inputBuffer, VpxOutputBuffer outputBuffer,
boolean reset) {
outputBuffer.timestampUs = inputBuffer.timeUs;
inputBuffer.data.position(inputBuffer.data.position() - inputBuffer.size);
if (vpxDecode(vpxDecContext, inputBuffer.data, inputBuffer.size) != 0) {
ByteBuffer inputData = inputBuffer.data;
int inputSize = inputData.limit();
if (vpxDecode(vpxDecContext, inputData, inputSize) != 0) {
return new VpxDecoderException("Decode error: " + vpxGetErrorMessage(vpxDecContext));
}
outputBuffer.mode = outputMode;
outputBuffer.init(inputBuffer.timeUs, outputMode);
if (vpxGetFrame(vpxDecContext, outputBuffer) != 0) {
outputBuffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
}

View file

@ -22,7 +22,7 @@ import java.nio.ByteBuffer;
/**
* Output buffer containing video frame data, populated by {@link VpxDecoder}.
*/
public final class VpxOutputBuffer extends OutputBuffer {
/* package */ final class VpxOutputBuffer extends OutputBuffer {
public static final int COLORSPACE_UNKNOWN = 0;
public static final int COLORSPACE_BT601 = 1;
@ -44,7 +44,7 @@ public final class VpxOutputBuffer extends OutputBuffer {
public int[] yuvStrides;
public int colorspace;
/* package */ VpxOutputBuffer(VpxDecoder owner) {
public VpxOutputBuffer(VpxDecoder owner) {
this.owner = owner;
}
@ -53,10 +53,22 @@ public final class VpxOutputBuffer extends OutputBuffer {
owner.releaseOutputBuffer(this);
}
/**
* Initializes the buffer.
*
* @param timestampUs The presentation timestamp for the buffer, in microseconds.
* @param mode The output mode. One of {@link VpxDecoder#OUTPUT_MODE_NONE},
* {@link VpxDecoder#OUTPUT_MODE_RGB} and {@link VpxDecoder#OUTPUT_MODE_YUV}.
*/
public void init(long timestampUs, int mode) {
this.timestampUs = timestampUs;
this.mode = mode;
}
/**
* Resizes the buffer based on the given dimensions. Called via JNI after decoding completes.
*/
/* package */ void initForRgbFrame(int width, int height) {
public void initForRgbFrame(int width, int height) {
this.width = width;
this.height = height;
this.yuvPlanes = null;
@ -68,7 +80,7 @@ public final class VpxOutputBuffer extends OutputBuffer {
/**
* Resizes the buffer based on the given stride. Called via JNI after decoding completes.
*/
/* package */ void initForYuvFrame(int width, int height, int yStride, int uvStride,
public void initForYuvFrame(int width, int height, int yStride, int uvStride,
int colorspace) {
this.width = width;
this.height = height;

View file

@ -49,11 +49,6 @@ public class DecoderInputBuffer extends Buffer {
*/
public ByteBuffer data;
/**
* The size of the data in bytes.
*/
public int size;
/**
* The time at which the sample should be presented.
*/
@ -114,6 +109,15 @@ public class DecoderInputBuffer extends Buffer {
return getFlag(C.BUFFER_FLAG_ENCRYPTED);
}
/**
* Flips {@link #data} in preparation for being queued to a decoder.
*
* @see java.nio.Buffer#flip()
*/
public final void flip() {
data.flip();
}
@Override
public void clear() {
super.clear();

View file

@ -250,13 +250,10 @@ public final class FrameworkSampleSource implements SampleSource {
}
int extractorTrackIndex = extractor.getSampleTrackIndex();
if (extractorTrackIndex == track) {
if (buffer.data != null) {
int offset = buffer.data.position();
buffer.size = extractor.readSampleData(buffer.data, offset);
buffer.data.position(offset + buffer.size);
} else {
buffer.size = 0;
}
ByteBuffer bufferData = buffer.data;
int offset = bufferData.position();
int size = extractor.readSampleData(bufferData, offset);
bufferData.position(offset + size);
buffer.timeUs = extractor.getSampleTime();
int flags = extractor.getSampleFlags();
if ((flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {

View file

@ -527,6 +527,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
int result;
int adaptiveReconfigurationBytes = 0;
if (waitingForKeys) {
// We've already read an encrypted sample into buffer, and are waiting for keys.
result = TrackStream.BUFFER_READ;
@ -540,6 +541,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
codecReconfigurationState = RECONFIGURATION_STATE_QUEUE_PENDING;
}
adaptiveReconfigurationBytes = buffer.data.position();
result = readSource(formatHolder, buffer);
}
@ -598,21 +600,20 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
codecNeedsDiscardToSpsWorkaround = false;
}
try {
int bufferSize = buffer.data.position();
int adaptiveReconfigurationBytes = bufferSize - buffer.size;
long presentationTimeUs = buffer.timeUs;
if (buffer.isDecodeOnly()) {
decodeOnlyPresentationTimestamps.add(presentationTimeUs);
}
onQueuedInputBuffer(presentationTimeUs, buffer.data, bufferSize, bufferEncrypted);
buffer.flip();
onQueueInputBuffer(buffer);
if (bufferEncrypted) {
MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(buffer,
adaptiveReconfigurationBytes);
codec.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0);
} else {
codec.queueInputBuffer(inputIndex, 0, bufferSize, presentationTimeUs, 0);
codec.queueInputBuffer(inputIndex, 0, buffer.data.limit(), presentationTimeUs, 0);
}
inputIndex = -1;
codecReceivedBuffers = true;
@ -705,13 +706,9 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
* <p>
* The default implementation is a no-op.
*
* @param presentationTimeUs The timestamp associated with the input buffer.
* @param buffer The buffer to be queued.
* @param bufferSize The size of the sample data stored in the buffer.
* @param bufferEncrypted Whether the buffer is encrypted.
*/
protected void onQueuedInputBuffer(long presentationTimeUs, ByteBuffer buffer, int bufferSize,
boolean bufferEncrypted) {
protected void onQueueInputBuffer(DecoderInputBuffer buffer) {
// Do nothing.
}

View file

@ -203,9 +203,8 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
return NOTHING_READ;
} else {
buffer.timeUs = 0;
buffer.size = sampleSize;
buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
buffer.ensureSpaceForWrite(buffer.size);
buffer.ensureSpaceForWrite(sampleSize);
buffer.data.put(sampleData, 0, sampleSize);
streamState = STREAM_STATE_END_OF_STREAM;
return BUFFER_READ;

View file

@ -58,9 +58,8 @@ public interface TrackStream {
*
* @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
* @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
* end of the stream. If the caller requires the sample data then it must ensure that
* {@link DecoderInputBuffer#data} references a valid buffer. If the end of the stream has
* been reached, the {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
* end of the stream. If the end of the stream has been reached, the
* {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
* @return The result, which can be {@link #NOTHING_READ}, {@link #FORMAT_READ} or
* {@link #BUFFER_READ}.
*/

View file

@ -217,9 +217,8 @@ public final class DefaultTrackOutput implements TrackOutput {
*
* @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
* @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
* end of the stream. If the caller requires the sample data then it must ensure that
* {@link DecoderInputBuffer#data} references a valid buffer. If the end of the stream has
* been reached, the {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
* end of the stream. If the end of the stream has been reached, the
* {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
* @param loadingFinished True if an empty queue should be considered the end of the stream.
* @param decodeOnlyUntilUs If a buffer is read, the {@link C#BUFFER_FLAG_DECODE_ONLY} flag will
* be set if the buffer's timestamp is less than this value.
@ -247,8 +246,8 @@ public final class DefaultTrackOutput implements TrackOutput {
readEncryptionData(buffer, extrasHolder);
}
// Write the sample data into the holder.
buffer.ensureSpaceForWrite(buffer.size);
readData(extrasHolder.offset, buffer.data, buffer.size);
buffer.ensureSpaceForWrite(extrasHolder.size);
readData(extrasHolder.offset, buffer.data, extrasHolder.size);
// Advance the read head.
dropDownstreamTo(extrasHolder.nextOffset);
return TrackStream.BUFFER_READ;
@ -261,7 +260,7 @@ public final class DefaultTrackOutput implements TrackOutput {
* Reads encryption data for the current sample.
* <p>
* The encryption data is written into {@link DecoderInputBuffer#cryptoInfo}, and
* {@link DecoderInputBuffer#size} is adjusted to subtract the number of bytes that were read. The
* {@link BufferExtrasHolder#size} is adjusted to subtract the number of bytes that were read. The
* same value is added to {@link BufferExtrasHolder#offset}.
*
* @param buffer The buffer into which the encryption data should be written.
@ -316,7 +315,7 @@ public final class DefaultTrackOutput implements TrackOutput {
}
} else {
clearDataSizes[0] = 0;
encryptedDataSizes[0] = buffer.size - (int) (offset - extrasHolder.offset);
encryptedDataSizes[0] = extrasHolder.size - (int) (offset - extrasHolder.offset);
}
// Populate the cryptoInfo.
@ -326,7 +325,7 @@ public final class DefaultTrackOutput implements TrackOutput {
// Adjust the offset and size to take into account the bytes read.
int bytesRead = (int) (offset - extrasHolder.offset);
extrasHolder.offset += bytesRead;
buffer.size -= bytesRead;
extrasHolder.size -= bytesRead;
}
/**
@ -633,10 +632,10 @@ public final class DefaultTrackOutput implements TrackOutput {
* @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
* @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
* end of the stream. If a sample is read then the buffer is populated with information
* about the sample, but not its data. The absolute position of the data in the rolling
* buffer is stored in {@code extrasHolder}, along with an encryption id if present and the
* absolute position of the first byte that may still be required after the current sample
* has been read.
* about the sample, but not its data. The size and absolute position of the data in the
* rolling buffer is stored in {@code extrasHolder}, along with an encryption id if present
* and the absolute position of the first byte that may still be required after the current
* sample has been read.
* @param downstreamFormat The current downstream {@link Format}. If the format of the next
* sample is different to the current downstream format then a format will be read.
* @param extrasHolder The holder into which extra sample information should be written.
@ -659,8 +658,8 @@ public final class DefaultTrackOutput implements TrackOutput {
}
buffer.timeUs = timesUs[relativeReadIndex];
buffer.size = sizes[relativeReadIndex];
buffer.setFlags(flags[relativeReadIndex]);
extrasHolder.size = sizes[relativeReadIndex];
extrasHolder.offset = offsets[relativeReadIndex];
extrasHolder.encryptionKeyId = encryptionKeys[relativeReadIndex];
@ -674,7 +673,7 @@ public final class DefaultTrackOutput implements TrackOutput {
}
extrasHolder.nextOffset = queueSize > 0 ? offsets[relativeReadIndex]
: extrasHolder.offset + buffer.size;
: extrasHolder.offset + extrasHolder.size;
return TrackStream.BUFFER_READ;
}
@ -830,6 +829,7 @@ public final class DefaultTrackOutput implements TrackOutput {
*/
private static final class BufferExtrasHolder {
public int size;
public long offset;
public long nextOffset;
public byte[] encryptionKeyId;

View file

@ -30,6 +30,7 @@ import android.os.Looper;
import android.os.Message;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A {@link TrackRenderer} for metadata embedded in a media stream.
@ -113,7 +114,9 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal
} else {
pendingMetadataTimestamp = buffer.timeUs;
try {
pendingMetadata = metadataParser.parse(buffer.data.array(), buffer.size);
buffer.flip();
ByteBuffer bufferData = buffer.data;
pendingMetadata = metadataParser.parse(bufferData.array(), bufferData.limit());
} catch (IOException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}

View file

@ -18,6 +18,8 @@ package com.google.android.exoplayer.text;
import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.util.extensions.SimpleDecoder;
import java.nio.ByteBuffer;
/**
* Base class for subtitle parsers that use their own decode thread.
*/
@ -54,7 +56,8 @@ public abstract class SimpleSubtitleParser extends
protected final ParserException decode(SubtitleInputBuffer inputBuffer,
SubtitleOutputBuffer outputBuffer, boolean reset) {
try {
Subtitle subtitle = decode(inputBuffer.data.array(), inputBuffer.size);
ByteBuffer inputData = inputBuffer.data;
Subtitle subtitle = decode(inputData.array(), inputData.limit());
outputBuffer.setOutput(inputBuffer.timeUs, subtitle, inputBuffer.subsampleOffsetUs);
return null;
} catch (ParserException e) {

View file

@ -95,7 +95,7 @@ public final class TextTrackRenderer extends TrackRenderer implements Callback {
public int getTrackType() {
return C.TRACK_TYPE_TEXT;
}
@Override
protected int supportsFormat(Format format) {
return parserFactory.supportsFormat(format) ? TrackRenderer.FORMAT_HANDLED
@ -197,6 +197,7 @@ public final class TextTrackRenderer extends TrackRenderer implements Callback {
} else {
nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
}
nextInputBuffer.flip();
parser.queueInputBuffer(nextInputBuffer);
nextInputBuffer = null;
} else if (result == TrackStream.NOTHING_READ) {

View file

@ -26,6 +26,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
import android.text.TextUtils;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.TreeSet;
@ -304,11 +305,13 @@ public final class Eia608Parser implements SubtitleParser {
}
private void decode(SubtitleInputBuffer inputBuffer) {
if (inputBuffer.size < 10) {
ByteBuffer inputData = inputBuffer.data;
int inputSize = inputData.limit();
if (inputSize < 10) {
return;
}
seiBuffer.reset(inputBuffer.data.array());
seiBuffer.reset(inputData.array(), inputSize);
// country_code (8) + provider_code (16) + user_identifier (32) + user_data_type_code (8) +
// reserved (1) + process_cc_data_flag (1) + zero_bit (1)
seiBuffer.skipBits(67);

View file

@ -207,6 +207,7 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
inputStreamEnded = true;
}
inputBuffer.flip();
decoder.queueInputBuffer(inputBuffer);
inputBuffer = null;
return true;

View file

@ -30,12 +30,21 @@ public class SimpleOutputBuffer extends OutputBuffer {
this.owner = owner;
}
public void init(int size) {
/**
* Initializes the buffer.
*
* @param timestampUs The presentation timestamp for the buffer, in microseconds.
* @param size An upper bound on the size of the data that will be written to the buffer.
* @return The {@link #data} buffer, for convenience.
*/
public ByteBuffer init(long timestampUs, int size) {
this.timestampUs = timestampUs;
if (data == null || data.capacity() < size) {
data = ByteBuffer.allocateDirect(size);
}
data.position(0);
data.limit(size);
return data;
}
@Override