Skip to content

Commit

Permalink
Force single audio and video sample queues
Browse files Browse the repository at this point in the history
This solves the problem of having dense tracks' ids change.
For example, if the available variants offer both HEVC and AVC video
tracks, all video samples will map to the same sample queue even if
IDs don't match.

Issue:#3653

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182070486
  • Loading branch information
AquilesCanta authored and ojw28 committed Jan 23, 2018
1 parent be30448 commit 3919843
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public HlsMediaChunk(HlsExtractorFactory extractorFactory, DataSource dataSource
*/
public void init(HlsSampleStreamWrapper output) {
this.output = output;
output.init(uid, shouldSpliceIn);
output.init(uid, shouldSpliceIn, reusingExtractor);
if (!reusingExtractor) {
extractor.init(output);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ public interface Callback extends SequenceableLoader.Callback<HlsSampleStreamWra

private SampleQueue[] sampleQueues;
private int[] sampleQueueTrackIds;
private boolean audioSampleQueueMappingDone;
private int audioSampleQueueIndex;
private boolean videoSampleQueueMappingDone;
private int videoSampleQueueIndex;
private boolean sampleQueuesBuilt;
private boolean prepared;
private int enabledTrackGroupCount;
Expand Down Expand Up @@ -143,6 +147,8 @@ public HlsSampleStreamWrapper(int trackType, Callback callback, HlsChunkSource c
loader = new Loader("Loader:HlsSampleStreamWrapper");
nextChunkHolder = new HlsChunkSource.HlsChunkHolder();
sampleQueueTrackIds = new int[0];
audioSampleQueueIndex = C.INDEX_UNSET;
videoSampleQueueIndex = C.INDEX_UNSET;
sampleQueues = new SampleQueue[0];
sampleQueueIsAudioVideoFlags = new boolean[0];
sampleQueuesEnabledStates = new boolean[0];
Expand Down Expand Up @@ -616,8 +622,14 @@ public int onLoadError(Chunk loadable, long elapsedRealtimeMs, long loadDuration
* @param chunkUid The chunk's uid.
* @param shouldSpliceIn Whether the samples parsed from the chunk should be spliced into any
* samples already queued to the wrapper.
* @param reusingExtractor Whether the extractor for the chunk has already been used for preceding
* chunks.
*/
public void init(int chunkUid, boolean shouldSpliceIn) {
public void init(int chunkUid, boolean shouldSpliceIn, boolean reusingExtractor) {
if (!reusingExtractor) {
audioSampleQueueMappingDone = false;
videoSampleQueueMappingDone = false;
}
for (SampleQueue sampleQueue : sampleQueues) {
sampleQueue.sourceId(chunkUid);
}
Expand All @@ -633,14 +645,43 @@ public void init(int chunkUid, boolean shouldSpliceIn) {
@Override
public TrackOutput track(int id, int type) {
int trackCount = sampleQueues.length;
for (int i = 0; i < trackCount; i++) {
if (sampleQueueTrackIds[i] == id) {
return sampleQueues[i];

// Audio and video tracks are handled manually to ignore ids.
if (type == C.TRACK_TYPE_AUDIO) {
if (audioSampleQueueIndex != C.INDEX_UNSET) {
if (audioSampleQueueMappingDone) {
return sampleQueueTrackIds[audioSampleQueueIndex] == id
? sampleQueues[audioSampleQueueIndex]
: createDummyTrackOutput(id, type);
}
audioSampleQueueMappingDone = true;
sampleQueueTrackIds[audioSampleQueueIndex] = id;
return sampleQueues[audioSampleQueueIndex];
} else if (tracksEnded) {
return createDummyTrackOutput(id, type);
}
} else if (type == C.TRACK_TYPE_VIDEO) {
if (videoSampleQueueIndex != C.INDEX_UNSET) {
if (videoSampleQueueMappingDone) {
return sampleQueueTrackIds[videoSampleQueueIndex] == id
? sampleQueues[videoSampleQueueIndex]
: createDummyTrackOutput(id, type);
}
videoSampleQueueMappingDone = true;
sampleQueueTrackIds[videoSampleQueueIndex] = id;
return sampleQueues[videoSampleQueueIndex];
} else if (tracksEnded) {
return createDummyTrackOutput(id, type);
}
} else /* sparse track */ {
for (int i = 0; i < trackCount; i++) {
if (sampleQueueTrackIds[i] == id) {
return sampleQueues[i];
}
}
if (tracksEnded) {
return createDummyTrackOutput(id, type);
}
}
if (tracksEnded) {
Log.w(TAG, "Unmapped track with id " + id + " of type " + type);
return new DummyTrackOutput();
}
SampleQueue trackOutput = new SampleQueue(allocator);
trackOutput.setSampleOffsetUs(sampleOffsetUs);
Expand All @@ -653,6 +694,13 @@ public TrackOutput track(int id, int type) {
sampleQueueIsAudioVideoFlags[trackCount] = type == C.TRACK_TYPE_AUDIO
|| type == C.TRACK_TYPE_VIDEO;
haveAudioVideoSampleQueues |= sampleQueueIsAudioVideoFlags[trackCount];
if (type == C.TRACK_TYPE_AUDIO) {
audioSampleQueueMappingDone = true;
audioSampleQueueIndex = trackCount;
} else if (type == C.TRACK_TYPE_VIDEO) {
videoSampleQueueMappingDone = true;
videoSampleQueueIndex = trackCount;
}
sampleQueuesEnabledStates = Arrays.copyOf(sampleQueuesEnabledStates, trackCount + 1);
return trackOutput;
}
Expand Down Expand Up @@ -913,4 +961,9 @@ private static boolean formatsMatch(Format manifestFormat, Format sampleFormat)
}
return true;
}

private static DummyTrackOutput createDummyTrackOutput(int id, int type) {
Log.w(TAG, "Unmapped track with id " + id + " of type " + type);
return new DummyTrackOutput();
}
}

0 comments on commit 3919843

Please sign in to comment.