Use regular array for SampleQueues in ExtractorMediaPeriod

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=160138881
This commit is contained in:
olly 2017-06-26 06:50:08 -07:00 committed by Oliver Woodman
parent c448463a05
commit acbddbc0a5

View File

@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.util.SparseArray;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
@ -42,6 +41,7 @@ import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
/** /**
* A {@link MediaPeriod} that extracts data using an {@link Extractor}. * A {@link MediaPeriod} that extracts data using an {@link Extractor}.
@ -71,11 +71,12 @@ import java.io.IOException;
private final Runnable maybeFinishPrepareRunnable; private final Runnable maybeFinishPrepareRunnable;
private final Runnable onContinueLoadingRequestedRunnable; private final Runnable onContinueLoadingRequestedRunnable;
private final Handler handler; private final Handler handler;
private final SparseArray<SampleQueue> sampleQueues;
private Callback callback; private Callback callback;
private SeekMap seekMap; private SeekMap seekMap;
private boolean tracksBuilt; private SampleQueue[] sampleQueues;
private int[] sampleQueueTrackIds;
private boolean sampleQueuesBuilt;
private boolean prepared; private boolean prepared;
private boolean seenFirstTrackSelection; private boolean seenFirstTrackSelection;
@ -140,19 +141,19 @@ import java.io.IOException;
} }
}; };
handler = new Handler(); handler = new Handler();
sampleQueueTrackIds = new int[0];
sampleQueues = new SampleQueue[0];
pendingResetPositionUs = C.TIME_UNSET; pendingResetPositionUs = C.TIME_UNSET;
sampleQueues = new SparseArray<>();
length = C.LENGTH_UNSET; length = C.LENGTH_UNSET;
} }
public void release() { public void release() {
boolean releasedSynchronously = loader.release(this); boolean releasedSynchronously = loader.release(this);
if (!releasedSynchronously) { if (prepared && !releasedSynchronously) {
// Discard as much as we can synchronously. // Discard as much as we can synchronously. We only do this if we're prepared, since
int trackCount = sampleQueues.size(); // otherwise sampleQueues may still be being modified by the loading thread.
for (int i = 0; i < trackCount; i++) { for (SampleQueue sampleQueue : sampleQueues) {
sampleQueues.valueAt(i).discardToEnd(); sampleQueue.discardToEnd();
} }
} }
handler.removeCallbacksAndMessages(null); handler.removeCallbacksAndMessages(null);
@ -162,9 +163,8 @@ import java.io.IOException;
@Override @Override
public void onLoaderReleased() { public void onLoaderReleased() {
extractorHolder.release(); extractorHolder.release();
int trackCount = sampleQueues.size(); for (SampleQueue sampleQueue : sampleQueues) {
for (int i = 0; i < trackCount; i++) { sampleQueue.reset(true);
sampleQueues.valueAt(i).reset(true);
} }
} }
@ -217,7 +217,7 @@ import java.io.IOException;
streamResetFlags[i] = true; streamResetFlags[i] = true;
// If there's still a chance of avoiding a seek, try and seek within the sample queue. // If there's still a chance of avoiding a seek, try and seek within the sample queue.
if (!seekRequired) { if (!seekRequired) {
SampleQueue sampleQueue = sampleQueues.valueAt(i); SampleQueue sampleQueue = sampleQueues[i];
sampleQueue.rewind(); sampleQueue.rewind();
seekRequired = !sampleQueue.advanceTo(positionUs, true, true) seekRequired = !sampleQueue.advanceTo(positionUs, true, true)
&& sampleQueue.getReadIndex() != 0; && sampleQueue.getReadIndex() != 0;
@ -244,9 +244,9 @@ import java.io.IOException;
@Override @Override
public void discardBuffer(long positionUs) { public void discardBuffer(long positionUs) {
int trackCount = sampleQueues.size(); int trackCount = sampleQueues.length;
for (int i = 0; i < trackCount; i++) { for (int i = 0; i < trackCount; i++) {
sampleQueues.valueAt(i).discardTo(positionUs, false, trackEnabledStates[i]); sampleQueues[i].discardTo(positionUs, false, trackEnabledStates[i]);
} }
} }
@ -288,11 +288,11 @@ import java.io.IOException;
if (haveAudioVideoTracks) { if (haveAudioVideoTracks) {
// Ignore non-AV tracks, which may be sparse or poorly interleaved. // Ignore non-AV tracks, which may be sparse or poorly interleaved.
largestQueuedTimestampUs = Long.MAX_VALUE; largestQueuedTimestampUs = Long.MAX_VALUE;
int trackCount = sampleQueues.size(); int trackCount = sampleQueues.length;
for (int i = 0; i < trackCount; i++) { for (int i = 0; i < trackCount; i++) {
if (trackIsAudioVideoFlags[i]) { if (trackIsAudioVideoFlags[i]) {
largestQueuedTimestampUs = Math.min(largestQueuedTimestampUs, largestQueuedTimestampUs = Math.min(largestQueuedTimestampUs,
sampleQueues.valueAt(i).getLargestQueuedTimestampUs()); sampleQueues[i].getLargestQueuedTimestampUs());
} }
} }
} else { } else {
@ -307,11 +307,11 @@ import java.io.IOException;
// Treat all seeks into non-seekable media as being to t=0. // Treat all seeks into non-seekable media as being to t=0.
positionUs = seekMap.isSeekable() ? positionUs : 0; positionUs = seekMap.isSeekable() ? positionUs : 0;
lastSeekPositionUs = positionUs; lastSeekPositionUs = positionUs;
int trackCount = sampleQueues.size();
// If we're not pending a reset, see if we can seek within the sample queues. // If we're not pending a reset, see if we can seek within the sample queues.
boolean seekInsideBuffer = !isPendingReset(); boolean seekInsideBuffer = !isPendingReset();
int trackCount = sampleQueues.length;
for (int i = 0; seekInsideBuffer && i < trackCount; i++) { for (int i = 0; seekInsideBuffer && i < trackCount; i++) {
SampleQueue sampleQueue = sampleQueues.valueAt(i); SampleQueue sampleQueue = sampleQueues[i];
sampleQueue.rewind(); sampleQueue.rewind();
// TODO: For sparse tracks (e.g. text, metadata) this may return false when an in-buffer // TODO: For sparse tracks (e.g. text, metadata) this may return false when an in-buffer
// seek should be allowed. If there are non-sparse tracks (e.g. video, audio) for which // seek should be allowed. If there are non-sparse tracks (e.g. video, audio) for which
@ -327,7 +327,7 @@ import java.io.IOException;
loader.cancelLoading(); loader.cancelLoading();
} else { } else {
for (int i = 0; i < trackCount; i++) { for (int i = 0; i < trackCount; i++) {
sampleQueues.valueAt(i).reset(trackEnabledStates[i]); sampleQueues[i].reset(trackEnabledStates[i]);
} }
} }
} }
@ -338,7 +338,7 @@ import java.io.IOException;
// SampleStream methods. // SampleStream methods.
/* package */ boolean isReady(int track) { /* package */ boolean isReady(int track) {
return loadingFinished || (!isPendingReset() && sampleQueues.valueAt(track).hasNextSample()); return loadingFinished || (!isPendingReset() && sampleQueues[track].hasNextSample());
} }
/* package */ void maybeThrowError() throws IOException { /* package */ void maybeThrowError() throws IOException {
@ -350,12 +350,12 @@ import java.io.IOException;
if (notifyReset || isPendingReset()) { if (notifyReset || isPendingReset()) {
return C.RESULT_NOTHING_READ; return C.RESULT_NOTHING_READ;
} }
return sampleQueues.valueAt(track).read(formatHolder, buffer, formatRequired, return sampleQueues[track].read(formatHolder, buffer, formatRequired, loadingFinished,
loadingFinished, lastSeekPositionUs); lastSeekPositionUs);
} }
/* package */ void skipData(int track, long positionUs) { /* package */ void skipData(int track, long positionUs) {
SampleQueue sampleQueue = sampleQueues.valueAt(track); SampleQueue sampleQueue = sampleQueues[track];
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) { if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
sampleQueue.advanceToEnd(); sampleQueue.advanceToEnd();
} else { } else {
@ -387,9 +387,8 @@ import java.io.IOException;
return; return;
} }
copyLengthFromLoader(loadable); copyLengthFromLoader(loadable);
int trackCount = sampleQueues.size(); for (SampleQueue sampleQueue : sampleQueues) {
for (int i = 0; i < trackCount; i++) { sampleQueue.reset(true);
sampleQueues.valueAt(i).reset(true);
} }
if (enabledTrackCount > 0) { if (enabledTrackCount > 0) {
callback.onContinueLoadingRequested(this); callback.onContinueLoadingRequested(this);
@ -415,18 +414,24 @@ import java.io.IOException;
@Override @Override
public TrackOutput track(int id, int type) { public TrackOutput track(int id, int type) {
SampleQueue trackOutput = sampleQueues.get(id); int trackCount = sampleQueues.length;
if (trackOutput == null) { for (int i = 0; i < trackCount; i++) {
trackOutput = new SampleQueue(allocator); if (sampleQueueTrackIds[i] == id) {
trackOutput.setUpstreamFormatChangeListener(this); return sampleQueues[i];
sampleQueues.put(id, trackOutput); }
} }
SampleQueue trackOutput = new SampleQueue(allocator);
trackOutput.setUpstreamFormatChangeListener(this);
sampleQueueTrackIds = Arrays.copyOf(sampleQueueTrackIds, trackCount + 1);
sampleQueueTrackIds[trackCount] = id;
sampleQueues = Arrays.copyOf(sampleQueues, trackCount + 1);
sampleQueues[trackCount] = trackOutput;
return trackOutput; return trackOutput;
} }
@Override @Override
public void endTracks() { public void endTracks() {
tracksBuilt = true; sampleQueuesBuilt = true;
handler.post(maybeFinishPrepareRunnable); handler.post(maybeFinishPrepareRunnable);
} }
@ -446,22 +451,22 @@ import java.io.IOException;
// Internal methods. // Internal methods.
private void maybeFinishPrepare() { private void maybeFinishPrepare() {
if (released || prepared || seekMap == null || !tracksBuilt) { if (released || prepared || seekMap == null || !sampleQueuesBuilt) {
return; return;
} }
int trackCount = sampleQueues.size(); for (SampleQueue sampleQueue : sampleQueues) {
for (int i = 0; i < trackCount; i++) { if (sampleQueue.getUpstreamFormat() == null) {
if (sampleQueues.valueAt(i).getUpstreamFormat() == null) {
return; return;
} }
} }
loadCondition.close(); loadCondition.close();
int trackCount = sampleQueues.length;
TrackGroup[] trackArray = new TrackGroup[trackCount]; TrackGroup[] trackArray = new TrackGroup[trackCount];
trackIsAudioVideoFlags = new boolean[trackCount]; trackIsAudioVideoFlags = new boolean[trackCount];
trackEnabledStates = new boolean[trackCount]; trackEnabledStates = new boolean[trackCount];
durationUs = seekMap.getDurationUs(); durationUs = seekMap.getDurationUs();
for (int i = 0; i < trackCount; i++) { for (int i = 0; i < trackCount; i++) {
Format trackFormat = sampleQueues.valueAt(i).getUpstreamFormat(); Format trackFormat = sampleQueues[i].getUpstreamFormat();
trackArray[i] = new TrackGroup(trackFormat); trackArray[i] = new TrackGroup(trackFormat);
String mimeType = trackFormat.sampleMimeType; String mimeType = trackFormat.sampleMimeType;
boolean isAudioVideo = MimeTypes.isVideo(mimeType) || MimeTypes.isAudio(mimeType); boolean isAudioVideo = MimeTypes.isVideo(mimeType) || MimeTypes.isAudio(mimeType);
@ -520,9 +525,8 @@ import java.io.IOException;
// a new load. // a new load.
lastSeekPositionUs = 0; lastSeekPositionUs = 0;
notifyReset = prepared; notifyReset = prepared;
int trackCount = sampleQueues.size(); for (SampleQueue sampleQueue : sampleQueues) {
for (int i = 0; i < trackCount; i++) { sampleQueue.reset(true);
sampleQueues.valueAt(i).reset(true);
} }
loadable.setLoadPosition(0, 0); loadable.setLoadPosition(0, 0);
} }
@ -530,19 +534,17 @@ import java.io.IOException;
private int getExtractedSamplesCount() { private int getExtractedSamplesCount() {
int extractedSamplesCount = 0; int extractedSamplesCount = 0;
int trackCount = sampleQueues.size(); for (SampleQueue sampleQueue : sampleQueues) {
for (int i = 0; i < trackCount; i++) { extractedSamplesCount += sampleQueue.getWriteIndex();
extractedSamplesCount += sampleQueues.valueAt(i).getWriteIndex();
} }
return extractedSamplesCount; return extractedSamplesCount;
} }
private long getLargestQueuedTimestampUs() { private long getLargestQueuedTimestampUs() {
long largestQueuedTimestampUs = Long.MIN_VALUE; long largestQueuedTimestampUs = Long.MIN_VALUE;
int trackCount = sampleQueues.size(); for (SampleQueue sampleQueue : sampleQueues) {
for (int i = 0; i < trackCount; i++) {
largestQueuedTimestampUs = Math.max(largestQueuedTimestampUs, largestQueuedTimestampUs = Math.max(largestQueuedTimestampUs,
sampleQueues.valueAt(i).getLargestQueuedTimestampUs()); sampleQueue.getLargestQueuedTimestampUs());
} }
return largestQueuedTimestampUs; return largestQueuedTimestampUs;
} }