use of com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment in project ExoPlayer by google.
the class DefaultDashChunkSource method onChunkLoadError.
@Override
public boolean onChunkLoadError(Chunk chunk, boolean cancelable, LoadErrorHandlingPolicy.LoadErrorInfo loadErrorInfo, LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
if (!cancelable) {
return false;
}
if (playerTrackEmsgHandler != null && playerTrackEmsgHandler.onChunkLoadError(chunk)) {
return true;
}
// Workaround for missing segment at the end of the period
if (!manifest.dynamic && chunk instanceof MediaChunk && loadErrorInfo.exception instanceof InvalidResponseCodeException && ((InvalidResponseCodeException) loadErrorInfo.exception).responseCode == 404) {
RepresentationHolder representationHolder = representationHolders[trackSelection.indexOf(chunk.trackFormat)];
long segmentCount = representationHolder.getSegmentCount();
if (segmentCount != DashSegmentIndex.INDEX_UNBOUNDED && segmentCount != 0) {
long lastAvailableSegmentNum = representationHolder.getFirstSegmentNum() + segmentCount - 1;
if (((MediaChunk) chunk).getNextChunkIndex() > lastAvailableSegmentNum) {
missingLastSegment = true;
return true;
}
}
}
int trackIndex = trackSelection.indexOf(chunk.trackFormat);
RepresentationHolder representationHolder = representationHolders[trackIndex];
@Nullable BaseUrl newBaseUrl = baseUrlExclusionList.selectBaseUrl(representationHolder.representation.baseUrls);
if (newBaseUrl != null && !representationHolder.selectedBaseUrl.equals(newBaseUrl)) {
// which will use the new base URL.
return true;
}
LoadErrorHandlingPolicy.FallbackOptions fallbackOptions = createFallbackOptions(trackSelection, representationHolder.representation.baseUrls);
if (!fallbackOptions.isFallbackAvailable(LoadErrorHandlingPolicy.FALLBACK_TYPE_TRACK) && !fallbackOptions.isFallbackAvailable(LoadErrorHandlingPolicy.FALLBACK_TYPE_LOCATION)) {
return false;
}
@Nullable LoadErrorHandlingPolicy.FallbackSelection fallbackSelection = loadErrorHandlingPolicy.getFallbackSelectionFor(fallbackOptions, loadErrorInfo);
if (fallbackSelection == null || !fallbackOptions.isFallbackAvailable(fallbackSelection.type)) {
// Policy indicated to not use any fallback or a fallback type that is not available.
return false;
}
boolean cancelLoad = false;
if (fallbackSelection.type == LoadErrorHandlingPolicy.FALLBACK_TYPE_TRACK) {
cancelLoad = trackSelection.blacklist(trackSelection.indexOf(chunk.trackFormat), fallbackSelection.exclusionDurationMs);
} else if (fallbackSelection.type == LoadErrorHandlingPolicy.FALLBACK_TYPE_LOCATION) {
baseUrlExclusionList.exclude(representationHolder.selectedBaseUrl, fallbackSelection.exclusionDurationMs);
cancelLoad = true;
}
return cancelLoad;
}
use of com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment in project ExoPlayer by google.
the class DashMediaSourceTest method prepare_targetLiveOffsetInWindow_manifestTargetOffsetAndAlignedWindowStartPosition.
@Test
public void prepare_targetLiveOffsetInWindow_manifestTargetOffsetAndAlignedWindowStartPosition() throws InterruptedException {
DashMediaSource mediaSource = new DashMediaSource.Factory(() -> createSampleMpdDataSource(SAMPLE_MPD_LIVE_WITH_OFFSET_INSIDE_WINDOW)).createMediaSource(MediaItem.fromUri(Uri.EMPTY));
Window window = prepareAndWaitForTimelineRefresh(mediaSource);
// Expect the target live offset as defined in the manifest.
assertThat(window.liveConfiguration.targetOffsetMs).isEqualTo(3000);
// Expect the default position at the first segment start before the live edge.
assertThat(window.getDefaultPositionMs()).isEqualTo(2_000);
}
use of com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment in project ExoPlayer by google.
the class DashMediaSourceTest method prepare_targetLiveOffsetTooShort_correctedTargetOffsetAndAlignedWindowStartPosition.
@Test
public void prepare_targetLiveOffsetTooShort_correctedTargetOffsetAndAlignedWindowStartPosition() throws InterruptedException {
// Load manifest with now time far behind the start of the window.
DashMediaSource mediaSource = new DashMediaSource.Factory(() -> createSampleMpdDataSource(SAMPLE_MPD_LIVE_WITH_OFFSET_TOO_SHORT)).createMediaSource(MediaItem.fromUri(Uri.EMPTY));
Window window = prepareAndWaitForTimelineRefresh(mediaSource);
// Expect the default position at the start of the last segment.
assertThat(window.getDefaultPositionMs()).isEqualTo(12_000);
// Expect the target live offset reaching from now time to the end of the window.
assertThat(window.liveConfiguration.targetOffsetMs).isEqualTo(60_000 - 16_000);
}
use of com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment in project ExoPlayer by google.
the class MatroskaExtractor method startMasterElement.
/**
* Called when the start of a master element is encountered.
*
* @see EbmlProcessor#startMasterElement(int, long, long)
*/
@CallSuper
protected void startMasterElement(int id, long contentPosition, long contentSize) throws ParserException {
assertInitialized();
switch(id) {
case ID_SEGMENT:
if (segmentContentPosition != C.POSITION_UNSET && segmentContentPosition != contentPosition) {
throw ParserException.createForMalformedContainer("Multiple Segment elements not supported", /* cause= */
null);
}
segmentContentPosition = contentPosition;
segmentContentSize = contentSize;
break;
case ID_SEEK:
seekEntryId = UNSET_ENTRY_ID;
seekEntryPosition = C.POSITION_UNSET;
break;
case ID_CUES:
cueTimesUs = new LongArray();
cueClusterPositions = new LongArray();
break;
case ID_CUE_POINT:
seenClusterPositionForCurrentCuePoint = false;
break;
case ID_CLUSTER:
if (!sentSeekMap) {
// We need to build cues before parsing the cluster.
if (seekForCuesEnabled && cuesContentPosition != C.POSITION_UNSET) {
// We know where the Cues element is located. Seek to request it.
seekForCues = true;
} else {
// We don't know where the Cues element is located. It's most likely omitted. Allow
// playback, but disable seeking.
extractorOutput.seekMap(new SeekMap.Unseekable(durationUs));
sentSeekMap = true;
}
}
break;
case ID_BLOCK_GROUP:
blockHasReferenceBlock = false;
break;
case ID_CONTENT_ENCODING:
// TODO: check and fail if more than one content encoding is present.
break;
case ID_CONTENT_ENCRYPTION:
getCurrentTrack(id).hasContentEncryption = true;
break;
case ID_TRACK_ENTRY:
currentTrack = new Track();
break;
case ID_MASTERING_METADATA:
getCurrentTrack(id).hasColorInfo = true;
break;
default:
break;
}
}
use of com.google.android.exoplayer2.metadata.mp4.SlowMotionData.Segment in project ExoPlayer by google.
the class SegmentSpeedProvider method extractSlowMotionSegments.
private static ImmutableList<Segment> extractSlowMotionSegments(Format format) {
List<Segment> segments = new ArrayList<>();
@Nullable Metadata metadata = format.metadata;
if (metadata != null) {
for (int i = 0; i < metadata.length(); i++) {
Metadata.Entry entry = metadata.get(i);
if (entry instanceof SlowMotionData) {
segments.addAll(((SlowMotionData) entry).segments);
}
}
}
return ImmutableList.sortedCopyOf(BY_START_THEN_END_THEN_DIVISOR, segments);
}
Aggregations