From 08dc691ff7b1e4449493ba0fa77ddb9456f37702 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Mon, 27 Jul 2015 16:20:40 +0100 Subject: [PATCH] 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). --- .../exoplayer/extractor/mp4/FragmentedMp4Extractor.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/FragmentedMp4Extractor.java b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/FragmentedMp4Extractor.java index a6b957bd02..09f5ecb4c0 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/FragmentedMp4Extractor.java @@ -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; } }