mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Change decodeOnly to be a sample flag.
This commit is contained in:
parent
70b0e55a8b
commit
d745384d99
12 changed files with 47 additions and 26 deletions
|
|
@ -55,6 +55,11 @@ public final class C {
|
||||||
@SuppressWarnings("InlinedApi")
|
@SuppressWarnings("InlinedApi")
|
||||||
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
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -95,6 +90,27 @@ public final class SampleHolder {
|
||||||
return false;
|
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.
|
* Clears {@link #data}. Does nothing if {@link #data} is null.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
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 @@
|
||||||
*/
|
*/
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
// 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 @@
|
||||||
*/
|
*/
|
||||||
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 {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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 @@
|
||||||
*/
|
*/
|
||||||
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 {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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 {
|
||||||
|
|
||||||
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 {
|
||||||
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);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue