diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java index ac3cef00b9..71bc09c6d1 100644 --- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java +++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java @@ -46,6 +46,7 @@ import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.ListenerSet; import com.google.android.exoplayer2.util.Log; +import com.google.android.exoplayer2.util.Size; import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.video.VideoSize; import com.google.android.gms.cast.CastStatusCodes; @@ -725,6 +726,12 @@ public final class CastPlayer extends BasePlayer { return VideoSize.UNKNOWN; } + /** This method is not supported and returns {@link Size#UNKNOWN}. */ + @Override + public Size getVideoSurfaceSize() { + return Size.UNKNOWN; + } + /** This method is not supported and returns an empty {@link CueGroup}. */ @Override public CueGroup getCurrentCues() { diff --git a/library/common/src/main/java/com/google/android/exoplayer2/ForwardingPlayer.java b/library/common/src/main/java/com/google/android/exoplayer2/ForwardingPlayer.java index 942e690833..90289a6fca 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/ForwardingPlayer.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/ForwardingPlayer.java @@ -26,6 +26,7 @@ import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.CueGroup; import com.google.android.exoplayer2.trackselection.TrackSelectionParameters; +import com.google.android.exoplayer2.util.Size; import com.google.android.exoplayer2.video.VideoSize; import java.util.List; @@ -761,6 +762,12 @@ public class ForwardingPlayer implements Player { return player.getVideoSize(); } + /** Calls {@link Player#getVideoSurfaceSize()} on the delegate and returns the result. */ + @Override + public Size getVideoSurfaceSize() { + return player.getVideoSurfaceSize(); + } + /** Calls {@link Player#clearVideoSurface()} on the delegate. */ @Override public void clearVideoSurface() { diff --git a/library/common/src/main/java/com/google/android/exoplayer2/Player.java b/library/common/src/main/java/com/google/android/exoplayer2/Player.java index 436910a90c..9c384ef5f5 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/Player.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/Player.java @@ -37,6 +37,7 @@ import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.CueGroup; import com.google.android.exoplayer2.trackselection.TrackSelectionParameters; import com.google.android.exoplayer2.util.FlagSet; +import com.google.android.exoplayer2.util.Size; import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.video.VideoSize; import com.google.common.base.Objects; @@ -2471,6 +2472,13 @@ public interface Player { */ VideoSize getVideoSize(); + /** + * Gets the size of the surface on which the video is rendered. + * + * @see Listener#onSurfaceSizeChanged(int, int) + */ + Size getVideoSurfaceSize(); + /** Returns the current {@link CueGroup}. */ CueGroup getCurrentCues(); diff --git a/library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java b/library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java index 111c2f59dc..c56347edda 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java @@ -30,6 +30,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionParameters; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.HandlerWrapper; import com.google.android.exoplayer2.util.ListenerSet; +import com.google.android.exoplayer2.util.Size; import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.video.VideoSize; import com.google.common.base.Supplier; @@ -590,6 +591,12 @@ public abstract class SimpleBasePlayer extends BasePlayer { throw new IllegalStateException(); } + @Override + public final Size getVideoSurfaceSize() { + // TODO: implement. + throw new IllegalStateException(); + } + @Override public final CueGroup getCurrentCues() { // TODO: implement. diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/Size.java b/library/common/src/main/java/com/google/android/exoplayer2/util/Size.java new file mode 100644 index 0000000000..c273fbf5ee --- /dev/null +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/Size.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2022 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.util; + +import static com.google.android.exoplayer2.util.Assertions.checkArgument; + +import androidx.annotation.Nullable; +import com.google.android.exoplayer2.C; + +/** Immutable class for describing width and height dimensions in pixels. */ +public final class Size { + + /** A static instance to represent an unknown size value. */ + public static final Size UNKNOWN = + new Size(/* width= */ C.LENGTH_UNSET, /* height= */ C.LENGTH_UNSET); + + private final int width; + private final int height; + + /** + * Creates a new immutable Size instance. + * + * @param width The width of the size, in pixels, or {@link C#LENGTH_UNSET} if unknown. + * @param height The height of the size, in pixels, or {@link C#LENGTH_UNSET} if unknown. + * @throws IllegalArgumentException if an invalid {@code width} or {@code height} is specified. + */ + public Size(int width, int height) { + checkArgument( + (width == C.LENGTH_UNSET || width >= 0) && (height == C.LENGTH_UNSET || height >= 0)); + + this.width = width; + this.height = height; + } + + /** Returns the width of the size (in pixels), or {@link C#LENGTH_UNSET} if unknown. */ + public int getWidth() { + return width; + } + + /** Returns the height of the size (in pixels), or {@link C#LENGTH_UNSET} if unknown. */ + public int getHeight() { + return height; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (obj == null) { + return false; + } + if (this == obj) { + return true; + } + if (obj instanceof Size) { + Size other = (Size) obj; + return width == other.width && height == other.height; + } + return false; + } + + @Override + public String toString() { + return width + "x" + height; + } + + @Override + public int hashCode() { + // assuming most sizes are <2^16, doing a rotate will give us perfect hashing + return height ^ ((width << (Integer.SIZE / 2)) | (width >>> (Integer.SIZE / 2))); + } +} diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index c2b9bb4a8f..6f60dc4247 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -88,6 +88,7 @@ import com.google.android.exoplayer2.util.HandlerWrapper; import com.google.android.exoplayer2.util.ListenerSet; import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.PriorityTaskManager; +import com.google.android.exoplayer2.util.Size; import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.video.VideoDecoderOutputBufferRenderer; import com.google.android.exoplayer2.video.VideoFrameMetadataListener; @@ -181,8 +182,7 @@ import java.util.concurrent.TimeoutException; @Nullable private TextureView textureView; private @C.VideoScalingMode int videoScalingMode; private @C.VideoChangeFrameRateStrategy int videoChangeFrameRateStrategy; - private int surfaceWidth; - private int surfaceHeight; + private Size surfaceSize; @Nullable private DecoderCounters videoDecoderCounters; @Nullable private DecoderCounters audioDecoderCounters; private int audioSessionId; @@ -371,6 +371,7 @@ import java.util.concurrent.TimeoutException; wifiLockManager.setEnabled(builder.wakeMode == C.WAKE_MODE_NETWORK); deviceInfo = createDeviceInfo(streamVolumeManager); videoSize = VideoSize.UNKNOWN; + surfaceSize = Size.UNKNOWN; trackSelector.setAudioAttributes(audioAttributes); sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_SESSION_ID, audioSessionId); @@ -1218,6 +1219,12 @@ import java.util.concurrent.TimeoutException; return videoSize; } + @Override + public Size getVideoSurfaceSize() { + verifyApplicationThread(); + return surfaceSize; + } + @Override public void clearVideoSurface() { verifyApplicationThread(); @@ -2534,9 +2541,8 @@ import java.util.concurrent.TimeoutException; } private void maybeNotifySurfaceSizeChanged(int width, int height) { - if (width != surfaceWidth || height != surfaceHeight) { - surfaceWidth = width; - surfaceHeight = height; + if (width != surfaceSize.getWidth() || height != surfaceSize.getHeight()) { + surfaceSize = new Size(width, height); listeners.sendEvent( EVENT_SURFACE_SIZE_CHANGED, listener -> listener.onSurfaceSizeChanged(width, height)); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java index ddd3df45bc..0f0e334246 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java @@ -44,6 +44,7 @@ import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.ConditionVariable; import com.google.android.exoplayer2.util.PriorityTaskManager; +import com.google.android.exoplayer2.util.Size; import com.google.android.exoplayer2.video.VideoFrameMetadataListener; import com.google.android.exoplayer2.video.VideoSize; import com.google.android.exoplayer2.video.spherical.CameraMotionListener; @@ -517,6 +518,12 @@ public class SimpleExoPlayer extends BasePlayer return player.getVideoSize(); } + @Override + public Size getVideoSurfaceSize() { + blockUntilConstructorFinished(); + return player.getVideoSurfaceSize(); + } + @Override public void clearVideoSurface() { blockUntilConstructorFinished(); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/StubPlayer.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/StubPlayer.java index e4e04b4fd3..ae245c5d8c 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/StubPlayer.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/StubPlayer.java @@ -33,6 +33,7 @@ import com.google.android.exoplayer2.Tracks; import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.text.CueGroup; import com.google.android.exoplayer2.trackselection.TrackSelectionParameters; +import com.google.android.exoplayer2.util.Size; import com.google.android.exoplayer2.video.VideoSize; import java.util.List; @@ -349,6 +350,11 @@ public class StubPlayer extends BasePlayer { throw new UnsupportedOperationException(); } + @Override + public Size getVideoSurfaceSize() { + throw new UnsupportedOperationException(); + } + @Override public CueGroup getCurrentCues() { throw new UnsupportedOperationException();