Skip to content

Commit

Permalink
Take adaptation set into account to avoid undesired key collisions (e…
Browse files Browse the repository at this point in the history
….g. similar audio and video segment numbers)
  • Loading branch information
protyposis committed Nov 6, 2016
1 parent bd86d9c commit 98a4083
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ class CachedSegment {
int number;
Segment segment;
Representation representation;
AdaptationSet adaptationSet;
File file;
long ptsOffsetUs;

CachedSegment(int number, Segment segment, Representation representation) {
CachedSegment(int number, Segment segment, Representation representation, AdaptationSet adaptationSet) {
this.number = number;
this.segment = segment;
this.representation = representation;
this.adaptationSet = adaptationSet;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private void init(Integer segmentNr) throws IOException {
cachedSegment = mUsedCache.get(segmentNr);
if(cachedSegment == null) {
// Third, check if a request is already active
boolean downloading = mSegmentDownloader.isDownloading(segmentNr);
boolean downloading = mSegmentDownloader.isDownloading(mAdaptationSet, segmentNr);
/* TODO add synchronization to the whole caching code
* E.g., a request could have finished between this mFutureCacheRequests call and
* the previous mUsedCache call, whose result is missed.
Expand Down Expand Up @@ -453,7 +453,7 @@ private CachedSegment downloadFile(Integer segmentNr) throws IOException {
Response response = mSegmentDownloader.downloadBlocking(segment, segmentNr);
byte[] segmentData = response.body().bytes();
mAdaptationLogic.reportSegmentDownload(mAdaptationSet, mRepresentation, segment, segmentData.length, SystemClock.elapsedRealtime() - startTime);
CachedSegment cachedSegment = new CachedSegment(segmentNr, segment, mRepresentation);
CachedSegment cachedSegment = new CachedSegment(segmentNr, segment, mRepresentation, mAdaptationSet);
handleSegment(segmentData, cachedSegment);
Log.d(TAG, "sync dl " + segmentNr + " " + segment.toString() + " -> " + cachedSegment.file.getPath());

Expand All @@ -466,9 +466,9 @@ private CachedSegment downloadFile(Integer segmentNr) throws IOException {
private synchronized void fillFutureCache(Representation representation) {
int segmentsToBuffer = (int)Math.ceil((double)mMinBufferTimeUs / mRepresentation.segmentDurationUs);
for(int i = mCurrentSegment + 1; i < Math.min(mCurrentSegment + 1 + segmentsToBuffer, mRepresentation.segments.size()); i++) {
if(!mFutureCache.containsKey(i) && !mSegmentDownloader.isDownloading(i)) {
if(!mFutureCache.containsKey(i) && !mSegmentDownloader.isDownloading(mAdaptationSet, i)) {
Segment segment = representation.segments.get(i);
CachedSegment cachedSegment = new CachedSegment(i, segment, representation); // segment could be accessed through representation by i
CachedSegment cachedSegment = new CachedSegment(i, segment, representation, mAdaptationSet); // segment could be accessed through representation by i
Call call = mSegmentDownloader.downloadAsync(segment, cachedSegment, mSegmentDownloadCallback);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class SegmentDownloader {
private OkHttpClient mHttpClient;
private Headers mHeaders;
private PriorityQueue<CachedSegment> mDownloadQueue; // segments waiting in line to be requested
private Map<Integer, Call> mDownloadRequests; // segments currently being requested
private Map<String, Call> mDownloadRequests; // segments currently being requested
private int mMaxConcurrentDownloadRequests = 3;

SegmentDownloader(OkHttpClient httpClient, Map<String, String> headers) {
Expand Down Expand Up @@ -91,21 +91,21 @@ Call downloadAsync(Segment segment, CachedSegment cachedSegment, SegmentDownload
Request request = buildSegmentRequest(segment);

Call call = mHttpClient.newCall(request);
mDownloadRequests.put(cachedSegment.number, call);
mDownloadRequests.put(getKey(cachedSegment.adaptationSet, cachedSegment.number), call);
call.enqueue(new ResponseCallback(cachedSegment, callback));

return call;
}

boolean isDownloading(int segmentNr) {
boolean isDownloading(AdaptationSet adaptationSet, int segmentNr) {
// Check if the segment is in transfer
if(mDownloadRequests.containsKey(segmentNr)) {
if(mDownloadRequests.containsKey(getKey(adaptationSet, segmentNr))) {
return true;
}

// Check if the segment is queued
for(CachedSegment segment : mDownloadQueue) {
if(segment.number == segmentNr) {
if(segment.number == segmentNr && segment.adaptationSet == adaptationSet) {
return true;
}
}
Expand All @@ -118,12 +118,21 @@ void cancelDownloads() {
mDownloadQueue.clear();

// Cancel requests
for(Integer segmentNumber : mDownloadRequests.keySet()) {
mDownloadRequests.get(segmentNumber).cancel();
for(String key : mDownloadRequests.keySet()) {
mDownloadRequests.get(key).cancel();
}
mDownloadRequests.clear();
}

/**
* Returns a unique key for a segment of an adaptation set. Just using the segment number as
* key does not suffice because multiple adaptation sets (e.g. video and audio) have overlapping
* segment numbers.
*/
private String getKey(AdaptationSet adaptationSet, int segmentNr) {
return adaptationSet.group + "-" + segmentNr;
}

/**
* Builds a request object for a segment.
*/
Expand Down

0 comments on commit 98a4083

Please sign in to comment.