I’m working on a new, relatively high profile service that over a thousand developers have expressed in using for their games and high-end graphics applications, but I’ve run into a problem on Tegra devices. I’m trying to get MediaCodec to decode an h264 stream on a Nexus 7/2012. My MediaCodec path works perfectly on the Nexus 7/2013 (which isn’t Tegra), but it fails on Nexus 7/2012.
I spent some time trying to figure out if some subtle stream formatting problem were the cause, but I tracked down the real problem to the options being fed to x264 (the h264 encoder we’re using). It seems that the MediaCodec path for Tegra is failing on some valid streams.
The server is encoding using (the equivalent of):
x264 --preset veryfast --tune zerolatency …
When trying to display an h264 stream created with those options, I either get solid grey or garbage, depending on the other flags I pass and the details of the stream itself.
I tracked it down to the specific option that causes it to fail (part of the zerolatency tuning): If I add --no-sliced-threads to the x264 command line, it renders fine on Tegra. If instead of --tune zerolatency I pass --slices 4, it also fails, though differently. Even a combination of --slices 4 and --no-sliced-threads fails, though in a different way (visually). So it seems that the Tegra-based hardware decode is failing when slices are used at all.
The server team is telling me that if we disable slices, that we’ll have latency problems, so it’s not an option to disable slices on the server (latency is a VERY important business goal).
The Nexus 7/2012 is up to date with the latest 4.4.2 release of Android (downloaded and updated yesterday; it was failing before and after the update).
Thoughts on how we could make this work? At the moment we’re looking at disabling hardware rendering on Tegra devices and using a software rendering path, which gives us ~20FPS on the Nexus 7.