Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
bd664ad
Detect HEVC HDR10 codec profile more accurately
christosts Feb 6, 2023
ba2b9b3
Fix AudioTrackPositionTracker logic for playback speed adjustments
tonihei Feb 7, 2023
e89c14a
Merge pull request #248 from lemondoglol:update-segment-size
microkatz Feb 8, 2023
70db687
Merge pull request #10959 from balachandarlinks:handle-sql-exception-…
christosts Feb 14, 2023
0ebb8ff
Document spatialization behavior constants.
tonihei Feb 10, 2023
3cc93b1
Add null check to `ExoPlayerImpl.isTunnelingEnabled`
icbaker Feb 10, 2023
3696076
AsynchronousMediaCodecAdapter: surface queueing errors sooner
christosts Feb 10, 2023
f2753e2
Add ad event listeners in the Looper event of the ad manager callback
marcbaechinger Feb 13, 2023
cfe861e
Catch IllegalArgumentExceptions in RTSP Response parsing
microkatz Feb 13, 2023
6a273a5
Add exception cause to thrown exception
a-googler Feb 14, 2023
3b00561
Fix error in documentation string
a-googler Feb 16, 2023
629a75e
Map `PLAYER_STATE_LOADING` to `STATE_BUFFERING`
marcbaechinger Feb 17, 2023
0e5dad5
Reduce number of calls to AudioTrack.getPlaybackHeadPosition
tonihei Feb 20, 2023
58a977e
Skip rendering multiple frames on the same vsync
christosts Feb 20, 2023
5ab4223
Use ArrayDeque for pending output stream changes.
tonihei Feb 23, 2023
a09bb70
Do not specify export flags for protected system broadcasts.
tonihei Feb 24, 2023
abf1eb8
Use more realistic time values for MediaCodecVideoRendererTest
tonihei Feb 27, 2023
f011cc8
Correctly update output info if previous stream has been fully rendered
tonihei Feb 27, 2023
512ca60
Add workaround for wrong PerformancePoints on some devices.
tonihei Feb 27, 2023
5822d68
Ensure output format is updated in sync with stream changes.
tonihei Feb 27, 2023
ad42800
Update notification play/pause button with matching player state
tianyif Feb 10, 2023
f690ebd
Fix some playback parameter signalling problems.
tonihei Feb 27, 2023
b44fb57
Ensure getPlaybackHeadPosition isn't called if not needed
tonihei Feb 28, 2023
ee4ac61
Update translations
tonihei Feb 28, 2023
7d6a359
Minor change in ForwardingPlayer javadoc
christosts Feb 28, 2023
ddd5e9b
Remove @see tags with <a> tags
icbaker Mar 1, 2023
dbf737d
Merge pull request #255 from mayurk2:use_edts_offset_if_it_is_for_ent…
tonihei Mar 1, 2023
64c6d8f
Update release notes for 1.0.0-rc02
tonihei Mar 2, 2023
67fd41a
Bump version numbers to Media3 1.0.0-rc02 and ExoPlayer 2.18.4
tonihei Mar 2, 2023
d47675f
Fix some JavaDoc in the Media3 session module
marcbaechinger Mar 2, 2023
2e6484d
Remove unreleased changed
tonihei Mar 2, 2023
7958737
Fix lint-baseline.xml for latest UI translations
tonihei Mar 2, 2023
af30f00
Add missing RELEASENOTES line
tonihei Mar 2, 2023
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
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ body:
label: Media3 Version
description: What version of Media3 are you using?
options:
- 1.0.0-rc02
- 1.0.0-rc01
- 1.0.0-beta03
- 1.0.0-beta02
Expand Down
57 changes: 49 additions & 8 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
# Release notes

### 1.0.0-rc02 (2023-03-02)

This release corresponds to the
[ExoPlayer 2.18.4 release](https://github.com/google/ExoPlayer/releases/tag/r2.18.4).

* Core library:
* Fix network type detection on API 33
([#10970](https://github.com/google/ExoPlayer/issues/10970)).
* Fix `NullPointerException` when calling `ExoPlayer.isTunnelingEnabled`
([#10977](https://github.com/google/ExoPlayer/issues/10977)).
* Downloads:
* Make the maximum difference of the start time of two segments to be
merged configurable in `SegmentDownloader` and subclasses
([#248](https://github.com/androidx/media/pull/248)).
* Audio:
* Fix broken gapless MP3 playback on Samsung devices
([#8594](https://github.com/google/ExoPlayer/issues/8594)).
* Fix bug where playback speeds set immediately after disabling audio may
be overridden by a previous speed change
([#10882](https://github.com/google/ExoPlayer/issues/10882)).
* Video:
* Map HEVC HDR10 format to `HEVCProfileMain10HDR10` instead of
`HEVCProfileMain10`.
* Add workaround for a device issue on Chromecast with Google TV and
Lenovo M10 FHD Plus that causes 60fps AVC streams to be marked as
unsupported
([#10898](https://github.com/google/ExoPlayer/issues/10898)).
* Fix frame release performance issues when playing media with a frame
rate far higher than the screen refresh rate.
* Cast:
* Fix transient `STATE_IDLE` when transitioning between media items
([#245](https://github.com/androidx/media/issues/245)).
* RTSP:
* Catch the IllegalArgumentException thrown in parsing of invalid RTSP
Describe response messages
([#10971](https://github.com/google/ExoPlayer/issues/10971)).
* Session:
* Fix a bug where notification play/pause button doesn't update with
player state ([#192](https://github.com/androidx/media/issues/192)).
* IMA extension:
* Fix a bug which prevented DAI streams without any ads from starting
because the first (and in the case without ads the only) `LOADED` event
wasn't received.

### 1.0.0-rc01 (2023-02-16)

This release corresponds to the
Expand Down Expand Up @@ -73,17 +117,12 @@ This release corresponds to the
([#233](https://github.com/androidx/media/issues/233)).
* Make `QueueTimeline` more robust in case of a shady legacy session state
([#241](https://github.com/androidx/media/issues/241)).
* Metadata:
* Parse multiple null-separated values from ID3 frames, as permitted by
ID3 v2.4.
* Add `MediaMetadata.mediaType` to denote the type of content or the type
of folder described by the metadata.
* Add `MediaMetadata.isBrowsable` as a replacement for
`MediaMetadata.folderType`. The folder type will be deprecated in the
next release.
* Cast extension:
* Bump Cast SDK version to 21.2.0.
* IMA extension:
* Map `PLAYER_STATE_LOADING` to `STATE_BUFFERING`
([#245](\(https://github.com/androidx/media/issues/245\)).
* IMA extension
* Remove player listener of the `ImaServerSideAdInsertionMediaSource` on
the application thread to avoid threading issues.
* Add a property `focusSkipButtonWhenAvailable` to the
Expand All @@ -92,6 +131,8 @@ This release corresponds to the
* Add a method `focusSkipButton()` to the
`ImaServerSideAdInsertionMediaSource.AdsLoader` to programmatically
request to focus the skip button.
* Fix a bug which prevented playback from starting for a DAI stream
without any ads.
* Bump IMA SDK version to 3.29.0.
* Demo app:
* Request notification permission for download notifications at runtime
Expand Down
4 changes: 2 additions & 2 deletions constants.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
project.ext {
releaseVersion = '1.0.0-rc01'
releaseVersionCode = 1_000_000_2_01
releaseVersion = '1.0.0-rc02'
releaseVersionCode = 1_000_000_2_02
minSdkVersion = 16
appTargetSdkVersion = 33
// API version before restricting local file access.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,7 @@ private static int fetchPlaybackState(RemoteMediaClient remoteMediaClient) {
int receiverAppStatus = remoteMediaClient.getPlayerState();
switch (receiverAppStatus) {
case MediaStatus.PLAYER_STATE_BUFFERING:
case MediaStatus.PLAYER_STATE_LOADING:
return STATE_BUFFERING;
case MediaStatus.PLAYER_STATE_PLAYING:
case MediaStatus.PLAYER_STATE_PAUSED:
Expand Down Expand Up @@ -1299,6 +1300,7 @@ private static boolean isTrackActive(long id, long[] activeTrackIds) {
return false;
}

@SuppressWarnings("VisibleForTests")
private static int getCastRepeatMode(@RepeatMode int repeatMode) {
switch (repeatMode) {
case REPEAT_MODE_ONE:
Expand Down
5 changes: 4 additions & 1 deletion libraries/common/src/main/java/androidx/media3/common/C.java
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,10 @@ private C() {}
*/
@UnstableApi public static final int ENCODING_OPUS = AudioFormat.ENCODING_OPUS;

/** Represents the behavior affecting whether spatialization will be used. */
/**
* Represents the behavior affecting whether spatialization will be used. One of {@link
* #SPATIALIZATION_BEHAVIOR_AUTO} or {@link #SPATIALIZATION_BEHAVIOR_NEVER}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import java.util.List;

/**
* A {@link Player} that forwards operations to another {@link Player}. Applications can use this
* A {@link Player} that forwards method calls to another {@link Player}. Applications can use this
* class to suppress or modify specific operations, by overriding the respective methods.
*/
@UnstableApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ public final class MediaLibraryInfo {

/** The version of the library expressed as a string, for example "1.2.3" or "1.2.3-beta01". */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public static final String VERSION = "1.0.0-rc01";
public static final String VERSION = "1.0.0-rc02";

/** The version of the library expressed as {@code TAG + "/" + VERSION}. */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final String VERSION_SLASHY = "AndroidXMedia3/1.0.0-rc01";
public static final String VERSION_SLASHY = "AndroidXMedia3/1.0.0-rc02";

/**
* The version of the library expressed as an integer, for example 1002003300.
Expand All @@ -47,7 +47,7 @@ public final class MediaLibraryInfo {
* (123-045-006-3-00).
*/
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final int VERSION_INT = 1_000_000_2_01;
public static final int VERSION_INT = 1_000_000_2_02;

/** Whether the library was compiled with {@link Assertions} checks enabled. */
public static final boolean ASSERTIONS_ENABLED = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@
/**
* Parser for color expressions found in styling formats, e.g. TTML and CSS.
*
* @see <a href="https://w3c.github.io/webvtt/#styling">WebVTT CSS Styling</a>
* @see <a href="https://www.w3.org/TR/ttml2/">Timed Text Markup Language 2 (TTML2) - 10.3.5</a>
* <p>See also:
*
* <ul>
* <li><a href="https://w3c.github.io/webvtt/#styling">WebVTT CSS Styling</a>
* <li><a href="https://www.w3.org/TR/ttml2/">Timed Text Markup Language 2 (TTML2) - 10.3.5</a>
* </ul>
*/
@UnstableApi
public final class ColorParser {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ private NetworkTypeObserver(Context context) {
networkType = C.NETWORK_TYPE_UNKNOWN;
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Util.registerReceiverNotExported(context, new Receiver(), filter);
context.registerReceiver(new Receiver(), filter);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ public static byte[] toByteArray(InputStream inputStream) throws IOException {
* apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link
* #SDK_INT} is 33 or above.
*
* <p>Do not use this method if registering a receiver for a <a
* href="https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml">protected
* system broadcast</a>.
*
* @param context The context on which {@link Context#registerReceiver} will be called.
* @param receiver The {@link BroadcastReceiver} to register. This value may be null.
* @param filter Selects the Intent broadcasts to be received.
Expand All @@ -222,33 +226,6 @@ public static Intent registerReceiverNotExported(
}
}

/**
* Registers a {@link BroadcastReceiver} that's not intended to receive broadcasts from other
* apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link
* #SDK_INT} is 33 or above.
*
* @param context The context on which {@link Context#registerReceiver} will be called.
* @param receiver The {@link BroadcastReceiver} to register. This value may be null.
* @param filter Selects the Intent broadcasts to be received.
* @param handler Handler identifying the thread that will receive the Intent.
* @return The first sticky intent found that matches {@code filter}, or null if there are none.
*/
@UnstableApi
@Nullable
public static Intent registerReceiverNotExported(
Context context, BroadcastReceiver receiver, IntentFilter filter, Handler handler) {
if (SDK_INT < 33) {
return context.registerReceiver(receiver, filter, /* broadcastPermission= */ null, handler);
} else {
return context.registerReceiver(
receiver,
filter,
/* broadcastPermission= */ null,
handler,
Context.RECEIVER_NOT_EXPORTED);
}
}

/**
* Calls {@link Context#startForegroundService(Intent)} if {@link #SDK_INT} is 26 or higher, or
* {@link Context#startService(Intent)} otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,11 +794,15 @@ public void initialize(long uid) {

@Override
public boolean exists() throws DatabaseIOException {
return VersionTable.getVersion(
databaseProvider.getReadableDatabase(),
VersionTable.FEATURE_CACHE_CONTENT_METADATA,
checkNotNull(hexUid))
!= VersionTable.VERSION_UNSET;
try {
return VersionTable.getVersion(
databaseProvider.getReadableDatabase(),
VersionTable.FEATURE_CACHE_CONTENT_METADATA,
checkNotNull(hexUid))
!= VersionTable.VERSION_UNSET;
} catch (SQLException e) {
throw new DatabaseIOException(e);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Handler;
import androidx.media3.common.util.Util;

/* package */ final class AudioBecomingNoisyManager {

Expand All @@ -47,8 +46,8 @@ public AudioBecomingNoisyManager(Context context, Handler eventHandler, EventLis
*/
public void setEnabled(boolean enabled) {
if (enabled && !receiverRegistered) {
Util.registerReceiverNotExported(
context, receiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
context.registerReceiver(
receiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
receiverRegistered = true;
} else if (!enabled && receiverRegistered) {
context.unregisterReceiver(receiver);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1724,8 +1724,9 @@ public void setDeviceMuted(boolean muted) {
@Override
public boolean isTunnelingEnabled() {
verifyApplicationThread();
for (RendererConfiguration config : playbackInfo.trackSelectorResult.rendererConfigurations) {
if (config.tunneling) {
for (@Nullable
RendererConfiguration config : playbackInfo.trackSelectorResult.rendererConfigurations) {
if (config != null && config.tunneling) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@ && shouldUseLivePlaybackSpeedControl(playbackInfo.timeline, playbackInfo.periodI
livePlaybackSpeedControl.getAdjustedPlaybackSpeed(
getCurrentLiveOffsetUs(), getTotalBufferedDurationUs());
if (mediaClock.getPlaybackParameters().speed != adjustedSpeed) {
mediaClock.setPlaybackParameters(playbackInfo.playbackParameters.withSpeed(adjustedSpeed));
setMediaClockPlaybackParameters(playbackInfo.playbackParameters.withSpeed(adjustedSpeed));
handlePlaybackParameters(
playbackInfo.playbackParameters,
/* currentPlaybackSpeed= */ mediaClock.getPlaybackParameters().speed,
Expand All @@ -956,6 +956,12 @@ && shouldUseLivePlaybackSpeedControl(playbackInfo.timeline, playbackInfo.periodI
}
}

private void setMediaClockPlaybackParameters(PlaybackParameters playbackParameters) {
// Previously sent speed updates from the media clock now become stale.
handler.removeMessages(MSG_PLAYBACK_PARAMETERS_CHANGED_INTERNAL);
mediaClock.setPlaybackParameters(playbackParameters);
}

private void notifyTrackSelectionRebuffer() {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) {
Expand Down Expand Up @@ -1342,7 +1348,7 @@ private void resetRendererPosition(long periodPositionUs) throws ExoPlaybackExce

private void setPlaybackParametersInternal(PlaybackParameters playbackParameters)
throws ExoPlaybackException {
mediaClock.setPlaybackParameters(playbackParameters);
setMediaClockPlaybackParameters(playbackParameters);
handlePlaybackParameters(mediaClock.getPlaybackParameters(), /* acknowledgeCommand= */ true);
}

Expand Down Expand Up @@ -1657,7 +1663,7 @@ private void maybeTriggerPendingMessages(long oldPeriodPositionUs, long newPerio
nextPendingMessageIndexHint = nextPendingMessageIndex;
}

private void ensureStopped(Renderer renderer) throws ExoPlaybackException {
private void ensureStopped(Renderer renderer) {
if (renderer.getState() == Renderer.STATE_STARTED) {
renderer.stop();
}
Expand Down Expand Up @@ -1914,14 +1920,20 @@ private void updatePlaybackSpeedSettingsForNewPeriod(
MediaPeriodId newPeriodId,
Timeline oldTimeline,
MediaPeriodId oldPeriodId,
long positionForTargetOffsetOverrideUs) {
long positionForTargetOffsetOverrideUs)
throws ExoPlaybackException {
if (!shouldUseLivePlaybackSpeedControl(newTimeline, newPeriodId)) {
// Live playback speed control is unused for the current period, reset speed to user-defined
// playback parameters or 1.0 for ad playback.
PlaybackParameters targetPlaybackParameters =
newPeriodId.isAd() ? PlaybackParameters.DEFAULT : playbackInfo.playbackParameters;
if (!mediaClock.getPlaybackParameters().equals(targetPlaybackParameters)) {
mediaClock.setPlaybackParameters(targetPlaybackParameters);
setMediaClockPlaybackParameters(targetPlaybackParameters);
handlePlaybackParameters(
playbackInfo.playbackParameters,
targetPlaybackParameters.speed,
/* updatePlaybackInfo= */ false,
/* acknowledgeCommand= */ false);
}
return;
}
Expand Down Expand Up @@ -1970,7 +1982,7 @@ private long getMaxRendererReadPositionUs() {
return maxReadPositionUs;
}

private void updatePeriods() throws ExoPlaybackException, IOException {
private void updatePeriods() throws ExoPlaybackException {
if (playbackInfo.timeline.isEmpty() || !mediaSourceList.isPrepared()) {
// No periods available.
return;
Expand Down Expand Up @@ -2012,7 +2024,7 @@ private void maybeUpdateLoadingPeriod() throws ExoPlaybackException {
}
}

private void maybeUpdateReadingPeriod() {
private void maybeUpdateReadingPeriod() throws ExoPlaybackException {
@Nullable MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
if (readingPeriodHolder == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public StreamVolumeManager(Context context, Handler eventHandler, Listener liste
VolumeChangeReceiver receiver = new VolumeChangeReceiver();
IntentFilter filter = new IntentFilter(VOLUME_CHANGED_ACTION);
try {
Util.registerReceiverNotExported(applicationContext, receiver, filter);
applicationContext.registerReceiver(receiver, filter);
this.receiver = receiver;
} catch (RuntimeException e) {
Log.w(TAG, "Error registering stream volume receiver", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ public final class AudioCapabilities {
@SuppressWarnings("InlinedApi")
public static AudioCapabilities getCapabilities(Context context) {
Intent intent =
Util.registerReceiverNotExported(
context, /* receiver= */ null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG));
context.registerReceiver(
/* receiver= */ null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG));
return getCapabilities(context, intent);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ public AudioCapabilities register() {
@Nullable Intent stickyIntent = null;
if (receiver != null) {
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG);
stickyIntent = Util.registerReceiverNotExported(context, receiver, intentFilter, handler);
stickyIntent =
context.registerReceiver(
receiver, intentFilter, /* broadcastPermission= */ null, handler);
}
audioCapabilities = AudioCapabilities.getCapabilities(context, stickyIntent);
return audioCapabilities;
Expand Down
Loading