Skip to content

Commit

Permalink
Fix video player crash
Browse files Browse the repository at this point in the history
Sometimes the video player will crash if you rotate the device
while a video is playing, because we aren't waiting for video
playback to stop before returning from onPause().  This causes the
TextureView to get torn down, which makes the MediaCodec unhappy
the next time it tries to decode a frame.

Now we wait for the playback thread to stop.
  • Loading branch information
fadden committed May 22, 2014
1 parent 6e000f4 commit 8a2b595
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 6 deletions.
2 changes: 1 addition & 1 deletion AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.grafika"
android:versionCode="32"
android:versionCode="33"
android:versionName="1.0" >

<uses-sdk
Expand Down
26 changes: 26 additions & 0 deletions src/com/android/grafika/MoviePlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,9 @@ public static class PlayTask implements Runnable {
private Thread mThread;
private LocalHandler mLocalHandler;

private final Object mStopLock = new Object();
private boolean mStopped = false;

/**
* Prepares new PlayTask.
*
Expand Down Expand Up @@ -460,13 +463,36 @@ public void requestStop() {
mPlayer.requestStop();
}

/**
* Wait for the player to stop.
* <p>
* Called from any thread other than the PlayTask thread.
*/
public void waitForStop() {
synchronized (mStopLock) {
while (!mStopped) {
try {
mStopLock.wait();
} catch (InterruptedException ie) {
// discard
}
}
}
}

@Override
public void run() {
try {
mPlayer.play();
} catch (IOException ioe) {
throw new RuntimeException(ioe);
} finally {
// tell anybody waiting on us that we're done
synchronized (mStopLock) {
mStopped = true;
mStopLock.notifyAll();
}

// Send message through Handler so it runs on the right thread.
mLocalHandler.sendMessage(
mLocalHandler.obtainMessage(MSG_PLAY_STOPPED, mFeedback));
Expand Down
13 changes: 10 additions & 3 deletions src/com/android/grafika/PlayMovieActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class PlayMovieActivity extends Activity implements OnItemSelectedListene
private MoviePlayer.PlayTask mPlayTask;
private boolean mSurfaceTextureReady = false;

private final Object mStopper = new Object(); // used to signal stop

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -93,7 +95,13 @@ protected void onPause() {
// We're not keeping track of the state in static fields, so we need to shut the
// playback down. Ideally we'd preserve the state so that the player would continue
// after a device rotation.
stopPlayback();
//
// We want to be sure that the player won't continue to send frames after we pause,
// because we're tearing the view down. So we wait for it to stop here.
if (mPlayTask != null) {
stopPlayback();
mPlayTask.waitForStop();
}
}

@Override
Expand Down Expand Up @@ -184,12 +192,11 @@ public void clickPlayStop(@SuppressWarnings("unused") View unused) {
}

/**
* Requests stoppage if a movie is currently playing.
* Requests stoppage if a movie is currently playing. Does not wait for it to stop.
*/
private void stopPlayback() {
if (mPlayTask != null) {
mPlayTask.requestStop();
mPlayTask = null;
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/com/android/grafika/PlayMovieSurfaceActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ protected void onPause() {
// We're not keeping track of the state in static fields, so we need to shut the
// playback down. Ideally we'd preserve the state so that the player would continue
// after a device rotation.
stopPlayback();
//
// We want to be sure that the player won't continue to send frames after we pause,
// because we're tearing the view down. So we wait for it to stop here.
if (mPlayTask != null) {
stopPlayback();
mPlayTask.waitForStop();
}
}

@Override
Expand Down Expand Up @@ -210,7 +216,6 @@ public void clickPlayStop(@SuppressWarnings("unused") View unused) {
private void stopPlayback() {
if (mPlayTask != null) {
mPlayTask.requestStop();
mPlayTask = null;
}
}

Expand Down

0 comments on commit 8a2b595

Please sign in to comment.