From 9f6ff55c0f4d518132d98b9cddac4eb128f01613 Mon Sep 17 00:00:00 2001 From: tonihei Date: Mon, 30 Nov 2020 09:27:31 +0000 Subject: [PATCH] Replace PeriodSeekInfo by static methods. The inner class was only used to obtain 3 distinct pieces of information which is better handled by static methods. #exofixit PiperOrigin-RevId: 344767661 --- .../source/dash/DashMediaSource.java | 149 ++++++++++-------- 1 file changed, 79 insertions(+), 70 deletions(-) diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java index e66df6c5a6..4dc0921b0a 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java @@ -891,15 +891,12 @@ public final class DashMediaSource extends BaseMediaSource { Period lastPeriod = manifest.getPeriod(lastPeriodIndex); long lastPeriodDurationUs = manifest.getPeriodDurationUs(lastPeriodIndex); long nowUnixTimeUs = C.msToUs(Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs)); - PeriodSeekInfo firstPeriodSeekInfo = - PeriodSeekInfo.createPeriodSeekInfo( - manifest.getPeriod(0), manifest.getPeriodDurationUs(0), nowUnixTimeUs); - PeriodSeekInfo lastPeriodSeekInfo = - PeriodSeekInfo.createPeriodSeekInfo(lastPeriod, lastPeriodDurationUs, nowUnixTimeUs); // Get the period-relative start/end times. - long currentStartTimeUs = firstPeriodSeekInfo.availableStartTimeUs; - long currentEndTimeUs = lastPeriodSeekInfo.availableEndTimeUs; - if (manifest.dynamic && !lastPeriodSeekInfo.isIndexExplicit) { + long currentStartTimeUs = + getAvailableStartTimeUs( + manifest.getPeriod(0), manifest.getPeriodDurationUs(0), nowUnixTimeUs); + long currentEndTimeUs = getAvailableEndTimeUs(lastPeriod, lastPeriodDurationUs, nowUnixTimeUs); + if (manifest.dynamic && !isIndexExplicit(lastPeriod)) { // The manifest describes an incomplete live stream. Update the start/end times to reflect the // live stream duration and the manifest's time shift buffer depth. long liveStreamEndPositionInLastPeriodUs = currentEndTimeUs - C.msToUs(lastPeriod.startMs); @@ -1141,74 +1138,86 @@ public final class DashMediaSource extends BaseMediaSource { return LongMath.divide(intervalUs, 1000, RoundingMode.CEILING); } - private static final class PeriodSeekInfo { - - public static PeriodSeekInfo createPeriodSeekInfo( - Period period, long periodDurationUs, long nowUnixTimeUs) { - int adaptationSetCount = period.adaptationSets.size(); - long availableStartTimeUs = 0; - long availableEndTimeUs = Long.MAX_VALUE; - boolean isIndexExplicit = false; - boolean seenEmptyIndex = false; - - boolean haveAudioVideoAdaptationSets = false; - for (int i = 0; i < adaptationSetCount; i++) { - int type = period.adaptationSets.get(i).type; - if (type == C.TRACK_TYPE_AUDIO || type == C.TRACK_TYPE_VIDEO) { - haveAudioVideoAdaptationSets = true; - break; - } + private static long getAvailableStartTimeUs( + Period period, long periodDurationUs, long nowUnixTimeUs) { + long availableStartTimeUs = 0; + boolean haveAudioVideoAdaptationSets = hasVideoOrAudioAdaptationSets(period); + for (int i = 0; i < period.adaptationSets.size(); i++) { + AdaptationSet adaptationSet = period.adaptationSets.get(i); + List representations = adaptationSet.representations; + // Exclude text adaptation sets from duration calculations, if we have at least one audio + // or video adaptation set. See: https://github.com/google/ExoPlayer/issues/4029 + if ((haveAudioVideoAdaptationSets && adaptationSet.type == C.TRACK_TYPE_TEXT) + || representations.isEmpty()) { + continue; } - - for (int i = 0; i < adaptationSetCount; i++) { - AdaptationSet adaptationSet = period.adaptationSets.get(i); - List representations = adaptationSet.representations; - // Exclude text adaptation sets from duration calculations, if we have at least one audio - // or video adaptation set. See: https://github.com/google/ExoPlayer/issues/4029 - if ((haveAudioVideoAdaptationSets && adaptationSet.type == C.TRACK_TYPE_TEXT) - || representations.isEmpty()) { - continue; - } - - @Nullable DashSegmentIndex index = representations.get(0).getIndex(); - if (index == null) { - return new PeriodSeekInfo( - /* isIndexExplicit= */ true, - /* availableStartTimeUs= */ 0, - /* availableEndTimeUs= */ periodDurationUs); - } - isIndexExplicit |= index.isExplicit(); - int availableSegmentCount = index.getAvailableSegmentCount(periodDurationUs, nowUnixTimeUs); - if (availableSegmentCount == 0) { - seenEmptyIndex = true; - availableStartTimeUs = 0; - availableEndTimeUs = 0; - } else if (!seenEmptyIndex) { - long firstAvailableSegmentNum = - index.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs); - long adaptationSetAvailableStartTimeUs = index.getTimeUs(firstAvailableSegmentNum); - availableStartTimeUs = max(availableStartTimeUs, adaptationSetAvailableStartTimeUs); - long lastAvailableSegmentNum = firstAvailableSegmentNum + availableSegmentCount - 1; - long adaptationSetAvailableEndTimeUs = - index.getTimeUs(lastAvailableSegmentNum) - + index.getDurationUs(lastAvailableSegmentNum, periodDurationUs); - availableEndTimeUs = min(availableEndTimeUs, adaptationSetAvailableEndTimeUs); - } + @Nullable DashSegmentIndex index = representations.get(0).getIndex(); + if (index == null) { + return 0; } - return new PeriodSeekInfo(isIndexExplicit, availableStartTimeUs, availableEndTimeUs); + int availableSegmentCount = index.getAvailableSegmentCount(periodDurationUs, nowUnixTimeUs); + if (availableSegmentCount == 0) { + return 0; + } + long firstAvailableSegmentNum = + index.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs); + long adaptationSetAvailableStartTimeUs = index.getTimeUs(firstAvailableSegmentNum); + availableStartTimeUs = max(availableStartTimeUs, adaptationSetAvailableStartTimeUs); } + return availableStartTimeUs; + } - public final boolean isIndexExplicit; - public final long availableStartTimeUs; - public final long availableEndTimeUs; - - private PeriodSeekInfo(boolean isIndexExplicit, long availableStartTimeUs, - long availableEndTimeUs) { - this.isIndexExplicit = isIndexExplicit; - this.availableStartTimeUs = availableStartTimeUs; - this.availableEndTimeUs = availableEndTimeUs; + private static long getAvailableEndTimeUs( + Period period, long periodDurationUs, long nowUnixTimeUs) { + long availableEndTimeUs = Long.MAX_VALUE; + boolean haveAudioVideoAdaptationSets = hasVideoOrAudioAdaptationSets(period); + for (int i = 0; i < period.adaptationSets.size(); i++) { + AdaptationSet adaptationSet = period.adaptationSets.get(i); + List representations = adaptationSet.representations; + // Exclude text adaptation sets from duration calculations, if we have at least one audio + // or video adaptation set. See: https://github.com/google/ExoPlayer/issues/4029 + if ((haveAudioVideoAdaptationSets && adaptationSet.type == C.TRACK_TYPE_TEXT) + || representations.isEmpty()) { + continue; + } + @Nullable DashSegmentIndex index = representations.get(0).getIndex(); + if (index == null) { + return periodDurationUs; + } + int availableSegmentCount = index.getAvailableSegmentCount(periodDurationUs, nowUnixTimeUs); + if (availableSegmentCount == 0) { + return 0; + } + long firstAvailableSegmentNum = + index.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs); + long lastAvailableSegmentNum = firstAvailableSegmentNum + availableSegmentCount - 1; + long adaptationSetAvailableEndTimeUs = + index.getTimeUs(lastAvailableSegmentNum) + + index.getDurationUs(lastAvailableSegmentNum, periodDurationUs); + availableEndTimeUs = min(availableEndTimeUs, adaptationSetAvailableEndTimeUs); } + return availableEndTimeUs; + } + private static boolean isIndexExplicit(Period period) { + for (int i = 0; i < period.adaptationSets.size(); i++) { + @Nullable + DashSegmentIndex index = period.adaptationSets.get(i).representations.get(0).getIndex(); + if (index == null || index.isExplicit()) { + return true; + } + } + return false; + } + + private static boolean hasVideoOrAudioAdaptationSets(Period period) { + for (int i = 0; i < period.adaptationSets.size(); i++) { + int type = period.adaptationSets.get(i).type; + if (type == C.TRACK_TYPE_AUDIO || type == C.TRACK_TYPE_VIDEO) { + return true; + } + } + return false; } private static final class DashTimeline extends Timeline {