Change decodeOnly to be a sample flag.

This commit is contained in:
Oliver Woodman 2015-04-10 22:55:12 +01:00
parent 70b0e55a8b
commit d745384d99
12 changed files with 47 additions and 26 deletions

View file

@ -55,6 +55,11 @@ public final class C {
@SuppressWarnings("InlinedApi")
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
*/

View file

@ -604,7 +604,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
if (waitingForFirstSyncFrame) {
// TODO: Find out if it's possible to supply samples prior to the first sync
// frame for HE-AAC.
if ((sampleHolder.flags & C.SAMPLE_FLAG_SYNC) == 0) {
if (!sampleHolder.isSyncFrame()) {
sampleHolder.data.clear();
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
// The buffer we just cleared contained reconfiguration data. We need to re-write this
@ -615,7 +615,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
waitingForFirstSyncFrame = false;
}
boolean sampleEncrypted = (sampleHolder.flags & C.SAMPLE_FLAG_ENCRYPTED) != 0;
boolean sampleEncrypted = sampleHolder.isEncrypted();
waitingForKeys = shouldWaitForKeys(sampleEncrypted);
if (waitingForKeys) {
return false;
@ -624,7 +624,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
int bufferSize = sampleHolder.data.position();
int adaptiveReconfigurationBytes = bufferSize - sampleHolder.size;
long presentationTimeUs = sampleHolder.timeUs;
if (sampleHolder.decodeOnly) {
if (sampleHolder.isDecodeOnly()) {
decodeOnlyPresentationTimestamps.add(presentationTimeUs);
}
if (sampleEncrypted) {

View file

@ -50,8 +50,8 @@ public final class SampleHolder {
public int size;
/**
* Flags that accompany the sample. A combination of {@link C#SAMPLE_FLAG_SYNC} and
* {@link C#SAMPLE_FLAG_ENCRYPTED}
* Flags that accompany the sample. A combination of {@link C#SAMPLE_FLAG_SYNC},
* {@link C#SAMPLE_FLAG_ENCRYPTED} and {@link C#SAMPLE_FLAG_DECODE_ONLY}.
*/
public int flags;
@ -60,11 +60,6 @@ public final class SampleHolder {
*/
public long timeUs;
/**
* If true then the sample should be decoded, but should not be presented.
*/
public boolean decodeOnly;
private final int bufferReplacementMode;
/**
@ -95,6 +90,27 @@ public final class SampleHolder {
return false;
}
/**
* 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.
*/

View file

@ -358,7 +358,8 @@ public class ChunkSampleSource implements SampleSource, Loader.Callback {
}
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);
return SAMPLE_READ;
} else {

View file

@ -467,8 +467,8 @@ public final class WebmExtractor implements Extractor {
}
long elementEndOffsetBytes = elementOffsetBytes + headerSizeBytes + contentsSizeBytes;
simpleBlockTimecodeUs = clusterTimecodeUs + timecodeUs;
sampleHolder.flags = keyframe ? C.SAMPLE_FLAG_SYNC : 0;
sampleHolder.decodeOnly = invisible;
sampleHolder.flags = (keyframe ? C.SAMPLE_FLAG_SYNC : 0)
| (invisible ? C.SAMPLE_FLAG_DECODE_ONLY : 0);
sampleHolder.timeUs = clusterTimecodeUs + timecodeUs;
sampleHolder.size = (int) (elementEndOffsetBytes - reader.getBytesRead());

View file

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer.hls;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.MediaFormatHolder;
import com.google.android.exoplayer.SampleHolder;
@ -223,7 +224,8 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
}
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;
}

View file

@ -97,7 +97,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
// Write the sample information into the holder and extrasHolder.
infoQueue.peekSample(sampleHolder, extrasHolder);
// Read encryption data if the sample is encrypted.
if ((sampleHolder.flags & C.SAMPLE_FLAG_ENCRYPTED) != 0) {
if (sampleHolder.isEncrypted()) {
readEncryptionData(sampleHolder, extrasHolder);
}
// Write the sample data into the holder.

View file

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer.hls.parser;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.hls.parser.HlsExtractor.TrackOutput;
@ -128,8 +127,7 @@ public final class SampleQueue implements TrackOutput {
}
RollingSampleBuffer nextRollingBuffer = nextQueue.rollingBuffer;
while (nextRollingBuffer.peekSample(sampleInfoHolder)
&& (sampleInfoHolder.timeUs < firstPossibleSpliceTime
|| (sampleInfoHolder.flags & C.SAMPLE_FLAG_SYNC) == 0)) {
&& (sampleInfoHolder.timeUs < firstPossibleSpliceTime || !sampleInfoHolder.isSyncFrame())) {
// Discard samples from the next queue for as long as they are before the earliest possible
// splice time, or not keyframes.
nextRollingBuffer.skipSample();
@ -152,7 +150,7 @@ public final class SampleQueue implements TrackOutput {
private boolean advanceToEligibleSample() {
boolean haveNext = rollingBuffer.peekSample(sampleInfoHolder);
if (needKeyframe) {
while (haveNext && (sampleInfoHolder.flags & C.SAMPLE_FLAG_SYNC) == 0) {
while (haveNext && !sampleInfoHolder.isSyncFrame()) {
rollingBuffer.skipSample();
haveNext = rollingBuffer.peekSample(sampleInfoHolder);
}

View file

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer.source;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSource;
@ -164,7 +163,7 @@ public final class FrameworkSampleExtractor implements SampleExtractor {
}
sampleHolder.timeUs = mediaExtractor.getSampleTime();
sampleHolder.flags = mediaExtractor.getSampleFlags();
if ((sampleHolder.flags & C.SAMPLE_FLAG_ENCRYPTED) != 0) {
if (sampleHolder.isEncrypted()) {
sampleHolder.cryptoInfo.setFromExtractorV16(mediaExtractor);
}

View file

@ -179,7 +179,7 @@ public class TextTrackRenderer extends TrackRenderer implements Callback {
SampleHolder sampleHolder = parserHelper.getSampleHolder();
sampleHolder.clearData();
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();
textRendererNeedsUpdate = false;
} else if (result == SampleSource.END_OF_STREAM) {

View file

@ -200,7 +200,7 @@ public class Eia608Parser {
ClosedCaption[] captionArray = new ClosedCaption[captions.size()];
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) {

View file

@ -358,9 +358,9 @@ public class WebmExtractorTest extends InstrumentationTestCase {
assertTrue(Arrays.equals(
mediaSegment.videoBytes, Arrays.copyOf(sampleHolder.data.array(), sampleHolder.size)));
assertEquals(timeUs, sampleHolder.timeUs);
assertEquals(keyframe, (sampleHolder.flags & C.SAMPLE_FLAG_SYNC) != 0);
assertEquals(invisible, sampleHolder.decodeOnly);
assertEquals(encrypted, (sampleHolder.flags & C.SAMPLE_FLAG_ENCRYPTED) != 0);
assertEquals(keyframe, sampleHolder.isSyncFrame());
assertEquals(invisible, sampleHolder.isDecodeOnly());
assertEquals(encrypted, sampleHolder.isEncrypted());
if (encrypted) {
android.test.MoreAsserts.assertEquals(TEST_INITIALIZATION_VECTOR, sampleHolder.cryptoInfo.iv);
assertEquals(C.CRYPTO_MODE_AES_CTR, sampleHolder.cryptoInfo.mode);