Trim more than one sample for elst gapless

Allow trimming an arbitrary small number of samples (needing to trim up to two
samples actually seems to be common). For larger numbers of samples we do coarse
trimming by applying the edit list in the normal path, and don't use gapless
playback.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=192736956
This commit is contained in:
andrewlewis 2018-04-13 01:58:59 -07:00 committed by Oliver Woodman
parent 0a68d1f09c
commit 387cc2f2bd
2 changed files with 28 additions and 11 deletions

View file

@ -43,6 +43,8 @@
((#3845)[https://github.com/google/ExoPlayer/issues/3845]).
* Handle non-empty end-of-stream buffers, to fix gapless playback of streams
with encoder padding when the decoder returns a non-empty final buffer.
* Allow trimming more than one sample when applying an elst audio edit via
gapless playback info.
* Caching:
* Add release method to Cache interface.
* Prevent multiple instances of SimpleCache in the same folder.

View file

@ -53,6 +53,12 @@ import java.util.List;
private static final int TYPE_clcp = Util.getIntegerCodeForString("clcp");
private static final int TYPE_meta = Util.getIntegerCodeForString("meta");
/**
* The threshold number of samples to trim from the start/end of an audio track when applying an
* edit below which gapless info can be used (rather than removing samples from the sample table).
*/
private static final int MAX_GAPLESS_TRIM_SIZE_SAMPLES = 3;
/**
* Parses a trak atom (defined in 14496-12).
*
@ -311,22 +317,18 @@ import java.util.List;
// See the BMFF spec (ISO 14496-12) subsection 8.6.6. Edit lists that require prerolling from a
// sync sample after reordering are not supported. Partial audio sample truncation is only
// supported in edit lists with one edit that removes less than one sample from the start/end of
// the track, for gapless audio playback. This implementation handles simple discarding/delaying
// of samples. The extractor may place further restrictions on what edited streams are playable.
// supported in edit lists with one edit that removes less than MAX_GAPLESS_TRIM_SIZE_SAMPLES
// samples from the start/end of the track. This implementation handles simple
// discarding/delaying of samples. The extractor may place further restrictions on what edited
// streams are playable.
if (track.editListDurations.length == 1 && track.type == C.TRACK_TYPE_AUDIO
if (track.editListDurations.length == 1
&& track.type == C.TRACK_TYPE_AUDIO
&& timestamps.length >= 2) {
// Handle the edit by setting gapless playback metadata, if possible. This implementation
// assumes that only one "roll" sample is needed, which is the case for AAC, so the start/end
// points of the edit must lie within the first/last samples respectively.
long editStartTime = track.editListMediaTimes[0];
long editEndTime = editStartTime + Util.scaleLargeTimestamp(track.editListDurations[0],
track.timescale, track.movieTimescale);
if (timestamps[0] <= editStartTime
&& editStartTime < timestamps[1]
&& timestamps[timestamps.length - 1] < editEndTime
&& editEndTime <= duration) {
if (canApplyEditWithGaplessInfo(timestamps, duration, editStartTime, editEndTime)) {
long paddingTimeUnits = duration - editEndTime;
long encoderDelay = Util.scaleLargeTimestamp(editStartTime - timestamps[0],
track.format.sampleRate, track.timescale);
@ -1180,6 +1182,19 @@ import java.util.List;
return size;
}
/** Returns whether it's possible to apply the specified edit using gapless playback info. */
private static boolean canApplyEditWithGaplessInfo(
long[] timestamps, long duration, long editStartTime, long editEndTime) {
int lastIndex = timestamps.length - 1;
int latestDelayIndex = Util.constrainValue(MAX_GAPLESS_TRIM_SIZE_SAMPLES, 0, lastIndex);
int earliestPaddingIndex =
Util.constrainValue(timestamps.length - MAX_GAPLESS_TRIM_SIZE_SAMPLES, 0, lastIndex);
return timestamps[0] <= editStartTime
&& editStartTime < timestamps[latestDelayIndex]
&& timestamps[earliestPaddingIndex] < editEndTime
&& editEndTime <= duration;
}
private AtomParsers() {
// Prevent instantiation.
}