Core/UI decoupling: Move spherical back to core
A subsequent change will make the UI module access SphericalGLSurfaceView and VideoDecoderGLSurfaceView using reflection, now we're at the point where we only need to reflect the constructors. PiperOrigin-RevId: 369630102
This commit is contained in:
parent
a78b18298b
commit
2e5a616f26
@ -74,8 +74,6 @@
|
|||||||
cache.
|
cache.
|
||||||
* Library restructuring:
|
* Library restructuring:
|
||||||
* `DebugTextViewHelper` moved from `ui` package to `util` package.
|
* `DebugTextViewHelper` moved from `ui` package to `util` package.
|
||||||
* Spherical UI components moved from `video.spherical` package to
|
|
||||||
`ui.spherical` package, and made package private.
|
|
||||||
* Remove deprecated symbols:
|
* Remove deprecated symbols:
|
||||||
* Remove `ExoPlayerFactory` methods. Use `SimpleExoPlayer.Builder`
|
* Remove `ExoPlayerFactory` methods. Use `SimpleExoPlayer.Builder`
|
||||||
instead.
|
instead.
|
||||||
|
@ -48,8 +48,6 @@ import com.google.android.exoplayer2.util.ListenerSet;
|
|||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
|
||||||
import com.google.android.gms.cast.CastStatusCodes;
|
import com.google.android.gms.cast.CastStatusCodes;
|
||||||
import com.google.android.gms.cast.MediaInfo;
|
import com.google.android.gms.cast.MediaInfo;
|
||||||
import com.google.android.gms.cast.MediaQueueItem;
|
import com.google.android.gms.cast.MediaQueueItem;
|
||||||
@ -653,22 +651,6 @@ public final class CastPlayer extends BasePlayer {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
|
||||||
@Override
|
|
||||||
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {}
|
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
|
||||||
@Override
|
|
||||||
public void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener) {}
|
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
|
||||||
@Override
|
|
||||||
public void setCameraMotionListener(CameraMotionListener listener) {}
|
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
|
||||||
@Override
|
|
||||||
public void clearCameraMotionListener(CameraMotionListener listener) {}
|
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
/** This method is not supported and does nothing. */
|
||||||
@Override
|
@Override
|
||||||
public void clearVideoSurface() {}
|
public void clearVideoSurface() {}
|
||||||
|
@ -35,9 +35,7 @@ import com.google.android.exoplayer2.text.TextOutput;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.util.ExoFlags;
|
import com.google.android.exoplayer2.util.ExoFlags;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
|
||||||
import com.google.android.exoplayer2.video.VideoListener;
|
import com.google.android.exoplayer2.video.VideoListener;
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@ -1686,40 +1684,6 @@ public interface Player {
|
|||||||
*/
|
*/
|
||||||
float getVolume();
|
float getVolume();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a listener to receive video frame metadata events.
|
|
||||||
*
|
|
||||||
* <p>This method is intended to be called by the same component that sets the {@link Surface}
|
|
||||||
* onto which video will be rendered. If using ExoPlayer's standard UI components, this method
|
|
||||||
* should not be called directly from application code.
|
|
||||||
*
|
|
||||||
* @param listener The listener.
|
|
||||||
*/
|
|
||||||
void setVideoFrameMetadataListener(VideoFrameMetadataListener listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the listener which receives video frame metadata events if it matches the one passed.
|
|
||||||
* Else does nothing.
|
|
||||||
*
|
|
||||||
* @param listener The listener to clear.
|
|
||||||
*/
|
|
||||||
void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a listener of camera motion events.
|
|
||||||
*
|
|
||||||
* @param listener The listener.
|
|
||||||
*/
|
|
||||||
void setCameraMotionListener(CameraMotionListener listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the listener which receives camera motion events if it matches the one passed. Else does
|
|
||||||
* nothing.
|
|
||||||
*
|
|
||||||
* @param listener The listener to clear.
|
|
||||||
*/
|
|
||||||
void clearCameraMotionListener(CameraMotionListener listener);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears any {@link Surface}, {@link SurfaceHolder}, {@link SurfaceView} or {@link TextureView}
|
* Clears any {@link Surface}, {@link SurfaceHolder}, {@link SurfaceView} or {@link TextureView}
|
||||||
* currently set on the player.
|
* currently set on the player.
|
||||||
|
@ -52,8 +52,6 @@ import com.google.android.exoplayer2.util.HandlerWrapper;
|
|||||||
import com.google.android.exoplayer2.util.ListenerSet;
|
import com.google.android.exoplayer2.util.ListenerSet;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -1010,22 +1008,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
|
||||||
@Override
|
|
||||||
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {}
|
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
|
||||||
@Override
|
|
||||||
public void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener) {}
|
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
|
||||||
@Override
|
|
||||||
public void setCameraMotionListener(CameraMotionListener listener) {}
|
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
|
||||||
@Override
|
|
||||||
public void clearCameraMotionListener(CameraMotionListener listener) {}
|
|
||||||
|
|
||||||
/** This method is not supported and does nothing. */
|
/** This method is not supported and does nothing. */
|
||||||
@Override
|
@Override
|
||||||
public void clearVideoSurface() {}
|
public void clearVideoSurface() {}
|
||||||
|
@ -15,12 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2;
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_AUDIO_ATTRIBUTES;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_AUDIO_SESSION_ID;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_AUX_EFFECT_INFO;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_CAMERA_MOTION_LISTENER;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_SCALING_MODE;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_SKIP_SILENCE_ENABLED;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_VIDEO_OUTPUT;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_VOLUME;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
|
import android.media.MediaFormat;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
@ -66,6 +77,7 @@ import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
|||||||
import com.google.android.exoplayer2.video.VideoListener;
|
import com.google.android.exoplayer2.video.VideoListener;
|
||||||
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
||||||
|
import com.google.android.exoplayer2.video.spherical.SphericalGLSurfaceView;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -586,6 +598,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
private final Context applicationContext;
|
private final Context applicationContext;
|
||||||
private final ExoPlayerImpl player;
|
private final ExoPlayerImpl player;
|
||||||
private final ComponentListener componentListener;
|
private final ComponentListener componentListener;
|
||||||
|
private final FrameMetadataListener frameMetadataListener;
|
||||||
private final CopyOnWriteArraySet<VideoListener> videoListeners;
|
private final CopyOnWriteArraySet<VideoListener> videoListeners;
|
||||||
private final CopyOnWriteArraySet<AudioListener> audioListeners;
|
private final CopyOnWriteArraySet<AudioListener> audioListeners;
|
||||||
private final CopyOnWriteArraySet<TextOutput> textOutputs;
|
private final CopyOnWriteArraySet<TextOutput> textOutputs;
|
||||||
@ -605,6 +618,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
@Nullable private Object videoOutput;
|
@Nullable private Object videoOutput;
|
||||||
@Nullable private Surface ownedSurface;
|
@Nullable private Surface ownedSurface;
|
||||||
@Nullable private SurfaceHolder surfaceHolder;
|
@Nullable private SurfaceHolder surfaceHolder;
|
||||||
|
@Nullable private SphericalGLSurfaceView sphericalGLSurfaceView;
|
||||||
private boolean surfaceHolderSurfaceIsVideoOutput;
|
private boolean surfaceHolderSurfaceIsVideoOutput;
|
||||||
@Nullable private TextureView textureView;
|
@Nullable private TextureView textureView;
|
||||||
@C.VideoScalingMode private int videoScalingMode;
|
@C.VideoScalingMode private int videoScalingMode;
|
||||||
@ -664,6 +678,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
skipSilenceEnabled = builder.skipSilenceEnabled;
|
skipSilenceEnabled = builder.skipSilenceEnabled;
|
||||||
detachSurfaceTimeoutMs = builder.detachSurfaceTimeoutMs;
|
detachSurfaceTimeoutMs = builder.detachSurfaceTimeoutMs;
|
||||||
componentListener = new ComponentListener();
|
componentListener = new ComponentListener();
|
||||||
|
frameMetadataListener = new FrameMetadataListener();
|
||||||
videoListeners = new CopyOnWriteArraySet<>();
|
videoListeners = new CopyOnWriteArraySet<>();
|
||||||
audioListeners = new CopyOnWriteArraySet<>();
|
audioListeners = new CopyOnWriteArraySet<>();
|
||||||
textOutputs = new CopyOnWriteArraySet<>();
|
textOutputs = new CopyOnWriteArraySet<>();
|
||||||
@ -739,12 +754,15 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
deviceInfo = createDeviceInfo(streamVolumeManager);
|
deviceInfo = createDeviceInfo(streamVolumeManager);
|
||||||
currentMediaMetadata = MediaMetadata.EMPTY;
|
currentMediaMetadata = MediaMetadata.EMPTY;
|
||||||
|
|
||||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
||||||
sendRendererMessage(C.TRACK_TYPE_VIDEO, Renderer.MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
sendRendererMessage(C.TRACK_TYPE_VIDEO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
||||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_ATTRIBUTES, audioAttributes);
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_AUDIO_ATTRIBUTES, audioAttributes);
|
||||||
sendRendererMessage(C.TRACK_TYPE_VIDEO, Renderer.MSG_SET_SCALING_MODE, videoScalingMode);
|
sendRendererMessage(C.TRACK_TYPE_VIDEO, MSG_SET_SCALING_MODE, videoScalingMode);
|
||||||
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_SKIP_SILENCE_ENABLED, skipSilenceEnabled);
|
||||||
sendRendererMessage(
|
sendRendererMessage(
|
||||||
C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_SKIP_SILENCE_ENABLED, skipSilenceEnabled);
|
C.TRACK_TYPE_VIDEO, MSG_SET_VIDEO_FRAME_METADATA_LISTENER, frameMetadataListener);
|
||||||
|
sendRendererMessage(
|
||||||
|
C.TRACK_TYPE_CAMERA_MOTION, MSG_SET_CAMERA_MOTION_LISTENER, frameMetadataListener);
|
||||||
} finally {
|
} finally {
|
||||||
constructorFinished.open();
|
constructorFinished.open();
|
||||||
}
|
}
|
||||||
@ -804,7 +822,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
public void setVideoScalingMode(@C.VideoScalingMode int videoScalingMode) {
|
public void setVideoScalingMode(@C.VideoScalingMode int videoScalingMode) {
|
||||||
verifyApplicationThread();
|
verifyApplicationThread();
|
||||||
this.videoScalingMode = videoScalingMode;
|
this.videoScalingMode = videoScalingMode;
|
||||||
sendRendererMessage(C.TRACK_TYPE_VIDEO, Renderer.MSG_SET_SCALING_MODE, videoScalingMode);
|
sendRendererMessage(C.TRACK_TYPE_VIDEO, MSG_SET_SCALING_MODE, videoScalingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -874,19 +892,18 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
if (surfaceView instanceof VideoDecoderOutputBufferRenderer) {
|
if (surfaceView instanceof VideoDecoderOutputBufferRenderer) {
|
||||||
removeSurfaceCallbacks();
|
removeSurfaceCallbacks();
|
||||||
setVideoOutputInternal(surfaceView);
|
setVideoOutputInternal(surfaceView);
|
||||||
// Although we won't use the surface directly as the video output, still use the holder to
|
setNonVideoOutputSurfaceHolderInternal(surfaceView.getHolder());
|
||||||
// query the surface size, to be informed in changes to the size via componentListener, and
|
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
||||||
// for equality checking in clearVideoSurfaceHolder.
|
removeSurfaceCallbacks();
|
||||||
surfaceHolderSurfaceIsVideoOutput = false;
|
sphericalGLSurfaceView = (SphericalGLSurfaceView) surfaceView;
|
||||||
surfaceHolder = surfaceView.getHolder();
|
player
|
||||||
surfaceHolder.addCallback(componentListener);
|
.createMessage(frameMetadataListener)
|
||||||
Surface surface = surfaceHolder.getSurface();
|
.setType(FrameMetadataListener.MSG_SET_SPHERICAL_SURFACE_VIEW)
|
||||||
if (surface != null && surface.isValid()) {
|
.setPayload(sphericalGLSurfaceView)
|
||||||
Rect surfaceSize = surfaceHolder.getSurfaceFrame();
|
.send();
|
||||||
maybeNotifySurfaceSizeChanged(surfaceSize.width(), surfaceSize.height());
|
sphericalGLSurfaceView.addVideoSurfaceListener(componentListener);
|
||||||
} else {
|
setVideoOutputInternal(sphericalGLSurfaceView.getVideoSurface());
|
||||||
maybeNotifySurfaceSizeChanged(/* width= */ 0, /* height= */ 0);
|
setNonVideoOutputSurfaceHolderInternal(surfaceView.getHolder());
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
setVideoSurfaceHolder(surfaceView == null ? null : surfaceView.getHolder());
|
setVideoSurfaceHolder(surfaceView == null ? null : surfaceView.getHolder());
|
||||||
}
|
}
|
||||||
@ -964,7 +981,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
}
|
}
|
||||||
if (!Util.areEqual(this.audioAttributes, audioAttributes)) {
|
if (!Util.areEqual(this.audioAttributes, audioAttributes)) {
|
||||||
this.audioAttributes = audioAttributes;
|
this.audioAttributes = audioAttributes;
|
||||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_ATTRIBUTES, audioAttributes);
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_AUDIO_ATTRIBUTES, audioAttributes);
|
||||||
streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage));
|
streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage));
|
||||||
analyticsCollector.onAudioAttributesChanged(audioAttributes);
|
analyticsCollector.onAudioAttributesChanged(audioAttributes);
|
||||||
for (AudioListener audioListener : audioListeners) {
|
for (AudioListener audioListener : audioListeners) {
|
||||||
@ -1003,8 +1020,8 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
initializeKeepSessionIdAudioTrack(audioSessionId);
|
initializeKeepSessionIdAudioTrack(audioSessionId);
|
||||||
}
|
}
|
||||||
this.audioSessionId = audioSessionId;
|
this.audioSessionId = audioSessionId;
|
||||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
||||||
sendRendererMessage(C.TRACK_TYPE_VIDEO, Renderer.MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
sendRendererMessage(C.TRACK_TYPE_VIDEO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
||||||
analyticsCollector.onAudioSessionIdChanged(audioSessionId);
|
analyticsCollector.onAudioSessionIdChanged(audioSessionId);
|
||||||
for (AudioListener audioListener : audioListeners) {
|
for (AudioListener audioListener : audioListeners) {
|
||||||
audioListener.onAudioSessionIdChanged(audioSessionId);
|
audioListener.onAudioSessionIdChanged(audioSessionId);
|
||||||
@ -1019,7 +1036,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
@Override
|
@Override
|
||||||
public void setAuxEffectInfo(AuxEffectInfo auxEffectInfo) {
|
public void setAuxEffectInfo(AuxEffectInfo auxEffectInfo) {
|
||||||
verifyApplicationThread();
|
verifyApplicationThread();
|
||||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_AUX_EFFECT_INFO, auxEffectInfo);
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_AUX_EFFECT_INFO, auxEffectInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1059,8 +1076,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.skipSilenceEnabled = skipSilenceEnabled;
|
this.skipSilenceEnabled = skipSilenceEnabled;
|
||||||
sendRendererMessage(
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_SKIP_SILENCE_ENABLED, skipSilenceEnabled);
|
||||||
C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_SKIP_SILENCE_ENABLED, skipSilenceEnabled);
|
|
||||||
notifySkipSilenceEnabledChanged();
|
notifySkipSilenceEnabledChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1173,8 +1189,11 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {
|
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {
|
||||||
verifyApplicationThread();
|
verifyApplicationThread();
|
||||||
videoFrameMetadataListener = listener;
|
videoFrameMetadataListener = listener;
|
||||||
sendRendererMessage(
|
player
|
||||||
C.TRACK_TYPE_VIDEO, Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER, listener);
|
.createMessage(frameMetadataListener)
|
||||||
|
.setType(FrameMetadataListener.MSG_SET_VIDEO_FRAME_METADATA_LISTENER)
|
||||||
|
.setPayload(listener)
|
||||||
|
.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1183,16 +1202,22 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
if (videoFrameMetadataListener != listener) {
|
if (videoFrameMetadataListener != listener) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sendRendererMessage(
|
player
|
||||||
C.TRACK_TYPE_VIDEO, Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER, /* payload= */ null);
|
.createMessage(frameMetadataListener)
|
||||||
|
.setType(FrameMetadataListener.MSG_SET_VIDEO_FRAME_METADATA_LISTENER)
|
||||||
|
.setPayload(null)
|
||||||
|
.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCameraMotionListener(CameraMotionListener listener) {
|
public void setCameraMotionListener(CameraMotionListener listener) {
|
||||||
verifyApplicationThread();
|
verifyApplicationThread();
|
||||||
cameraMotionListener = listener;
|
cameraMotionListener = listener;
|
||||||
sendRendererMessage(
|
player
|
||||||
C.TRACK_TYPE_CAMERA_MOTION, Renderer.MSG_SET_CAMERA_MOTION_LISTENER, listener);
|
.createMessage(frameMetadataListener)
|
||||||
|
.setType(FrameMetadataListener.MSG_SET_CAMERA_MOTION_LISTENER)
|
||||||
|
.setPayload(listener)
|
||||||
|
.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1201,8 +1226,11 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
if (cameraMotionListener != listener) {
|
if (cameraMotionListener != listener) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sendRendererMessage(
|
player
|
||||||
C.TRACK_TYPE_CAMERA_MOTION, Renderer.MSG_SET_CAMERA_MOTION_LISTENER, /* payload= */ null);
|
.createMessage(frameMetadataListener)
|
||||||
|
.setType(FrameMetadataListener.MSG_SET_CAMERA_MOTION_LISTENER)
|
||||||
|
.setPayload(null)
|
||||||
|
.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1832,6 +1860,15 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
// Internal methods.
|
// Internal methods.
|
||||||
|
|
||||||
private void removeSurfaceCallbacks() {
|
private void removeSurfaceCallbacks() {
|
||||||
|
if (sphericalGLSurfaceView != null) {
|
||||||
|
player
|
||||||
|
.createMessage(frameMetadataListener)
|
||||||
|
.setType(FrameMetadataListener.MSG_SET_SPHERICAL_SURFACE_VIEW)
|
||||||
|
.setPayload(null)
|
||||||
|
.send();
|
||||||
|
sphericalGLSurfaceView.removeVideoSurfaceListener(componentListener);
|
||||||
|
sphericalGLSurfaceView = null;
|
||||||
|
}
|
||||||
if (textureView != null) {
|
if (textureView != null) {
|
||||||
if (textureView.getSurfaceTextureListener() != componentListener) {
|
if (textureView.getSurfaceTextureListener() != componentListener) {
|
||||||
Log.w(TAG, "SurfaceTextureListener already unset or replaced.");
|
Log.w(TAG, "SurfaceTextureListener already unset or replaced.");
|
||||||
@ -1861,7 +1898,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
messages.add(
|
messages.add(
|
||||||
player
|
player
|
||||||
.createMessage(renderer)
|
.createMessage(renderer)
|
||||||
.setType(Renderer.MSG_SET_VIDEO_OUTPUT)
|
.setType(MSG_SET_VIDEO_OUTPUT)
|
||||||
.setPayload(videoOutput)
|
.setPayload(videoOutput)
|
||||||
.send());
|
.send());
|
||||||
}
|
}
|
||||||
@ -1891,6 +1928,30 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
this.videoOutput = videoOutput;
|
this.videoOutput = videoOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the holder of the surface that will be displayed to the user, but which should
|
||||||
|
* <em>not</em> be the output for video renderers. This case occurs when video frames need to be
|
||||||
|
* rendered to an intermediate surface (which is not the one held by the provided holder).
|
||||||
|
*
|
||||||
|
* @param nonVideoOutputSurfaceHolder The holder of the surface that will eventually be displayed
|
||||||
|
* to the user.
|
||||||
|
*/
|
||||||
|
private void setNonVideoOutputSurfaceHolderInternal(SurfaceHolder nonVideoOutputSurfaceHolder) {
|
||||||
|
// Although we won't use the view's surface directly as the video output, still use the holder
|
||||||
|
// to query the surface size, to be informed in changes to the size via componentListener, and
|
||||||
|
// for equality checking in clearVideoSurfaceHolder.
|
||||||
|
surfaceHolderSurfaceIsVideoOutput = false;
|
||||||
|
surfaceHolder = nonVideoOutputSurfaceHolder;
|
||||||
|
surfaceHolder.addCallback(componentListener);
|
||||||
|
Surface surface = surfaceHolder.getSurface();
|
||||||
|
if (surface != null && surface.isValid()) {
|
||||||
|
Rect surfaceSize = surfaceHolder.getSurfaceFrame();
|
||||||
|
maybeNotifySurfaceSizeChanged(surfaceSize.width(), surfaceSize.height());
|
||||||
|
} else {
|
||||||
|
maybeNotifySurfaceSizeChanged(/* width= */ 0, /* height= */ 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void maybeNotifySurfaceSizeChanged(int width, int height) {
|
private void maybeNotifySurfaceSizeChanged(int width, int height) {
|
||||||
if (width != surfaceWidth || height != surfaceHeight) {
|
if (width != surfaceWidth || height != surfaceHeight) {
|
||||||
surfaceWidth = width;
|
surfaceWidth = width;
|
||||||
@ -1904,7 +1965,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
|
|
||||||
private void sendVolumeToRenderers() {
|
private void sendVolumeToRenderers() {
|
||||||
float scaledVolume = audioVolume * audioFocusManager.getVolumeMultiplier();
|
float scaledVolume = audioVolume * audioFocusManager.getVolumeMultiplier();
|
||||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, Renderer.MSG_SET_VOLUME, scaledVolume);
|
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_VOLUME, scaledVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("SuspiciousMethodCalls")
|
@SuppressWarnings("SuspiciousMethodCalls")
|
||||||
@ -2026,6 +2087,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
MetadataOutput,
|
MetadataOutput,
|
||||||
SurfaceHolder.Callback,
|
SurfaceHolder.Callback,
|
||||||
TextureView.SurfaceTextureListener,
|
TextureView.SurfaceTextureListener,
|
||||||
|
SphericalGLSurfaceView.VideoSurfaceListener,
|
||||||
AudioFocusManager.PlayerControl,
|
AudioFocusManager.PlayerControl,
|
||||||
AudioBecomingNoisyManager.EventListener,
|
AudioBecomingNoisyManager.EventListener,
|
||||||
StreamVolumeManager.Listener,
|
StreamVolumeManager.Listener,
|
||||||
@ -2232,6 +2294,18 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SphericalGLSurfaceView.VideoSurfaceListener
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoSurfaceCreated(Surface surface) {
|
||||||
|
setVideoOutputInternal(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoSurfaceDestroyed(Surface surface) {
|
||||||
|
setVideoOutputInternal(/* videoOutput= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
// AudioFocusManager.PlayerControl implementation
|
// AudioFocusManager.PlayerControl implementation
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -2315,4 +2389,84 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
updateWakeAndWifiLock();
|
updateWakeAndWifiLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Listeners that are called on the playback thread. */
|
||||||
|
private static final class FrameMetadataListener
|
||||||
|
implements VideoFrameMetadataListener, CameraMotionListener, PlayerMessage.Target {
|
||||||
|
|
||||||
|
public static final int MSG_SET_VIDEO_FRAME_METADATA_LISTENER =
|
||||||
|
Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER;
|
||||||
|
public static final int MSG_SET_CAMERA_MOTION_LISTENER =
|
||||||
|
Renderer.MSG_SET_CAMERA_MOTION_LISTENER;
|
||||||
|
public static final int MSG_SET_SPHERICAL_SURFACE_VIEW = Renderer.MSG_CUSTOM_BASE;
|
||||||
|
|
||||||
|
@Nullable private VideoFrameMetadataListener videoFrameMetadataListener;
|
||||||
|
@Nullable private CameraMotionListener cameraMotionListener;
|
||||||
|
@Nullable private VideoFrameMetadataListener internalVideoFrameMetadataListener;
|
||||||
|
@Nullable private CameraMotionListener internalCameraMotionListener;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(int messageType, @Nullable Object payload) {
|
||||||
|
switch (messageType) {
|
||||||
|
case MSG_SET_VIDEO_FRAME_METADATA_LISTENER:
|
||||||
|
videoFrameMetadataListener = (VideoFrameMetadataListener) payload;
|
||||||
|
break;
|
||||||
|
case MSG_SET_CAMERA_MOTION_LISTENER:
|
||||||
|
cameraMotionListener = (CameraMotionListener) payload;
|
||||||
|
break;
|
||||||
|
case MSG_SET_SPHERICAL_SURFACE_VIEW:
|
||||||
|
SphericalGLSurfaceView surfaceView = (SphericalGLSurfaceView) payload;
|
||||||
|
if (surfaceView == null) {
|
||||||
|
internalVideoFrameMetadataListener = null;
|
||||||
|
internalCameraMotionListener = null;
|
||||||
|
} else {
|
||||||
|
internalVideoFrameMetadataListener = surfaceView.getVideoFrameMetadataListener();
|
||||||
|
internalCameraMotionListener = surfaceView.getCameraMotionListener();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// VideoFrameMetadataListener
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoFrameAboutToBeRendered(
|
||||||
|
long presentationTimeUs,
|
||||||
|
long releaseTimeNs,
|
||||||
|
Format format,
|
||||||
|
@Nullable MediaFormat mediaFormat) {
|
||||||
|
if (internalVideoFrameMetadataListener != null) {
|
||||||
|
internalVideoFrameMetadataListener.onVideoFrameAboutToBeRendered(
|
||||||
|
presentationTimeUs, releaseTimeNs, format, mediaFormat);
|
||||||
|
}
|
||||||
|
if (videoFrameMetadataListener != null) {
|
||||||
|
videoFrameMetadataListener.onVideoFrameAboutToBeRendered(
|
||||||
|
presentationTimeUs, releaseTimeNs, format, mediaFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CameraMotionListener
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCameraMotion(long timeUs, float[] rotation) {
|
||||||
|
if (internalCameraMotionListener != null) {
|
||||||
|
internalCameraMotionListener.onCameraMotion(timeUs, rotation);
|
||||||
|
}
|
||||||
|
if (cameraMotionListener != null) {
|
||||||
|
cameraMotionListener.onCameraMotion(timeUs, rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCameraMotionReset() {
|
||||||
|
if (internalCameraMotionListener != null) {
|
||||||
|
internalCameraMotionListener.onCameraMotionReset();
|
||||||
|
}
|
||||||
|
if (cameraMotionListener != null) {
|
||||||
|
cameraMotionListener.onCameraMotionReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import android.opengl.Matrix;
|
import android.opengl.Matrix;
|
||||||
import com.google.android.exoplayer2.util.TimedValueQueue;
|
import com.google.android.exoplayer2.util.TimedValueQueue;
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
@ -13,15 +13,15 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ui.spherical.Projection.Mesh;
|
|
||||||
import com.google.android.exoplayer2.ui.spherical.Projection.SubMesh;
|
|
||||||
import com.google.android.exoplayer2.util.ParsableBitArray;
|
import com.google.android.exoplayer2.util.ParsableBitArray;
|
||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import com.google.android.exoplayer2.video.spherical.Projection.Mesh;
|
||||||
|
import com.google.android.exoplayer2.video.spherical.Projection.SubMesh;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.zip.Inflater;
|
import java.util.zip.Inflater;
|
||||||
|
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import static com.google.android.exoplayer2.util.GlUtil.checkGlError;
|
import static com.google.android.exoplayer2.util.GlUtil.checkGlError;
|
||||||
|
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import static com.google.android.exoplayer2.util.GlUtil.checkGlError;
|
import static com.google.android.exoplayer2.util.GlUtil.checkGlError;
|
||||||
|
|
||||||
@ -28,7 +28,6 @@ import com.google.android.exoplayer2.util.Assertions;
|
|||||||
import com.google.android.exoplayer2.util.GlUtil;
|
import com.google.android.exoplayer2.util.GlUtil;
|
||||||
import com.google.android.exoplayer2.util.TimedValueQueue;
|
import com.google.android.exoplayer2.util.TimedValueQueue;
|
||||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
@ -36,9 +36,10 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Player;
|
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
|
||||||
@ -54,6 +55,16 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
*/
|
*/
|
||||||
public final class SphericalGLSurfaceView extends GLSurfaceView {
|
public final class SphericalGLSurfaceView extends GLSurfaceView {
|
||||||
|
|
||||||
|
/** Listener for the {@link Surface} to which video frames should be rendered. */
|
||||||
|
public interface VideoSurfaceListener {
|
||||||
|
|
||||||
|
/** Called when the {@link Surface} to which video frames should be rendered is created. */
|
||||||
|
void onVideoSurfaceCreated(Surface surface);
|
||||||
|
|
||||||
|
/** Called when the {@link Surface} to which video frames should be rendered is destroyed. */
|
||||||
|
void onVideoSurfaceDestroyed(Surface surface);
|
||||||
|
}
|
||||||
|
|
||||||
// Arbitrary vertical field of view.
|
// Arbitrary vertical field of view.
|
||||||
private static final int FIELD_OF_VIEW_DEGREES = 90;
|
private static final int FIELD_OF_VIEW_DEGREES = 90;
|
||||||
private static final float Z_NEAR = 0.1f;
|
private static final float Z_NEAR = 0.1f;
|
||||||
@ -64,6 +75,7 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
|
|||||||
|
|
||||||
/* package */ static final float UPRIGHT_ROLL = (float) Math.PI;
|
/* package */ static final float UPRIGHT_ROLL = (float) Math.PI;
|
||||||
|
|
||||||
|
private final CopyOnWriteArrayList<VideoSurfaceListener> videoSurfaceListeners;
|
||||||
private final SensorManager sensorManager;
|
private final SensorManager sensorManager;
|
||||||
@Nullable private final Sensor orientationSensor;
|
@Nullable private final Sensor orientationSensor;
|
||||||
private final OrientationListener orientationListener;
|
private final OrientationListener orientationListener;
|
||||||
@ -72,7 +84,6 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
|
|||||||
private final SceneRenderer scene;
|
private final SceneRenderer scene;
|
||||||
@Nullable private SurfaceTexture surfaceTexture;
|
@Nullable private SurfaceTexture surfaceTexture;
|
||||||
@Nullable private Surface surface;
|
@Nullable private Surface surface;
|
||||||
@Nullable private Player player;
|
|
||||||
private boolean useSensorRotation;
|
private boolean useSensorRotation;
|
||||||
private boolean isStarted;
|
private boolean isStarted;
|
||||||
private boolean isOrientationListenerRegistered;
|
private boolean isOrientationListenerRegistered;
|
||||||
@ -83,6 +94,7 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
|
|||||||
|
|
||||||
public SphericalGLSurfaceView(Context context, @Nullable AttributeSet attributeSet) {
|
public SphericalGLSurfaceView(Context context, @Nullable AttributeSet attributeSet) {
|
||||||
super(context, attributeSet);
|
super(context, attributeSet);
|
||||||
|
videoSurfaceListeners = new CopyOnWriteArrayList<>();
|
||||||
mainHandler = new Handler(Looper.getMainLooper());
|
mainHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
// Configure sensors and touch.
|
// Configure sensors and touch.
|
||||||
@ -115,6 +127,43 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
|
|||||||
setOnTouchListener(touchTracker);
|
setOnTouchListener(touchTracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a {@link VideoSurfaceListener}.
|
||||||
|
*
|
||||||
|
* @param listener The listener to add.
|
||||||
|
*/
|
||||||
|
public void addVideoSurfaceListener(VideoSurfaceListener listener) {
|
||||||
|
videoSurfaceListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a {@link VideoSurfaceListener}.
|
||||||
|
*
|
||||||
|
* @param listener The listener to remove.
|
||||||
|
*/
|
||||||
|
public void removeVideoSurfaceListener(VideoSurfaceListener listener) {
|
||||||
|
videoSurfaceListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Surface} to which video frames should be rendered, or {@code null} if it has
|
||||||
|
* not been created.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Surface getVideoSurface() {
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the {@link VideoFrameMetadataListener} that should be registered during playback. */
|
||||||
|
public VideoFrameMetadataListener getVideoFrameMetadataListener() {
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the {@link CameraMotionListener} that should be registered during playback. */
|
||||||
|
public CameraMotionListener getCameraMotionListener() {
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the default stereo mode. If the played video doesn't contain a stereo mode the default one
|
* Sets the default stereo mode. If the played video doesn't contain a stereo mode the default one
|
||||||
* is used.
|
* is used.
|
||||||
@ -125,26 +174,6 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
|
|||||||
scene.setDefaultStereoMode(stereoMode);
|
scene.setDefaultStereoMode(stereoMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the {@link Player} to use. */
|
|
||||||
public void setPlayer(@Nullable Player newPlayer) {
|
|
||||||
if (newPlayer == player) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (player != null) {
|
|
||||||
if (surface != null) {
|
|
||||||
player.clearVideoSurface(surface);
|
|
||||||
}
|
|
||||||
player.clearVideoFrameMetadataListener(scene);
|
|
||||||
player.clearCameraMotionListener(scene);
|
|
||||||
}
|
|
||||||
player = newPlayer;
|
|
||||||
if (this.player != null) {
|
|
||||||
player.setVideoFrameMetadataListener(scene);
|
|
||||||
player.setCameraMotionListener(scene);
|
|
||||||
player.setVideoSurface(surface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets whether to use the orientation sensor for rotation (if available). */
|
/** Sets whether to use the orientation sensor for rotation (if available). */
|
||||||
public void setUseSensorRotation(boolean useSensorRotation) {
|
public void setUseSensorRotation(boolean useSensorRotation) {
|
||||||
this.useSensorRotation = useSensorRotation;
|
this.useSensorRotation = useSensorRotation;
|
||||||
@ -173,14 +202,15 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
|
|||||||
// Post to make sure we occur in order with any onSurfaceTextureAvailable calls.
|
// Post to make sure we occur in order with any onSurfaceTextureAvailable calls.
|
||||||
mainHandler.post(
|
mainHandler.post(
|
||||||
() -> {
|
() -> {
|
||||||
if (surface != null) {
|
@Nullable Surface oldSurface = surface;
|
||||||
if (player != null) {
|
if (oldSurface != null) {
|
||||||
player.clearVideoSurface(surface);
|
for (VideoSurfaceListener videoSurfaceListener : videoSurfaceListeners) {
|
||||||
|
videoSurfaceListener.onVideoSurfaceDestroyed(oldSurface);
|
||||||
}
|
}
|
||||||
releaseSurface(surfaceTexture, surface);
|
|
||||||
surfaceTexture = null;
|
|
||||||
surface = null;
|
|
||||||
}
|
}
|
||||||
|
releaseSurface(surfaceTexture, oldSurface);
|
||||||
|
surfaceTexture = null;
|
||||||
|
surface = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,15 +229,16 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Called on GL thread.
|
// Called on GL thread.
|
||||||
private void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture) {
|
private void onSurfaceTextureAvailable(SurfaceTexture newSurfaceTexture) {
|
||||||
mainHandler.post(
|
mainHandler.post(
|
||||||
() -> {
|
() -> {
|
||||||
SurfaceTexture oldSurfaceTexture = this.surfaceTexture;
|
@Nullable SurfaceTexture oldSurfaceTexture = surfaceTexture;
|
||||||
Surface oldSurface = this.surface;
|
@Nullable Surface oldSurface = surface;
|
||||||
this.surfaceTexture = surfaceTexture;
|
Surface newSurface = new Surface(newSurfaceTexture);
|
||||||
this.surface = new Surface(surfaceTexture);
|
surfaceTexture = newSurfaceTexture;
|
||||||
if (player != null) {
|
surface = newSurface;
|
||||||
player.setVideoSurface(surface);
|
for (VideoSurfaceListener videoSurfaceListener : videoSurfaceListeners) {
|
||||||
|
videoSurfaceListener.onVideoSurfaceCreated(newSurface);
|
||||||
}
|
}
|
||||||
releaseSurface(oldSurfaceTexture, oldSurface);
|
releaseSurface(oldSurfaceTexture, oldSurface);
|
||||||
});
|
});
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
@ -13,7 +13,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.video.spherical;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
@ -62,12 +62,12 @@ import com.google.android.exoplayer2.text.Cue;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
|
||||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
||||||
import com.google.android.exoplayer2.ui.spherical.SphericalGLSurfaceView;
|
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.ErrorMessageProvider;
|
import com.google.android.exoplayer2.util.ErrorMessageProvider;
|
||||||
import com.google.android.exoplayer2.util.RepeatModeUtil;
|
import com.google.android.exoplayer2.util.RepeatModeUtil;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoDecoderGLSurfaceView;
|
import com.google.android.exoplayer2.video.VideoDecoderGLSurfaceView;
|
||||||
|
import com.google.android.exoplayer2.video.spherical.SphericalGLSurfaceView;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@ -566,8 +566,6 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
|||||||
if (oldPlayer.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
if (oldPlayer.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
||||||
if (surfaceView instanceof TextureView) {
|
if (surfaceView instanceof TextureView) {
|
||||||
oldPlayer.clearVideoTextureView((TextureView) surfaceView);
|
oldPlayer.clearVideoTextureView((TextureView) surfaceView);
|
||||||
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
|
||||||
((SphericalGLSurfaceView) surfaceView).setPlayer(null);
|
|
||||||
} else if (surfaceView instanceof SurfaceView) {
|
} else if (surfaceView instanceof SurfaceView) {
|
||||||
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
|
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
|
||||||
}
|
}
|
||||||
@ -587,8 +585,6 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
|
|||||||
if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
||||||
if (surfaceView instanceof TextureView) {
|
if (surfaceView instanceof TextureView) {
|
||||||
player.setVideoTextureView((TextureView) surfaceView);
|
player.setVideoTextureView((TextureView) surfaceView);
|
||||||
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
|
||||||
((SphericalGLSurfaceView) surfaceView).setPlayer(player);
|
|
||||||
} else if (surfaceView instanceof SurfaceView) {
|
} else if (surfaceView instanceof SurfaceView) {
|
||||||
player.setVideoSurfaceView((SurfaceView) surfaceView);
|
player.setVideoSurfaceView((SurfaceView) surfaceView);
|
||||||
}
|
}
|
||||||
|
@ -63,12 +63,12 @@ import com.google.android.exoplayer2.text.Cue;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
|
||||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
||||||
import com.google.android.exoplayer2.ui.spherical.SphericalGLSurfaceView;
|
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.ErrorMessageProvider;
|
import com.google.android.exoplayer2.util.ErrorMessageProvider;
|
||||||
import com.google.android.exoplayer2.util.RepeatModeUtil;
|
import com.google.android.exoplayer2.util.RepeatModeUtil;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoDecoderGLSurfaceView;
|
import com.google.android.exoplayer2.video.VideoDecoderGLSurfaceView;
|
||||||
|
import com.google.android.exoplayer2.video.spherical.SphericalGLSurfaceView;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@ -570,11 +570,8 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
|
|||||||
}
|
}
|
||||||
@Nullable Player oldPlayer = this.player;
|
@Nullable Player oldPlayer = this.player;
|
||||||
if (oldPlayer != null) {
|
if (oldPlayer != null) {
|
||||||
oldPlayer.removeListener(componentListener);
|
|
||||||
if (surfaceView instanceof TextureView) {
|
if (surfaceView instanceof TextureView) {
|
||||||
oldPlayer.clearVideoTextureView((TextureView) surfaceView);
|
oldPlayer.clearVideoTextureView((TextureView) surfaceView);
|
||||||
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
|
||||||
((SphericalGLSurfaceView) surfaceView).setPlayer(null);
|
|
||||||
} else if (surfaceView instanceof SurfaceView) {
|
} else if (surfaceView instanceof SurfaceView) {
|
||||||
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
|
oldPlayer.clearVideoSurfaceView((SurfaceView) surfaceView);
|
||||||
}
|
}
|
||||||
@ -593,8 +590,6 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
|
|||||||
if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
if (player.isCommandAvailable(COMMAND_SET_VIDEO_SURFACE)) {
|
||||||
if (surfaceView instanceof TextureView) {
|
if (surfaceView instanceof TextureView) {
|
||||||
player.setVideoTextureView((TextureView) surfaceView);
|
player.setVideoTextureView((TextureView) surfaceView);
|
||||||
} else if (surfaceView instanceof SphericalGLSurfaceView) {
|
|
||||||
((SphericalGLSurfaceView) surfaceView).setPlayer(player);
|
|
||||||
} else if (surfaceView instanceof SurfaceView) {
|
} else if (surfaceView instanceof SurfaceView) {
|
||||||
player.setVideoSurfaceView((SurfaceView) surfaceView);
|
player.setVideoSurfaceView((SurfaceView) surfaceView);
|
||||||
}
|
}
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
|
||||||
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
|
|
||||||
/** Listens tap events on a {@link android.view.View}. */
|
|
||||||
public interface SingleTapListener {
|
|
||||||
/**
|
|
||||||
* Notified when a tap occurs with the up {@link MotionEvent} that triggered it.
|
|
||||||
*
|
|
||||||
* @param e The up motion event that completed the first tap.
|
|
||||||
* @return Whether the event is consumed.
|
|
||||||
*/
|
|
||||||
boolean onSingleTapUp(MotionEvent e);
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 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.
|
|
||||||
*/
|
|
||||||
@NonNullApi
|
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
|
||||||
|
|
||||||
import com.google.android.exoplayer2.util.NonNullApi;
|
|
@ -41,8 +41,6 @@ import com.google.android.exoplayer2.text.Cue;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||||
import com.google.android.exoplayer2.util.Clock;
|
import com.google.android.exoplayer2.util.Clock;
|
||||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -446,26 +444,6 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setVideoFrameMetadataListener(VideoFrameMetadataListener listener) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCameraMotionListener(CameraMotionListener listener) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearCameraMotionListener(CameraMotionListener listener) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearVideoSurface() {
|
public void clearVideoSurface() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user