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

MediaCodec.setOutputSurface #8329

Closed
Turalllb opened this issue Dec 8, 2020 · 14 comments
Closed

MediaCodec.setOutputSurface #8329

Turalllb opened this issue Dec 8, 2020 · 14 comments

Comments

@Turalllb
Copy link

Turalllb commented Dec 8, 2020

We already know about this problem and there are quite a few already closed issues. The problem is that some devices do not support DummySurface. And you need to be careful when working with the PlayerLayerView, if you set it visibility to GONE while the player is running, then we will get the below exception. If we pause the video, we need to wait for an unknown time (about 2 seconds on android TV devices) before we can block the visibility of GONE. All these problems can be solved, for example, we can use alpha instead of visibility to hide the display when we need it (There are cases when it is needed). But there is a case when I cannot solve the problem: The video is playing, the application is minimized, in onPause before calling super.onPause I execute exoPlayer.playWhenReady = false. But I will still get the following exception in the logs and when I deploy the application I will have a black screen on some devices. Why am I not listing what devices they are? Because there have already been many questions related to this exception, which you closed with crutches. Tell me how best to get out of the situation when you need to minimize the application on such a problematic device and not get a black screen when you deploy the application?

java.lang.IllegalArgumentException
at android.media.MediaCodec.native_setSurface(Native Method)
at android.media.MediaCodec.setOutputSurface(MediaCodec.java:1979)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.setOutputSurfaceV23(MediaCodecVideoRenderer.java:1308)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.setSurface(MediaCodecVideoRenderer.java:627)
at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.handleMessage(MediaCodecVideoRenderer.java:593)
at com.google.android.exoplayer2.ExoPlayerImplInternal.deliverMessage(ExoPlayerImplInternal.java:1022)
at com.google.android.exoplayer2.ExoPlayerImplInternal.sendMessageToTarget(ExoPlayerImplInternal.java:988)
at com.google.android.exoplayer2.ExoPlayerImplInternal.sendMessageInternal(ExoPlayerImplInternal.java:970)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:367)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:193)
at android.os.HandlerThread.run(HandlerThread.java:65)

The problem exists on exoplayer 11.7, I'm almost sure that in version 12, you did not fix it and it may not be fixed due to problems with MediaCodec

p.s. Conducted an experiment: Paused the video, waited 10 seconds, minimized the application. PlayerLayerView continues to exist, this is a TV and there are no screen rotations, but I get the same exception in the logs.

I researched a little the question, when the player is paused and I minimize the application, then this code is executed:

Снимок экрана 2020-12-08 в 15 06 46
Снимок экрана 2020-12-08 в 15 11 42

@Turalllb
Copy link
Author

Turalllb commented Dec 8, 2020

I will give a couple of examples where this bug was discussed and steps were given to reproduce the problem: #6930 #677 #2703

@Turalllb
Copy link
Author

Turalllb commented Dec 8, 2020

I tried to check how it works on YouTube. After I pause, minimize the application and re-deploy, they ignore my user pause and apparently re-do exoplayer.prepare (mediaSource)

@krocard
Copy link
Contributor

krocard commented Dec 9, 2020

This is a known bug of some implementations of some platform video codecs. ExoPlayer can not fix it, only workaround it by releasing the codec and then re-initializing it instead of setting the outputSurface:

if (Util.SDK_INT >= 23 && surface != null && !codecNeedsSetOutputSurfaceWorkaround) {
setOutputSurfaceV23(codec, surface);
} else {
releaseCodec();
maybeInitCodecOrBypass();
}

Unfortunately, we can only find out which problematic decoders to workaround through issues like yours.

You may try to enable the workaround by adding your problematic device here. If it solves your issue, please let us know so that we can add it the list for the next ExoPlayer version.

@Turalllb
Copy link
Author

@krocard Please clarify if I understood you correctly. In such situations, you check if the device is included in your list of problem devices and if it is found there, then mediaKodec is released, if it is not in the list, but the device has problems, I will get this exception

@krocard
Copy link
Contributor

krocard commented Dec 14, 2020

Exactly. We have a list devices known to not support setOutputSurface. For them we use the inefficient workaround of destroying and recreating the codec.

If a device has this setOutputSurface issue, but is not on the list, the workanourd will not be used and this IllegalArgumentException will be thrown.

If you could please answer the device you are observing the issue on, as well as it's android version, we will update this list and you should no longer see the issue.

@Turalllb
Copy link
Author

Turalllb commented Dec 16, 2020

@krocard the problem device Xiaomi Mi Box S, In the settings, the model is called MIBOX4

@krocard
Copy link
Contributor

krocard commented Dec 16, 2020

Do you also know the android version this issue is observed on?

@Turalllb
Copy link
Author

in 9 android

@Turalllb
Copy link
Author

You can give me a release branch and I will test it on this device

krocard added a commit to krocard/ExoPlayer that referenced this issue Dec 17, 2020
krocard added a commit to krocard/ExoPlayer that referenced this issue Dec 17, 2020
@krocard
Copy link
Contributor

krocard commented Dec 17, 2020

I have created a branch on my fork for you to test over 2.12.2: https://github.com/krocard/ExoPlayer/tree/mi-box-s-set-surface-workaround. The fix is krocard@e27732f.

I believe the DEVICE value is oneday. Looking at the official list of android devices, we can see that similar (dangal, magnolia...) Xiaomi devices are already workaround:

if (Util.SDK_INT <= 28) {
// Workaround for MiTV devices which have been observed broken up to API 28.
// https://github.com/google/ExoPlayer/issues/5169,
// https://github.com/google/ExoPlayer/issues/6899.
// https://github.com/google/ExoPlayer/issues/8014.
switch (Util.DEVICE) {
case "dangal":
case "dangalUHD":
case "dangalFHD":
case "magnolia":
case "machuca":
return true;
default:
break; // Do nothing.
}
}

oneday probably shares the same decoder, so it make sense to workaround it too.

I'm wondering if the MiBox 1,2,3 and mini also share the same bug.

[internal change cl/347975125]

@Turalllb
Copy link
Author

@krocard, Hi, sorry for taking too long.
Yes, I checked the Device value, it is oneday. Unfortunately, we do not have these MiBox 1,2,3 and mini devices.
I tested on MiBox s, it really stopped crashing.
Since my project uses version 2.11.7, and the transition to 2.12. + Due to changes in working with the drm is not very fast, I tested it on the 2.11.7 branch, adding your code. The screenshot shows the result. And it worked.

Tell me in which version we can expect this change. Thank you

@krocard
Copy link
Contributor

krocard commented Jan 6, 2021

The fix should be present in the next minor release 2.12.3.

@krocard krocard closed this as completed Jan 6, 2021
icbaker pushed a commit that referenced this issue Jan 8, 2021
Reported by #8329.

PiperOrigin-RevId: 350547523
icbaker pushed a commit that referenced this issue Jan 11, 2021
Reported by #8329.

PiperOrigin-RevId: 350547523
@wazerstar
Copy link

@krocard, Hi, sorry for taking too long.
Yes, I checked the Device value, it is oneday. Unfortunately, we do not have these MiBox 1,2,3 and mini devices.
I tested on MiBox s, it really stopped crashing.
Since my project uses version 2.11.7, and the transition to 2.12. + Due to changes in working with the drm is not very fast, I tested it on the 2.11.7 branch, adding your code. The screenshot shows the result. And it worked.

Tell me in which version we can expect this change. Thank you

@krocard, Hi, sorry for taking too long.
Yes, I checked the Device value, it is oneday. Unfortunately, we do not have these MiBox 1,2,3 and mini devices.
I tested on MiBox s, it really stopped crashing.
Since my project uses version 2.11.7, and the transition to 2.12. + Due to changes in working with the drm is not very fast, I tested it on the 2.11.7 branch, adding your code. The screenshot shows the result. And it worked.

Tell me in which version we can expect this change. Thank you

I have an Mibox 3, I can test with if needed you can also get control over it via remote if needed, not sure what I would be doing here to help out.

@krocard
Copy link
Contributor

krocard commented Feb 5, 2021

2.12.3 was released a few weeks ago. If the issue is still observed on it or a more recent version, please reopen the issue.

@google google locked and limited conversation to collaborators Mar 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants