make merged segment size configurable
This commit is contained in:
parent
e2ece2f5bc
commit
b65baf7d72
@ -76,7 +76,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final int BUFFER_SIZE_BYTES = 128 * 1024;
|
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;
|
public static final long DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_US = 20 * C.MICROS_PER_SECOND;
|
||||||
|
|
||||||
private final DataSpec manifestDataSpec;
|
private final DataSpec manifestDataSpec;
|
||||||
private final Parser<M> manifestParser;
|
private final Parser<M> manifestParser;
|
||||||
@ -86,6 +86,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||||||
private final CacheKeyFactory cacheKeyFactory;
|
private final CacheKeyFactory cacheKeyFactory;
|
||||||
@Nullable private final PriorityTaskManager priorityTaskManager;
|
@Nullable private final PriorityTaskManager priorityTaskManager;
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
|
private final long maxMergedSegmentStartTimeDiffUs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The currently active runnables.
|
* The currently active runnables.
|
||||||
@ -100,19 +101,16 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||||||
private volatile boolean isCanceled;
|
private volatile boolean isCanceled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mediaItem The {@link MediaItem} to be downloaded.
|
* @deprecated Use {@link SegmentDownloader#SegmentDownloader(MediaItem, Parser,
|
||||||
* @param manifestParser A parser for manifests belonging to the media to be downloaded.
|
* CacheDataSource.Factory, Executor, long)} instead.
|
||||||
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
|
||||||
* download will be written.
|
|
||||||
* @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.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public SegmentDownloader(
|
public SegmentDownloader(
|
||||||
MediaItem mediaItem,
|
MediaItem mediaItem,
|
||||||
Parser<M> manifestParser,
|
Parser<M> manifestParser,
|
||||||
CacheDataSource.Factory cacheDataSourceFactory,
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
Executor executor) {
|
Executor executor
|
||||||
|
) {
|
||||||
checkNotNull(mediaItem.localConfiguration);
|
checkNotNull(mediaItem.localConfiguration);
|
||||||
this.manifestDataSpec = getCompressibleDataSpec(mediaItem.localConfiguration.uri);
|
this.manifestDataSpec = getCompressibleDataSpec(mediaItem.localConfiguration.uri);
|
||||||
this.manifestParser = manifestParser;
|
this.manifestParser = manifestParser;
|
||||||
@ -123,6 +121,39 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||||||
cacheKeyFactory = cacheDataSourceFactory.getCacheKeyFactory();
|
cacheKeyFactory = cacheDataSourceFactory.getCacheKeyFactory();
|
||||||
priorityTaskManager = cacheDataSourceFactory.getUpstreamPriorityTaskManager();
|
priorityTaskManager = cacheDataSourceFactory.getUpstreamPriorityTaskManager();
|
||||||
activeRunnables = new ArrayList<>();
|
activeRunnables = new ArrayList<>();
|
||||||
|
maxMergedSegmentStartTimeDiffUs = DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_US;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mediaItem The {@link MediaItem} to be downloaded.
|
||||||
|
* @param manifestParser A parser for manifests belonging to the media to be downloaded.
|
||||||
|
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||||
|
* download will be written.
|
||||||
|
* @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<M> manifestParser,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
Executor executor,
|
||||||
|
long maxMergedSegmentStartTimeDiffMs
|
||||||
|
) {
|
||||||
|
checkNotNull(mediaItem.localConfiguration);
|
||||||
|
this.manifestDataSpec = getCompressibleDataSpec(mediaItem.localConfiguration.uri);
|
||||||
|
this.manifestParser = manifestParser;
|
||||||
|
this.streamKeys = new ArrayList<>(mediaItem.localConfiguration.streamKeys);
|
||||||
|
this.cacheDataSourceFactory = cacheDataSourceFactory;
|
||||||
|
this.executor = executor;
|
||||||
|
cache = Assertions.checkNotNull(cacheDataSourceFactory.getCache());
|
||||||
|
cacheKeyFactory = cacheDataSourceFactory.getCacheKeyFactory();
|
||||||
|
priorityTaskManager = cacheDataSourceFactory.getUpstreamPriorityTaskManager();
|
||||||
|
activeRunnables = new ArrayList<>();
|
||||||
|
maxMergedSegmentStartTimeDiffUs = Util.msToUs(maxMergedSegmentStartTimeDiffMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -145,7 +176,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||||||
// Sort the segments so that we download media in the right order from the start of the
|
// 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.
|
// content, and merge segments where possible to minimize the number of server round trips.
|
||||||
Collections.sort(segments);
|
Collections.sort(segments);
|
||||||
mergeSegments(segments, cacheKeyFactory);
|
mergeSegments(segments, cacheKeyFactory, maxMergedSegmentStartTimeDiffUs);
|
||||||
|
|
||||||
// Scan the segments, removing any that are fully downloaded.
|
// Scan the segments, removing any that are fully downloaded.
|
||||||
int totalSegments = segments.size();
|
int totalSegments = segments.size();
|
||||||
@ -416,7 +447,11 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void mergeSegments(List<Segment> segments, CacheKeyFactory keyFactory) {
|
private static void mergeSegments(
|
||||||
|
List<Segment> segments,
|
||||||
|
CacheKeyFactory keyFactory,
|
||||||
|
long maxMergedSegmentStartTimeDiffUs
|
||||||
|
) {
|
||||||
HashMap<String, Integer> lastIndexByCacheKey = new HashMap<>();
|
HashMap<String, Integer> lastIndexByCacheKey = new HashMap<>();
|
||||||
int nextOutIndex = 0;
|
int nextOutIndex = 0;
|
||||||
for (int i = 0; i < segments.size(); i++) {
|
for (int i = 0; i < segments.size(); i++) {
|
||||||
@ -425,7 +460,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||||||
@Nullable Integer lastIndex = lastIndexByCacheKey.get(cacheKey);
|
@Nullable Integer lastIndex = lastIndexByCacheKey.get(cacheKey);
|
||||||
@Nullable Segment lastSegment = lastIndex == null ? null : segments.get(lastIndex);
|
@Nullable Segment lastSegment = lastIndex == null ? null : segments.get(lastIndex);
|
||||||
if (lastSegment == null
|
if (lastSegment == null
|
||||||
|| segment.startTimeUs > lastSegment.startTimeUs + MAX_MERGED_SEGMENT_START_TIME_DIFF_US
|
|| segment.startTimeUs > lastSegment.startTimeUs + maxMergedSegmentStartTimeDiffUs
|
||||||
|| !canMergeSegments(lastSegment.dataSpec, segment.dataSpec)) {
|
|| !canMergeSegments(lastSegment.dataSpec, segment.dataSpec)) {
|
||||||
lastIndexByCacheKey.put(cacheKey, nextOutIndex);
|
lastIndexByCacheKey.put(cacheKey, nextOutIndex);
|
||||||
segments.set(nextOutIndex, segment);
|
segments.set(nextOutIndex, segment);
|
||||||
|
@ -100,7 +100,28 @@ public final class DashDownloader extends SegmentDownloader<DashManifest> {
|
|||||||
*/
|
*/
|
||||||
public DashDownloader(
|
public DashDownloader(
|
||||||
MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory, Executor executor) {
|
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_US);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link DashDownloader#DashDownloader(MediaItem, Parser,
|
||||||
|
* CacheDataSource.Factory, Executor, long)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public DashDownloader(
|
||||||
|
MediaItem mediaItem,
|
||||||
|
Parser<DashManifest> manifestParser,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
Executor executor
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
mediaItem,
|
||||||
|
manifestParser,
|
||||||
|
cacheDataSourceFactory,
|
||||||
|
executor,
|
||||||
|
DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_US
|
||||||
|
);
|
||||||
|
baseUrlExclusionList = new BaseUrlExclusionList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,13 +134,24 @@ public final class DashDownloader extends SegmentDownloader<DashManifest> {
|
|||||||
* @param executor An {@link Executor} used to make requests for the media being downloaded.
|
* @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
|
* Providing an {@link Executor} that uses multiple threads will speed up the download by
|
||||||
* allowing parts of it to be executed in parallel.
|
* 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(
|
public DashDownloader(
|
||||||
MediaItem mediaItem,
|
MediaItem mediaItem,
|
||||||
Parser<DashManifest> manifestParser,
|
Parser<DashManifest> manifestParser,
|
||||||
CacheDataSource.Factory cacheDataSourceFactory,
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
Executor executor) {
|
Executor executor,
|
||||||
super(mediaItem, manifestParser, cacheDataSourceFactory, executor);
|
long maxMergedSegmentStartTimeDiffMs
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
mediaItem,
|
||||||
|
manifestParser,
|
||||||
|
cacheDataSourceFactory,
|
||||||
|
executor,
|
||||||
|
maxMergedSegmentStartTimeDiffMs
|
||||||
|
);
|
||||||
baseUrlExclusionList = new BaseUrlExclusionList();
|
baseUrlExclusionList = new BaseUrlExclusionList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,33 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
|
|||||||
*/
|
*/
|
||||||
public HlsDownloader(
|
public HlsDownloader(
|
||||||
MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory, Executor executor) {
|
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_US
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link HlsDownloader#HlsDownloader(MediaItem, Parser,
|
||||||
|
* CacheDataSource.Factory, Executor, long)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public HlsDownloader(
|
||||||
|
MediaItem mediaItem,
|
||||||
|
Parser<HlsPlaylist> manifestParser,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
Executor executor
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
mediaItem,
|
||||||
|
manifestParser,
|
||||||
|
cacheDataSourceFactory,
|
||||||
|
executor,
|
||||||
|
DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_US
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,13 +128,24 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
|
|||||||
* @param executor An {@link Executor} used to make requests for the media being downloaded.
|
* @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
|
* Providing an {@link Executor} that uses multiple threads will speed up the download by
|
||||||
* allowing parts of it to be executed in parallel.
|
* 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(
|
public HlsDownloader(
|
||||||
MediaItem mediaItem,
|
MediaItem mediaItem,
|
||||||
Parser<HlsPlaylist> manifestParser,
|
Parser<HlsPlaylist> manifestParser,
|
||||||
CacheDataSource.Factory cacheDataSourceFactory,
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
Executor executor) {
|
Executor executor,
|
||||||
super(mediaItem, manifestParser, cacheDataSourceFactory, executor);
|
long maxMergedSegmentStartTimeDiffMs
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
mediaItem,
|
||||||
|
manifestParser,
|
||||||
|
cacheDataSourceFactory,
|
||||||
|
executor,
|
||||||
|
maxMergedSegmentStartTimeDiffMs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,7 +93,29 @@ public final class SsDownloader extends SegmentDownloader<SsManifest> {
|
|||||||
.build(),
|
.build(),
|
||||||
new SsManifestParser(),
|
new SsManifestParser(),
|
||||||
cacheDataSourceFactory,
|
cacheDataSourceFactory,
|
||||||
executor);
|
executor,
|
||||||
|
DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_US
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link SsDownloader#SsDownloader(MediaItem, Parser,
|
||||||
|
* CacheDataSource.Factory, Executor, long)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public SsDownloader(
|
||||||
|
MediaItem mediaItem,
|
||||||
|
Parser<SsManifest> manifestParser,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
Executor executor
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
mediaItem,
|
||||||
|
manifestParser,
|
||||||
|
cacheDataSourceFactory,
|
||||||
|
executor,
|
||||||
|
DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_US
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,13 +128,24 @@ public final class SsDownloader extends SegmentDownloader<SsManifest> {
|
|||||||
* @param executor An {@link Executor} used to make requests for the media being downloaded.
|
* @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
|
* Providing an {@link Executor} that uses multiple threads will speed up the download by
|
||||||
* allowing parts of it to be executed in parallel.
|
* 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(
|
public SsDownloader(
|
||||||
MediaItem mediaItem,
|
MediaItem mediaItem,
|
||||||
Parser<SsManifest> manifestParser,
|
Parser<SsManifest> manifestParser,
|
||||||
CacheDataSource.Factory cacheDataSourceFactory,
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
Executor executor) {
|
Executor executor,
|
||||||
super(mediaItem, manifestParser, cacheDataSourceFactory, executor);
|
long maxMergedSegmentStartTimeDiffMs
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
mediaItem,
|
||||||
|
manifestParser,
|
||||||
|
cacheDataSourceFactory,
|
||||||
|
executor,
|
||||||
|
maxMergedSegmentStartTimeDiffMs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user