From a5ebb49a1a1b2bda285f72d90b92f8fb99de17be Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Mon, 12 Oct 2015 12:20:15 +0100 Subject: [PATCH] Set the maximum input size based on the sample table for MP4s. --- .../exoplayer/MediaCodecTrackRenderer.java | 2 +- .../google/android/exoplayer/MediaFormat.java | 6 ++++ .../exoplayer/extractor/mp4/AtomParsers.java | 8 +++-- .../exoplayer/extractor/mp4/Mp4Extractor.java | 5 ++- .../extractor/mp4/TrackSampleTable.java | 36 ++++++++++++++----- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java index 8952c20da3..f8a2518f88 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java @@ -643,7 +643,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer adaptiveReconfigurationBytes); codec.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0); } else { - codec.queueInputBuffer(inputIndex, 0 , bufferSize, presentationTimeUs, 0); + codec.queueInputBuffer(inputIndex, 0, bufferSize, presentationTimeUs, 0); } inputIndex = -1; codecHasQueuedBuffers = true; diff --git a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java index be21897c55..f97fbdcdec 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaFormat.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaFormat.java @@ -205,6 +205,12 @@ public final class MediaFormat { this.maxHeight = maxHeight; } + public MediaFormat copyWithMaxInputSize(int maxInputSize) { + return new MediaFormat(trackId, mimeType, bitrate, maxInputSize, durationUs, width, height, + rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, language, + subsampleOffsetUs, initializationData, adaptive, maxWidth, maxHeight); + } + public MediaFormat copyWithMaxVideoDimensions(int maxWidth, int maxHeight) { return new MediaFormat(trackId, mimeType, bitrate, maxInputSize, durationUs, width, height, rotationDegrees, pixelWidthHeightRatio, channelCount, sampleRate, language, diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java index 7028cf5159..f0c10fcd3e 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java @@ -106,10 +106,11 @@ import java.util.List; long[] offsets = new long[sampleCount]; int[] sizes = new int[sampleCount]; + int maximumSize = 0; long[] timestamps = new long[sampleCount]; int[] flags = new int[sampleCount]; if (sampleCount == 0) { - return new TrackSampleTable(offsets, sizes, timestamps, flags); + return new TrackSampleTable(offsets, sizes, maximumSize, timestamps, flags); } // Prepare to read chunk offsets. @@ -172,6 +173,9 @@ import java.util.List; for (int i = 0; i < sampleCount; i++) { offsets[i] = offsetBytes; sizes[i] = fixedSampleSize == 0 ? stsz.readUnsignedIntToInt() : fixedSampleSize; + if (sizes[i] > maximumSize) { + maximumSize = sizes[i]; + } timestamps[i] = timestampTimeUnits + timestampOffset; // All samples are synchronization samples if the stss is not present. @@ -244,7 +248,7 @@ import java.util.List; Assertions.checkArgument(remainingSamplesInChunk == 0); Assertions.checkArgument(remainingTimestampDeltaChanges == 0); Assertions.checkArgument(remainingTimestampOffsetChanges == 0); - return new TrackSampleTable(offsets, sizes, timestamps, flags); + return new TrackSampleTable(offsets, sizes, maximumSize, timestamps, flags); } /** diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java index b5db6e4cc5..3c7611b02c 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java @@ -262,7 +262,10 @@ public final class Mp4Extractor implements Extractor, SeekMap { } Mp4Track mp4Track = new Mp4Track(track, trackSampleTable, extractorOutput.track(i)); - mp4Track.trackOutput.format(track.mediaFormat); + // Each sample has up to three bytes of overhead for the start code that replaces its length. + // Allow ten source samples per output sample, like the platform extractor. + int maxInputSize = trackSampleTable.maximumSize + 3 * 10; + mp4Track.trackOutput.format(track.mediaFormat.copyWithMaxInputSize(maxInputSize)); tracks.add(mp4Track); long firstSampleOffset = trackSampleTable.offsets[0]; diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/TrackSampleTable.java b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/TrackSampleTable.java index 1848185e97..6717b3c54a 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/mp4/TrackSampleTable.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/mp4/TrackSampleTable.java @@ -19,31 +19,49 @@ import com.google.android.exoplayer.C; import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Util; -/** Sample table for a track in an MP4 file. */ +/** + * Sample table for a track in an MP4 file. + */ /* package */ final class TrackSampleTable { - /** Sample index when no sample is available. */ + /** + * Sample index when no sample is available. + */ public static final int NO_SAMPLE = -1; - /** Number of samples. */ + /** + * Number of samples. + */ public final int sampleCount; - /** Sample offsets in bytes. */ + /** + * Sample offsets in bytes. + */ public final long[] offsets; - /** Sample sizes in bytes. */ + /** + * Sample sizes in bytes. + */ public final int[] sizes; - /** Sample timestamps in microseconds. */ + /** + * Maximum sample size in {@link #sizes}. + */ + public final int maximumSize; + /** + * Sample timestamps in microseconds. + */ public final long[] timestampsUs; - /** Sample flags. */ + /** + * Sample flags. + */ public final int[] flags; - TrackSampleTable( - long[] offsets, int[] sizes, long[] timestampsUs, int[] flags) { + TrackSampleTable(long[] offsets, int[] sizes, int maximumSize, long[] timestampsUs, int[] flags) { Assertions.checkArgument(sizes.length == timestampsUs.length); Assertions.checkArgument(offsets.length == timestampsUs.length); Assertions.checkArgument(flags.length == timestampsUs.length); this.offsets = offsets; this.sizes = sizes; + this.maximumSize = maximumSize; this.timestampsUs = timestampsUs; this.flags = flags; sampleCount = offsets.length;