mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Partially merge InputBuffer and SampleHolder.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=117908518
This commit is contained in:
parent
0d1ae1dd67
commit
1175f50fb8
21 changed files with 166 additions and 166 deletions
|
|
@ -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 {
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
// 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 @@
|
||||||
*/
|
*/
|
||||||
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 {
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -49,11 +54,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.
|
||||||
*/
|
*/
|
||||||
|
|
@ -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() {
|
public final boolean isEncrypted() {
|
||||||
return (flags & C.SAMPLE_FLAG_ENCRYPTED) != 0;
|
return getFlag(C.SAMPLE_FLAG_ENCRYPTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Returns whether {@link #flags} has {@link C#SAMPLE_FLAG_DECODE_ONLY} set.
|
public void clear() {
|
||||||
*/
|
super.clear();
|
||||||
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() {
|
|
||||||
return (flags & C.SAMPLE_FLAG_SYNC) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears {@link #data}. Does nothing if {@link #data} is null.
|
|
||||||
*/
|
|
||||||
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
|
||||||
@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
|
||||||
} 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
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
/**
|
/**
|
||||||
* 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;
|
||||||
* 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;
|
||||||
* 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;
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|
||||||
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 {
|
||||||
* {@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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
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 @@
|
||||||
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;
|
||||||
owner.releaseOutputBuffer(this);
|
owner.releaseOutputBuffer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
super.clear();
|
||||||
|
subtitle = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* 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> {
|
||||||
/**
|
/**
|
||||||
* 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;
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 @@
|
||||||
*/
|
*/
|
||||||
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 @@
|
||||||
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;
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
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
|
||||||
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
|
||||||
*/
|
*/
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
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.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue