Skip to content

Commit

Permalink
Merge pull request #5388 from google/dev-v2-r2.9.4
Browse files Browse the repository at this point in the history
r2.9.4
  • Loading branch information
ojw28 authored Jan 21, 2019
2 parents 71f72c5 + 200c877 commit 1c4ea26
Show file tree
Hide file tree
Showing 72 changed files with 1,030 additions and 317 deletions.
40 changes: 31 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ repository and depend on the modules locally.

### From JCenter ###

#### 1. Add repositories ####

The easiest way to get started using ExoPlayer is to add it as a gradle
dependency. You need to make sure you have the Google and JCenter repositories
included in the `build.gradle` file in the root of your project:
Expand All @@ -38,22 +40,16 @@ repositories {
}
```

#### 2. Add ExoPlayer module dependencies ####

Next add a dependency in the `build.gradle` file of your app module. The
following will add a dependency to the full library:

```gradle
implementation 'com.google.android.exoplayer:exoplayer:2.X.X'
```

where `2.X.X` is your preferred version. If not enabled already, you also need
to turn on Java 8 support in all `build.gradle` files depending on ExoPlayer, by
adding the following to the `android` section:

```gradle
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
}
```
where `2.X.X` is your preferred version.

As an alternative to the full library, you can depend on only the library
modules that you actually need. For example the following will add dependencies
Expand Down Expand Up @@ -87,6 +83,32 @@ JCenter can be found on [Bintray][].
[extensions directory]: https://github.com/google/ExoPlayer/tree/release-v2/extensions/
[Bintray]: https://bintray.com/google/exoplayer

#### 3. Turn on Java 8 support ####

If not enabled already, you also need to turn on Java 8 support in all
`build.gradle` files depending on ExoPlayer, by adding the following to the
`android` section:

```gradle
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
}
```

Note that if you want to use Java 8 features in your own code, the following
additional options need to be set:

```gradle
// For Java compilers:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
}
// For Kotlin compilers:
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
```

### Locally ###

Cloning the repository and depending on the modules locally is required when
Expand Down
29 changes: 29 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Release notes #

### 2.9.4 ###

* IMA extension: Clear ads loader listeners on release
([#4114](https://github.com/google/ExoPlayer/issues/4114)).
* SmoothStreaming: Fix support for subtitles in DRM protected streams
([#5378](https://github.com/google/ExoPlayer/issues/5378)).
* FFmpeg extension: Treat invalid data errors as non-fatal to match the behavior
of MediaCodec ([#5293](https://github.com/google/ExoPlayer/issues/5293)).
* GVR extension: upgrade GVR SDK dependency to 1.190.0.
* Associate fatal player errors of type SOURCE with the loading source in
`AnalyticsListener.EventTime`
([#5407](https://github.com/google/ExoPlayer/issues/5407)).
* Add `startPositionUs` to `MediaSource.createPeriod`. This fixes an issue where
using lazy preparation in `ConcatenatingMediaSource` with an
`ExtractorMediaSource` overrides initial seek positions
([#5350](https://github.com/google/ExoPlayer/issues/5350)).
* Add subtext to the `MediaDescriptionAdapter` of the
`PlayerNotificationManager`.
* Add workaround for video quality problems with Amlogic decoders
([#5003](https://github.com/google/ExoPlayer/issues/5003)).
* Fix issue where sending callbacks for playlist changes may cause problems
because of parallel player access
([#5240](https://github.com/google/ExoPlayer/issues/5240)).
* Fix issue with reusing a `ClippingMediaSource` with an inner
`ExtractorMediaSource` and a non-zero start position
([#5351](https://github.com/google/ExoPlayer/issues/5351)).
* Fix issue where uneven track durations in MP4 streams can cause OOM problems
([#3670](https://github.com/google/ExoPlayer/issues/3670)).

### 2.9.3 ###

* Captions: Support PNG subtitles in SMPTE-TT
Expand Down
4 changes: 2 additions & 2 deletions constants.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
// limitations under the License.
project.ext {
// ExoPlayer version and version code.
releaseVersion = '2.9.3'
releaseVersionCode = 2009003
releaseVersion = '2.9.4'
releaseVersionCode = 2009004
// Important: ExoPlayer specifies a minSdkVersion of 14 because various
// components provided by the library may be of use on older devices.
// However, please note that the core media playback functionality provided
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.gms.cast.framework.CastButtonFactory;
import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.dynamite.DynamiteModule;

/**
* An activity that plays video using {@link SimpleExoPlayer} and {@link CastPlayer}.
Expand All @@ -61,7 +62,20 @@ public class MainActivity extends AppCompatActivity implements OnClickListener,
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Getting the cast context later than onStart can cause device discovery not to take place.
castContext = CastContext.getSharedInstance(this);
try {
castContext = CastContext.getSharedInstance(this);
} catch (RuntimeException e) {
Throwable cause = e.getCause();
while (cause != null) {
if (cause instanceof DynamiteModule.LoadingException) {
setContentView(R.layout.cast_context_error_message_layout);
return;
}
cause = cause.getCause();
}
// Unknown error. We propagate it.
throw e;
}

setContentView(R.layout.main_activity);

Expand Down Expand Up @@ -91,6 +105,10 @@ public boolean onCreateOptionsMenu(Menu menu) {
@Override
public void onResume() {
super.onResume();
if (castContext == null) {
// There is no Cast context to work with. Do nothing.
return;
}
playerManager =
PlayerManager.createPlayerManager(
/* queuePositionListener= */ this,
Expand All @@ -104,6 +122,10 @@ public void onResume() {
@Override
public void onPause() {
super.onPause();
if (castContext == null) {
// Nothing to release.
return;
}
mediaQueueListAdapter.notifyItemRangeRemoved(0, mediaQueueListAdapter.getItemCount());
mediaQueueList.setAdapter(null);
playerManager.release();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:textSize="20sp"
android:gravity="center"
android:text="@string/cast_context_error"/>
</LinearLayout>
2 changes: 2 additions & 0 deletions demos/cast/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@

<string name="sample_list_dialog_title">Add samples</string>

<string name="cast_context_error">Failed to get Cast context. Try updating Google Play Services and restart the app.</string>

</resources>
4 changes: 3 additions & 1 deletion extensions/cast/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ android {
}

dependencies {
api 'com.google.android.gms:play-services-cast-framework:16.0.3'
api 'com.google.android.gms:play-services-cast-framework:16.1.2'
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
compileOnly 'org.checkerframework:checker-compat-qual:' + checkerframeworkVersion
implementation project(modulePrefix + 'library-core')
implementation project(modulePrefix + 'library-ui')
testImplementation project(modulePrefix + 'testutils')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
private static final int OUTPUT_BUFFER_SIZE_16BIT = 65536;
private static final int OUTPUT_BUFFER_SIZE_32BIT = OUTPUT_BUFFER_SIZE_16BIT * 2;

// Error codes matching ffmpeg_jni.cc.
private static final int DECODER_ERROR_INVALID_DATA = -1;
private static final int DECODER_ERROR_OTHER = -2;

private final String codecName;
private final @Nullable byte[] extraData;
private final @C.Encoding int encoding;
Expand Down Expand Up @@ -106,8 +110,14 @@ protected FfmpegDecoderException createUnexpectedDecodeException(Throwable error
int inputSize = inputData.limit();
ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, outputBufferSize);
int result = ffmpegDecode(nativeContext, inputData, inputSize, outputData, outputBufferSize);
if (result < 0) {
return new FfmpegDecoderException("Error decoding (see logcat). Code: " + result);
if (result == DECODER_ERROR_INVALID_DATA) {
// Treat invalid data errors as non-fatal to match the behavior of MediaCodec. No output will
// be produced for this buffer, so mark it as decode-only to ensure that the audio sink's
// position is reset when more audio is produced.
outputBuffer.setFlags(C.BUFFER_FLAG_DECODE_ONLY);
return null;
} else if (result == DECODER_ERROR_OTHER) {
return new FfmpegDecoderException("Error decoding (see logcat).");
}
if (!hasOutputFormat) {
channelCount = ffmpegGetChannelCount(nativeContext);
Expand Down
10 changes: 8 additions & 2 deletions extensions/ffmpeg/src/main/jni/ffmpeg_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ static const AVSampleFormat OUTPUT_FORMAT_PCM_16BIT = AV_SAMPLE_FMT_S16;
// Output format corresponding to AudioFormat.ENCODING_PCM_FLOAT.
static const AVSampleFormat OUTPUT_FORMAT_PCM_FLOAT = AV_SAMPLE_FMT_FLT;

// Error codes matching FfmpegDecoder.java.
static const int DECODER_ERROR_INVALID_DATA = -1;
static const int DECODER_ERROR_OTHER = -2;

/**
* Returns the AVCodec with the specified name, or NULL if it is not available.
*/
Expand All @@ -79,7 +83,7 @@ AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,

/**
* Decodes the packet into the output buffer, returning the number of bytes
* written, or a negative value in the case of an error.
* written, or a negative DECODER_ERROR constant value in the case of an error.
*/
int decodePacket(AVCodecContext *context, AVPacket *packet,
uint8_t *outputBuffer, int outputSize);
Expand Down Expand Up @@ -238,6 +242,7 @@ AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
context->channels = rawChannelCount;
context->channel_layout = av_get_default_channel_layout(rawChannelCount);
}
context->err_recognition = AV_EF_IGNORE_ERR;
int result = avcodec_open2(context, codec, NULL);
if (result < 0) {
logError("avcodec_open2", result);
Expand All @@ -254,7 +259,8 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
result = avcodec_send_packet(context, packet);
if (result) {
logError("avcodec_send_packet", result);
return result;
return result == AVERROR_INVALIDDATA ? DECODER_ERROR_INVALID_DATA
: DECODER_ERROR_OTHER;
}

// Dequeue output data until it runs out.
Expand Down
3 changes: 2 additions & 1 deletion extensions/gvr/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ android {
dependencies {
implementation project(modulePrefix + 'library-core')
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
implementation 'com.google.vr:sdk-audio:1.80.0'
api 'com.google.vr:sdk-base:1.190.0'
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
}

ext {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,8 @@ public void release() {
adsManager.destroy();
adsManager = null;
}
adsLoader.removeAdsLoadedListener(/* adsLoadedListener= */ this);
adsLoader.removeAdErrorListener(/* adErrorListener= */ this);
imaPausedContent = false;
imaAdState = IMA_AD_STATE_NONE;
pendingAdLoadError = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ public void maybeThrowSourceInfoRefreshError() throws IOException {
}

@Override
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
return adsMediaSource.createPeriod(id, allocator);
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
return adsMediaSource.createPeriod(id, allocator, startPositionUs);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,17 @@ public double getTimeOffset() {
};
}

@Override
public int getVastMediaWidth() {
throw new UnsupportedOperationException();
}

@Override
public int getVastMediaHeight() {
throw new UnsupportedOperationException();
}

@Override
public int getVastMediaBitrate() {
throw new UnsupportedOperationException();
}
Expand Down
2 changes: 1 addition & 1 deletion extensions/rtmp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ either instantiated and injected from application code, or obtained from
instances of `DataSource.Factory` that are instantiated and injected from
application code.

`DefaultDataSource` will automatically use uses the RTMP extension whenever it's
`DefaultDataSource` will automatically use the RTMP extension whenever it's
available. Hence if your application is using `DefaultDataSource` or
`DefaultDataSourceFactory`, adding support for RTMP streams is as simple as
adding a dependency to the RTMP extension as described above. No changes to your
Expand Down
27 changes: 25 additions & 2 deletions library/core/src/main/java/com/google/android/exoplayer2/C.java
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ private C() {}

/**
* Flags which can apply to a buffer containing a media sample. Possible flag values are {@link
* #BUFFER_FLAG_KEY_FRAME}, {@link #BUFFER_FLAG_END_OF_STREAM}, {@link #BUFFER_FLAG_ENCRYPTED} and
* {@link #BUFFER_FLAG_DECODE_ONLY}.
* #BUFFER_FLAG_KEY_FRAME}, {@link #BUFFER_FLAG_END_OF_STREAM}, {@link #BUFFER_FLAG_LAST_SAMPLE},
* {@link #BUFFER_FLAG_ENCRYPTED} and {@link #BUFFER_FLAG_DECODE_ONLY}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
Expand All @@ -470,6 +470,7 @@ private C() {}
value = {
BUFFER_FLAG_KEY_FRAME,
BUFFER_FLAG_END_OF_STREAM,
BUFFER_FLAG_LAST_SAMPLE,
BUFFER_FLAG_ENCRYPTED,
BUFFER_FLAG_DECODE_ONLY
})
Expand All @@ -482,6 +483,8 @@ private C() {}
* Flag for empty buffers that signal that the end of the stream was reached.
*/
public static final int BUFFER_FLAG_END_OF_STREAM = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
/** Indicates that a buffer is known to contain the last media sample of the stream. */
public static final int BUFFER_FLAG_LAST_SAMPLE = 1 << 29; // 0x20000000
/** Indicates that a buffer is (at least partially) encrypted. */
public static final int BUFFER_FLAG_ENCRYPTED = 1 << 30; // 0x40000000
/** Indicates that a buffer should be decoded but not rendered. */
Expand Down Expand Up @@ -896,6 +899,26 @@ private C() {}
*/
public static final int COLOR_RANGE_FULL = MediaFormat.COLOR_RANGE_FULL;

/** Video projection types. */
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
Format.NO_VALUE,
PROJECTION_RECTANGULAR,
PROJECTION_EQUIRECTANGULAR,
PROJECTION_CUBEMAP,
PROJECTION_MESH
})
public @interface Projection {}
/** Conventional rectangular projection. */
public static final int PROJECTION_RECTANGULAR = 0;
/** Equirectangular spherical projection. */
public static final int PROJECTION_EQUIRECTANGULAR = 1;
/** Cube map projection. */
public static final int PROJECTION_CUBEMAP = 2;
/** 3-D mesh projection. */
public static final int PROJECTION_MESH = 3;

/**
* Priority for media playback.
*
Expand Down
Loading

0 comments on commit 1c4ea26

Please sign in to comment.