[Android] VideoPlayer: Fix undefined behaviour when one activity is created before the previous is destroyed
Thomas Guillem
git at videolan.org
Tue Mar 17 18:06:27 CET 2015
vlc-ports/android | branch: master | Thomas Guillem <thomas at gllm.fr> | Tue Mar 17 17:38:23 2015 +0100| [b4f996f1ed45591d493e91ccca88ecb8c29e9294] | committer: Thomas Guillem
VideoPlayer: Fix undefined behaviour when one activity is created before the previous is destroyed
Do all VLC init and deinit in startPlayback/stopPlayback. That way, the onStart
of one activity can be called after the onStop of the previous activity.
> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=b4f996f1ed45591d493e91ccca88ecb8c29e9294
---
.../vlc/gui/video/VideoPlayerActivity.java | 86 +++++++++-----------
1 file changed, 40 insertions(+), 46 deletions(-)
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
index 8dc36ce..3bc67a1 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -459,9 +459,6 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
"Hardware acceleration mode: "
+ Integer.toString(mLibVLC.getHardwareAcceleration()));
- // Signal to LibVLC that the videoPlayerActivity was created, thus the
- // SurfaceView is now available for MediaCodec direct rendering.
- mLibVLC.eventVideoPlayerActivityCreated(true);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
@@ -515,16 +512,8 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
protected void onPause() {
super.onPause();
- if(mSwitchingView) {
- Log.d(TAG, "mLocation = \"" + mLocation + "\"");
- AudioServiceController.getInstance().showWithoutParse(savedIndexPosition);
- AudioServiceController.getInstance().unbindAudioService(this);
- return;
- }
-
stopPlayback();
- AudioServiceController.getInstance().unbindAudioService(this);
}
@Override
@@ -536,26 +525,6 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
- protected void onStart() {
- if (LibVlcUtil.isHoneycombOrLater()) {
- if (mOnLayoutChangeListener == null) {
- mOnLayoutChangeListener = new View.OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right,
- int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
- if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom)
- setSurfaceLayout(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight, mSarNum, mSarDen);
- }
- };
- }
- mSurfaceFrame.addOnLayoutChangeListener(mOnLayoutChangeListener);
- }
- setSurfaceLayout(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight, mSarNum, mSarDen);
- super.onStart();
- }
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
- @Override
protected void onStop() {
super.onStop();
@@ -566,8 +535,6 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
mPresentation = null;
}
restoreBrightness();
- if (LibVlcUtil.isHoneycombOrLater() && mOnLayoutChangeListener != null)
- mSurfaceFrame.removeOnLayoutChangeListener(mOnLayoutChangeListener);
}
@TargetApi(android.os.Build.VERSION_CODES.FROYO)
@@ -588,12 +555,6 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
super.onDestroy();
unregisterReceiver(mReceiver);
- // MediaCodec opaque direct rendering should not be used anymore since there is no surface to attach.
- mLibVLC.eventVideoPlayerActivityCreated(false);
- // HW acceleration was temporarily disabled because of an error, restore the previous value.
- if (mDisabledHardwareAcceleration)
- mLibVLC.setHardwareAcceleration(mPreviousHardwareAccelerationMode);
-
mAudioManager = null;
}
@@ -638,6 +599,22 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
if (mPlaybackStarted)
return;
mPlaybackStarted = true;
+
+ if (LibVlcUtil.isHoneycombOrLater()) {
+ if (mOnLayoutChangeListener == null) {
+ mOnLayoutChangeListener = new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right,
+ int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom)
+ setSurfaceLayout(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight, mSarNum, mSarDen);
+ }
+ };
+ }
+ mSurfaceFrame.addOnLayoutChangeListener(mOnLayoutChangeListener);
+ }
+ setSurfaceLayout(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight, mSarNum, mSarDen);
+
/*
* If the activity has been paused by pressing the power button, then
* pressing it again will show the lock screen.
@@ -659,6 +636,10 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
final EventHandler em = EventHandler.getInstance();
em.addHandler(mEventHandler);
+ // Signal to LibVLC that the videoPlayerActivity was created, thus the
+ // SurfaceView is now available for MediaCodec direct rendering.
+ mLibVLC.eventVideoPlayerActivityCreated(true);
+
loadMedia();
// Add any selected subtitle file from the file picker
@@ -674,7 +655,16 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
private void stopPlayback() {
if (!mPlaybackStarted)
return;
+
mPlaybackStarted = false;
+
+ if(mSwitchingView) {
+ Log.d(TAG, "mLocation = \"" + mLocation + "\"");
+ AudioServiceController.getInstance().showWithoutParse(savedIndexPosition);
+ unbindAudioService();
+ return;
+ }
+
final EventHandler em = EventHandler.getInstance();
em.removeHandler(mEventHandler);
mEventHandler.removeCallbacksAndMessages(null);
@@ -699,13 +689,6 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
else
time -= 5000; // go back 5 seconds, to compensate loading time
- /*
- * Pausing here generates errors because the vout is constantly
- * trying to refresh itself every 80ms while the surface is not
- * accessible anymore.
- * To workaround that, we keep the last known position in the playlist
- * in savedIndexPosition to be able to restore it during onResume().
- */
mLibVLC.stop();
SharedPreferences.Editor editor = mSettings.edit();
@@ -741,6 +724,17 @@ public class VideoPlayerActivity extends ActionBarActivity implements IVideoPlay
editor.putString(PreferencesActivity.VIDEO_LAST, Uri.encode(mLocation));
Util.commitPreferences(editor);
+
+ // MediaCodec opaque direct rendering should not be used anymore since there is no surface to attach.
+ mLibVLC.eventVideoPlayerActivityCreated(false);
+ // HW acceleration was temporarily disabled because of an error, restore the previous value.
+ if (mDisabledHardwareAcceleration)
+ mLibVLC.setHardwareAcceleration(mPreviousHardwareAccelerationMode);
+
+ if (LibVlcUtil.isHoneycombOrLater() && mOnLayoutChangeListener != null)
+ mSurfaceFrame.removeOnLayoutChangeListener(mOnLayoutChangeListener);
+
+ unbindAudioService();
}
@Override
More information about the Android
mailing list