Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IllegalStateException when drainToEndOfStream when in tunneling mode #10847

Closed
1 task done
tomjhall opened this issue Dec 7, 2022 · 7 comments
Closed
1 task done

IllegalStateException when drainToEndOfStream when in tunneling mode #10847

tomjhall opened this issue Dec 7, 2022 · 7 comments
Assignees
Labels

Comments

@tomjhall
Copy link

tomjhall commented Dec 7, 2022

ExoPlayer Version

2.18.2

Devices that reproduce the issue

Model: TalkTalk STB
Os: Android
Version: 10

Devices that do not reproduce the issue

Fire TV Stick (2nd Gen) running Fire OS 5.2.9.2 (Tunneling was not enabled for this media, tried other media with tunneling enabled but the issue was not present)

Reproducible in the demo app?

Yes

Reproduction steps

Turn on tunneling ie in PlayerActivity:

      trackSelectionParameters =
          new DefaultTrackSelector.ParametersBuilder(/* context= */ this)
              .setTunnelingEnabled(true)
              .build();

As our media is over http you will need to allow clear text, so in an xml file in res/xml:

<network-security-config>
  <base-config cleartextTrafficPermitted="true"/>
</network-security-config>

And in the android manifest of the demo app tag:

    android:networkSecurityConfig="@xml/network_config"

Play the video to the end, where the crash should occur.

Expected result

The audio sink should be released successfully

Actual result

The following exception is thown:

playerFailed [eventTime=33.10, mediaPos=29.47, window=0, period=0, errorCode=ERROR_CODE_FAILED_RUNTIME_CHECK
  com.google.android.exoplayer2.ExoPlaybackException: Unexpected runtime error
      at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:621)
      at android.os.Handler.dispatchMessage(Handler.java:103)
      at android.os.Looper.loop(Looper.java:214)
      at android.os.HandlerThread.run(HandlerThread.java:67)
  Caused by: java.lang.IllegalStateException
      at com.google.android.exoplayer2.util.Assertions.checkState(Assertions.java:84)
      at com.google.android.exoplayer2.audio.DefaultAudioSink.writeBuffer(DefaultAudioSink.java:1159)
      at com.google.android.exoplayer2.audio.DefaultAudioSink.processBuffers(DefaultAudioSink.java:1099)
      at com.google.android.exoplayer2.audio.DefaultAudioSink.drainToEndOfStream(DefaultAudioSink.java:1259)
      at com.google.android.exoplayer2.audio.DefaultAudioSink.handleBuffer(DefaultAudioSink.java:893)
      at com.google.android.exoplayer2.audio.MediaCodecAudioRenderer.processOutputBuffer(MediaCodecAudioRenderer.java:706)
      at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.drainOutputBuffer(MediaCodecRenderer.java:1905)
      at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:792)
      at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:994)
      at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:495)
      at android.os.Handler.dispatchMessage(Handler.java:103) 
      at android.os.Looper.loop(Looper.java:214) 
      at android.os.HandlerThread.run(HandlerThread.java:67) 
]

Media

Media Url is sent via email

Bug Report

  • You will email the zip file produced by adb bugreport to [email protected] after filing this issue.
@tonihei
Copy link
Collaborator

tonihei commented Dec 8, 2022

Do you have any custom AudioProcessors in your app? I can reproduce the error by adding a custom processor, but can't see a way to trigger the problem with the default processors only.

@tomjhall
Copy link
Author

tomjhall commented Dec 14, 2022

No this should be reproducible in the ExoPlayer reference application - we have not added a custom AudioProcessor to the reference app. I have created a patch file (sending to you via email) for the Exoplayer reference app so that you can better see the changes/apply it

@tonihei
Copy link
Collaborator

tonihei commented Dec 21, 2022

I just checked the emails, but can't see anything related to this issue. Could you make sure to use "Issue #10847" in the subject line? Otherwise the email may get lost in some filters.

@tomjhall
Copy link
Author

I've resent the email

@tonihei
Copy link
Collaborator

tonihei commented Jan 9, 2023

Thanks! It again wasn't forwarded by our filters, but I was able to dig it out regardless. (Need to investigate what's going on there, but yours seem to be the only "correct" email that wasn't forwarded to us).

@tonihei
Copy link
Collaborator

tonihei commented Jan 9, 2023

It looks like your stream may cause this issue because it requires gapless trimming. This enables an AudioProcessor for the trimming (see my question above) and in some situations this may then run into this assertion. Will provide a fix for this!

christosts pushed a commit that referenced this issue Jan 11, 2023
When audio processors are enabled during tunneling, they must produce
output immediately, ensuring that the timestamps of the output samples
correspond to the input and that no additional samples are produced.
This requirement is documented in the Javadoc of DefaultAudioSink.

However, this alone doesn't guarantee all buffers are immediately
written to the AudioTrack, because the AudioTrack writes are
non-blocking and may need multiple attempts.

When draining the audio sink at the end of the stream, we currently
fail in this situation because we assert that the timestamp must be
set (=the drain operation is a no-op). But this may not be true when
the previous non-blocking write wasn't fully handled. We can fix this
by saving the last timestamp and reusing it during draining.

Issue: #10847
PiperOrigin-RevId: 500943891
stoyicker pushed a commit to stoyicker/media that referenced this issue Jan 11, 2023
When audio processors are enabled during tunneling, they must produce
output immediately, ensuring that the timestamps of the output samples
correspond to the input and that no additional samples are produced.
This requirement is documented in the Javadoc of DefaultAudioSink.

However, this alone doesn't guarantee all buffers are immediately
written to the AudioTrack, because the AudioTrack writes are
non-blocking and may need multiple attempts.

When draining the audio sink at the end of the stream, we currently
fail in this situation because we assert that the timestamp must be
set (=the drain operation is a no-op). But this may not be true when
the previous non-blocking write wasn't fully handled. We can fix this
by saving the last timestamp and reusing it during draining.

Issue: google/ExoPlayer#10847
PiperOrigin-RevId: 500943891
@tonihei
Copy link
Collaborator

tonihei commented Jan 26, 2023

The problem is likely fixed by the commit above.

@tonihei tonihei closed this as completed Jan 26, 2023
@google google locked and limited conversation to collaborators Mar 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants