From 951fea231d5f3f339075b1a9a885733ade2d68b0 Mon Sep 17 00:00:00 2001 From: rohks Date: Tue, 13 Dec 2022 18:09:51 +0000 Subject: [PATCH] Remove parameters with default values from bundle in `MediaItem` This improves the time taken to construct PlayerInfo from bundle from ~600ms to ~450ms. PiperOrigin-RevId: 495055355 (cherry picked from commit 7de47fe2a1493da1b0720ddeb357052d2b1dc5bb) --- .../google/android/exoplayer2/MediaItem.java | 97 ++++++++++---- .../android/exoplayer2/MediaItemTest.java | 119 +++++++++++++++++- 2 files changed, 188 insertions(+), 28 deletions(-) diff --git a/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java b/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java index cd104145d4..456149b8c7 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java @@ -1094,7 +1094,7 @@ public final class MediaItem implements Bundleable { private float minPlaybackSpeed; private float maxPlaybackSpeed; - /** Constructs an instance. */ + /** Creates a new instance with default values. */ public Builder() { this.targetOffsetMs = C.TIME_UNSET; this.minOffsetMs = C.TIME_UNSET; @@ -1296,11 +1296,21 @@ public final class MediaItem implements Bundleable { @Override public Bundle toBundle() { Bundle bundle = new Bundle(); - bundle.putLong(keyForField(FIELD_TARGET_OFFSET_MS), targetOffsetMs); - bundle.putLong(keyForField(FIELD_MIN_OFFSET_MS), minOffsetMs); - bundle.putLong(keyForField(FIELD_MAX_OFFSET_MS), maxOffsetMs); - bundle.putFloat(keyForField(FIELD_MIN_PLAYBACK_SPEED), minPlaybackSpeed); - bundle.putFloat(keyForField(FIELD_MAX_PLAYBACK_SPEED), maxPlaybackSpeed); + if (targetOffsetMs != UNSET.targetOffsetMs) { + bundle.putLong(keyForField(FIELD_TARGET_OFFSET_MS), targetOffsetMs); + } + if (minOffsetMs != UNSET.minOffsetMs) { + bundle.putLong(keyForField(FIELD_MIN_OFFSET_MS), minOffsetMs); + } + if (maxOffsetMs != UNSET.maxOffsetMs) { + bundle.putLong(keyForField(FIELD_MAX_OFFSET_MS), maxOffsetMs); + } + if (minPlaybackSpeed != UNSET.minPlaybackSpeed) { + bundle.putFloat(keyForField(FIELD_MIN_PLAYBACK_SPEED), minPlaybackSpeed); + } + if (maxPlaybackSpeed != UNSET.maxPlaybackSpeed) { + bundle.putFloat(keyForField(FIELD_MAX_PLAYBACK_SPEED), maxPlaybackSpeed); + } return bundle; } @@ -1309,13 +1319,17 @@ public final class MediaItem implements Bundleable { bundle -> new LiveConfiguration( bundle.getLong( - keyForField(FIELD_TARGET_OFFSET_MS), /* defaultValue= */ C.TIME_UNSET), - bundle.getLong(keyForField(FIELD_MIN_OFFSET_MS), /* defaultValue= */ C.TIME_UNSET), - bundle.getLong(keyForField(FIELD_MAX_OFFSET_MS), /* defaultValue= */ C.TIME_UNSET), + keyForField(FIELD_TARGET_OFFSET_MS), /* defaultValue= */ UNSET.targetOffsetMs), + bundle.getLong( + keyForField(FIELD_MIN_OFFSET_MS), /* defaultValue= */ UNSET.minOffsetMs), + bundle.getLong( + keyForField(FIELD_MAX_OFFSET_MS), /* defaultValue= */ UNSET.maxOffsetMs), bundle.getFloat( - keyForField(FIELD_MIN_PLAYBACK_SPEED), /* defaultValue= */ C.RATE_UNSET), + keyForField(FIELD_MIN_PLAYBACK_SPEED), + /* defaultValue= */ UNSET.minPlaybackSpeed), bundle.getFloat( - keyForField(FIELD_MAX_PLAYBACK_SPEED), /* defaultValue= */ C.RATE_UNSET)); + keyForField(FIELD_MAX_PLAYBACK_SPEED), + /* defaultValue= */ UNSET.maxPlaybackSpeed)); private static String keyForField(@LiveConfiguration.FieldNumber int field) { return Integer.toString(field, Character.MAX_RADIX); @@ -1554,7 +1568,7 @@ public final class MediaItem implements Bundleable { private boolean relativeToDefaultPosition; private boolean startsAtKeyFrame; - /** Constructs an instance. */ + /** Creates a new instance with default values. */ public Builder() { endPositionMs = C.TIME_END_OF_SOURCE; } @@ -1727,11 +1741,22 @@ public final class MediaItem implements Bundleable { @Override public Bundle toBundle() { Bundle bundle = new Bundle(); - bundle.putLong(keyForField(FIELD_START_POSITION_MS), startPositionMs); - bundle.putLong(keyForField(FIELD_END_POSITION_MS), endPositionMs); - bundle.putBoolean(keyForField(FIELD_RELATIVE_TO_LIVE_WINDOW), relativeToLiveWindow); - bundle.putBoolean(keyForField(FIELD_RELATIVE_TO_DEFAULT_POSITION), relativeToDefaultPosition); - bundle.putBoolean(keyForField(FIELD_STARTS_AT_KEY_FRAME), startsAtKeyFrame); + if (startPositionMs != UNSET.startPositionMs) { + bundle.putLong(keyForField(FIELD_START_POSITION_MS), startPositionMs); + } + if (endPositionMs != UNSET.endPositionMs) { + bundle.putLong(keyForField(FIELD_END_POSITION_MS), endPositionMs); + } + if (relativeToLiveWindow != UNSET.relativeToLiveWindow) { + bundle.putBoolean(keyForField(FIELD_RELATIVE_TO_LIVE_WINDOW), relativeToLiveWindow); + } + if (relativeToDefaultPosition != UNSET.relativeToDefaultPosition) { + bundle.putBoolean( + keyForField(FIELD_RELATIVE_TO_DEFAULT_POSITION), relativeToDefaultPosition); + } + if (startsAtKeyFrame != UNSET.startsAtKeyFrame) { + bundle.putBoolean(keyForField(FIELD_STARTS_AT_KEY_FRAME), startsAtKeyFrame); + } return bundle; } @@ -1740,17 +1765,25 @@ public final class MediaItem implements Bundleable { bundle -> new ClippingConfiguration.Builder() .setStartPositionMs( - bundle.getLong(keyForField(FIELD_START_POSITION_MS), /* defaultValue= */ 0)) + bundle.getLong( + keyForField(FIELD_START_POSITION_MS), + /* defaultValue= */ UNSET.startPositionMs)) .setEndPositionMs( bundle.getLong( keyForField(FIELD_END_POSITION_MS), - /* defaultValue= */ C.TIME_END_OF_SOURCE)) + /* defaultValue= */ UNSET.endPositionMs)) .setRelativeToLiveWindow( - bundle.getBoolean(keyForField(FIELD_RELATIVE_TO_LIVE_WINDOW), false)) + bundle.getBoolean( + keyForField(FIELD_RELATIVE_TO_LIVE_WINDOW), + /* defaultValue= */ UNSET.relativeToLiveWindow)) .setRelativeToDefaultPosition( - bundle.getBoolean(keyForField(FIELD_RELATIVE_TO_DEFAULT_POSITION), false)) + bundle.getBoolean( + keyForField(FIELD_RELATIVE_TO_DEFAULT_POSITION), + /* defaultValue= */ UNSET.relativeToDefaultPosition)) .setStartsAtKeyFrame( - bundle.getBoolean(keyForField(FIELD_STARTS_AT_KEY_FRAME), false)) + bundle.getBoolean( + keyForField(FIELD_STARTS_AT_KEY_FRAME), + /* defaultValue= */ UNSET.startsAtKeyFrame)) .buildClippingProperties(); private static String keyForField(@ClippingConfiguration.FieldNumber int field) { @@ -2033,11 +2066,21 @@ public final class MediaItem implements Bundleable { @Override public Bundle toBundle() { Bundle bundle = new Bundle(); - bundle.putString(keyForField(FIELD_MEDIA_ID), mediaId); - bundle.putBundle(keyForField(FIELD_LIVE_CONFIGURATION), liveConfiguration.toBundle()); - bundle.putBundle(keyForField(FIELD_MEDIA_METADATA), mediaMetadata.toBundle()); - bundle.putBundle(keyForField(FIELD_CLIPPING_PROPERTIES), clippingConfiguration.toBundle()); - bundle.putBundle(keyForField(FIELD_REQUEST_METADATA), requestMetadata.toBundle()); + if (!mediaId.equals(DEFAULT_MEDIA_ID)) { + bundle.putString(keyForField(FIELD_MEDIA_ID), mediaId); + } + if (!liveConfiguration.equals(LiveConfiguration.UNSET)) { + bundle.putBundle(keyForField(FIELD_LIVE_CONFIGURATION), liveConfiguration.toBundle()); + } + if (!mediaMetadata.equals(MediaMetadata.EMPTY)) { + bundle.putBundle(keyForField(FIELD_MEDIA_METADATA), mediaMetadata.toBundle()); + } + if (!clippingConfiguration.equals(ClippingConfiguration.UNSET)) { + bundle.putBundle(keyForField(FIELD_CLIPPING_PROPERTIES), clippingConfiguration.toBundle()); + } + if (!requestMetadata.equals(RequestMetadata.EMPTY)) { + bundle.putBundle(keyForField(FIELD_REQUEST_METADATA), requestMetadata.toBundle()); + } return bundle; } diff --git a/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java b/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java index 8b2ac0e054..c354ceec99 100644 --- a/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java +++ b/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java @@ -362,10 +362,12 @@ public class MediaItemTest { } @Test - public void clippingConfigurationDefaults() { + public void createDefaultClippingConfigurationInstance_checksDefaultValues() { MediaItem.ClippingConfiguration clippingConfiguration = new MediaItem.ClippingConfiguration.Builder().build(); + // Please refrain from altering default values since doing so would cause issues with backwards + // compatibility. assertThat(clippingConfiguration.startPositionMs).isEqualTo(0L); assertThat(clippingConfiguration.endPositionMs).isEqualTo(C.TIME_END_OF_SOURCE); assertThat(clippingConfiguration.relativeToLiveWindow).isFalse(); @@ -374,6 +376,32 @@ public class MediaItemTest { assertThat(clippingConfiguration).isEqualTo(MediaItem.ClippingConfiguration.UNSET); } + @Test + public void createDefaultClippingConfigurationInstance_roundTripViaBundle_yieldsEqualInstance() { + MediaItem.ClippingConfiguration clippingConfiguration = + new MediaItem.ClippingConfiguration.Builder().build(); + + MediaItem.ClippingConfiguration clippingConfigurationFromBundle = + MediaItem.ClippingConfiguration.CREATOR.fromBundle(clippingConfiguration.toBundle()); + + assertThat(clippingConfigurationFromBundle).isEqualTo(clippingConfiguration); + } + + @Test + public void createClippingConfigurationInstance_roundTripViaBundle_yieldsEqualInstance() { + // Creates instance by setting some non-default values + MediaItem.ClippingConfiguration clippingConfiguration = + new MediaItem.ClippingConfiguration.Builder() + .setStartPositionMs(1000L) + .setStartsAtKeyFrame(true) + .build(); + + MediaItem.ClippingConfiguration clippingConfigurationFromBundle = + MediaItem.ClippingConfiguration.CREATOR.fromBundle(clippingConfiguration.toBundle()); + + assertThat(clippingConfigurationFromBundle).isEqualTo(clippingConfiguration); + } + @Test public void clippingConfigurationBuilder_throwsOnInvalidValues() { MediaItem.ClippingConfiguration.Builder clippingConfigurationBuilder = @@ -516,6 +544,47 @@ public class MediaItemTest { assertThat(mediaItem.mediaMetadata).isEqualTo(mediaMetadata); } + @Test + public void createDefaultLiveConfigurationInstance_checksDefaultValues() { + MediaItem.LiveConfiguration liveConfiguration = + new MediaItem.LiveConfiguration.Builder().build(); + + // Please refrain from altering default values since doing so would cause issues with backwards + // compatibility. + assertThat(liveConfiguration.targetOffsetMs).isEqualTo(C.TIME_UNSET); + assertThat(liveConfiguration.minOffsetMs).isEqualTo(C.TIME_UNSET); + assertThat(liveConfiguration.maxOffsetMs).isEqualTo(C.TIME_UNSET); + assertThat(liveConfiguration.minPlaybackSpeed).isEqualTo(C.RATE_UNSET); + assertThat(liveConfiguration.maxPlaybackSpeed).isEqualTo(C.RATE_UNSET); + assertThat(liveConfiguration).isEqualTo(MediaItem.LiveConfiguration.UNSET); + } + + @Test + public void createDefaultLiveConfigurationInstance_roundTripViaBundle_yieldsEqualInstance() { + MediaItem.LiveConfiguration liveConfiguration = + new MediaItem.LiveConfiguration.Builder().build(); + + MediaItem.LiveConfiguration liveConfigurationFromBundle = + MediaItem.LiveConfiguration.CREATOR.fromBundle(liveConfiguration.toBundle()); + + assertThat(liveConfigurationFromBundle).isEqualTo(liveConfiguration); + } + + @Test + public void createLiveConfigurationInstance_roundTripViaBundle_yieldsEqualInstance() { + // Creates instance by setting some non-default values + MediaItem.LiveConfiguration liveConfiguration = + new MediaItem.LiveConfiguration.Builder() + .setTargetOffsetMs(10_000) + .setMaxPlaybackSpeed(2f) + .build(); + + MediaItem.LiveConfiguration liveConfigurationFromBundle = + MediaItem.LiveConfiguration.CREATOR.fromBundle(liveConfiguration.toBundle()); + + assertThat(liveConfigurationFromBundle).isEqualTo(liveConfiguration); + } + @Test public void builderSetLiveConfiguration() { MediaItem mediaItem = @@ -749,4 +818,52 @@ public class MediaItemTest { assertThat(mediaItem.localConfiguration).isNotNull(); assertThat(MediaItem.CREATOR.fromBundle(mediaItem.toBundle()).localConfiguration).isNull(); } + + @Test + public void createDefaultMediaItemInstance_checksDefaultValues() { + MediaItem mediaItem = new MediaItem.Builder().build(); + + // Please refrain from altering default values since doing so would cause issues with backwards + // compatibility. + assertThat(mediaItem.mediaId).isEqualTo(MediaItem.DEFAULT_MEDIA_ID); + assertThat(mediaItem.liveConfiguration).isEqualTo(MediaItem.LiveConfiguration.UNSET); + assertThat(mediaItem.mediaMetadata).isEqualTo(MediaMetadata.EMPTY); + assertThat(mediaItem.clippingConfiguration).isEqualTo(MediaItem.ClippingConfiguration.UNSET); + assertThat(mediaItem.requestMetadata).isEqualTo(RequestMetadata.EMPTY); + assertThat(mediaItem).isEqualTo(MediaItem.EMPTY); + } + + @Test + public void createDefaultMediaItemInstance_roundTripViaBundle_yieldsEqualInstance() { + MediaItem mediaItem = new MediaItem.Builder().build(); + + MediaItem mediaItemFromBundle = MediaItem.CREATOR.fromBundle(mediaItem.toBundle()); + + assertThat(mediaItemFromBundle).isEqualTo(mediaItem); + } + + @Test + public void createMediaItemInstance_roundTripViaBundle_yieldsEqualInstance() { + // Creates instance by setting some non-default values + MediaItem mediaItem = + new MediaItem.Builder() + .setLiveConfiguration( + new MediaItem.LiveConfiguration.Builder() + .setTargetOffsetMs(20_000) + .setMinOffsetMs(2_222) + .setMaxOffsetMs(4_444) + .setMinPlaybackSpeed(.9f) + .setMaxPlaybackSpeed(1.1f) + .build()) + .setRequestMetadata( + new RequestMetadata.Builder() + .setMediaUri(Uri.parse("http://test.test")) + .setSearchQuery("search") + .build()) + .build(); + + MediaItem mediaItemFromBundle = MediaItem.CREATOR.fromBundle(mediaItem.toBundle()); + + assertThat(mediaItemFromBundle).isEqualTo(mediaItem); + } }