Commit 3a9d08ed by Oliver Woodman

Misc performance/correctness tweaks.

parent f1fe109b
...@@ -53,6 +53,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -53,6 +53,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
public ExoPlayerImpl(int rendererCount, int minBufferMs, int minRebufferMs) { public ExoPlayerImpl(int rendererCount, int minBufferMs, int minRebufferMs) {
Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION); Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION);
this.playWhenReady = false;
this.playbackState = STATE_IDLE; this.playbackState = STATE_IDLE;
this.listeners = new CopyOnWriteArraySet<Listener>(); this.listeners = new CopyOnWriteArraySet<Listener>();
this.rendererEnabledFlags = new boolean[rendererCount]; this.rendererEnabledFlags = new boolean[rendererCount];
......
...@@ -156,7 +156,7 @@ public class MediaFormat { ...@@ -156,7 +156,7 @@ public class MediaFormat {
public int hashCode() { public int hashCode() {
if (hashCode == 0) { if (hashCode == 0) {
int result = 17; int result = 17;
result = 31 * result + mimeType == null ? 0 : mimeType.hashCode(); result = 31 * result + (mimeType == null ? 0 : mimeType.hashCode());
result = 31 * result + maxInputSize; result = 31 * result + maxInputSize;
result = 31 * result + width; result = 31 * result + width;
result = 31 * result + height; result = 31 * result + height;
......
...@@ -80,9 +80,11 @@ import java.util.ArrayList; ...@@ -80,9 +80,11 @@ import java.util.ArrayList;
public final static class ContainerAtom extends Atom { public final static class ContainerAtom extends Atom {
public final ArrayList<Atom> children; public final ArrayList<Atom> children;
public final int endByteOffset;
public ContainerAtom(int type) { public ContainerAtom(int type, int endByteOffset) {
super(type); super(type);
this.endByteOffset = endByteOffset;
children = new ArrayList<Atom>(); children = new ArrayList<Atom>();
} }
......
...@@ -139,7 +139,6 @@ public final class FragmentedMp4Extractor implements Extractor { ...@@ -139,7 +139,6 @@ public final class FragmentedMp4Extractor implements Extractor {
private final ParsableByteArray atomHeader; private final ParsableByteArray atomHeader;
private final byte[] extendedTypeScratch; private final byte[] extendedTypeScratch;
private final Stack<ContainerAtom> containerAtoms; private final Stack<ContainerAtom> containerAtoms;
private final Stack<Integer> containerAtomEndPoints;
private final TrackFragment fragmentRun; private final TrackFragment fragmentRun;
private int parserState; private int parserState;
...@@ -174,7 +173,6 @@ public final class FragmentedMp4Extractor implements Extractor { ...@@ -174,7 +173,6 @@ public final class FragmentedMp4Extractor implements Extractor {
atomHeader = new ParsableByteArray(ATOM_HEADER_SIZE); atomHeader = new ParsableByteArray(ATOM_HEADER_SIZE);
extendedTypeScratch = new byte[16]; extendedTypeScratch = new byte[16];
containerAtoms = new Stack<ContainerAtom>(); containerAtoms = new Stack<ContainerAtom>();
containerAtomEndPoints = new Stack<Integer>();
fragmentRun = new TrackFragment(); fragmentRun = new TrackFragment();
psshData = new HashMap<UUID, byte[]>(); psshData = new HashMap<UUID, byte[]>();
} }
...@@ -258,7 +256,6 @@ public final class FragmentedMp4Extractor implements Extractor { ...@@ -258,7 +256,6 @@ public final class FragmentedMp4Extractor implements Extractor {
} }
} }
containerAtoms.clear(); containerAtoms.clear();
containerAtomEndPoints.clear();
enterState(STATE_READING_ATOM_HEADER); enterState(STATE_READING_ATOM_HEADER);
return true; return true;
} }
...@@ -267,7 +264,7 @@ public final class FragmentedMp4Extractor implements Extractor { ...@@ -267,7 +264,7 @@ public final class FragmentedMp4Extractor implements Extractor {
switch (state) { switch (state) {
case STATE_READING_ATOM_HEADER: case STATE_READING_ATOM_HEADER:
atomBytesRead = 0; atomBytesRead = 0;
if (containerAtomEndPoints.isEmpty()) { if (containerAtoms.isEmpty()) {
rootAtomBytesRead = 0; rootAtomBytesRead = 0;
} }
break; break;
...@@ -300,11 +297,12 @@ public final class FragmentedMp4Extractor implements Extractor { ...@@ -300,11 +297,12 @@ public final class FragmentedMp4Extractor implements Extractor {
return 0; return 0;
} }
if (PARSED_ATOMS.contains(atomType)) { Integer atomTypeInteger = atomType; // Avoids boxing atomType twice.
if (CONTAINER_TYPES.contains(atomType)) { if (PARSED_ATOMS.contains(atomTypeInteger)) {
if (CONTAINER_TYPES.contains(atomTypeInteger)) {
enterState(STATE_READING_ATOM_HEADER); enterState(STATE_READING_ATOM_HEADER);
containerAtoms.add(new ContainerAtom(atomType)); containerAtoms.add(new ContainerAtom(atomType,
containerAtomEndPoints.add(rootAtomBytesRead + atomSize - ATOM_HEADER_SIZE); rootAtomBytesRead + atomSize - ATOM_HEADER_SIZE));
} else { } else {
atomData = new ParsableByteArray(atomSize); atomData = new ParsableByteArray(atomSize);
System.arraycopy(atomHeader.data, 0, atomData.data, 0, ATOM_HEADER_SIZE); System.arraycopy(atomHeader.data, 0, atomData.data, 0, ATOM_HEADER_SIZE);
...@@ -339,9 +337,7 @@ public final class FragmentedMp4Extractor implements Extractor { ...@@ -339,9 +337,7 @@ public final class FragmentedMp4Extractor implements Extractor {
results |= onLeafAtomRead(new LeafAtom(atomType, atomData)); results |= onLeafAtomRead(new LeafAtom(atomType, atomData));
} }
while (!containerAtomEndPoints.isEmpty() while (!containerAtoms.isEmpty() && containerAtoms.peek().endByteOffset == rootAtomBytesRead) {
&& containerAtomEndPoints.peek() == rootAtomBytesRead) {
containerAtomEndPoints.pop();
results |= onContainerAtomRead(containerAtoms.pop()); results |= onContainerAtomRead(containerAtoms.pop());
} }
......
...@@ -343,8 +343,8 @@ public class SmoothStreamingChunkSource implements ChunkSource { ...@@ -343,8 +343,8 @@ public class SmoothStreamingChunkSource implements ChunkSource {
TrackElement trackElement = streamElement.tracks[trackIndex]; TrackElement trackElement = streamElement.tracks[trackIndex];
String mimeType = trackElement.mimeType; String mimeType = trackElement.mimeType;
if (streamElement.type == StreamElement.TYPE_VIDEO) { if (streamElement.type == StreamElement.TYPE_VIDEO) {
MediaFormat format = MediaFormat.createVideoFormat(mimeType, -1, trackElement.maxWidth, MediaFormat format = MediaFormat.createVideoFormat(mimeType, MediaFormat.NO_VALUE,
trackElement.maxHeight, Arrays.asList(trackElement.csd)); trackElement.maxWidth, trackElement.maxHeight, Arrays.asList(trackElement.csd));
format.setMaxVideoDimensions(streamElement.maxWidth, streamElement.maxHeight); format.setMaxVideoDimensions(streamElement.maxWidth, streamElement.maxHeight);
return format; return format;
} else if (streamElement.type == StreamElement.TYPE_AUDIO) { } else if (streamElement.type == StreamElement.TYPE_AUDIO) {
...@@ -355,8 +355,8 @@ public class SmoothStreamingChunkSource implements ChunkSource { ...@@ -355,8 +355,8 @@ public class SmoothStreamingChunkSource implements ChunkSource {
csd = Collections.singletonList(CodecSpecificDataUtil.buildAudioSpecificConfig( csd = Collections.singletonList(CodecSpecificDataUtil.buildAudioSpecificConfig(
trackElement.sampleRate, trackElement.numChannels)); trackElement.sampleRate, trackElement.numChannels));
} }
MediaFormat format = MediaFormat.createAudioFormat(mimeType, -1, trackElement.numChannels, MediaFormat format = MediaFormat.createAudioFormat(mimeType, MediaFormat.NO_VALUE,
trackElement.sampleRate, csd); trackElement.numChannels, trackElement.sampleRate, csd);
return format; return format;
} else if (streamElement.type == StreamElement.TYPE_TEXT) { } else if (streamElement.type == StreamElement.TYPE_TEXT) {
return MediaFormat.createFormatForMimeType(streamElement.tracks[trackIndex].mimeType); return MediaFormat.createFormatForMimeType(streamElement.tracks[trackIndex].mimeType);
......
...@@ -273,7 +273,7 @@ public class SmoothStreamingManifest { ...@@ -273,7 +273,7 @@ public class SmoothStreamingManifest {
Assertions.checkState(chunkIndex < chunkStartTimes.size()); Assertions.checkState(chunkIndex < chunkStartTimes.size());
String chunkUrl = chunkTemplate String chunkUrl = chunkTemplate
.replace(URL_PLACEHOLDER_BITRATE, Integer.toString(tracks[track].bitrate)) .replace(URL_PLACEHOLDER_BITRATE, Integer.toString(tracks[track].bitrate))
.replace(URL_PLACEHOLDER_START_TIME, Long.toString(chunkStartTimes.get(chunkIndex))); .replace(URL_PLACEHOLDER_START_TIME, chunkStartTimes.get(chunkIndex).toString());
return Util.getMergedUri(baseUri, chunkUrl); return Util.getMergedUri(baseUri, chunkUrl);
} }
......
...@@ -97,7 +97,7 @@ public class SubtitleView extends View { ...@@ -97,7 +97,7 @@ public class SubtitleView extends View {
Resources resources = getContext().getResources(); Resources resources = getContext().getResources();
DisplayMetrics displayMetrics = resources.getDisplayMetrics(); DisplayMetrics displayMetrics = resources.getDisplayMetrics();
int twoDpInPx = Math.round((2 * displayMetrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT); int twoDpInPx = Math.round((2f * displayMetrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT);
cornerRadius = twoDpInPx; cornerRadius = twoDpInPx;
outlineWidth = twoDpInPx; outlineWidth = twoDpInPx;
shadowRadius = twoDpInPx; shadowRadius = twoDpInPx;
......
...@@ -53,10 +53,17 @@ public final class NetworkLock { ...@@ -53,10 +53,17 @@ public final class NetworkLock {
*/ */
public static final int DOWNLOAD_PRIORITY = 10; public static final int DOWNLOAD_PRIORITY = 10;
private final Object lock = new Object();
/** Guarded by {@link #lock}. */
private final PriorityQueue<Integer> queue; private final PriorityQueue<Integer> queue;
/** Guarded by {@link #lock}. */
private int highestPriority;
private NetworkLock() { private NetworkLock() {
queue = new PriorityQueue<Integer>(); queue = new PriorityQueue<Integer>();
highestPriority = Integer.MAX_VALUE;
} }
/** /**
...@@ -64,9 +71,11 @@ public final class NetworkLock { ...@@ -64,9 +71,11 @@ public final class NetworkLock {
* *
* @param priority The priority of the task that would like to proceed. * @param priority The priority of the task that would like to proceed.
*/ */
public synchronized void proceed(int priority) throws InterruptedException { public void proceed(int priority) throws InterruptedException {
while (queue.peek() < priority) { synchronized (lock) {
wait(); while (highestPriority < priority) {
lock.wait();
}
} }
} }
...@@ -76,8 +85,10 @@ public final class NetworkLock { ...@@ -76,8 +85,10 @@ public final class NetworkLock {
* @param priority The priority of the task that would like to proceed. * @param priority The priority of the task that would like to proceed.
* @return Whether the passed priority is allowed to proceed. * @return Whether the passed priority is allowed to proceed.
*/ */
public synchronized boolean proceedNonBlocking(int priority) { public boolean proceedNonBlocking(int priority) {
return queue.peek() >= priority; synchronized (lock) {
return highestPriority >= priority;
}
} }
/** /**
...@@ -86,10 +97,11 @@ public final class NetworkLock { ...@@ -86,10 +97,11 @@ public final class NetworkLock {
* @param priority The priority of the task that would like to proceed. * @param priority The priority of the task that would like to proceed.
* @throws PriorityTooLowException If the passed priority is not high enough to proceed. * @throws PriorityTooLowException If the passed priority is not high enough to proceed.
*/ */
public synchronized void proceedOrThrow(int priority) throws PriorityTooLowException { public void proceedOrThrow(int priority) throws PriorityTooLowException {
int highestPriority = queue.peek(); synchronized (lock) {
if (highestPriority < priority) { if (highestPriority < priority) {
throw new PriorityTooLowException(priority, highestPriority); throw new PriorityTooLowException(priority, highestPriority);
}
} }
} }
...@@ -100,8 +112,11 @@ public final class NetworkLock { ...@@ -100,8 +112,11 @@ public final class NetworkLock {
* *
* @param priority The priority of the task. * @param priority The priority of the task.
*/ */
public synchronized void add(int priority) { public void add(int priority) {
queue.add(priority); synchronized (lock) {
queue.add(priority);
highestPriority = Math.min(highestPriority, priority);
}
} }
/** /**
...@@ -109,9 +124,12 @@ public final class NetworkLock { ...@@ -109,9 +124,12 @@ public final class NetworkLock {
* *
* @param priority The priority of the task. * @param priority The priority of the task.
*/ */
public synchronized void remove(int priority) { public void remove(int priority) {
queue.remove(priority); synchronized (lock) {
notifyAll(); queue.remove(priority);
highestPriority = queue.isEmpty() ? Integer.MAX_VALUE : queue.peek();
lock.notifyAll();
}
} }
} }
...@@ -317,8 +317,8 @@ public final class Util { ...@@ -317,8 +317,8 @@ public final class Util {
} else if (matcher.group(9).equalsIgnoreCase("Z")) { } else if (matcher.group(9).equalsIgnoreCase("Z")) {
timezoneShift = 0; timezoneShift = 0;
} else { } else {
timezoneShift = ((Integer.valueOf(matcher.group(12)) * 60 timezoneShift = ((Integer.parseInt(matcher.group(12)) * 60
+ Integer.valueOf(matcher.group(13)))); + Integer.parseInt(matcher.group(13))));
if (matcher.group(11).equals("-")) { if (matcher.group(11).equals("-")) {
timezoneShift *= -1; timezoneShift *= -1;
} }
...@@ -328,12 +328,12 @@ public final class Util { ...@@ -328,12 +328,12 @@ public final class Util {
dateTime.clear(); dateTime.clear();
// Note: The month value is 0-based, hence the -1 on group(2) // Note: The month value is 0-based, hence the -1 on group(2)
dateTime.set(Integer.valueOf(matcher.group(1)), dateTime.set(Integer.parseInt(matcher.group(1)),
Integer.valueOf(matcher.group(2)) - 1, Integer.parseInt(matcher.group(2)) - 1,
Integer.valueOf(matcher.group(3)), Integer.parseInt(matcher.group(3)),
Integer.valueOf(matcher.group(4)), Integer.parseInt(matcher.group(4)),
Integer.valueOf(matcher.group(5)), Integer.parseInt(matcher.group(5)),
Integer.valueOf(matcher.group(6))); Integer.parseInt(matcher.group(6)));
if (!TextUtils.isEmpty(matcher.group(8))) { if (!TextUtils.isEmpty(matcher.group(8))) {
final BigDecimal bd = new BigDecimal("0." + matcher.group(8)); final BigDecimal bd = new BigDecimal("0." + matcher.group(8));
// we care only for milliseconds, so movePointRight(3) // we care only for milliseconds, so movePointRight(3)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment