protyposis/MediaPlayer-Extended

IllegalStateException sometimes happens when playing Dash streams

oseparovic opened this issue · 5 comments

I haven't been able to reproduce this yet but I wanted to let you know there's an uncommon crash floating around in there. From the Play Store console the stacktrace looks like this:

java.lang.IllegalStateException: 
  at net.protyposis.android.mediaplayer.MediaPlayer.prepareAsync (MediaPlayer.java:466)
  at net.protyposis.android.mediaplayer.VideoView$2.run (VideoView.java:210)
  at java.lang.Thread.run (Thread.java:818)

Affected devices so far:

  • Samsung Galaxy J5(2016) (j5xnlte), 2048MB RAM, Android 6.0
  • Google Pixel (sailfish), 4096MB RAM, Android 7.1
  • Samsung Galaxy S8+ (dream2lte), 4096MB RAM, Android 7.0

Currently used lib version are:

compile 'net.protyposis.android.mediaplayer:mediaplayer:4.3.1-rc1'
compile 'net.protyposis.android.mediaplayer:mediaplayer-dash:4.3.0'

From the source it looks like this is what's triggering the exception:

public void prepare() throws IOException, IllegalStateException {
    if(mCurrentState != State.INITIALIZED && mCurrentState != State.STOPPED) {
        throw new IllegalStateException();
    }

Any suggestions how to reproduce this?

Thanks for reporting! Looks like this tends to happen on faster manycore devices. I have no idea how to reproduce this yet, but I think the problem lies within the VideoView. My feeling says it's a race condition / synchronization issue, probably in openVideo() when openVideo() and release() are overlapping.

Do you use the MediaPlayer directly through getMediaPlayer(), or call setVideoSource from an non-UI thread?

I'm using mVideoView.setVideoSource(mediaSource);

I'm using retrofit to load the MPD and an AsyncTask to load the media source. I'm not using RX java so the callback is on the main thread. I also verified through the debugger and setVideoSource() happens on main thread.

clipboard01

The only other setVideoSource is

    if (mVideoView.isPlaying()) {
        mVideoView.stopPlayback();
        mVideoView.setVideoSource(null);
    }

which happens right before super.onPause(); in my onPause() @OverRide.

I could not reproduce this, but the issue is probably fixed in 4.3.2.

Btw, calling

if (mVideoView.isPlaying()) {
    mVideoView.stopPlayback();
    mVideoView.setVideoSource(null);
}

in onPause should be unnecessary and redundant because the MediaPlayer is stopped and released anyway by the VideoView when the activity is left. Is there any specific reason why you're calling this?

I think I added it when trying to debug that weird dash freezing crash you fixed in the last patch. I was testing to see if it had something to do with incomplete teardown when leaving the activity but I never ended up removing it after you fixed the issue.

I'll remove it in my next build, thanks for the heads up.

Also I'm closing this issue until I see proof that it still exists in 4.3.2