Search code examples
androidencodingsamsung-mobileandroid-mediacodec

Android MediaCodec.createEncoderByType - Multiple encoders available, which one should/will be used?


My question is similar to this one Mime type video/avc supported by multiple encoders on my Android device but not quite the same.

In all Samsung devices I have, I see that there're multiple encoders available for MIME type "audio/mp4a-latm":

OMX.google.aac.encoder
OMX.SEC.aac.enc (Android < 5)
OMX.SEC.naac.enc (Android >= 5)

MediaCodec.createEncoderByType would return the optimized one, I would think. But on all the Samsung devices I have, this method always create the Google encoder. Problem is when I compare the time spent to create the two encoders, creating a google encoder is much slower than creating the samsung encoder.

Then WHY would MediaCodec.createEncoderByType return the slower encoder? Should I still be using the google encoder if that is much slower? (Takes like a few hundred ms). Or should I iterate all available encoders and choose the samsung one instead?

Thanks!


Solution

  • In practice, the method MediaCodec.createEncoderByType (and MediaCodec.createDecoderByType) only returns the first matching codec, in the order they are listed. A vendor can either make sure to order the list (it's in practice in /etc/media_codecs.xml on the device) to list the preferred ones first, or override the implementation of the methods to use a different logic than just picking the first matching.

    In this case, it seems like Samsung haven't thought about this, or their own hardware AAC encoder is less featureful than the google SW encoder, like supporting fewer profiles/options.

    I guess they have made sure that at least the HW codecs for video are listed first, since the difference in speed there is much more significant.

    If you are concerned with speed, you can indeed try to pick the Samsung one instead. Or conversely, instead of explicitly looking for the Samsung ones, you can be pretty sure that any codec starting with OMX.google. is a SW codec. So first you can look for the first matching one that doesn't start with OMX.google.. If no such encoder is found, you can iterate another round, picking the first matching one (or use MediaCodec.createEncoderByType).