Commit 08dc691f by Oliver Woodman

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