Commit d745384d by Oliver Woodman

Change decodeOnly to be a sample flag.

parent 70b0e55a
...@@ -56,6 +56,11 @@ public final class C { ...@@ -56,6 +56,11 @@ public final class C {
public static final int SAMPLE_FLAG_ENCRYPTED = MediaExtractor.SAMPLE_FLAG_ENCRYPTED; public static final int SAMPLE_FLAG_ENCRYPTED = MediaExtractor.SAMPLE_FLAG_ENCRYPTED;
/** /**
* Indicates that a sample should be decoded but not rendered.
*/
public static final int SAMPLE_FLAG_DECODE_ONLY = 0x8000000;
/**
* @see MediaCodec#CRYPTO_MODE_AES_CTR * @see MediaCodec#CRYPTO_MODE_AES_CTR
*/ */
@SuppressWarnings("InlinedApi") @SuppressWarnings("InlinedApi")
......
...@@ -604,7 +604,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { ...@@ -604,7 +604,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
if (waitingForFirstSyncFrame) { if (waitingForFirstSyncFrame) {
// TODO: Find out if it's possible to supply samples prior to the first sync // TODO: Find out if it's possible to supply samples prior to the first sync
// frame for HE-AAC. // frame for HE-AAC.
if ((sampleHolder.flags & C.SAMPLE_FLAG_SYNC) == 0) { if (!sampleHolder.isSyncFrame()) {
sampleHolder.data.clear(); sampleHolder.data.clear();
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) { if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
// The buffer we just cleared contained reconfiguration data. We need to re-write this // The buffer we just cleared contained reconfiguration data. We need to re-write this
...@@ -615,7 +615,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { ...@@ -615,7 +615,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
} }
waitingForFirstSyncFrame = false; waitingForFirstSyncFrame = false;
} }
boolean sampleEncrypted = (sampleHolder.flags & C.SAMPLE_FLAG_ENCRYPTED) != 0; boolean sampleEncrypted = sampleHolder.isEncrypted();
waitingForKeys = shouldWaitForKeys(sampleEncrypted); waitingForKeys = shouldWaitForKeys(sampleEncrypted);
if (waitingForKeys) { if (waitingForKeys) {
return false; return false;
...@@ -624,7 +624,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { ...@@ -624,7 +624,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
int bufferSize = sampleHolder.data.position(); int bufferSize = sampleHolder.data.position();
int adaptiveReconfigurationBytes = bufferSize - sampleHolder.size; int adaptiveReconfigurationBytes = bufferSize - sampleHolder.size;
long presentationTimeUs = sampleHolder.timeUs; long presentationTimeUs = sampleHolder.timeUs;
if (sampleHolder.decodeOnly) { if (sampleHolder.isDecodeOnly()) {
decodeOnlyPresentationTimestamps.add(presentationTimeUs); decodeOnlyPresentationTimestamps.add(presentationTimeUs);
} }
if (sampleEncrypted) { if (sampleEncrypted) {
......
...@@ -50,8 +50,8 @@ public final class SampleHolder { ...@@ -50,8 +50,8 @@ public final class SampleHolder {
public int size; public int size;
/** /**
* Flags that accompany the sample. A combination of {@link C#SAMPLE_FLAG_SYNC} and * Flags that accompany the sample. A combination of {@link C#SAMPLE_FLAG_SYNC},
* {@link C#SAMPLE_FLAG_ENCRYPTED} * {@link C#SAMPLE_FLAG_ENCRYPTED} and {@link C#SAMPLE_FLAG_DECODE_ONLY}.
*/ */
public int flags; public int flags;
...@@ -60,11 +60,6 @@ public final class SampleHolder { ...@@ -60,11 +60,6 @@ public final class SampleHolder {
*/ */
public long timeUs; public long timeUs;
/**
* If true then the sample should be decoded, but should not be presented.
*/
public boolean decodeOnly;
private final int bufferReplacementMode; private final int bufferReplacementMode;
/** /**
...@@ -96,6 +91,27 @@ public final class SampleHolder { ...@@ -96,6 +91,27 @@ public final class SampleHolder {
} }
/** /**
* Returns whether {@link #flags} has {@link C#SAMPLE_FLAG_ENCRYPTED} 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() {
return (flags & C.SAMPLE_FLAG_SYNC) != 0;
}
/**
* Clears {@link #data}. Does nothing if {@link #data} is null. * Clears {@link #data}. Does nothing if {@link #data} is null.
*/ */
public void clearData() { public void clearData() {
......
...@@ -358,7 +358,8 @@ public class ChunkSampleSource implements SampleSource, Loader.Callback { ...@@ -358,7 +358,8 @@ public class ChunkSampleSource implements SampleSource, Loader.Callback {
} }
if (mediaChunk.read(sampleHolder)) { if (mediaChunk.read(sampleHolder)) {
sampleHolder.decodeOnly = frameAccurateSeeking && sampleHolder.timeUs < lastSeekPositionUs; boolean decodeOnly = frameAccurateSeeking && sampleHolder.timeUs < lastSeekPositionUs;
sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0;
onSampleRead(mediaChunk, sampleHolder); onSampleRead(mediaChunk, sampleHolder);
return SAMPLE_READ; return SAMPLE_READ;
} else { } else {
......
...@@ -467,8 +467,8 @@ public final class WebmExtractor implements Extractor { ...@@ -467,8 +467,8 @@ public final class WebmExtractor implements Extractor {
} }
long elementEndOffsetBytes = elementOffsetBytes + headerSizeBytes + contentsSizeBytes; long elementEndOffsetBytes = elementOffsetBytes + headerSizeBytes + contentsSizeBytes;
simpleBlockTimecodeUs = clusterTimecodeUs + timecodeUs; simpleBlockTimecodeUs = clusterTimecodeUs + timecodeUs;
sampleHolder.flags = keyframe ? C.SAMPLE_FLAG_SYNC : 0; sampleHolder.flags = (keyframe ? C.SAMPLE_FLAG_SYNC : 0)
sampleHolder.decodeOnly = invisible; | (invisible ? C.SAMPLE_FLAG_DECODE_ONLY : 0);
sampleHolder.timeUs = clusterTimecodeUs + timecodeUs; sampleHolder.timeUs = clusterTimecodeUs + timecodeUs;
sampleHolder.size = (int) (elementEndOffsetBytes - reader.getBytesRead()); sampleHolder.size = (int) (elementEndOffsetBytes - reader.getBytesRead());
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer.hls; package com.google.android.exoplayer.hls;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat; import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.MediaFormatHolder; import com.google.android.exoplayer.MediaFormatHolder;
import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.SampleHolder;
...@@ -223,7 +224,8 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -223,7 +224,8 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
} }
if (extractor.getSample(track, sampleHolder)) { if (extractor.getSample(track, sampleHolder)) {
sampleHolder.decodeOnly = frameAccurateSeeking && sampleHolder.timeUs < lastSeekPositionUs; boolean decodeOnly = frameAccurateSeeking && sampleHolder.timeUs < lastSeekPositionUs;
sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0;
return SAMPLE_READ; return SAMPLE_READ;
} }
......
...@@ -97,7 +97,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; ...@@ -97,7 +97,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
// Write the sample information into the holder and extrasHolder. // Write the sample information into the holder and extrasHolder.
infoQueue.peekSample(sampleHolder, extrasHolder); infoQueue.peekSample(sampleHolder, extrasHolder);
// Read encryption data if the sample is encrypted. // Read encryption data if the sample is encrypted.
if ((sampleHolder.flags & C.SAMPLE_FLAG_ENCRYPTED) != 0) { if (sampleHolder.isEncrypted()) {
readEncryptionData(sampleHolder, extrasHolder); readEncryptionData(sampleHolder, extrasHolder);
} }
// Write the sample data into the holder. // Write the sample data into the holder.
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
*/ */
package com.google.android.exoplayer.hls.parser; package com.google.android.exoplayer.hls.parser;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat; import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.hls.parser.HlsExtractor.TrackOutput; import com.google.android.exoplayer.hls.parser.HlsExtractor.TrackOutput;
...@@ -128,8 +127,7 @@ public final class SampleQueue implements TrackOutput { ...@@ -128,8 +127,7 @@ public final class SampleQueue implements TrackOutput {
} }
RollingSampleBuffer nextRollingBuffer = nextQueue.rollingBuffer; RollingSampleBuffer nextRollingBuffer = nextQueue.rollingBuffer;
while (nextRollingBuffer.peekSample(sampleInfoHolder) while (nextRollingBuffer.peekSample(sampleInfoHolder)
&& (sampleInfoHolder.timeUs < firstPossibleSpliceTime && (sampleInfoHolder.timeUs < firstPossibleSpliceTime || !sampleInfoHolder.isSyncFrame())) {
|| (sampleInfoHolder.flags & C.SAMPLE_FLAG_SYNC) == 0)) {
// Discard samples from the next queue for as long as they are before the earliest possible // Discard samples from the next queue for as long as they are before the earliest possible
// splice time, or not keyframes. // splice time, or not keyframes.
nextRollingBuffer.skipSample(); nextRollingBuffer.skipSample();
...@@ -152,7 +150,7 @@ public final class SampleQueue implements TrackOutput { ...@@ -152,7 +150,7 @@ public final class SampleQueue implements TrackOutput {
private boolean advanceToEligibleSample() { private boolean advanceToEligibleSample() {
boolean haveNext = rollingBuffer.peekSample(sampleInfoHolder); boolean haveNext = rollingBuffer.peekSample(sampleInfoHolder);
if (needKeyframe) { if (needKeyframe) {
while (haveNext && (sampleInfoHolder.flags & C.SAMPLE_FLAG_SYNC) == 0) { while (haveNext && !sampleInfoHolder.isSyncFrame()) {
rollingBuffer.skipSample(); rollingBuffer.skipSample();
haveNext = rollingBuffer.peekSample(sampleInfoHolder); haveNext = rollingBuffer.peekSample(sampleInfoHolder);
} }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
*/ */
package com.google.android.exoplayer.source; package com.google.android.exoplayer.source;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat; import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.SampleSource;
...@@ -164,7 +163,7 @@ public final class FrameworkSampleExtractor implements SampleExtractor { ...@@ -164,7 +163,7 @@ public final class FrameworkSampleExtractor implements SampleExtractor {
} }
sampleHolder.timeUs = mediaExtractor.getSampleTime(); sampleHolder.timeUs = mediaExtractor.getSampleTime();
sampleHolder.flags = mediaExtractor.getSampleFlags(); sampleHolder.flags = mediaExtractor.getSampleFlags();
if ((sampleHolder.flags & C.SAMPLE_FLAG_ENCRYPTED) != 0) { if (sampleHolder.isEncrypted()) {
sampleHolder.cryptoInfo.setFromExtractorV16(mediaExtractor); sampleHolder.cryptoInfo.setFromExtractorV16(mediaExtractor);
} }
......
...@@ -179,7 +179,7 @@ public class TextTrackRenderer extends TrackRenderer implements Callback { ...@@ -179,7 +179,7 @@ public class TextTrackRenderer extends TrackRenderer implements Callback {
SampleHolder sampleHolder = parserHelper.getSampleHolder(); SampleHolder sampleHolder = parserHelper.getSampleHolder();
sampleHolder.clearData(); sampleHolder.clearData();
int result = source.readData(trackIndex, positionUs, formatHolder, sampleHolder, false); int result = source.readData(trackIndex, positionUs, formatHolder, sampleHolder, false);
if (result == SampleSource.SAMPLE_READ && !sampleHolder.decodeOnly) { if (result == SampleSource.SAMPLE_READ && !sampleHolder.isDecodeOnly()) {
parserHelper.startParseOperation(); parserHelper.startParseOperation();
textRendererNeedsUpdate = false; textRendererNeedsUpdate = false;
} else if (result == SampleSource.END_OF_STREAM) { } else if (result == SampleSource.END_OF_STREAM) {
......
...@@ -200,7 +200,7 @@ public class Eia608Parser { ...@@ -200,7 +200,7 @@ public class Eia608Parser {
ClosedCaption[] captionArray = new ClosedCaption[captions.size()]; ClosedCaption[] captionArray = new ClosedCaption[captions.size()];
captions.toArray(captionArray); captions.toArray(captionArray);
return new ClosedCaptionList(sampleHolder.timeUs, sampleHolder.decodeOnly, captionArray); return new ClosedCaptionList(sampleHolder.timeUs, sampleHolder.isDecodeOnly(), captionArray);
} }
private static char getChar(byte ccData) { private static char getChar(byte ccData) {
......
...@@ -358,9 +358,9 @@ public class WebmExtractorTest extends InstrumentationTestCase { ...@@ -358,9 +358,9 @@ public class WebmExtractorTest extends InstrumentationTestCase {
assertTrue(Arrays.equals( assertTrue(Arrays.equals(
mediaSegment.videoBytes, Arrays.copyOf(sampleHolder.data.array(), sampleHolder.size))); mediaSegment.videoBytes, Arrays.copyOf(sampleHolder.data.array(), sampleHolder.size)));
assertEquals(timeUs, sampleHolder.timeUs); assertEquals(timeUs, sampleHolder.timeUs);
assertEquals(keyframe, (sampleHolder.flags & C.SAMPLE_FLAG_SYNC) != 0); assertEquals(keyframe, sampleHolder.isSyncFrame());
assertEquals(invisible, sampleHolder.decodeOnly); assertEquals(invisible, sampleHolder.isDecodeOnly());
assertEquals(encrypted, (sampleHolder.flags & C.SAMPLE_FLAG_ENCRYPTED) != 0); assertEquals(encrypted, sampleHolder.isEncrypted());
if (encrypted) { if (encrypted) {
android.test.MoreAsserts.assertEquals(TEST_INITIALIZATION_VECTOR, sampleHolder.cryptoInfo.iv); android.test.MoreAsserts.assertEquals(TEST_INITIALIZATION_VECTOR, sampleHolder.cryptoInfo.iv);
assertEquals(C.CRYPTO_MODE_AES_CTR, sampleHolder.cryptoInfo.mode); assertEquals(C.CRYPTO_MODE_AES_CTR, sampleHolder.cryptoInfo.mode);
......
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