mirror of
https://github.com/androidx/media.git
synced 2025-05-09 00:20:45 +08:00
Align live window to available DASH segments
PiperOrigin-RevId: 333720336
This commit is contained in:
parent
c107017a4b
commit
d1416aeb98
@ -1032,20 +1032,21 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||||||
// Update the window.
|
// Update the window.
|
||||||
boolean windowChangingImplicitly = false;
|
boolean windowChangingImplicitly = false;
|
||||||
int lastPeriodIndex = manifest.getPeriodCount() - 1;
|
int lastPeriodIndex = manifest.getPeriodCount() - 1;
|
||||||
PeriodSeekInfo firstPeriodSeekInfo = PeriodSeekInfo.createPeriodSeekInfo(manifest.getPeriod(0),
|
Period lastPeriod = manifest.getPeriod(lastPeriodIndex);
|
||||||
manifest.getPeriodDurationUs(0));
|
long lastPeriodDurationUs = manifest.getPeriodDurationUs(lastPeriodIndex);
|
||||||
PeriodSeekInfo lastPeriodSeekInfo = PeriodSeekInfo.createPeriodSeekInfo(
|
long nowUnixTimeUs = C.msToUs(Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs));
|
||||||
manifest.getPeriod(lastPeriodIndex), manifest.getPeriodDurationUs(lastPeriodIndex));
|
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.
|
// Get the period-relative start/end times.
|
||||||
long currentStartTimeUs = firstPeriodSeekInfo.availableStartTimeUs;
|
long currentStartTimeUs = firstPeriodSeekInfo.availableStartTimeUs;
|
||||||
long currentEndTimeUs = lastPeriodSeekInfo.availableEndTimeUs;
|
long currentEndTimeUs = lastPeriodSeekInfo.availableEndTimeUs;
|
||||||
if (manifest.dynamic && !lastPeriodSeekInfo.isIndexExplicit) {
|
if (manifest.dynamic && !lastPeriodSeekInfo.isIndexExplicit) {
|
||||||
// The manifest describes an incomplete live stream. Update the start/end times to reflect the
|
// 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.
|
// live stream duration and the manifest's time shift buffer depth.
|
||||||
long nowUnixTimeUs = C.msToUs(Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs));
|
long liveStreamEndPositionInLastPeriodUs = currentEndTimeUs - C.msToUs(lastPeriod.startMs);
|
||||||
long liveStreamDurationUs = nowUnixTimeUs - C.msToUs(manifest.availabilityStartTimeMs);
|
|
||||||
long liveStreamEndPositionInLastPeriodUs = liveStreamDurationUs
|
|
||||||
- C.msToUs(manifest.getPeriod(lastPeriodIndex).startMs);
|
|
||||||
currentEndTimeUs = min(liveStreamEndPositionInLastPeriodUs, currentEndTimeUs);
|
currentEndTimeUs = min(liveStreamEndPositionInLastPeriodUs, currentEndTimeUs);
|
||||||
if (manifest.timeShiftBufferDepthMs != C.TIME_UNSET) {
|
if (manifest.timeShiftBufferDepthMs != C.TIME_UNSET) {
|
||||||
long timeShiftBufferDepthUs = C.msToUs(manifest.timeShiftBufferDepthMs);
|
long timeShiftBufferDepthUs = C.msToUs(manifest.timeShiftBufferDepthMs);
|
||||||
@ -1098,7 +1099,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||||||
windowStartTimeMs,
|
windowStartTimeMs,
|
||||||
elapsedRealtimeOffsetMs,
|
elapsedRealtimeOffsetMs,
|
||||||
firstPeriodId,
|
firstPeriodId,
|
||||||
currentStartTimeUs,
|
/* offsetInFirstPeriodUs= */ currentStartTimeUs,
|
||||||
windowDurationUs,
|
windowDurationUs,
|
||||||
windowDefaultStartPositionUs,
|
windowDefaultStartPositionUs,
|
||||||
manifest,
|
manifest,
|
||||||
@ -1207,7 +1208,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||||||
private static final class PeriodSeekInfo {
|
private static final class PeriodSeekInfo {
|
||||||
|
|
||||||
public static PeriodSeekInfo createPeriodSeekInfo(
|
public static PeriodSeekInfo createPeriodSeekInfo(
|
||||||
com.google.android.exoplayer2.source.dash.manifest.Period period, long durationUs) {
|
Period period, long periodDurationUs, long nowUnixTimeUs) {
|
||||||
int adaptationSetCount = period.adaptationSets.size();
|
int adaptationSetCount = period.adaptationSets.size();
|
||||||
long availableStartTimeUs = 0;
|
long availableStartTimeUs = 0;
|
||||||
long availableEndTimeUs = Long.MAX_VALUE;
|
long availableEndTimeUs = Long.MAX_VALUE;
|
||||||
@ -1225,32 +1226,37 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||||||
|
|
||||||
for (int i = 0; i < adaptationSetCount; i++) {
|
for (int i = 0; i < adaptationSetCount; i++) {
|
||||||
AdaptationSet adaptationSet = period.adaptationSets.get(i);
|
AdaptationSet adaptationSet = period.adaptationSets.get(i);
|
||||||
|
List<Representation> representations = adaptationSet.representations;
|
||||||
// Exclude text adaptation sets from duration calculations, if we have at least one audio
|
// 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
|
// or video adaptation set. See: https://github.com/google/ExoPlayer/issues/4029
|
||||||
if (haveAudioVideoAdaptationSets && adaptationSet.type == C.TRACK_TYPE_TEXT) {
|
if ((haveAudioVideoAdaptationSets && adaptationSet.type == C.TRACK_TYPE_TEXT)
|
||||||
|
|| representations.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DashSegmentIndex index = adaptationSet.representations.get(0).getIndex();
|
@Nullable DashSegmentIndex index = representations.get(0).getIndex();
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
return new PeriodSeekInfo(true, 0, durationUs);
|
return new PeriodSeekInfo(
|
||||||
|
/* isIndexExplicit= */ true,
|
||||||
|
/* availableStartTimeUs= */ 0,
|
||||||
|
/* availableEndTimeUs= */ periodDurationUs);
|
||||||
}
|
}
|
||||||
isIndexExplicit |= index.isExplicit();
|
isIndexExplicit |= index.isExplicit();
|
||||||
int segmentCount = index.getSegmentCount(durationUs);
|
int availableSegmentCount = index.getAvailableSegmentCount(periodDurationUs, nowUnixTimeUs);
|
||||||
if (segmentCount == 0) {
|
if (availableSegmentCount == 0) {
|
||||||
seenEmptyIndex = true;
|
seenEmptyIndex = true;
|
||||||
availableStartTimeUs = 0;
|
availableStartTimeUs = 0;
|
||||||
availableEndTimeUs = 0;
|
availableEndTimeUs = 0;
|
||||||
} else if (!seenEmptyIndex) {
|
} else if (!seenEmptyIndex) {
|
||||||
long firstSegmentNum = index.getFirstSegmentNum();
|
long firstAvailableSegmentNum =
|
||||||
long adaptationSetAvailableStartTimeUs = index.getTimeUs(firstSegmentNum);
|
index.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs);
|
||||||
|
long adaptationSetAvailableStartTimeUs = index.getTimeUs(firstAvailableSegmentNum);
|
||||||
availableStartTimeUs = max(availableStartTimeUs, adaptationSetAvailableStartTimeUs);
|
availableStartTimeUs = max(availableStartTimeUs, adaptationSetAvailableStartTimeUs);
|
||||||
if (segmentCount != DashSegmentIndex.INDEX_UNBOUNDED) {
|
long lastAvailableSegmentNum = firstAvailableSegmentNum + availableSegmentCount - 1;
|
||||||
long lastSegmentNum = firstSegmentNum + segmentCount - 1;
|
long adaptationSetAvailableEndTimeUs =
|
||||||
long adaptationSetAvailableEndTimeUs = index.getTimeUs(lastSegmentNum)
|
index.getTimeUs(lastAvailableSegmentNum)
|
||||||
+ index.getDurationUs(lastSegmentNum, durationUs);
|
+ index.getDurationUs(lastAvailableSegmentNum, periodDurationUs);
|
||||||
availableEndTimeUs = min(availableEndTimeUs, adaptationSetAvailableEndTimeUs);
|
availableEndTimeUs = min(availableEndTimeUs, adaptationSetAvailableEndTimeUs);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new PeriodSeekInfo(isIndexExplicit, availableStartTimeUs, availableEndTimeUs);
|
return new PeriodSeekInfo(isIndexExplicit, availableStartTimeUs, availableEndTimeUs);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user