Skip to content

Commit

Permalink
Merge pull request #2 from google/dev-v2
Browse files Browse the repository at this point in the history
Pull from google/ExoPlayer dev-v2
  • Loading branch information
ybai001 authored Dec 6, 2018
2 parents 7a924d6 + 556dd7e commit 246d464
Show file tree
Hide file tree
Showing 35 changed files with 404 additions and 279 deletions.
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
([#3314](https://github.com/google/ExoPlayer/issues/3314)).
* Do not retry failed loads whose error is `FileNotFoundException`.
* Prevent Cea608Decoder from generating Subtitles with null Cues list
* Caching: Cache data with unknown length by default. The previous flag to opt in
to this behavior (`DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH`) has been
replaced with an opt out flag (`DataSpec.FLAG_DONT_CACHE_IF_LENGTH_UNKNOWN`).

### 2.9.2 ###

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ public ImaAdsMediaSource(
adUiViewGroup, eventHandler, eventListener);
}

@Override
@Nullable
public Object getTag() {
return adsMediaSource.getTag();
}

@Override
public void prepareSourceInternal(
final ExoPlayer player,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
import com.google.android.exoplayer2.util.Assertions;

/**
* Listener of audio {@link Renderer} events.
* Listener of audio {@link Renderer} events. All methods have no-op default implementations to
* allow selective overrides.
*/
public interface AudioRendererEventListener {

Expand All @@ -35,14 +36,14 @@ public interface AudioRendererEventListener {
* @param counters {@link DecoderCounters} that will be updated by the renderer for as long as it
* remains enabled.
*/
void onAudioEnabled(DecoderCounters counters);
default void onAudioEnabled(DecoderCounters counters) {}

/**
* Called when the audio session is set.
*
* @param audioSessionId The audio session id.
*/
void onAudioSessionId(int audioSessionId);
default void onAudioSessionId(int audioSessionId) {}

/**
* Called when a decoder is created.
Expand All @@ -52,15 +53,15 @@ public interface AudioRendererEventListener {
* finished.
* @param initializationDurationMs The time taken to initialize the decoder in milliseconds.
*/
void onAudioDecoderInitialized(String decoderName, long initializedTimestampMs,
long initializationDurationMs);
default void onAudioDecoderInitialized(
String decoderName, long initializedTimestampMs, long initializationDurationMs) {}

/**
* Called when the format of the media being consumed by the renderer changes.
*
* @param format The new format.
*/
void onAudioInputFormatChanged(Format format);
default void onAudioInputFormatChanged(Format format) {}

/**
* Called when an {@link AudioSink} underrun occurs.
Expand All @@ -71,14 +72,15 @@ void onAudioDecoderInitialized(String decoderName, long initializedTimestampMs,
* as the buffered media can have a variable bitrate so the duration may be unknown.
* @param elapsedSinceLastFeedMs The time since the {@link AudioSink} was last fed data.
*/
void onAudioSinkUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs);
default void onAudioSinkUnderrun(
int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {}

/**
* Called when the renderer is disabled.
*
* @param counters {@link DecoderCounters} that were updated by the renderer.
*/
void onAudioDisabled(DecoderCounters counters);
default void onAudioDisabled(DecoderCounters counters) {}

/**
* Dispatches events to a {@link AudioRendererEventListener}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,21 @@
*/
package com.google.android.exoplayer2.offline;

import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
import java.util.List;

/** A helper for initializing and removing downloads. */
public abstract class DownloadHelper {
/**
* A helper for initializing and removing downloads.
*
* @param <T> The manifest type.
*/
public abstract class DownloadHelper<T> {

/** A callback to be notified when the {@link DownloadHelper} is prepared. */
public interface Callback {
Expand All @@ -44,21 +50,42 @@ public interface Callback {
void onPrepareError(DownloadHelper helper, IOException e);
}

private final String downloadType;
private final Uri uri;
@Nullable private final String cacheKey;

@Nullable private T manifest;
@Nullable private TrackGroupArray[] trackGroupArrays;

/**
* Create download helper.
*
* @param downloadType A download type. This value will be used as {@link DownloadAction#type}.
* @param uri A {@link Uri}.
* @param cacheKey An optional cache key.
*/
public DownloadHelper(String downloadType, Uri uri, @Nullable String cacheKey) {
this.downloadType = downloadType;
this.uri = uri;
this.cacheKey = cacheKey;
}

/**
* Initializes the helper for starting a download.
*
* @param callback A callback to be notified when preparation completes or fails. The callback
* will be invoked on the calling thread unless that thread does not have an associated {@link
* Looper}, in which case it will be called on the application's main thread.
*/
public void prepare(final Callback callback) {
public final void prepare(final Callback callback) {
final Handler handler =
new Handler(Looper.myLooper() != null ? Looper.myLooper() : Looper.getMainLooper());
new Thread() {
@Override
public void run() {
try {
prepareInternal();
manifest = loadManifest(uri);
trackGroupArrays = getTrackGroupArrays(manifest);
handler.post(() -> callback.onPrepared(DownloadHelper.this));
} catch (final IOException e) {
handler.post(() -> callback.onPrepareError(DownloadHelper.this, e));
Expand All @@ -67,18 +94,20 @@ public void run() {
}.start();
}

/**
* Called on a background thread during preparation.
*
* @throws IOException If preparation fails.
*/
protected abstract void prepareInternal() throws IOException;
/** Returns the manifest. Must not be called until after preparation completes. */
public final T getManifest() {
Assertions.checkNotNull(manifest);
return manifest;
}

/**
* Returns the number of periods for which media is available. Must not be called until after
* preparation completes.
*/
public abstract int getPeriodCount();
public final int getPeriodCount() {
Assertions.checkNotNull(trackGroupArrays);
return trackGroupArrays.length;
}

/**
* Returns the track groups for the given period. Must not be called until after preparation
Expand All @@ -88,7 +117,10 @@ public void run() {
* @return The track groups for the period. May be {@link TrackGroupArray#EMPTY} for single stream
* content.
*/
public abstract TrackGroupArray getTrackGroups(int periodIndex);
public final TrackGroupArray getTrackGroups(int periodIndex) {
Assertions.checkNotNull(trackGroupArrays);
return trackGroupArrays[periodIndex];
}

/**
* Builds a {@link DownloadAction} for downloading the specified tracks. Must not be called until
Expand All @@ -98,12 +130,41 @@ public void run() {
* @param trackKeys The selected tracks. If empty, all streams will be downloaded.
* @return The built {@link DownloadAction}.
*/
public abstract DownloadAction getDownloadAction(@Nullable byte[] data, List<TrackKey> trackKeys);
public final DownloadAction getDownloadAction(@Nullable byte[] data, List<TrackKey> trackKeys) {
return DownloadAction.createDownloadAction(
downloadType, uri, toStreamKeys(trackKeys), cacheKey, data);
}

/**
* Builds a {@link DownloadAction} for removing the media. May be called in any state.
*
* @return The built {@link DownloadAction}.
*/
public abstract DownloadAction getRemoveAction();
public final DownloadAction getRemoveAction() {
return DownloadAction.createRemoveAction(downloadType, uri, cacheKey);
}

/**
* Loads the manifest. This method is called on a background thread.
*
* @param uri The manifest uri.
* @throws IOException If loading fails.
*/
protected abstract T loadManifest(Uri uri) throws IOException;

/**
* Returns the track group arrays for each period in the manifest.
*
* @param manifest The manifest.
* @return An array of {@link TrackGroupArray}s. One for each period in the manifest.
*/
protected abstract TrackGroupArray[] getTrackGroupArrays(T manifest);

/**
* Converts a list of {@link TrackKey track keys} to {@link StreamKey stream keys}.
*
* @param trackKeys A list of track keys.
* @return A corresponding list of stream keys.
*/
protected abstract List<StreamKey> toStreamKeys(List<TrackKey> trackKeys);
}
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ private static final class Task implements Runnable {
*/
@TargetState private volatile int targetState;

@MonotonicNonNull private volatile Downloader downloader;
@MonotonicNonNull private Downloader downloader;
@MonotonicNonNull private Thread thread;
@MonotonicNonNull private Throwable error;

Expand Down Expand Up @@ -624,6 +624,7 @@ public void start() {
state = STATE_STARTED;
targetState = STATE_COMPLETED;
downloadManager.onTaskStateChange(this);
downloader = downloaderFactory.createDownloader(action);
thread = new Thread(this);
thread.start();
}
Expand All @@ -648,11 +649,7 @@ public void stop() {

private void stopDownloadThread(@TargetState int targetState) {
this.targetState = targetState;
// TODO: The possibility of downloader being null here may prevent the download thread from
// stopping in a timely way. Fix this.
if (downloader != null) {
downloader.cancel();
}
Assertions.checkNotNull(downloader).cancel();
Assertions.checkNotNull(thread).interrupt();
}

Expand All @@ -675,7 +672,6 @@ public void run() {
logd("Task is started", this);
Throwable error = null;
try {
downloader = downloaderFactory.createDownloader(action);
if (action.isRemoveAction) {
downloader.remove();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,47 +22,28 @@
import java.util.List;

/** A {@link DownloadHelper} for progressive streams. */
public final class ProgressiveDownloadHelper extends DownloadHelper {

private final Uri uri;
private final @Nullable String customCacheKey;
public final class ProgressiveDownloadHelper extends DownloadHelper<Void> {

public ProgressiveDownloadHelper(Uri uri) {
this(uri, null);
}

public ProgressiveDownloadHelper(Uri uri, @Nullable String customCacheKey) {
this.uri = uri;
this.customCacheKey = customCacheKey;
}

@Override
protected void prepareInternal() {
// Do nothing.
}

@Override
public int getPeriodCount() {
return 1;
super(DownloadAction.TYPE_PROGRESSIVE, uri, customCacheKey);
}

@Override
public TrackGroupArray getTrackGroups(int periodIndex) {
return TrackGroupArray.EMPTY;
protected Void loadManifest(Uri uri) {
return null;
}

@Override
public DownloadAction getDownloadAction(@Nullable byte[] data, List<TrackKey> trackKeys) {
return DownloadAction.createDownloadAction(
DownloadAction.TYPE_PROGRESSIVE,
uri,
/* keys= */ Collections.emptyList(),
customCacheKey,
data);
protected TrackGroupArray[] getTrackGroupArrays(Void manifest) {
return new TrackGroupArray[] {TrackGroupArray.EMPTY};
}

@Override
public DownloadAction getRemoveAction() {
return DownloadAction.createRemoveAction(DownloadAction.TYPE_PROGRESSIVE, uri, customCacheKey);
protected List<StreamKey> toStreamKeys(List<TrackKey> trackKeys) {
return Collections.emptyList();
}
}
Loading

0 comments on commit 246d464

Please sign in to comment.