Commit d9794696 by Oliver Woodman

Merge branch 'dev-v2' into release-v2

parents 65770131 b4fb8c3c
Showing with 543 additions and 214 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

...@@ -30,17 +30,39 @@ repositories { ...@@ -30,17 +30,39 @@ repositories {
} }
``` ```
Next, include the following in your module's `build.gradle` file: Next add a gradle compile dependency to the `build.gradle` file of your app
module. The following will add a dependency to the full ExoPlayer library:
```gradle ```gradle
compile 'com.google.android.exoplayer:exoplayer:rX.X.X' compile 'com.google.android.exoplayer:exoplayer:r2.X.X'
``` ```
where `rX.X.X` is the your preferred version. For the latest version, see the where `r2.X.X` is your preferred version. Alternatively, you can depend on only
project's [Releases][]. For more details, see the project on [Bintray][]. the library modules that you actually need. For example the following will add
dependencies on the Core, DASH and UI library modules, as might be required for
an app that plays DASH content:
[Releases]: https://github.com/google/ExoPlayer/releases ```gradle
[Bintray]: https://bintray.com/google/exoplayer/exoplayer/view compile 'com.google.android.exoplayer:exoplayer-core:r2.X.X'
compile 'com.google.android.exoplayer:exoplayer-dash:r2.X.X'
compile 'com.google.android.exoplayer:exoplayer-ui:r2.X.X'
```
The available modules are listed below. Adding a dependency to the full
ExoPlayer library is equivalent to adding dependencies on all of the modules
individually.
* `exoplayer-core`: Core functionality (required).
* `exoplayer-dash`: Support for DASH content.
* `exoplayer-hls`: Support for HLS content.
* `exoplayer-smoothstreaming`: Support for SmoothStreaming content.
* `exoplayer-ui`: UI components and resources for use with ExoPlayer.
For more details, see the project on [Bintray][]. For information about the
latest versions, see the [Release notes][].
[Bintray]: https://bintray.com/google/exoplayer
[Release notes]: https://github.com/google/ExoPlayer/blob/release-v2/RELEASENOTES.md
## Developing ExoPlayer ## ## Developing ExoPlayer ##
......
# Release notes # # Release notes #
### r2.4.0 ###
* New modular library structure. You can read more about depending on individual
library modules
[here](https://medium.com/google-exoplayer/exoplayers-new-modular-structure-a916c0874907).
* Variable speed playback support on API level 16+. You can read more about
changing the playback speed
[here](https://medium.com/google-exoplayer/variable-speed-playback-with-exoplayer-e6e6a71e0343)
([#26](https://github.com/google/ExoPlayer/issues/26)).
* New time bar view, including support for displaying ad break markers.
* Support DVB subtitles in MPEG-TS and MKV.
* Support adaptive playback for audio only DASH, HLS and SmoothStreaming
([#1975](https://github.com/google/ExoPlayer/issues/1975)).
* Support for setting extractor flags on DefaultExtractorsFactory
([#2657](https://github.com/google/ExoPlayer/issues/2657)).
* Support injecting custom renderers into SimpleExoPlayer using a new
RenderersFactory interface.
* Correctly set ExoPlayer's internal thread priority to `THREAD_PRIORITY_AUDIO`.
* TX3G: Support styling and positioning.
* FLV:
* Support MP3 in FLV.
* Skip unhandled metadata rather than failing
([#2634](https://github.com/google/ExoPlayer/issues/2634)).
* Fix potential OutOfMemory errors.
* ID3: Better handle malformed ID3 data
([#2604](https://github.com/google/ExoPlayer/issues/2604),
[#2663](https://github.com/google/ExoPlayer/issues/2663)).
* FFmpeg extension: Fixed build instructions
([#2561](https://github.com/google/ExoPlayer/issues/2561)).
* VP9 extension: Reduced binary size.
* FLAC extension: Enabled 64 bit targets.
* Misc bugfixes.
### r2.3.1 ### ### r2.3.1 ###
* Fix NPE enabling WebVTT subtitles in DASH streams * Fix NPE enabling WebVTT subtitles in DASH streams
...@@ -26,9 +59,8 @@ ...@@ -26,9 +59,8 @@
* HLS improvements: * HLS improvements:
* Respect initial track selection * Respect initial track selection
([#2353](https://github.com/google/ExoPlayer/issues/2353)). ([#2353](https://github.com/google/ExoPlayer/issues/2353)).
* Reduced frequency of media playlist requests when playback position is * Reduced frequency of media playlist requests when playback position is close
close to the live edge to the live edge ([#2548](https://github.com/google/ExoPlayer/issues/2548)).
([#2548](https://github.com/google/ExoPlayer/issues/2548)).
* Exposed the master playlist through ExoPlayer.getCurrentManifest() * Exposed the master playlist through ExoPlayer.getCurrentManifest()
([#2537](https://github.com/google/ExoPlayer/issues/2537)). ([#2537](https://github.com/google/ExoPlayer/issues/2537)).
* Support CLOSED-CAPTIONS #EXT-X-MEDIA type * Support CLOSED-CAPTIONS #EXT-X-MEDIA type
...@@ -237,25 +269,25 @@ some of the motivations behind ExoPlayer 2.x ...@@ -237,25 +269,25 @@ some of the motivations behind ExoPlayer 2.x
structure and class names have also been sanitized. Read more structure and class names have also been sanitized. Read more
[here](https://medium.com/google-exoplayer/exoplayer-2-x-new-package-and-class-names-ef8e1d9ba96f#.lv8sd4nez). [here](https://medium.com/google-exoplayer/exoplayer-2-x-new-package-and-class-names-ef8e1d9ba96f#.lv8sd4nez).
* Key architectural changes: * Key architectural changes:
* Late binding between rendering and media source components. Allows the * Late binding between rendering and media source components. Allows the same
same rendering components to be re-used from one playback to another. rendering components to be re-used from one playback to another. Enables
Enables features such as gapless playback through playlists and DASH features such as gapless playback through playlists and DASH multi-period
multi-period support. support.
* Improved track selection design. More details can be found * Improved track selection design. More details can be found
[here](https://medium.com/google-exoplayer/exoplayer-2-x-track-selection-2b62ff712cc9#.n00zo76b6). [here](https://medium.com/google-exoplayer/exoplayer-2-x-track-selection-2b62ff712cc9#.n00zo76b6).
* LoadControl now used to control buffering and loading across all playback * LoadControl now used to control buffering and loading across all playback
types. types.
* Media source components given additional structure. A new MediaSource * Media source components given additional structure. A new MediaSource class
class has been introduced. MediaSources expose Timelines that describe the has been introduced. MediaSources expose Timelines that describe the media
media they expose, and can consist of multiple MediaPeriods. This enables they expose, and can consist of multiple MediaPeriods. This enables features
features such as seeking in live playbacks and DASH multi-period support. such as seeking in live playbacks and DASH multi-period support.
* Responsibility for loading the initial DASH/SmoothStreaming/HLS manifest * Responsibility for loading the initial DASH/SmoothStreaming/HLS manifest is
is promoted to the corresponding MediaSource components and is no longer promoted to the corresponding MediaSource components and is no longer the
the application's responsibility. application's responsibility.
* Higher level abstractions such as SimpleExoPlayer have been added to the * Higher level abstractions such as SimpleExoPlayer have been added to the
library. These make the library easier to use for common use cases. The library. These make the library easier to use for common use cases. The demo
demo app is halved in size as a result, whilst at the same time gaining app is halved in size as a result, whilst at the same time gaining more
more functionality. Read more functionality. Read more
[here](https://medium.com/google-exoplayer/exoplayer-2-x-improved-demo-app-d97171aaaaa1). [here](https://medium.com/google-exoplayer/exoplayer-2-x-improved-demo-app-d97171aaaaa1).
* Enhanced library support for implementing audio extensions. Read more * Enhanced library support for implementing audio extensions. Read more
[here](https://medium.com/google-exoplayer/exoplayer-2-x-new-audio-features-cfb26c2883a#.ua75vu4s3). [here](https://medium.com/google-exoplayer/exoplayer-2-x-new-audio-features-cfb26c2883a#.ua75vu4s3).
...@@ -274,20 +306,19 @@ some of the motivations behind ExoPlayer 2.x ...@@ -274,20 +306,19 @@ some of the motivations behind ExoPlayer 2.x
[here](https://medium.com/google-exoplayer/exoplayer-2-x-mediasource-composition-6c285fcbca1f#.zfha8qupz). [here](https://medium.com/google-exoplayer/exoplayer-2-x-mediasource-composition-6c285fcbca1f#.zfha8qupz).
* Looping support (see above) * Looping support (see above)
([#490](https://github.com/google/ExoPlayer/issues/490)). ([#490](https://github.com/google/ExoPlayer/issues/490)).
* Ability to query information about all tracks in a piece of media * Ability to query information about all tracks in a piece of media (including
(including those not supported by the device) those not supported by the device)
([#1121](https://github.com/google/ExoPlayer/issues/1121)). ([#1121](https://github.com/google/ExoPlayer/issues/1121)).
* Improved player controls. * Improved player controls.
* Support for PSSH in fMP4 moof atoms * Support for PSSH in fMP4 moof atoms
([#1143](https://github.com/google/ExoPlayer/issues/1143)). ([#1143](https://github.com/google/ExoPlayer/issues/1143)).
* Support for Opus in Ogg * Support for Opus in Ogg
([#1447](https://github.com/google/ExoPlayer/issues/1447)). ([#1447](https://github.com/google/ExoPlayer/issues/1447)).
* CacheDataSource support for standalone media file playbacks (mp3, mp4 * CacheDataSource support for standalone media file playbacks (mp3, mp4 etc).
etc).
* FFMPEG extension (for audio only). * FFMPEG extension (for audio only).
* Key bug fixes: * Key bug fixes:
* Removed unnecessary secondary requests when playing standalone media * Removed unnecessary secondary requests when playing standalone media files
files ([#1041](https://github.com/google/ExoPlayer/issues/1041)). ([#1041](https://github.com/google/ExoPlayer/issues/1041)).
* Fixed playback of video only (i.e. no audio) live streams * Fixed playback of video only (i.e. no audio) live streams
([#758](https://github.com/google/ExoPlayer/issues/758)). ([#758](https://github.com/google/ExoPlayer/issues/758)).
* Fixed silent failure when media buffer is too small * Fixed silent failure when media buffer is too small
...@@ -304,6 +335,12 @@ in all V2 releases. This cannot be assumed for changes in r1.5.12 and later, ...@@ -304,6 +335,12 @@ in all V2 releases. This cannot be assumed for changes in r1.5.12 and later,
however it can be assumed that all such changes are included in the most recent however it can be assumed that all such changes are included in the most recent
V2 release. V2 release.
### r1.5.16 ###
* VP9 extension: Reduced binary size.
* FLAC extension: Enabled 64 bit targets and fixed proguard config.
* Misc bugfixes.
### r1.5.15 ### ### r1.5.15 ###
* SmoothStreaming: Fixed handling of start_time placeholder * SmoothStreaming: Fixed handling of start_time placeholder
......
...@@ -19,8 +19,15 @@ buildscript { ...@@ -19,8 +19,15 @@ buildscript {
classpath 'com.android.tools.build:gradle:2.3.0' classpath 'com.android.tools.build:gradle:2.3.0'
classpath 'com.novoda:bintray-release:0.4.0' classpath 'com.novoda:bintray-release:0.4.0'
} }
// Workaround for the following test coverage issue. Remove when fixed:
// https://code.google.com/p/android/issues/detail?id=226070
configurations.all {
resolutionStrategy {
force 'org.jacoco:org.jacoco.report:0.7.4.201502262128'
force 'org.jacoco:org.jacoco.core:0.7.4.201502262128'
}
}
} }
allprojects { allprojects {
repositories { repositories {
jcenter() jcenter()
...@@ -30,16 +37,26 @@ allprojects { ...@@ -30,16 +37,26 @@ allprojects {
// components provided by the library may be of use on older devices. // components provided by the library may be of use on older devices.
// However, please note that the core media playback functionality // However, please note that the core media playback functionality
// provided by the library requires API level 16 or greater. // provided by the library requires API level 16 or greater.
minSdkVersion=9 minSdkVersion = 9
compileSdkVersion=25 compileSdkVersion = 25
targetSdkVersion=25 targetSdkVersion = 25
buildToolsVersion='25' buildToolsVersion = '25'
testSupportLibraryVersion = '0.5'
supportLibraryVersion = '25.3.1'
dexmakerVersion = '1.2'
mockitoVersion = '1.9.5'
releaseRepoName = getBintrayRepo() releaseRepoName = getBintrayRepo()
releaseUserOrg = 'google' releaseUserOrg = 'google'
releaseGroupId = 'com.google.android.exoplayer' releaseGroupId = 'com.google.android.exoplayer'
releaseVersion = 'r2.3.1' releaseVersion = 'r2.4.0'
releaseWebsite = 'https://github.com/google/ExoPlayer' releaseWebsite = 'https://github.com/google/ExoPlayer'
} }
if (it.hasProperty('externalBuildDir')) {
if (!new File(externalBuildDir).isAbsolute()) {
externalBuildDir = new File(rootDir, externalBuildDir)
}
buildDir = "${externalBuildDir}/${project.name}"
}
} }
def getBintrayRepo() { def getBintrayRepo() {
...@@ -47,3 +64,5 @@ def getBintrayRepo() { ...@@ -47,3 +64,5 @@ def getBintrayRepo() {
property('publicRepo').toBoolean() property('publicRepo').toBoolean()
return publicRepo ? 'exoplayer' : 'exoplayer-test' return publicRepo ? 'exoplayer' : 'exoplayer-test'
} }
apply from: 'javadoc_combined.gradle'
...@@ -45,7 +45,11 @@ android { ...@@ -45,7 +45,11 @@ android {
} }
dependencies { dependencies {
compile project(':library') compile project(':library-core')
compile project(':library-dash')
compile project(':library-hls')
compile project(':library-smoothstreaming')
compile project(':library-ui')
withExtensionsCompile project(path: ':extension-ffmpeg') withExtensionsCompile project(path: ':extension-ffmpeg')
withExtensionsCompile project(path: ':extension-flac') withExtensionsCompile project(path: ':extension-flac')
withExtensionsCompile project(path: ':extension-opus') withExtensionsCompile project(path: ':extension-opus')
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.exoplayer2.demo" package="com.google.android.exoplayer2.demo"
android:versionCode="2301" android:versionCode="2400"
android:versionName="2.3.1"> android:versionName="2.4.0">
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
......
...@@ -416,13 +416,16 @@ ...@@ -416,13 +416,16 @@
] ]
}, },
{ {
"name": "Audio -> Video", "name": "Audio -> Video -> Audio",
"playlist": [ "playlist": [
{ {
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/audio-141.mp4" "uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/audio-141.mp4"
}, },
{ {
"uri": "http://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv" "uri": "http://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv"
},
{
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/audio-141.mp4"
} }
] ]
}, },
......
/*
* Copyright (C) 2017 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.
*/
package com.google.android.exoplayer2.demo;
import android.text.TextUtils;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.util.MimeTypes;
import java.util.Locale;
/**
* Utility methods for demo application.
*/
/*package*/ final class DemoUtil {
/**
* Builds a track name for display.
*
* @param format {@link Format} of the track.
* @return a generated name specific to the track.
*/
public static String buildTrackName(Format format) {
String trackName;
if (MimeTypes.isVideo(format.sampleMimeType)) {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(
buildResolutionString(format), buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
} else if (MimeTypes.isAudio(format.sampleMimeType)) {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(joinWithSeparator(
buildLanguageString(format), buildAudioPropertyString(format)),
buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
} else {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(buildLanguageString(format),
buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
}
return trackName.length() == 0 ? "unknown" : trackName;
}
private static String buildResolutionString(Format format) {
return format.width == Format.NO_VALUE || format.height == Format.NO_VALUE
? "" : format.width + "x" + format.height;
}
private static String buildAudioPropertyString(Format format) {
return format.channelCount == Format.NO_VALUE || format.sampleRate == Format.NO_VALUE
? "" : format.channelCount + "ch, " + format.sampleRate + "Hz";
}
private static String buildLanguageString(Format format) {
return TextUtils.isEmpty(format.language) || "und".equals(format.language) ? ""
: format.language;
}
private static String buildBitrateString(Format format) {
return format.bitrate == Format.NO_VALUE ? ""
: String.format(Locale.US, "%.2fMbit", format.bitrate / 1000000f);
}
private static String joinWithSeparator(String first, String second) {
return first.length() == 0 ? second : (second.length() == 0 ? first : first + ", " + second);
}
private static String buildTrackIdString(Format format) {
return format.id == null ? "" : ("id:" + format.id);
}
private static String buildSampleMimeTypeString(Format format) {
return format.sampleMimeType == null ? "" : format.sampleMimeType;
}
private DemoUtil() {}
}
...@@ -22,6 +22,7 @@ import com.google.android.exoplayer2.C; ...@@ -22,6 +22,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener;
...@@ -100,6 +101,12 @@ import java.util.Locale; ...@@ -100,6 +101,12 @@ import java.util.Locale;
} }
@Override @Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
Log.d(TAG, "playbackParameters " + String.format(
"[speed=%.2f, pitch=%.2f]", playbackParameters.speed, playbackParameters.pitch));
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) { public void onTimelineChanged(Timeline timeline, Object manifest) {
int periodCount = timeline.getPeriodCount(); int periodCount = timeline.getPeriodCount();
int windowCount = timeline.getWindowCount(); int windowCount = timeline.getWindowCount();
...@@ -274,7 +281,7 @@ import java.util.Locale; ...@@ -274,7 +281,7 @@ import java.util.Locale;
@Override @Override
public void onRenderedFirstFrame(Surface surface) { public void onRenderedFirstFrame(Surface surface) {
// Do nothing. Log.d(TAG, "renderedFirstFrame [" + surface + "]");
} }
// DefaultDrmSessionManager.EventListener // DefaultDrmSessionManager.EventListener
......
...@@ -21,6 +21,7 @@ import android.content.pm.PackageManager; ...@@ -21,6 +21,7 @@ import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
...@@ -30,10 +31,11 @@ import android.widget.LinearLayout; ...@@ -30,10 +31,11 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager; import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
...@@ -111,6 +113,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay ...@@ -111,6 +113,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
private TrackSelectionHelper trackSelectionHelper; private TrackSelectionHelper trackSelectionHelper;
private DebugTextViewHelper debugViewHelper; private DebugTextViewHelper debugViewHelper;
private boolean needRetrySource; private boolean needRetrySource;
private TrackGroupArray lastSeenTrackGroupArray;
private boolean shouldAutoPlay; private boolean shouldAutoPlay;
private int resumeWindow; private int resumeWindow;
...@@ -183,8 +186,8 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay ...@@ -183,8 +186,8 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
int[] grantResults) { @NonNull int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initializePlayer(); initializePlayer();
} else { } else {
...@@ -250,17 +253,21 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay ...@@ -250,17 +253,21 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
} }
} }
@SimpleExoPlayer.ExtensionRendererMode int extensionRendererMode = @DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode =
((DemoApplication) getApplication()).useExtensionRenderers() ((DemoApplication) getApplication()).useExtensionRenderers()
? (preferExtensionDecoders ? SimpleExoPlayer.EXTENSION_RENDERER_MODE_PREFER ? (preferExtensionDecoders ? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER
: SimpleExoPlayer.EXTENSION_RENDERER_MODE_ON) : DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
: SimpleExoPlayer.EXTENSION_RENDERER_MODE_OFF; : DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(this,
drmSessionManager, extensionRendererMode);
TrackSelection.Factory videoTrackSelectionFactory = TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(BANDWIDTH_METER); new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelectionHelper = new TrackSelectionHelper(trackSelector, videoTrackSelectionFactory); trackSelectionHelper = new TrackSelectionHelper(trackSelector, videoTrackSelectionFactory);
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl(), lastSeenTrackGroupArray = null;
drmSessionManager, extensionRendererMode);
player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector);
player.addListener(this); player.addListener(this);
eventLogger = new EventLogger(trackSelector); eventLogger = new EventLogger(trackSelector);
...@@ -428,6 +435,11 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay ...@@ -428,6 +435,11 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
} }
@Override @Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) { public void onTimelineChanged(Timeline timeline, Object manifest) {
// Do nothing. // Do nothing.
} }
...@@ -472,8 +484,10 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay ...@@ -472,8 +484,10 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
} }
@Override @Override
@SuppressWarnings("ReferenceEquality")
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
updateButtonVisibilities(); updateButtonVisibilities();
if (trackGroups != lastSeenTrackGroupArray) {
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo(); MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) { if (mappedTrackInfo != null) {
if (mappedTrackInfo.getTrackTypeRendererSupport(C.TRACK_TYPE_VIDEO) if (mappedTrackInfo.getTrackTypeRendererSupport(C.TRACK_TYPE_VIDEO)
...@@ -485,6 +499,8 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay ...@@ -485,6 +499,8 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
showToast(R.string.error_unsupported_audio); showToast(R.string.error_unsupported_audio);
} }
} }
lastSeenTrackGroupArray = trackGroups;
}
} }
// User controls // User controls
......
...@@ -21,13 +21,11 @@ import android.app.AlertDialog; ...@@ -21,13 +21,11 @@ import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.Pair; import android.util.Pair;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckedTextView; import android.widget.CheckedTextView;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
...@@ -37,9 +35,7 @@ import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedT ...@@ -37,9 +35,7 @@ import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedT
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.SelectionOverride; import com.google.android.exoplayer2.trackselection.MappingTrackSelector.SelectionOverride;
import com.google.android.exoplayer2.trackselection.RandomTrackSelection; import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.util.MimeTypes;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale;
/** /**
* Helper class for displaying track selection dialogs. * Helper class for displaying track selection dialogs.
...@@ -157,7 +153,7 @@ import java.util.Locale; ...@@ -157,7 +153,7 @@ import java.util.Locale;
CheckedTextView trackView = (CheckedTextView) inflater.inflate( CheckedTextView trackView = (CheckedTextView) inflater.inflate(
trackViewLayoutId, root, false); trackViewLayoutId, root, false);
trackView.setBackgroundResource(selectableItemBackgroundResourceId); trackView.setBackgroundResource(selectableItemBackgroundResourceId);
trackView.setText(buildTrackName(group.getFormat(trackIndex))); trackView.setText(DemoUtil.buildTrackName(group.getFormat(trackIndex)));
if (trackInfo.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex) if (trackInfo.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex)
== RendererCapabilities.FORMAT_HANDLED) { == RendererCapabilities.FORMAT_HANDLED) {
trackView.setFocusable(true); trackView.setFocusable(true);
...@@ -296,57 +292,4 @@ import java.util.Locale; ...@@ -296,57 +292,4 @@ import java.util.Locale;
return tracks; return tracks;
} }
// Track name construction.
private static String buildTrackName(Format format) {
String trackName;
if (MimeTypes.isVideo(format.sampleMimeType)) {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(
buildResolutionString(format), buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
} else if (MimeTypes.isAudio(format.sampleMimeType)) {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(joinWithSeparator(
buildLanguageString(format), buildAudioPropertyString(format)),
buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
} else {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(buildLanguageString(format),
buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
}
return trackName.length() == 0 ? "unknown" : trackName;
}
private static String buildResolutionString(Format format) {
return format.width == Format.NO_VALUE || format.height == Format.NO_VALUE
? "" : format.width + "x" + format.height;
}
private static String buildAudioPropertyString(Format format) {
return format.channelCount == Format.NO_VALUE || format.sampleRate == Format.NO_VALUE
? "" : format.channelCount + "ch, " + format.sampleRate + "Hz";
}
private static String buildLanguageString(Format format) {
return TextUtils.isEmpty(format.language) || "und".equals(format.language) ? ""
: format.language;
}
private static String buildBitrateString(Format format) {
return format.bitrate == Format.NO_VALUE ? ""
: String.format(Locale.US, "%.2fMbit", format.bitrate / 1000000f);
}
private static String joinWithSeparator(String first, String second) {
return first.length() == 0 ? second : (second.length() == 0 ? first : first + ", " + second);
}
private static String buildTrackIdString(Format format) {
return format.id == null ? "" : ("id:" + format.id);
}
private static String buildSampleMimeTypeString(Format format) {
return format.sampleMimeType == null ? "" : format.sampleMimeType;
}
} }
...@@ -29,13 +29,18 @@ android { ...@@ -29,13 +29,18 @@ android {
} }
dependencies { dependencies {
compile project(':library') compile project(':library-core')
compile files('libs/cronet_api.jar') compile files('libs/cronet_api.jar')
compile files('libs/cronet_impl_common_java.jar') compile files('libs/cronet_impl_common_java.jar')
compile files('libs/cronet_impl_native_java.jar') compile files('libs/cronet_impl_native_java.jar')
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile 'org.mockito:mockito-core:1.9.5'
androidTestCompile project(':library') androidTestCompile project(':library')
androidTestCompile 'com.android.support.test:runner:0.5' androidTestCompile 'com.google.dexmaker:dexmaker:' + dexmakerVersion
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion
androidTestCompile 'org.mockito:mockito-core:' + mockitoVersion
androidTestCompile 'com.android.support.test:runner:' + testSupportLibraryVersion
} }
ext {
javadocTitle = 'Cronet extension'
}
apply from: '../../javadoc_library.gradle'
...@@ -72,7 +72,7 @@ public final class CronetDataSourceFactory extends BaseFactory { ...@@ -72,7 +72,7 @@ public final class CronetDataSourceFactory extends BaseFactory {
protected CronetDataSource createDataSourceInternal(HttpDataSource.RequestProperties protected CronetDataSource createDataSourceInternal(HttpDataSource.RequestProperties
defaultRequestProperties) { defaultRequestProperties) {
return new CronetDataSource(cronetEngine, executor, contentTypePredicate, transferListener, return new CronetDataSource(cronetEngine, executor, contentTypePredicate, transferListener,
connectTimeoutMs, readTimeoutMs, resetTimeoutOnRedirects, null, defaultRequestProperties); connectTimeoutMs, readTimeoutMs, resetTimeoutOnRedirects, defaultRequestProperties);
} }
} }
...@@ -31,21 +31,18 @@ FFMPEG_EXT_PATH="${EXOPLAYER_ROOT}/extensions/ffmpeg/src/main" ...@@ -31,21 +31,18 @@ FFMPEG_EXT_PATH="${EXOPLAYER_ROOT}/extensions/ffmpeg/src/main"
NDK_PATH="<path to Android NDK>" NDK_PATH="<path to Android NDK>"
``` ```
* Fetch and build FFmpeg. For example, to fetch and build for armv7a: * Set up host platform ("darwin-x86_64" for Mac OS X):
``` ```
cd "${FFMPEG_EXT_PATH}/jni" && \ HOST_PLATFORM="linux-x86_64"
git clone git://source.ffmpeg.org/ffmpeg ffmpeg && cd ffmpeg && \ ```
./configure \
--libdir=android-libs/armeabi-v7a \ * Fetch and build FFmpeg. For example, to fetch and build for armeabi-v7a,
--arch=arm \ arm64-v8a and x86 on Linux x86_64:
--cpu=armv7-a \
--cross-prefix="${NDK_PATH}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-" \ ```
COMMON_OPTIONS="\
--target-os=android \ --target-os=android \
--sysroot="${NDK_PATH}/platforms/android-9/arch-arm/" \
--extra-cflags="-march=armv7-a -mfloat-abi=softfp" \
--extra-ldflags="-Wl,--fix-cortex-a8" \
--extra-ldexeflags=-pie \
--disable-static \ --disable-static \
--enable-shared \ --enable-shared \
--disable-doc \ --disable-doc \
...@@ -57,22 +54,56 @@ git clone git://source.ffmpeg.org/ffmpeg ffmpeg && cd ffmpeg && \ ...@@ -57,22 +54,56 @@ git clone git://source.ffmpeg.org/ffmpeg ffmpeg && cd ffmpeg && \
--disable-postproc \ --disable-postproc \
--disable-avfilter \ --disable-avfilter \
--disable-symver \ --disable-symver \
--disable-swresample \
--enable-avresample \ --enable-avresample \
--enable-decoder=vorbis \ --enable-decoder=vorbis \
--enable-decoder=opus \ --enable-decoder=opus \
--enable-decoder=flac \ --enable-decoder=flac \
--enable-decoder=alac \ " && \
cd "${FFMPEG_EXT_PATH}/jni" && \
git clone git://source.ffmpeg.org/ffmpeg ffmpeg && cd ffmpeg && \
./configure \
--libdir=android-libs/armeabi-v7a \
--arch=arm \
--cpu=armv7-a \
--cross-prefix="${NDK_PATH}/toolchains/arm-linux-androideabi-4.9/prebuilt/${HOST_PLATFORM}/bin/arm-linux-androideabi-" \
--sysroot="${NDK_PATH}/platforms/android-9/arch-arm/" \
--extra-cflags="-march=armv7-a -mfloat-abi=softfp" \
--extra-ldflags="-Wl,--fix-cortex-a8" \
--extra-ldexeflags=-pie \
${COMMON_OPTIONS} \
&& \
make -j4 && make install-libs && \
make clean && ./configure \
--libdir=android-libs/arm64-v8a \
--arch=aarch64 \
--cpu=armv8-a \
--cross-prefix="${NDK_PATH}/toolchains/aarch64-linux-android-4.9/prebuilt/${HOST_PLATFORM}/bin/aarch64-linux-android-" \
--sysroot="${NDK_PATH}/platforms/android-21/arch-arm64/" \
--extra-ldexeflags=-pie \
${COMMON_OPTIONS} \
&& \
make -j4 && make install-libs && \
make clean && ./configure \
--libdir=android-libs/x86 \
--arch=x86 \
--cpu=i686 \
--cross-prefix="${NDK_PATH}/toolchains/x86-4.9/prebuilt/${HOST_PLATFORM}/bin/i686-linux-android-" \
--sysroot="${NDK_PATH}/platforms/android-9/arch-x86/" \
--extra-ldexeflags=-pie \
--disable-asm \
${COMMON_OPTIONS} \
&& \ && \
make -j4 && \ make -j4 && make install-libs && \
make install-libs make clean
``` ```
* Build the JNI native libraries. Repeat this step for any other architectures * Build the JNI native libraries, setting `APP_ABI` to include the architectures
you need to support. built in the previous step. For example:
``` ```
cd "${FFMPEG_EXT_PATH}"/jni && \ cd "${FFMPEG_EXT_PATH}"/jni && \
${NDK_PATH}/ndk-build APP_ABI=armeabi-v7a -j4 ${NDK_PATH}/ndk-build APP_ABI="armeabi-v7a arm64-v8a x86" -j4
``` ```
* In your project, you can add a dependency on the extension by using a rule * In your project, you can add a dependency on the extension by using a rule
......
...@@ -30,5 +30,10 @@ android { ...@@ -30,5 +30,10 @@ android {
} }
dependencies { dependencies {
compile project(':library') compile project(':library-core')
} }
ext {
javadocTitle = 'FFmpeg extension'
}
apply from: '../../javadoc_library.gradle'
...@@ -32,14 +32,9 @@ LOCAL_SRC_FILES := ffmpeg/android-libs/$(TARGET_ARCH_ABI)/$(LOCAL_MODULE).so ...@@ -32,14 +32,9 @@ LOCAL_SRC_FILES := ffmpeg/android-libs/$(TARGET_ARCH_ABI)/$(LOCAL_MODULE).so
include $(PREBUILT_SHARED_LIBRARY) include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := libswresample
LOCAL_SRC_FILES := ffmpeg/android-libs/$(TARGET_ARCH_ABI)/$(LOCAL_MODULE).so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := ffmpeg_jni.cc LOCAL_SRC_FILES := ffmpeg_jni.cc
LOCAL_C_INCLUDES := ffmpeg LOCAL_C_INCLUDES := ffmpeg
LOCAL_SHARED_LIBRARIES := libavcodec libavresample libavutil libswresample LOCAL_SHARED_LIBRARIES := libavcodec libavresample libavutil
LOCAL_LDLIBS := -Lffmpeg/android-libs/$(TARGET_ARCH_ABI) -llog LOCAL_LDLIBS := -Lffmpeg/android-libs/$(TARGET_ARCH_ABI) -llog
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
...@@ -30,7 +30,11 @@ android { ...@@ -30,7 +30,11 @@ android {
} }
dependencies { dependencies {
compile project(':library') compile project(':library-core')
androidTestCompile project(':testutils') androidTestCompile project(':testutils')
} }
ext {
javadocTitle = 'FLAC extension'
}
apply from: '../../javadoc_library.gradle'
...@@ -22,6 +22,7 @@ import android.test.InstrumentationTestCase; ...@@ -22,6 +22,7 @@ import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
...@@ -103,6 +104,11 @@ public class FlacPlaybackTest extends InstrumentationTestCase { ...@@ -103,6 +104,11 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
} }
@Override @Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) { public void onTimelineChanged(Timeline timeline, Object manifest) {
// Do nothing. // Do nothing.
} }
......
...@@ -24,11 +24,16 @@ android { ...@@ -24,11 +24,16 @@ android {
} }
dependencies { dependencies {
compile project(':library') compile project(':library-core')
compile 'com.google.vr:sdk-audio:1.30.0' compile 'com.google.vr:sdk-audio:1.30.0'
} }
ext { ext {
javadocTitle = 'GVR extension'
}
apply from: '../../javadoc_library.gradle'
ext {
releaseArtifact = 'extension-gvr' releaseArtifact = 'extension-gvr'
releaseDescription = 'Google VR extension for ExoPlayer.' releaseDescription = 'Google VR extension for ExoPlayer.'
} }
......
...@@ -152,14 +152,19 @@ public final class GvrAudioProcessor implements AudioProcessor { ...@@ -152,14 +152,19 @@ public final class GvrAudioProcessor implements AudioProcessor {
@Override @Override
public void flush() { public void flush() {
if (gvrAudioSurround != null) {
gvrAudioSurround.flush(); gvrAudioSurround.flush();
}
inputEnded = false; inputEnded = false;
} }
@Override @Override
public synchronized void release() { public synchronized void reset() {
buffer = null;
maybeReleaseGvrAudioSurround(); maybeReleaseGvrAudioSurround();
inputEnded = false;
buffer = null;
sampleRateHz = Format.NO_VALUE;
channelCount = Format.NO_VALUE;
} }
private void maybeReleaseGvrAudioSurround() { private void maybeReleaseGvrAudioSurround() {
......
...@@ -29,13 +29,18 @@ android { ...@@ -29,13 +29,18 @@ android {
} }
dependencies { dependencies {
compile project(':library') compile project(':library-core')
compile('com.squareup.okhttp3:okhttp:3.6.0') { compile('com.squareup.okhttp3:okhttp:3.6.0') {
exclude group: 'org.json' exclude group: 'org.json'
} }
} }
ext { ext {
javadocTitle = 'OkHttp extension'
}
apply from: '../../javadoc_library.gradle'
ext {
releaseArtifact = 'extension-okhttp' releaseArtifact = 'extension-okhttp'
releaseDescription = 'OkHttp extension for ExoPlayer.' releaseDescription = 'OkHttp extension for ExoPlayer.'
} }
......
...@@ -30,5 +30,10 @@ android { ...@@ -30,5 +30,10 @@ android {
} }
dependencies { dependencies {
compile project(':library') compile project(':library-core')
} }
ext {
javadocTitle = 'Opus extension'
}
apply from: '../../javadoc_library.gradle'
...@@ -22,6 +22,7 @@ import android.test.InstrumentationTestCase; ...@@ -22,6 +22,7 @@ import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
...@@ -103,6 +104,11 @@ public class OpusPlaybackTest extends InstrumentationTestCase { ...@@ -103,6 +104,11 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
} }
@Override @Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) { public void onTimelineChanged(Timeline timeline, Object manifest) {
// Do nothing. // Do nothing.
} }
......
...@@ -161,7 +161,7 @@ import java.util.List; ...@@ -161,7 +161,7 @@ import java.util.List;
cryptoInfo.key, cryptoInfo.iv, cryptoInfo.numSubSamples, cryptoInfo.key, cryptoInfo.iv, cryptoInfo.numSubSamples,
cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData) cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData)
: opusDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(), : opusDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(),
outputBuffer, SAMPLE_RATE); outputBuffer);
if (result < 0) { if (result < 0) {
if (result == DRM_ERROR) { if (result == DRM_ERROR) {
String message = "Drm error: " + opusGetErrorMessage(nativeDecoderContext); String message = "Drm error: " + opusGetErrorMessage(nativeDecoderContext);
...@@ -210,7 +210,7 @@ import java.util.List; ...@@ -210,7 +210,7 @@ import java.util.List;
private native long opusInit(int sampleRate, int channelCount, int numStreams, int numCoupled, private native long opusInit(int sampleRate, int channelCount, int numStreams, int numCoupled,
int gain, byte[] streamMap); int gain, byte[] streamMap);
private native int opusDecode(long decoder, long timeUs, ByteBuffer inputBuffer, int inputSize, private native int opusDecode(long decoder, long timeUs, ByteBuffer inputBuffer, int inputSize,
SimpleOutputBuffer outputBuffer, int sampleRate); SimpleOutputBuffer outputBuffer);
private native int opusSecureDecode(long decoder, long timeUs, ByteBuffer inputBuffer, private native int opusSecureDecode(long decoder, long timeUs, ByteBuffer inputBuffer,
int inputSize, SimpleOutputBuffer outputBuffer, int sampleRate, int inputSize, SimpleOutputBuffer outputBuffer, int sampleRate,
ExoMediaCrypto mediaCrypto, int inputMode, byte[] key, byte[] iv, ExoMediaCrypto mediaCrypto, int inputMode, byte[] key, byte[] iv,
......
...@@ -59,6 +59,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { ...@@ -59,6 +59,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
} }
static const int kBytesPerSample = 2; // opus fixed point uses 16 bit samples. static const int kBytesPerSample = 2; // opus fixed point uses 16 bit samples.
static const int kMaxOpusOutputPacketSizeSamples = 960 * 6;
static int channelCount; static int channelCount;
static int errorCode; static int errorCode;
...@@ -92,16 +93,14 @@ DECODER_FUNC(jlong, opusInit, jint sampleRate, jint channelCount, ...@@ -92,16 +93,14 @@ DECODER_FUNC(jlong, opusInit, jint sampleRate, jint channelCount,
} }
DECODER_FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs, DECODER_FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs,
jobject jInputBuffer, jint inputSize, jobject jOutputBuffer, jobject jInputBuffer, jint inputSize, jobject jOutputBuffer) {
jint sampleRate) {
OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder); OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder);
const uint8_t* inputBuffer = const uint8_t* inputBuffer =
reinterpret_cast<const uint8_t*>( reinterpret_cast<const uint8_t*>(
env->GetDirectBufferAddress(jInputBuffer)); env->GetDirectBufferAddress(jInputBuffer));
const int32_t inputSampleCount = const jint outputSize =
opus_packet_get_nb_samples(inputBuffer, inputSize, sampleRate); kMaxOpusOutputPacketSizeSamples * kBytesPerSample * channelCount;
const jint outputSize = inputSampleCount * kBytesPerSample * channelCount;
env->CallObjectMethod(jOutputBuffer, outputBufferInit, jTimeUs, outputSize); env->CallObjectMethod(jOutputBuffer, outputBufferInit, jTimeUs, outputSize);
const jobject jOutputBufferData = env->CallObjectMethod(jOutputBuffer, const jobject jOutputBufferData = env->CallObjectMethod(jOutputBuffer,
...@@ -110,7 +109,7 @@ DECODER_FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs, ...@@ -110,7 +109,7 @@ DECODER_FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs,
int16_t* outputBufferData = reinterpret_cast<int16_t*>( int16_t* outputBufferData = reinterpret_cast<int16_t*>(
env->GetDirectBufferAddress(jOutputBufferData)); env->GetDirectBufferAddress(jOutputBufferData));
int sampleCount = opus_multistream_decode(decoder, inputBuffer, inputSize, int sampleCount = opus_multistream_decode(decoder, inputBuffer, inputSize,
outputBufferData, outputSize, 0); outputBufferData, kMaxOpusOutputPacketSizeSamples, 0);
// record error code // record error code
errorCode = (sampleCount < 0) ? sampleCount : 0; errorCode = (sampleCount < 0) ? sampleCount : 0;
return (sampleCount < 0) ? sampleCount return (sampleCount < 0) ? sampleCount
......
...@@ -49,7 +49,7 @@ git clone https://chromium.googlesource.com/libyuv/libyuv libyuv ...@@ -49,7 +49,7 @@ git clone https://chromium.googlesource.com/libyuv/libyuv libyuv
cd "${VP9_EXT_PATH}/jni/libvpx" && \ cd "${VP9_EXT_PATH}/jni/libvpx" && \
git checkout tags/v1.6.1 -b v1.6.1 && \ git checkout tags/v1.6.1 -b v1.6.1 && \
cd "${VP9_EXT_PATH}/jni/libyuv" && \ cd "${VP9_EXT_PATH}/jni/libyuv" && \
git checkout e2611a73 git checkout 996a2bbd
``` ```
* Run a script that generates necessary configuration files for libvpx: * Run a script that generates necessary configuration files for libvpx:
......
...@@ -30,6 +30,10 @@ android { ...@@ -30,6 +30,10 @@ android {
} }
dependencies { dependencies {
compile project(':library') compile project(':library-core')
} }
ext {
javadocTitle = 'VP9 extension'
}
apply from: '../../javadoc_library.gradle'
...@@ -23,6 +23,7 @@ import android.util.Log; ...@@ -23,6 +23,7 @@ import android.util.Log;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
...@@ -135,6 +136,11 @@ public class VpxPlaybackTest extends InstrumentationTestCase { ...@@ -135,6 +136,11 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
} }
@Override @Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) { public void onTimelineChanged(Timeline timeline, Object manifest) {
// Do nothing. // Do nothing.
} }
......
...@@ -21,6 +21,7 @@ LIBYUV_ROOT := $(WORKING_DIR)/libyuv ...@@ -21,6 +21,7 @@ LIBYUV_ROOT := $(WORKING_DIR)/libyuv
# build libyuv_static.a # build libyuv_static.a
LOCAL_PATH := $(WORKING_DIR) LOCAL_PATH := $(WORKING_DIR)
LIBYUV_DISABLE_JPEG := "yes"
include $(LIBYUV_ROOT)/Android.mk include $(LIBYUV_ROOT)/Android.mk
# build libvpx.so # build libvpx.so
......
...@@ -68,7 +68,7 @@ limit=$((${#arch[@]} - 1)) ...@@ -68,7 +68,7 @@ limit=$((${#arch[@]} - 1))
# everything else will be removed. # everything else will be removed.
allowed_files="libvpx_srcs.txt vpx_config.c vpx_config.h vpx_scale_rtcd.h" allowed_files="libvpx_srcs.txt vpx_config.c vpx_config.h vpx_scale_rtcd.h"
allowed_files+=" vp8_rtcd.h vp9_rtcd.h vpx_version.h vpx_config.asm" allowed_files+=" vp8_rtcd.h vp9_rtcd.h vpx_version.h vpx_config.asm"
allowed_files+=" vpx_dsp_rtcd.h" allowed_files+=" vpx_dsp_rtcd.h libvpx.ver"
remove_trailing_whitespace() { remove_trailing_whitespace() {
perl -pi -e 's/\s\+$//' "$@" perl -pi -e 's/\s\+$//' "$@"
......
...@@ -37,9 +37,7 @@ LOCAL_SRC_FILES += $(addprefix libvpx/, $(filter-out vpx_config.c, \ ...@@ -37,9 +37,7 @@ LOCAL_SRC_FILES += $(addprefix libvpx/, $(filter-out vpx_config.c, \
# include assembly files if they exist # include assembly files if they exist
# "%.asm.[sS]" covers neon assembly and "%.asm" covers x86 assembly # "%.asm.[sS]" covers neon assembly and "%.asm" covers x86 assembly
LOCAL_SRC_FILES += $(addprefix libvpx/, \ LOCAL_SRC_FILES += $(addprefix libvpx/, \
$(filter %.asm.s %.asm, $(libvpx_codec_srcs))) $(filter %.asm.s %.asm.S %.asm, $(libvpx_codec_srcs)))
LOCAL_SRC_FILES += $(addprefix libvpx/, \
$(filter %.asm.S %.asm, $(libvpx_codec_srcs)))
ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),) ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),)
# append .neon to *_neon.c and *.[sS] # append .neon to *_neon.c and *.[sS]
...@@ -48,10 +46,8 @@ LOCAL_SRC_FILES := $(subst .s,.s.neon,$(LOCAL_SRC_FILES)) ...@@ -48,10 +46,8 @@ LOCAL_SRC_FILES := $(subst .s,.s.neon,$(LOCAL_SRC_FILES))
LOCAL_SRC_FILES := $(subst .S,.S.neon,$(LOCAL_SRC_FILES)) LOCAL_SRC_FILES := $(subst .S,.S.neon,$(LOCAL_SRC_FILES))
endif endif
# remove duplicates
LOCAL_SRC_FILES := $(sort $(LOCAL_SRC_FILES))
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/libvpx \ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/libvpx \
$(LOCAL_PATH)/libvpx/vpx $(LOCAL_PATH)/libvpx/vpx
LOCAL_LDFLAGS := -Wl,--version-script=$(CONFIG_DIR)/libvpx.ver
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
...@@ -20,8 +20,9 @@ ...@@ -20,8 +20,9 @@
#include <android/log.h> #include <android/log.h>
#include <algorithm> #include <algorithm>
#include <cstdlib>
#include <cstdio> #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <new> #include <new>
#include "libyuv.h" // NOLINT #include "libyuv.h" // NOLINT
......
// Copyright (C) 2017 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.
class CombinedJavadocPlugin implements Plugin<Project> {
static final String TASK_NAME = "generateCombinedJavadoc"
@Override
void apply(Project project) {
project.gradle.projectsEvaluated {
Set<Project> libraryModules = getLibraryModules(project)
if (!libraryModules.isEmpty()) {
String sdkDirectory = getSdkDirectory(libraryModules)
project.task(TASK_NAME, type: Javadoc) {
description = "Generates combined Javadoc."
title = "ExoPlayer library"
source = libraryModules.generateJavadoc.source
classpath = project.files(libraryModules.generateJavadoc.classpath)
destinationDir = project.file("$project.buildDir/docs/javadoc")
options {
links "http://docs.oracle.com/javase/7/docs/api/"
linksOffline "https://developer.android.com/reference",
"${sdkDirectory}/docs/reference"
encoding = "UTF-8"
}
exclude "**/BuildConfig.java"
exclude "**/R.java"
destinationDir project.file("$project.buildDir/docs/javadoc")
doLast {
libraryModules.each { libraryModule ->
project.copy {
from "${libraryModule.projectDir}/src/main/javadoc"
into "${project.buildDir}/docs/javadoc"
}
}
}
}
}
}
}
// Returns Android library modules that declare a generateJavadoc task.
private Set<Project> getLibraryModules(Project project) {
project.subprojects.findAll {
it.plugins.findPlugin("com.android.library") &&
it.tasks.findByName("generateJavadoc")
}
}
// Returns the Android SDK directory given a set of Android library modules.
private String getSdkDirectory(Set<Project> libraryModules) {
// We can retrieve the Android SDK directory from any module.
return libraryModules.iterator().next().android.sdkDirectory
}
}
apply plugin: CombinedJavadocPlugin
// Copyright (C) 2017 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.
android.libraryVariants.all { variant ->
def name = variant.buildType.name
if (!name.equals("release")) {
return; // Skip non-release builds.
}
task("generateJavadoc", type: Javadoc) {
description = "Generates Javadoc for the ${javadocTitle}."
title = "ExoPlayer ${javadocTitle}"
source = variant.javaCompile.source
classpath = files(variant.javaCompile.classpath.files,
project.android.getBootClasspath())
options {
links "http://docs.oracle.com/javase/7/docs/api/"
linksOffline "https://developer.android.com/reference",
"${android.sdkDirectory}/docs/reference"
encoding = "UTF-8"
}
exclude "**/BuildConfig.java"
exclude "**/R.java"
doLast {
copy {
from "src/main/javadoc"
into "$buildDir/docs/javadoc"
}
}
}
}
// Copyright (C) 2016 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.
apply plugin: 'com.android.library'
android {
compileSdkVersion project.ext.compileSdkVersion
buildToolsVersion project.ext.buildToolsVersion
defaultConfig {
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
}
}
dependencies {
compile project(':library-core')
compile project(':library-dash')
compile project(':library-hls')
compile project(':library-smoothstreaming')
compile project(':library-ui')
}
ext {
releaseArtifact = 'exoplayer'
releaseDescription = 'The ExoPlayer library (all modules).'
}
apply from: '../../publish.gradle'
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import com.android.builder.core.BuilderConstants
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
android { android {
...@@ -22,66 +20,35 @@ android { ...@@ -22,66 +20,35 @@ android {
defaultConfig { defaultConfig {
minSdkVersion project.ext.minSdkVersion minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion targetSdkVersion project.ext.targetSdkVersion
consumerProguardFiles 'proguard-rules.txt'
}
buildTypes {
// Re-enable test coverage when the following issue is fixed:
// https://code.google.com/p/android/issues/detail?id=226070
// debug {
// testCoverageEnabled = true
// }
} }
sourceSets { sourceSets {
androidTest { androidTest {
java.srcDirs += "../testutils/src/main/java/" java.srcDirs += "../../testutils/src/main/java/"
} }
} }
}
dependencies { buildTypes {
compile 'com.android.support:support-annotations:25.2.0' debug {
androidTestCompile 'com.google.dexmaker:dexmaker:1.2' testCoverageEnabled = true
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2' }
androidTestCompile 'org.mockito:mockito-core:1.9.5' }
} }
android.libraryVariants.all { variant -> dependencies {
def name = variant.buildType.name compile 'com.android.support:support-annotations:' + supportLibraryVersion
if (name.equals(BuilderConstants.DEBUG)) { androidTestCompile 'com.google.dexmaker:dexmaker:' + dexmakerVersion
return; // Skip debug builds. androidTestCompile 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion
} androidTestCompile 'org.mockito:mockito-core:' + mockitoVersion
def task = project.tasks.create "jar${name.capitalize()}", Jar
task.dependsOn variant.javaCompile
task.from variant.javaCompile.destinationDir
artifacts.add('archives', task);
} }
android.libraryVariants.all { variant -> ext {
task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) { javadocTitle = 'Core module'
title = "ExoPlayer library"
description "Generates Javadoc for $variant.name."
source = variant.javaCompile.source
classpath = files(variant.javaCompile.classpath.files, project.android.getBootClasspath())
options {
links "http://docs.oracle.com/javase/7/docs/api/"
linksOffline "https://developer.android.com/reference","${android.sdkDirectory}/docs/reference"
encoding = 'UTF-8'
}
exclude '**/BuildConfig.java'
exclude '**/R.java'
doLast {
copy {
from "src/main/javadoc"
into "$buildDir/docs/javadoc"
}
}
}
} }
apply from: '../../javadoc_library.gradle'
ext { ext {
releaseArtifact = 'exoplayer' releaseArtifact = 'exoplayer-core'
releaseDescription = 'The ExoPlayer library.' releaseDescription = 'The ExoPlayer library core module.'
} }
apply from: '../publish.gradle' apply from: '../../publish.gradle'
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.google.android.exoplayer2.test"> package="com.google.android.exoplayer2.core.test">
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="24"/> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="24"/>
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
</application> </application>
<instrumentation <instrumentation
android:targetPackage="com.google.android.exoplayer2.test" android:targetPackage="com.google.android.exoplayer2.core.test"
android:name="android.test.InstrumentationTestRunner" android:name="android.test.InstrumentationTestRunner"
tools:replace="android:targetPackage"/> tools:replace="android:targetPackage"/>
......
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