Commit 1175f50f by andrewlewis Committed by Oliver Woodman

Partially merge InputBuffer and SampleHolder.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=117908518
parent 0d1ae1dd
Showing with 166 additions and 166 deletions
...@@ -194,7 +194,6 @@ public final class FrameworkSampleSource implements SampleSource { ...@@ -194,7 +194,6 @@ public final class FrameworkSampleSource implements SampleSource {
return TrackStream.FORMAT_READ; return TrackStream.FORMAT_READ;
} }
int extractorTrackIndex = extractor.getSampleTrackIndex(); int extractorTrackIndex = extractor.getSampleTrackIndex();
sampleHolder.flags = 0;
if (extractorTrackIndex == track) { if (extractorTrackIndex == track) {
if (sampleHolder.data != null) { if (sampleHolder.data != null) {
int offset = sampleHolder.data.position(); int offset = sampleHolder.data.position();
...@@ -206,17 +205,17 @@ public final class FrameworkSampleSource implements SampleSource { ...@@ -206,17 +205,17 @@ public final class FrameworkSampleSource implements SampleSource {
sampleHolder.timeUs = extractor.getSampleTime(); sampleHolder.timeUs = extractor.getSampleTime();
int flags = extractor.getSampleFlags(); int flags = extractor.getSampleFlags();
if ((flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) { if ((flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
sampleHolder.flags |= C.SAMPLE_FLAG_SYNC; sampleHolder.addFlag(C.SAMPLE_FLAG_SYNC);
} }
if ((flags & MediaExtractor.SAMPLE_FLAG_ENCRYPTED) != 0) { if ((flags & MediaExtractor.SAMPLE_FLAG_ENCRYPTED) != 0) {
sampleHolder.flags |= C.SAMPLE_FLAG_ENCRYPTED; sampleHolder.addFlag(C.SAMPLE_FLAG_ENCRYPTED);
sampleHolder.cryptoInfo.setFromExtractorV16(extractor); sampleHolder.cryptoInfo.setFromExtractorV16(extractor);
} }
pendingSeekPositionUs = C.UNKNOWN_TIME_US; pendingSeekPositionUs = C.UNKNOWN_TIME_US;
extractor.advance(); extractor.advance();
return TrackStream.SAMPLE_READ; return TrackStream.SAMPLE_READ;
} else if (extractorTrackIndex < 0) { } else if (extractorTrackIndex < 0) {
sampleHolder.flags |= C.SAMPLE_FLAG_END_OF_STREAM; sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
return TrackStream.END_OF_STREAM; return TrackStream.END_OF_STREAM;
} else { } else {
return TrackStream.NOTHING_READ; return TrackStream.NOTHING_READ;
......
...@@ -555,7 +555,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer ...@@ -555,7 +555,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
return false; return false;
} }
sampleHolder.data = inputBuffers[inputIndex]; sampleHolder.data = inputBuffers[inputIndex];
sampleHolder.clearData(); sampleHolder.clear();
} }
if (codecReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) { if (codecReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
...@@ -599,7 +599,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer ...@@ -599,7 +599,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) { if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
// We received two formats in a row. Clear the current buffer of any reconfiguration data // We received two formats in a row. Clear the current buffer of any reconfiguration data
// associated with the first format. // associated with the first format.
sampleHolder.clearData(); sampleHolder.clear();
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING; codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
} }
onInputFormatChanged(formatHolder); onInputFormatChanged(formatHolder);
...@@ -610,7 +610,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer ...@@ -610,7 +610,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
// We received a new format immediately before the end of the stream. We need to clear // We received a new format immediately before the end of the stream. We need to clear
// the corresponding reconfiguration data from the current buffer, but re-write it into // the corresponding reconfiguration data from the current buffer, but re-write it into
// a subsequent buffer if there are any (e.g. if the user seeks backwards). // a subsequent buffer if there are any (e.g. if the user seeks backwards).
sampleHolder.clearData(); sampleHolder.clear();
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING; codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
} }
inputStreamEnded = true; inputStreamEnded = true;
......
...@@ -15,12 +15,14 @@ ...@@ -15,12 +15,14 @@
*/ */
package com.google.android.exoplayer; package com.google.android.exoplayer;
import com.google.android.exoplayer.util.Buffer;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** /**
* Holds sample data and corresponding metadata. * Holds sample data and corresponding metadata.
*/ */
public final class SampleHolder { public class SampleHolder extends Buffer {
/** /**
* Disallows buffer replacement. * Disallows buffer replacement.
...@@ -37,10 +39,13 @@ public final class SampleHolder { ...@@ -37,10 +39,13 @@ public final class SampleHolder {
*/ */
public static final int BUFFER_REPLACEMENT_MODE_DIRECT = 2; public static final int BUFFER_REPLACEMENT_MODE_DIRECT = 2;
/**
* {@link CryptoInfo} for encrypted samples.
*/
public final CryptoInfo cryptoInfo; public final CryptoInfo cryptoInfo;
/** /**
* A buffer holding the sample data. * A buffer holding the sample data, or {@code null} if no sample data has been set.
*/ */
public ByteBuffer data; public ByteBuffer data;
...@@ -50,11 +55,6 @@ public final class SampleHolder { ...@@ -50,11 +55,6 @@ public final class SampleHolder {
public int size; public int size;
/** /**
* Flags that accompany the sample. A combination of the {@code C.SAMPLE_FLAG_*} constants.
*/
public int flags;
/**
* The time at which the sample should be presented. * The time at which the sample should be presented.
*/ */
public long timeUs; public long timeUs;
...@@ -108,30 +108,15 @@ public final class SampleHolder { ...@@ -108,30 +108,15 @@ public final class SampleHolder {
} }
/** /**
* Returns whether {@link #flags} has {@link C#SAMPLE_FLAG_ENCRYPTED} set. * Returns whether the sample has the {@link C#SAMPLE_FLAG_ENCRYPTED} flag set.
*/
public boolean isEncrypted() {
return (flags & C.SAMPLE_FLAG_ENCRYPTED) != 0;
}
/**
* Returns whether {@link #flags} has {@link C#SAMPLE_FLAG_DECODE_ONLY} set.
*/
public boolean isDecodeOnly() {
return (flags & C.SAMPLE_FLAG_DECODE_ONLY) != 0;
}
/**
* Returns whether {@link #flags} has {@link C#SAMPLE_FLAG_SYNC} set.
*/ */
public boolean isSyncFrame() { public final boolean isEncrypted() {
return (flags & C.SAMPLE_FLAG_SYNC) != 0; return getFlag(C.SAMPLE_FLAG_ENCRYPTED);
} }
/** @Override
* Clears {@link #data}. Does nothing if {@link #data} is null. public void clear() {
*/ super.clear();
public void clearData() {
if (data != null) { if (data != null) {
data.clear(); data.clear();
} }
......
...@@ -162,7 +162,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load ...@@ -162,7 +162,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
@Override @Override
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) { public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) {
if (state == STATE_END_OF_STREAM) { if (state == STATE_END_OF_STREAM) {
sampleHolder.flags = C.SAMPLE_FLAG_END_OF_STREAM; sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
return END_OF_STREAM; return END_OF_STREAM;
} else if (state == STATE_SEND_FORMAT) { } else if (state == STATE_SEND_FORMAT) {
formatHolder.format = format; formatHolder.format = format;
...@@ -176,7 +176,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load ...@@ -176,7 +176,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
} else { } else {
sampleHolder.timeUs = 0; sampleHolder.timeUs = 0;
sampleHolder.size = sampleSize; sampleHolder.size = sampleSize;
sampleHolder.flags = C.SAMPLE_FLAG_SYNC; sampleHolder.addFlag(C.SAMPLE_FLAG_SYNC);
sampleHolder.ensureSpaceForWrite(sampleHolder.size); sampleHolder.ensureSpaceForWrite(sampleHolder.size);
sampleHolder.data.put(sampleData, 0, sampleSize); sampleHolder.data.put(sampleData, 0, sampleSize);
state = STATE_END_OF_STREAM; state = STATE_END_OF_STREAM;
......
...@@ -273,15 +273,16 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -273,15 +273,16 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
if (!haveSamples) { if (!haveSamples) {
if (loadingFinished) { if (loadingFinished) {
sampleHolder.flags = C.SAMPLE_FLAG_END_OF_STREAM; sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
return END_OF_STREAM; return END_OF_STREAM;
} }
return NOTHING_READ; return NOTHING_READ;
} }
if (sampleQueue.getSample(sampleHolder)) { if (sampleQueue.getSample(sampleHolder)) {
boolean decodeOnly = sampleHolder.timeUs < lastSeekPositionUs; if (sampleHolder.timeUs < lastSeekPositionUs) {
sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0; sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY);
}
onSampleRead(currentChunk, sampleHolder); onSampleRead(currentChunk, sampleHolder);
return SAMPLE_READ; return SAMPLE_READ;
} }
......
...@@ -448,8 +448,9 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu ...@@ -448,8 +448,9 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
} }
if (sampleQueue.getSample(sampleHolder)) { if (sampleQueue.getSample(sampleHolder)) {
boolean decodeOnly = sampleHolder.timeUs < lastSeekPositionUs; if (sampleHolder.timeUs < lastSeekPositionUs) {
sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0; sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY);
}
if (havePendingNextSampleUs) { if (havePendingNextSampleUs) {
// Set the offset to make the timestamp of this sample equal to pendingNextSampleUs. // Set the offset to make the timestamp of this sample equal to pendingNextSampleUs.
sampleTimeOffsetUs = pendingNextSampleUs - sampleHolder.timeUs; sampleTimeOffsetUs = pendingNextSampleUs - sampleHolder.timeUs;
...@@ -460,7 +461,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu ...@@ -460,7 +461,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
} }
if (loadingFinished) { if (loadingFinished) {
sampleHolder.flags = C.SAMPLE_FLAG_END_OF_STREAM; sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
return TrackStream.END_OF_STREAM; return TrackStream.END_OF_STREAM;
} }
......
...@@ -135,8 +135,7 @@ import java.util.concurrent.LinkedBlockingDeque; ...@@ -135,8 +135,7 @@ import java.util.concurrent.LinkedBlockingDeque;
/** /**
* Fills {@code holder} with information about the current sample, but does not write its data. * Fills {@code holder} with information about the current sample, but does not write its data.
* <p> * <p>
* The fields set are {@link SampleHolder#size}, {@link SampleHolder#timeUs} and * Populates {@link SampleHolder#size}, {@link SampleHolder#timeUs} and the sample flags.
* {@link SampleHolder#flags}.
* *
* @param holder The holder into which the current sample information should be written. * @param holder The holder into which the current sample information should be written.
* @return True if the holder was filled. False if there is no current sample. * @return True if the holder was filled. False if there is no current sample.
...@@ -419,7 +418,7 @@ import java.util.concurrent.LinkedBlockingDeque; ...@@ -419,7 +418,7 @@ import java.util.concurrent.LinkedBlockingDeque;
* Indicates the end point for the current sample, making it available for consumption. * Indicates the end point for the current sample, making it available for consumption.
* *
* @param sampleTimeUs The sample timestamp. * @param sampleTimeUs The sample timestamp.
* @param flags Flags that accompany the sample. See {@link SampleHolder#flags}. * @param flags Flags that accompany the sample. See {@code C.SAMPLE_FLAG_*}.
* @param position The position of the sample data in the rolling buffer. * @param position The position of the sample data in the rolling buffer.
* @param size The size of the sample, in bytes. * @param size The size of the sample, in bytes.
* @param encryptionKey The encryption key associated with the sample, or null. * @param encryptionKey The encryption key associated with the sample, or null.
...@@ -528,8 +527,8 @@ import java.util.concurrent.LinkedBlockingDeque; ...@@ -528,8 +527,8 @@ import java.util.concurrent.LinkedBlockingDeque;
* The first entry in {@code offsetHolder} is filled with the absolute position of the sample's * The first entry in {@code offsetHolder} is filled with the absolute position of the sample's
* data in the rolling buffer. * data in the rolling buffer.
* <p> * <p>
* The fields set are {SampleHolder#size}, {SampleHolder#timeUs}, {SampleHolder#flags} and * Populates {@link SampleHolder#size}, {@link SampleHolder#timeUs}, the sample flags and
* {@code offsetHolder[0]}. * {@code extrasHolder}.
* *
* @param holder The holder into which the current sample information should be written. * @param holder The holder into which the current sample information should be written.
* @param extrasHolder The holder into which extra sample information should be written. * @param extrasHolder The holder into which extra sample information should be written.
...@@ -541,7 +540,7 @@ import java.util.concurrent.LinkedBlockingDeque; ...@@ -541,7 +540,7 @@ import java.util.concurrent.LinkedBlockingDeque;
} }
holder.timeUs = timesUs[relativeReadIndex]; holder.timeUs = timesUs[relativeReadIndex];
holder.size = sizes[relativeReadIndex]; holder.size = sizes[relativeReadIndex];
holder.flags = flags[relativeReadIndex]; holder.setFlags(flags[relativeReadIndex]);
extrasHolder.offset = offsets[relativeReadIndex]; extrasHolder.offset = offsets[relativeReadIndex];
extrasHolder.encryptionKeyId = encryptionKeys[relativeReadIndex]; extrasHolder.encryptionKeyId = encryptionKeys[relativeReadIndex];
return true; return true;
......
...@@ -17,7 +17,6 @@ package com.google.android.exoplayer.extractor; ...@@ -17,7 +17,6 @@ package com.google.android.exoplayer.extractor;
import com.google.android.exoplayer.C; import com.google.android.exoplayer.C;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.util.ParsableByteArray; import com.google.android.exoplayer.util.ParsableByteArray;
import java.io.EOFException; import java.io.EOFException;
...@@ -66,7 +65,7 @@ public interface TrackOutput { ...@@ -66,7 +65,7 @@ public interface TrackOutput {
* {@link #sampleData(ParsableByteArray, int)}. * {@link #sampleData(ParsableByteArray, int)}.
* *
* @param timeUs The media timestamp associated with the sample, in microseconds. * @param timeUs The media timestamp associated with the sample, in microseconds.
* @param flags Flags associated with the sample. See {@link SampleHolder#flags}. * @param flags Flags associated with the sample. See {@code C.SAMPLE_FLAG_*}.
* @param size The size of the sample data, in bytes. * @param size The size of the sample data, in bytes.
* @param offset The number of bytes that have been passed to * @param offset The number of bytes that have been passed to
* {@link #sampleData(ExtractorInput, int, boolean)} or * {@link #sampleData(ExtractorInput, int, boolean)} or
......
...@@ -331,13 +331,14 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -331,13 +331,14 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
} }
if (extractor.getSample(group, sampleHolder)) { if (extractor.getSample(group, sampleHolder)) {
boolean decodeOnly = sampleHolder.timeUs < lastSeekPositionUs; if (sampleHolder.timeUs < lastSeekPositionUs) {
sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0; sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY);
}
return TrackStream.SAMPLE_READ; return TrackStream.SAMPLE_READ;
} }
if (loadingFinished) { if (loadingFinished) {
sampleHolder.flags = C.SAMPLE_FLAG_END_OF_STREAM; sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
return TrackStream.END_OF_STREAM; return TrackStream.END_OF_STREAM;
} }
......
...@@ -101,7 +101,7 @@ public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer im ...@@ -101,7 +101,7 @@ public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer im
protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady) protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
throws ExoPlaybackException { throws ExoPlaybackException {
if (!inputStreamEnded && pendingMetadata == null) { if (!inputStreamEnded && pendingMetadata == null) {
sampleHolder.clearData(); sampleHolder.clear();
int result = readSource(formatHolder, sampleHolder); int result = readSource(formatHolder, sampleHolder);
if (result == TrackStream.SAMPLE_READ) { if (result == TrackStream.SAMPLE_READ) {
pendingMetadataTimestamp = sampleHolder.timeUs; pendingMetadataTimestamp = sampleHolder.timeUs;
......
...@@ -16,12 +16,11 @@ ...@@ -16,12 +16,11 @@
package com.google.android.exoplayer.text; package com.google.android.exoplayer.text;
import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.util.extensions.InputBuffer;
/** /**
* An input buffer for {@link SubtitleParser}. * An input buffer for {@link SubtitleParser}.
*/ */
/* package */ final class SubtitleInputBuffer extends InputBuffer { /* package */ final class SubtitleInputBuffer extends SampleHolder {
public long subsampleOffsetUs; public long subsampleOffsetUs;
......
...@@ -71,4 +71,10 @@ import java.util.List; ...@@ -71,4 +71,10 @@ import java.util.List;
owner.releaseOutputBuffer(this); owner.releaseOutputBuffer(this);
} }
@Override
public void clear() {
super.clear();
subtitle = null;
}
} }
...@@ -48,10 +48,8 @@ public abstract class SubtitleParser extends ...@@ -48,10 +48,8 @@ public abstract class SubtitleParser extends
protected final ParserException decode(SubtitleInputBuffer inputBuffer, protected final ParserException decode(SubtitleInputBuffer inputBuffer,
SubtitleOutputBuffer outputBuffer) { SubtitleOutputBuffer outputBuffer) {
try { try {
Subtitle subtitle = decode(inputBuffer.sampleHolder.data.array(), Subtitle subtitle = decode(inputBuffer.data.array(), inputBuffer.size);
inputBuffer.sampleHolder.size); outputBuffer.setOutput(inputBuffer.timeUs, subtitle, inputBuffer.subsampleOffsetUs);
outputBuffer.setOutput(inputBuffer.sampleHolder.timeUs, subtitle,
inputBuffer.subsampleOffsetUs);
return null; return null;
} catch (ParserException e) { } catch (ParserException e) {
return e; return e;
......
...@@ -19,7 +19,6 @@ import com.google.android.exoplayer.ExoPlaybackException; ...@@ -19,7 +19,6 @@ import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.ParserException; import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSourceTrackRenderer; import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream; import com.google.android.exoplayer.TrackStream;
...@@ -176,9 +175,7 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement ...@@ -176,9 +175,7 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
} }
} }
// Try and read the next subtitle from the source. // Try and read the next subtitle from the source.
SampleHolder sampleHolder = nextInputBuffer.sampleHolder; int result = readSource(formatHolder, nextInputBuffer);
sampleHolder.clearData();
int result = readSource(formatHolder, sampleHolder);
if (result == TrackStream.SAMPLE_READ) { if (result == TrackStream.SAMPLE_READ) {
nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs; nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
parser.queueInputBuffer(nextInputBuffer); parser.queueInputBuffer(nextInputBuffer);
......
...@@ -339,8 +339,8 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme ...@@ -339,8 +339,8 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
} }
private void clearPendingSample() { private void clearPendingSample() {
sampleHolder.clear();
sampleHolder.timeUs = C.UNKNOWN_TIME_US; sampleHolder.timeUs = C.UNKNOWN_TIME_US;
sampleHolder.clearData();
} }
private boolean isSamplePending() { private boolean isSamplePending() {
......
/*
* Copyright (C) 2014 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 com.google.android.exoplayer.util;
import com.google.android.exoplayer.C;
/**
* Base class for buffers with flags.
*/
public abstract class Buffer {
private int flags;
/**
* Clears the buffer.
*/
public void clear() {
flags = 0;
}
/**
* Returns whether the {@link C#SAMPLE_FLAG_DECODE_ONLY} flag is set.
*/
public final boolean isDecodeOnly() {
return getFlag(C.SAMPLE_FLAG_DECODE_ONLY);
}
/**
* Returns whether the {@link C#SAMPLE_FLAG_END_OF_STREAM} flag is set.
*/
public final boolean isEndOfStream() {
return getFlag(C.SAMPLE_FLAG_END_OF_STREAM);
}
/**
* Returns whether the sample has the {@link C#SAMPLE_FLAG_SYNC} flag set.
*/
public final boolean isSyncFrame() {
return getFlag(C.SAMPLE_FLAG_SYNC);
}
/**
* Replaces this buffer's flags with {@code flags}.
*
* @param flags The flags to set, which should be a combination of the {@code C.SAMPLE_FLAG_*}
* constants.
*/
public final void setFlags(int flags) {
this.flags = flags;
}
/**
* Adds the {@code flag} to this buffer's flags.
*
* @param flag The flag to add to this buffer's flags, which should be one of the
* {@code C.SAMPLE_FLAG_*} constants.
*/
public final void addFlag(int flag) {
flags |= flag;
}
/**
* Returns whether the specified flag has been set on this buffer.
*
* @param flag The flag to check.
* @return Whether the flag is set.
*/
protected final boolean getFlag(int flag) {
return (flags & flag) == flag;
}
}
/*
* Copyright (C) 2014 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 com.google.android.exoplayer.util.extensions;
/**
* Base class for {@link Decoder} buffers with flags.
*/
public abstract class Buffer {
private int flags;
public void reset() {
flags = 0;
}
public final void setFlag(int flag) {
flags |= flag;
}
public final boolean getFlag(int flag) {
return (flags & flag) == flag;
}
}
...@@ -27,7 +27,7 @@ public interface Decoder<I, O, E extends Exception> { ...@@ -27,7 +27,7 @@ public interface Decoder<I, O, E extends Exception> {
/** /**
* Dequeues the next input buffer to be filled and queued to the decoder. * Dequeues the next input buffer to be filled and queued to the decoder.
* *
* @return The input buffer, or null if an input buffer isn't available. * @return The input buffer, which will have been cleared, or null if a buffer isn't available.
* @throws E If a decoder error has occurred. * @throws E If a decoder error has occurred.
*/ */
I dequeueInputBuffer() throws E; I dequeueInputBuffer() throws E;
......
/*
* Copyright (C) 2014 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 com.google.android.exoplayer.util.extensions;
import com.google.android.exoplayer.SampleHolder;
/**
* Input buffer to be decoded by a {@link Decoder}.
*/
public class InputBuffer extends Buffer {
public final SampleHolder sampleHolder;
public InputBuffer() {
this(SampleHolder.BUFFER_REPLACEMENT_MODE_DIRECT);
}
public InputBuffer(int bufferReplacementMode) {
sampleHolder = new SampleHolder(bufferReplacementMode);
}
@Override
public void reset() {
super.reset();
sampleHolder.clearData();
}
}
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer.util.extensions; package com.google.android.exoplayer.util.extensions;
import com.google.android.exoplayer.util.Buffer;
/** /**
* Output buffer decoded by a {@link Decoder}. * Output buffer decoded by a {@link Decoder}.
*/ */
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.google.android.exoplayer.util.extensions; package com.google.android.exoplayer.util.extensions;
import com.google.android.exoplayer.C; import com.google.android.exoplayer.C;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Assertions;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -23,7 +24,7 @@ import java.util.LinkedList; ...@@ -23,7 +24,7 @@ import java.util.LinkedList;
/** /**
* Base class for {@link Decoder}s that use their own decode thread. * Base class for {@link Decoder}s that use their own decode thread.
*/ */
public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffer, public abstract class SimpleDecoder<I extends SampleHolder, O extends OutputBuffer,
E extends Exception> extends Thread implements Decoder<I, O, E> { E extends Exception> extends Thread implements Decoder<I, O, E> {
/** /**
...@@ -85,7 +86,7 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe ...@@ -85,7 +86,7 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
protected final void setInitialInputBufferSize(int size) { protected final void setInitialInputBufferSize(int size) {
Assertions.checkState(availableInputBufferCount == availableInputBuffers.length); Assertions.checkState(availableInputBufferCount == availableInputBuffers.length);
for (I inputBuffer : availableInputBuffers) { for (I inputBuffer : availableInputBuffers) {
inputBuffer.sampleHolder.ensureSpaceForWrite(size); inputBuffer.ensureSpaceForWrite(size);
} }
} }
...@@ -94,13 +95,9 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe ...@@ -94,13 +95,9 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
synchronized (lock) { synchronized (lock) {
maybeThrowException(); maybeThrowException();
Assertions.checkState(dequeuedInputBuffer == null); Assertions.checkState(dequeuedInputBuffer == null);
if (availableInputBufferCount == 0) { dequeuedInputBuffer = availableInputBufferCount == 0 ? null
return null; : availableInputBuffers[--availableInputBufferCount];
} return dequeuedInputBuffer;
I inputBuffer = availableInputBuffers[--availableInputBufferCount];
inputBuffer.reset();
dequeuedInputBuffer = inputBuffer;
return inputBuffer;
} }
} }
...@@ -133,7 +130,7 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe ...@@ -133,7 +130,7 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
*/ */
protected void releaseOutputBuffer(O outputBuffer) { protected void releaseOutputBuffer(O outputBuffer) {
synchronized (lock) { synchronized (lock) {
availableOutputBuffers[availableOutputBufferCount++] = outputBuffer; releaseOutputBufferInternal(outputBuffer);
maybeNotifyDecodeLoop(); maybeNotifyDecodeLoop();
} }
} }
...@@ -143,14 +140,14 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe ...@@ -143,14 +140,14 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
synchronized (lock) { synchronized (lock) {
flushDecodedOutputBuffer = true; flushDecodedOutputBuffer = true;
if (dequeuedInputBuffer != null) { if (dequeuedInputBuffer != null) {
availableInputBuffers[availableInputBufferCount++] = dequeuedInputBuffer; releaseInputBufferInternal(dequeuedInputBuffer);
dequeuedInputBuffer = null; dequeuedInputBuffer = null;
} }
while (!queuedInputBuffers.isEmpty()) { while (!queuedInputBuffers.isEmpty()) {
availableInputBuffers[availableInputBufferCount++] = queuedInputBuffers.removeFirst(); releaseInputBufferInternal(queuedInputBuffers.removeFirst());
} }
while (!queuedOutputBuffers.isEmpty()) { while (!queuedOutputBuffers.isEmpty()) {
availableOutputBuffers[availableOutputBufferCount++] = queuedOutputBuffers.removeFirst(); releaseOutputBufferInternal(queuedOutputBuffers.removeFirst());
} }
} }
} }
...@@ -220,12 +217,11 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe ...@@ -220,12 +217,11 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
flushDecodedOutputBuffer = false; flushDecodedOutputBuffer = false;
} }
outputBuffer.reset(); if (inputBuffer.isEndOfStream()) {
if (inputBuffer.getFlag(C.SAMPLE_FLAG_END_OF_STREAM)) { outputBuffer.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
outputBuffer.setFlag(C.SAMPLE_FLAG_END_OF_STREAM);
} else { } else {
if (inputBuffer.getFlag(C.SAMPLE_FLAG_DECODE_ONLY)) { if (inputBuffer.isDecodeOnly()) {
outputBuffer.setFlag(C.SAMPLE_FLAG_DECODE_ONLY); outputBuffer.addFlag(C.SAMPLE_FLAG_DECODE_ONLY);
} }
exception = decode(inputBuffer, outputBuffer); exception = decode(inputBuffer, outputBuffer);
if (exception != null) { if (exception != null) {
...@@ -236,16 +232,16 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe ...@@ -236,16 +232,16 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
} }
synchronized (lock) { synchronized (lock) {
if (flushDecodedOutputBuffer || outputBuffer.getFlag(C.SAMPLE_FLAG_DECODE_ONLY)) { if (flushDecodedOutputBuffer || outputBuffer.isDecodeOnly()) {
// If a flush occurred while decoding or the buffer was only for decoding (not presentation) // If a flush occurred while decoding or the buffer was only for decoding (not presentation)
// then make the output buffer available again rather than queueing it to be consumed. // then make the output buffer available again rather than queueing it to be consumed.
availableOutputBuffers[availableOutputBufferCount++] = outputBuffer; releaseOutputBufferInternal(outputBuffer);
} else { } else {
// Queue the decoded output buffer to be consumed. // Queue the decoded output buffer to be consumed.
queuedOutputBuffers.addLast(outputBuffer); queuedOutputBuffers.addLast(outputBuffer);
} }
// Make the input buffer available again. // Make the input buffer available again.
availableInputBuffers[availableInputBufferCount++] = inputBuffer; releaseInputBufferInternal(inputBuffer);
} }
return true; return true;
...@@ -255,6 +251,16 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe ...@@ -255,6 +251,16 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
return !queuedInputBuffers.isEmpty() && availableOutputBufferCount > 0; return !queuedInputBuffers.isEmpty() && availableOutputBufferCount > 0;
} }
private void releaseInputBufferInternal(I inputBuffer) {
inputBuffer.clear();
availableInputBuffers[availableInputBufferCount++] = inputBuffer;
}
private void releaseOutputBufferInternal(O outputBuffer) {
outputBuffer.clear();
availableOutputBuffers[availableOutputBufferCount++] = outputBuffer;
}
/** /**
* Creates a new input buffer. * Creates a new input buffer.
*/ */
......
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