Allow playback of unseekable fmp4 media.

This is useful to allow playback of individual segments from a
DASH stream as regular fmp4 files. These segments don't typically
contain a segment index. For playback to start, we need to invoke
seekMap with the UNSEEKABLE index. We do this if we haven't seen
a segment index when we encounter an mdat box (if one were present,
it would have been located earlier than this point).
This commit is contained in:
Oliver Woodman 2015-07-27 16:20:40 +01:00
parent e89c40cfd3
commit 08dc691ff7

View file

@ -22,6 +22,7 @@ import com.google.android.exoplayer.extractor.Extractor;
import com.google.android.exoplayer.extractor.ExtractorInput;
import com.google.android.exoplayer.extractor.ExtractorOutput;
import com.google.android.exoplayer.extractor.PositionHolder;
import com.google.android.exoplayer.extractor.SeekMap;
import com.google.android.exoplayer.extractor.TrackOutput;
import com.google.android.exoplayer.extractor.mp4.Atom.ContainerAtom;
import com.google.android.exoplayer.extractor.mp4.Atom.LeafAtom;
@ -94,6 +95,9 @@ public final class FragmentedMp4Extractor implements Extractor {
private ExtractorOutput extractorOutput;
private TrackOutput trackOutput;
// Whether extractorOutput.seekMap has been invoked.
private boolean haveOutputSeekMap;
public FragmentedMp4Extractor() {
this(0);
}
@ -182,6 +186,10 @@ public final class FragmentedMp4Extractor implements Extractor {
atomType = atomHeader.readInt();
if (atomType == Atom.TYPE_mdat) {
if (!haveOutputSeekMap) {
extractorOutput.seekMap(SeekMap.UNSEEKABLE);
haveOutputSeekMap = true;
}
if (fragmentRun.sampleEncryptionDataNeedsFill) {
parserState = STATE_READING_ENCRYPTION_DATA;
} else {
@ -233,6 +241,7 @@ public final class FragmentedMp4Extractor implements Extractor {
} else if (leaf.type == Atom.TYPE_sidx) {
ChunkIndex segmentIndex = parseSidx(leaf.data, inputPosition);
extractorOutput.seekMap(segmentIndex);
haveOutputSeekMap = true;
}
}