From 3dcdfe5d7cbc91f5d5118e565c8bb234e4fb05cc Mon Sep 17 00:00:00 2001 From: microkatz <45770613+microkatz@users.noreply.github.com> Date: Wed, 8 Feb 2023 15:38:48 +0000 Subject: [PATCH] Merge pull request #248 from lemondoglol:update-segment-size PiperOrigin-RevId: 507784608 (cherry picked from commit 08342ea9da96240c87e3e7c486eec0b0929138da) --- .../exoplayer2/offline/SegmentDownloader.java | 36 +++++++++++++++--- .../source/dash/offline/DashDownloader.java | 38 +++++++++++++++++-- .../source/hls/offline/HlsDownloader.java | 38 +++++++++++++++++-- .../smoothstreaming/offline/SsDownloader.java | 34 +++++++++++++++-- 4 files changed, 132 insertions(+), 14 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java index 764d2c63f5b..ef47bf0c17e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloader.java @@ -72,8 +72,9 @@ public int compareTo(Segment other) { } } + public static final long DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS = 20 * C.MILLIS_PER_SECOND; + private static final int BUFFER_SIZE_BYTES = 128 * 1024; - private static final long MAX_MERGED_SEGMENT_START_TIME_DIFF_US = 20 * C.MICROS_PER_SECOND; private final DataSpec manifestDataSpec; private final Parser manifestParser; @@ -83,6 +84,7 @@ public int compareTo(Segment other) { private final CacheKeyFactory cacheKeyFactory; @Nullable private final PriorityTaskManager priorityTaskManager; private final Executor executor; + private final long maxMergedSegmentStartTimeDiffUs; /** * The currently active runnables. @@ -96,6 +98,24 @@ public int compareTo(Segment other) { private volatile boolean isCanceled; + /** + * @deprecated Use {@link SegmentDownloader#SegmentDownloader(MediaItem, Parser, + * CacheDataSource.Factory, Executor, long)} instead. + */ + @Deprecated + public SegmentDownloader( + MediaItem mediaItem, + Parser manifestParser, + CacheDataSource.Factory cacheDataSourceFactory, + Executor executor) { + this( + mediaItem, + manifestParser, + cacheDataSourceFactory, + executor, + DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS); + } + /** * @param mediaItem The {@link MediaItem} to be downloaded. * @param manifestParser A parser for manifests belonging to the media to be downloaded. @@ -104,12 +124,16 @@ public int compareTo(Segment other) { * @param executor An {@link Executor} used to make requests for the media being downloaded. * Providing an {@link Executor} that uses multiple threads will speed up the download by * allowing parts of it to be executed in parallel. + * @param maxMergedSegmentStartTimeDiffMs The maximum difference of the start time of two + * segments, up to which the segments (of the same URI) should be merged into a single + * download segment, in milliseconds. */ public SegmentDownloader( MediaItem mediaItem, Parser manifestParser, CacheDataSource.Factory cacheDataSourceFactory, - Executor executor) { + Executor executor, + long maxMergedSegmentStartTimeDiffMs) { checkNotNull(mediaItem.localConfiguration); this.manifestDataSpec = getCompressibleDataSpec(mediaItem.localConfiguration.uri); this.manifestParser = manifestParser; @@ -120,6 +144,7 @@ public SegmentDownloader( cacheKeyFactory = cacheDataSourceFactory.getCacheKeyFactory(); priorityTaskManager = cacheDataSourceFactory.getUpstreamPriorityTaskManager(); activeRunnables = new ArrayList<>(); + maxMergedSegmentStartTimeDiffUs = Util.msToUs(maxMergedSegmentStartTimeDiffMs); } @Override @@ -142,7 +167,7 @@ public final void download(@Nullable ProgressListener progressListener) // Sort the segments so that we download media in the right order from the start of the // content, and merge segments where possible to minimize the number of server round trips. Collections.sort(segments); - mergeSegments(segments, cacheKeyFactory); + mergeSegments(segments, cacheKeyFactory, maxMergedSegmentStartTimeDiffUs); // Scan the segments, removing any that are fully downloaded. int totalSegments = segments.size(); @@ -413,7 +438,8 @@ private void removeActiveRunnable(int index) { } } - private static void mergeSegments(List segments, CacheKeyFactory keyFactory) { + private static void mergeSegments( + List segments, CacheKeyFactory keyFactory, long maxMergedSegmentStartTimeDiffUs) { HashMap lastIndexByCacheKey = new HashMap<>(); int nextOutIndex = 0; for (int i = 0; i < segments.size(); i++) { @@ -422,7 +448,7 @@ private static void mergeSegments(List segments, CacheKeyFactory keyFac @Nullable Integer lastIndex = lastIndexByCacheKey.get(cacheKey); @Nullable Segment lastSegment = lastIndex == null ? null : segments.get(lastIndex); if (lastSegment == null - || segment.startTimeUs > lastSegment.startTimeUs + MAX_MERGED_SEGMENT_START_TIME_DIFF_US + || segment.startTimeUs > lastSegment.startTimeUs + maxMergedSegmentStartTimeDiffUs || !canMergeSegments(lastSegment.dataSpec, segment.dataSpec)) { lastIndexByCacheKey.put(cacheKey, nextOutIndex); segments.set(nextOutIndex, segment); diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java index f397b5c2be9..b21c38c9c9c 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloader.java @@ -98,7 +98,30 @@ public DashDownloader(MediaItem mediaItem, CacheDataSource.Factory cacheDataSour */ public DashDownloader( MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory, Executor executor) { - this(mediaItem, new DashManifestParser(), cacheDataSourceFactory, executor); + this( + mediaItem, + new DashManifestParser(), + cacheDataSourceFactory, + executor, + DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS); + } + + /** + * @deprecated Use {@link DashDownloader#DashDownloader(MediaItem, Parser, + * CacheDataSource.Factory, Executor, long)} instead. + */ + @Deprecated + public DashDownloader( + MediaItem mediaItem, + Parser manifestParser, + CacheDataSource.Factory cacheDataSourceFactory, + Executor executor) { + this( + mediaItem, + manifestParser, + cacheDataSourceFactory, + executor, + DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS); } /** @@ -111,13 +134,22 @@ public DashDownloader( * @param executor An {@link Executor} used to make requests for the media being downloaded. * Providing an {@link Executor} that uses multiple threads will speed up the download by * allowing parts of it to be executed in parallel. + * @param maxMergedSegmentStartTimeDiffMs The maximum difference of the start time of two + * segments, up to which the segments (of the same URI) should be merged into a single + * download segment, in milliseconds. */ public DashDownloader( MediaItem mediaItem, Parser manifestParser, CacheDataSource.Factory cacheDataSourceFactory, - Executor executor) { - super(mediaItem, manifestParser, cacheDataSourceFactory, executor); + Executor executor, + long maxMergedSegmentStartTimeDiffMs) { + super( + mediaItem, + manifestParser, + cacheDataSourceFactory, + executor, + maxMergedSegmentStartTimeDiffMs); baseUrlExclusionList = new BaseUrlExclusionList(); } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloader.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloader.java index a22efa428a3..0deac215338 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloader.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloader.java @@ -87,7 +87,30 @@ public HlsDownloader(MediaItem mediaItem, CacheDataSource.Factory cacheDataSourc */ public HlsDownloader( MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory, Executor executor) { - this(mediaItem, new HlsPlaylistParser(), cacheDataSourceFactory, executor); + this( + mediaItem, + new HlsPlaylistParser(), + cacheDataSourceFactory, + executor, + DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS); + } + + /** + * @deprecated Use {@link HlsDownloader#HlsDownloader(MediaItem, Parser, CacheDataSource.Factory, + * Executor, long)} instead. + */ + @Deprecated + public HlsDownloader( + MediaItem mediaItem, + Parser manifestParser, + CacheDataSource.Factory cacheDataSourceFactory, + Executor executor) { + this( + mediaItem, + manifestParser, + cacheDataSourceFactory, + executor, + DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS); } /** @@ -100,13 +123,22 @@ public HlsDownloader( * @param executor An {@link Executor} used to make requests for the media being downloaded. * Providing an {@link Executor} that uses multiple threads will speed up the download by * allowing parts of it to be executed in parallel. + * @param maxMergedSegmentStartTimeDiffMs The maximum difference of the start time of two + * segments, up to which the segments (of the same URI) should be merged into a single + * download segment, in milliseconds. */ public HlsDownloader( MediaItem mediaItem, Parser manifestParser, CacheDataSource.Factory cacheDataSourceFactory, - Executor executor) { - super(mediaItem, manifestParser, cacheDataSourceFactory, executor); + Executor executor, + long maxMergedSegmentStartTimeDiffMs) { + super( + mediaItem, + manifestParser, + cacheDataSourceFactory, + executor, + maxMergedSegmentStartTimeDiffMs); } @Override diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java index 695cbad3213..8946922d22b 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.java @@ -91,7 +91,26 @@ public SsDownloader( .build(), new SsManifestParser(), cacheDataSourceFactory, - executor); + executor, + DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS); + } + + /** + * @deprecated Use {@link SsDownloader#SsDownloader(MediaItem, Parser, CacheDataSource.Factory, + * Executor, long)} instead. + */ + @Deprecated + public SsDownloader( + MediaItem mediaItem, + Parser manifestParser, + CacheDataSource.Factory cacheDataSourceFactory, + Executor executor) { + this( + mediaItem, + manifestParser, + cacheDataSourceFactory, + executor, + DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS); } /** @@ -104,13 +123,22 @@ public SsDownloader( * @param executor An {@link Executor} used to make requests for the media being downloaded. * Providing an {@link Executor} that uses multiple threads will speed up the download by * allowing parts of it to be executed in parallel. + * @param maxMergedSegmentStartTimeDiffMs The maximum difference of the start time of two + * segments, up to which the segments (of the same URI) should be merged into a single + * download segment, in milliseconds. */ public SsDownloader( MediaItem mediaItem, Parser manifestParser, CacheDataSource.Factory cacheDataSourceFactory, - Executor executor) { - super(mediaItem, manifestParser, cacheDataSourceFactory, executor); + Executor executor, + long maxMergedSegmentStartTimeDiffMs) { + super( + mediaItem, + manifestParser, + cacheDataSourceFactory, + executor, + maxMergedSegmentStartTimeDiffMs); } @Override