Crashing competing media players on Android
felix.abecassis.me
felix.abecassis.me
In addition to the point of the article (asserting on a file that is not processed correctly, instead of slowly bailing out), every piece of CPU/GPU behave differently and the Android test suite is extremely limited. On top of that, there are many layers (OMX IL, stagefright, MediaCodec, OMX AL, Java Media) that interact together in a complex way and everyone messes in those layers in a different way...
For example, fora long time, even after mediacodec API was out (4.1), you could get the data back from the codec, but the frame format was not standardized and there were no tests in the Android validation! So every GPU was doing something differently.
On top of that, the hw decoders don't even give the profile and level they support, so you have to guess them.
And even those days, there is no way to get a YUV 420 surface that works on most devices, even when using KitKat APIs.
And so many joyful things :)
Google's Stagefright developers told me they did not want to provide an API to query the hardware decoder's profile and level support because some hardware supports H.264 capabilities beyond their state profile or level. Their recommendation was to "just try decoding the video" to see if it works (as if that is something that can be easily determined programmatically), ignoring the fact that playing an unsupported or corrupt file will trigger Stagefright's fatal CHECK() aborts. In Flash, we had to duplicate a lot of Stagefright's MP4 parsing code so Flash could fall back to its H.264 software decoder instead of hitting Stagefright's CHECK() "landmines".
We also had to write almost 10 different color conversion functions for all the random color formats used by long-tail Android devices.
> We also had to write almost 10 different color conversion functions for all the random color formats used by long-tail Android devices. We have those too. Are some of yours shareable?
But Mozilla has some Android color conversion functions, including some quirk workarounds for specific devices, for Firefox on Android and Firefox OS:
https://hg.mozilla.org/mozilla-central/file/582b2d81ebe1/med...
Google also provides libyuv, which is also used in Firefox:
We actually put together a codec tester that runs right before the first time a user plays a video precisely because of this. It throws a few frames of every profile/level we plan to support at each decoder component on the device to figure out which profiles we can use and which component to use to decode them. :(
Failing to parse a file should not abort a process. Multimedia is about parsing broken files!
So instead, decoding is done in hardware using finicky SoCs that don't always make it possible to fully meet the OpenMAX IL spec. In fact most device makers hack up OMXCodec and other classes in libstagefright to get the higher level Android media APIs to work.
All this code is littered with CHECK()s probably because Google can't do any better due to hardware being too fragmented (what you would do to recover from a hosed decoder might work on one phone, but not another). And device makers don't because either 1) once they hack up their ROM to get the YouTube app working, they just ship the device, or 2) implementing a way to recover would require a hardware change and ain't nobody got time fo dat.
This is incorrect. Application access to hardware de/encoders isn't a matter of permissions. You can't get at them directly because the api isn't in the SDK/NDK. However, if you're willing to pull in headers from AOSP, and fool around with dlopen/dlsym you can develop and build against libstagefright.