-
Notifications
You must be signed in to change notification settings - Fork 6k
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 initialisation fails. #3835
Comments
Was able to reproduce your problem on a Moto C+. It seems the device has problems switching output surfaces and needs a workaround. This is similar to issues with other devices we had in the past (e.g. #3355, #3439). Can you provide us with the Build.DEVICE names of Meizu M5C and Lenovo K4 to add them to our workaround? |
As i see you already support something related to OMX.MTK codec in your workaround. Or you talking about some other workaround? |
Yes, the existing workaround checks decoder name and device name to be as restrictive as possible (see here). That's why I need the device names of the devices where it doesn't work to add to this list. |
Here is the device names(same as appear in your Util.DEVICE) Anyway, I tried to change the codecNeedsSetOutputSurfaceWorkaround(String name), so that Meizu M5c will be included in the list of workaround needed devices. The result was the same as in reported bug. Even if I force codecNeedsSetOutputSurfaceWorkaround always return true, it is still crashing. Do you manage to reslove issue on Moto C++ by adding it to the workaround list? Is there something more that I need to do in order to apply this workaround on Meizu? |
Yes, I added Were you able to test if it works for the Lenovo K4? |
First of all, that is good news, because one of the devices our customer reported on, was Moto C+. So I will check it with them. |
Not if it's exactly the same issue. Unfortunately, I don't have access to neither Meizu M5c nor Lenovo K4, so it's difficult to check what may cause it. Are the reproduction steps and the error message above the same for all three devices? Or is there something else? |
Yes, the flow is the same.
|
maybeInitCodec() always happened only after setSurface(Surface surface) was called two times |
Can you provide more details on why setSurface is called two times? It's usually only called once when you attach the UI. |
setSurface was called twice because we used old exoplayer api where you was supposed to call player.setSurfaceView(null) before you apply new surface (in order to clean the previous one. Now you are doing it with player.clearVideoSurfaceView() so the surface can be removed by SurfaceHolder) I updated our api to be aligned with yours. Now setSurface() called only once. But the issue still there. |
Another thing that I see is that with But I think it is too late, because almost immediately called |
With the workaround in place, When exactly do you attach the UI? I added a listener to |
So in order to be maximum aligned with you I have moved to work on your demo application.
and added this view instead:
This should simulate my parent view to which I attach player view. In PlayerActivity In
Also I added Meizu device name in MediaCodecVideoRenederer. Workaround method now looks like that:
From what I see from debugging the code flow looks like that:
You say that dummySurface should never be created in a proper workaround mode. But in my case it happens to work in exact that way. Also the |
It will be grate, if you add Meizu and Lenovo K4 devices to the list of excluded devices and push it on some side branch, that I can check if this fix apply for them. I am quite sure, that there is something that I am missing. Here is the device names(same as appear in your Util.DEVICE) |
Thanks a lot for this detailed analysis! Not many people make this effort to help us debug a problem :) It turns out that there is a difference I didn't know about (thanks to @ojw28 for pointing this out). The original fix for other devices (#3439) included some further changes to prevent the DummySurface from being instantiated. Please have a look at this commit to see the details. I guess it will work when you add this change to your code (especially that I'll add the Meizu M5C and the Lenovo K4 to our list. |
Thanks for your solution. I made the changes you suggest and it seems to work both on Meizu M5c and Lenovo K4 Note. Thank you very much for your support. |
Yes, there is also panell_d, panell_dl and panell_dp. Guess I better change it to include all devices starting with "panell" then. We also discussed the same question - whether we should enable the workaround for certain API levels and decoders for all devices or something similar. Because we also don't know for sure how many devices out there have this problem. Using the chipset may be a good idea, need to think about this a little bit further. For our release plans, there is probably a new release in the next couple of days. |
Thanks again. |
This problem often results in the application not responding on these devices instead of an exception. Especially when switching between two real surfaces. That means we can't just always try first and enable the workaround as soon as it fails. If you want to catch the exception and then set a flag in your app, you can still do so by overriding |
Issue:#3835 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=185501181
Also added comments for all existing devices for easier reference. Issue:#3835 Issue:#3236 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=185661900
Issue:#3835 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=185501181
Also added comments for all existing devices for easier reference. Issue:#3835 Issue:#3236 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=185661900
Hi @tonihei and @ojw28, thank you for fixing this issue.
But there are many other phones with the same chipset -- we just chose one that was easy to get. So either it was just a lucky guess, or all those other phones (which are not explicitly named by ExoPlayer) will also fail. Just my 2 cents. |
We agree that the current approach isn't doing a good job of targeting all affected devices. Although on the plus side, it's likely that we're targeting the popular ones; there are probably quite a lot of devices that barely anyone is using. An approach that targets the chipset would be preferable, but I'm not sure how to do that. I don't think there's anything suitable in Build. Do you have any idea how we'd be able to target the workaround to a specific chipset? |
Hi @ojw28, From what I found, the best (read: least bad) source of the chipset id is I don't know why the extra "m"; probably a variant. I'd read it into a static final field and query when required (maybe even create a "workaround-map"). At the end of the day, it's a matter of choosing between two hacks, so pick your poison. Using the chipset is more robust IMHO because I'm pretty sure that all devices with the same chipset have the same MediaCodec issues (also think about the adaptation workaround (#3257), which is required on some Exynos devices but not on MediaTek). Being a Googler, can you reach out to the Android people and ask them to add the chipset id to As for device popularity - we have a large customer in India; even unpopular, cheap, devices can have a few tens of thousands of users. |
Hello team. As was previously discussed on this thread, we made some sort of workaround test, that checks and gather potentially codec problematic devices. Those in order to report you and make exoplayer better. The problem we face now, is that amount of "problematic" devices that was collected by this test is huge. So I believe, that our test covers to much use-cases and probably we should somehow narrow/filter
Will appriciate your response on the subject |
I tried using your test code and the assets (mp4+mp4+init data) and also get |
No, we label device as needed workaround only when we get |
I used a Nexus 6P and got a DecoderInitializationException as well. I fear that the workaround test doesn't cover the real thing because it does never switches (or sets) surfaces and probably fails for other reasons. |
What was the cause fot this |
After looking into this in more detail, I think setting the surface shouldn't be necessary because the DummySurface is still created (as you don't set a surface at all). It just wouldn't catch devices which only have problems with switching surfaces but that's probably fine for the first try. However, it seems the test content is too small. The reason is fails for me is "Unsupported WxH = (32)x(32) supported range is min(64)x(64) - max(4096)x(4096)". When you look at the failing stack traces, you'll notice that it fails in |
Unfortunately we have no device that is run in to this size issue. Is it possible to ask you test this content, and tell if it`s good enough? |
Your new sample works for me (i.e. it reports as not needing the workaround), but only if I replace the |
@tonihei the problem is that at the time the test runs, we don't have a license URL that will respond correctly. Are you saying that when you set this proxy URL the response it provides (which is obviously not a valid license response) is good enough? What if I'll be offline at the time of testing? In other words -- the test works for you on a device that really shouldn't be problematic (shouldn't be listed in the workaround list). But I suspect it will also skip the real culprits (such as Meizu 5c). |
The To get a valid Widevine license (which allows to setup the secure surface), you either need the online license request or you manage to obtain an offline license which never expires. Unfortunately, I don't have one of the failing devices available at the moment. So I can't confirm whether the test with the real drm callback actually fails. Final remark: You should probably also release the test player for all other errors which are not a DecoderInitializationException to prevent resource leaking. |
|
The problem is that the player never reaches the READY state in such a setup. Instead, after 10 seconds waiting, it gets the wrong key request answers and fails with a DrmSessionException. If I understand you correctly, that's what you wanted. Waiting for the READY state is then probably not the right way to "pass" the test. When you say the number of problematic devices is huge - how do you determine that a device is problematic? Do you count the number of positive and negative examples of this workaround test? If so, you should be able to filter by flaky decoder initialization problems for other reasons. This problem should be reproducible 100% of the time, so there shouldn't be a single passing device of the problematic ones. |
Hi @tonihei, if (error.getCause() instanceof MediaCodecRenderer.DecoderInitializationException) {
workaroundRequired = true;
} Putting it all together, I suspect that the only reason for the huge amount of false positives is the video size. Am I right? BTW, in the released version we did move the |
Yes, that seems fine. I think I got quite confused that your example code set And yes I agree, that to some extent the failures were due to the video size. Please note that there will be other DecoderInitialization failures for various reasons and you'll still need to check that the test fails for all devices of the same model. |
We have another report of a device that should be added to the DummySurface workaround -- the new Huawei Y3 (2018), an Android Go device: https://www.gsmarena.com/huawei_y3_(2018)-9196.php. |
Thanks for reporting! That really is a never-ending-story ;( |
The Build.MODEL is listed as "gobo", but I don't think it's a real value. The tested device was not yet released at the time (TAGS=dev-keys), so all the values look strange:
The device was released since, but I don't have anyone that can check on a production device. The chipset is MT6737M -- the same as some other devices listed above. |
@tonihei / others -- does Google have a database of all the certified Android devices, that contain everything from android.os.Build? |
Yes, that's officially available here: https://support.google.com/googleplay/answer/1727131?hl=en-GB That's where my suggestion above came from. |
Thanks @tonihei, I didn't know about this list. Regarding the device, they both use the same chipset, and the issue is there. |
Do you also have the culprit decoder name? Forgot to ask about it. |
No, sorry. I don't have the device itself with me. |
Let's dupe this onto #4468, which is newer, but provides a more comprehensive list of (possibly) affected devices. We can use that for tracking. I think we'll also go ahead and make |
Issue description
On certain devices that use OMX.MTK.VIDEO.DECODER.AVC decoder, on DRM content ONLY we receive the below error.
Reproduction steps
only doing so, after player state READY received.
Link to test content
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd"
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
Version of ExoPlayer being used
We can see this issue reproduced on Exoplayer 2.5.0 and above (including 2.6.1)
Previous Exoplayer versions work as expected.
Device(s) and version(s) of Android being used
Device - Meizu M5C, Lenovo K4 and Moto C+ (all of them with OMX.MTK.VIDEO.DECODER.AVC)
Android version - 6.0
### A full bug report captured from the device
The text was updated successfully, but these errors were encountered: