Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r2.9.4 #5388

Merged
merged 38 commits into from
Jan 21, 2019
Merged

r2.9.4 #5388

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3833d98
Improve doc for setKeepContentOnPlayerReset.
tonihei Dec 21, 2018
f79005a
Fix manifest uri in SsDownloadHelper.
tonihei Dec 11, 2018
c9cf8e4
Update the Cast framework dependency
AquilesCanta Dec 17, 2018
c0cdf3c
Handle failure to get Cast context more gracefully
AquilesCanta Dec 17, 2018
d3f5057
Handle rectangular rotation projections in Matroska
andrewlewis Dec 24, 2018
e448ecd
Remove stray word
ojw28 Jan 2, 2019
13638f1
Remove AdsLoader listeners on releasing ImaAdsLoader
andrewlewis Jan 2, 2019
6373554
Move syncFileDescriptor to use an experimental method
ojw28 Jan 2, 2019
f11abbd
Fix replacement char check
andrewlewis Jan 3, 2019
fc16833
Use Handler instead of ExoPlayer messages in ConcatenatingMediaSource
tonihei Jan 3, 2019
aff689a
Fix bug when calculating EOF position in mp4 sniffing
AquilesCanta Jan 3, 2019
61a7750
Enable setOutputSurfaceWorkaround for Huawei P10 lite
AquilesCanta Jan 3, 2019
4847889
Prevent IllegalStateException in Mp4 sniffing
AquilesCanta Jan 3, 2019
a568fbd
Parse frame rate from 'mdta' metadata
andrewlewis Jan 4, 2019
189e3c3
Fix nullness issue
andrewlewis Jan 4, 2019
99bc132
Treat AVERROR_INVALIDDATA as non-fatal
andrewlewis Jan 4, 2019
ff9a40f
Update FakeAd overrides
andrewlewis Jan 4, 2019
32bad69
Increase search size in mp4 sniffing once moov has been found
AquilesCanta Jan 7, 2019
93f4a19
Expand check for muxed audio media tags to include uris that match va…
AquilesCanta Jan 7, 2019
8064505
Doc fix.
ojw28 Jan 8, 2019
e760965
Update README and dev guide with Java 8 config for Kotlin.
tonihei Jan 9, 2019
81ca7fe
Add missing call to timeline.getWindow.
tonihei Jan 9, 2019
34d0e0c
Blacklist OMX.SEC.mp3.dec for more devices
andrewlewis Jan 14, 2019
66ca43e
Don't forget isSeekable in ExtractorMediaSource.
tonihei Jan 14, 2019
546af06
Fix DRM protected SmoothStreaming with subtitles
ojw28 Jan 14, 2019
e1b55e6
Add buffer flag for last sample to improve buffered position calculat…
tonihei Jan 15, 2019
516e02c
Fix release branch
ojw28 Jan 15, 2019
84574d9
Bump version for 2.9.4 release
ojw28 Jan 15, 2019
4f1f4fb
Fix typo.
tonihei Jan 15, 2019
4483639
Fix bug where missing switch adaptation set causes multiple identical…
tonihei Jan 15, 2019
8bf1267
allow developers to set the subText of the notifcation
marcbaechinger Jan 16, 2019
9911c11
Add start position to MediaSource.createPeriod.
tonihei Jan 17, 2019
29376b3
Add missing @Nullable to SimpleExoPlayer fields and methods.
tonihei Jan 17, 2019
563d3c2
Add max video size workaround for Amlogic decoder.
tonihei Jan 21, 2019
95bef2d
Upgrade to GVR SDK 1.190.0
andrewlewis Jan 18, 2019
289f63c
Fix GVR dependency
andrewlewis Jan 21, 2019
0b49d00
Use loading period event time for fatal load errors.
tonihei Jan 21, 2019
200c877
Fix release notes
ojw28 Jan 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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