Thursday, June 28, 2012

Raw AAC Player for Android 2

Unbelievable !!!

Something pushed to me to open blogger today and write a comment about the big improvement (in my opinion) of the aacdecoder-android, which I finished also today.

Now looking at my old post Raw AAC Player for Android and see that today it is exactly 2 years since I wrote my first post about the AAC streaming problems!

HE-AAC+ Mono / Stereo

Today I released version 0.6.1 of the aacdecoder-android.

Why is it a minor change (0.6 to 0.6.1) ?
Because it does not affect the Java interface to the library - everybody can use it in his/her existing projects without any changes.

And why is it a big improvement ?
Because it is able to play HE-AAC+ streams in stereo!
Yes, before that, the library was not able to play them. The reason was, that HE-AAC+ streams use a feature called Parametric Stereo (PS), which had to be unfortunately disabled due to some errors in the underlying OpenCORE library. So the decoder was able to play HE-AAC+ streams, but only in mono, not stereo.

Fortunately the problem has been solved by patching the OpenCORE library. But it was not as easy as it looks like (or the patch itself looks like).

Which is the Right Source of OpenCORE ?

First of all: there exist several versions of the OpenCORE aacdec library across the internet:
  1. http://code.google.com/p/opencore-aacdec/ - this is the original (version 2009) from the PacketVideo team. Unfortunately there are problems with AAC+ (SBR) and HE-AAC+ (SBR+PS) streams. I used this library until mid of 2011, when I found:
  2. http://android.git.kernel.org - GIT repository of the Android's source code including the OpenCORE aacdec code. Unfortunately this was not accessible during last months (spring 2012), so I had then to look for other possibilities. Unbelievable - today there is again (a new) web front-end for browsing. But the code in platform/external/opencore was better - it was able to play AAC+ (SBR), but still not the HE-AAC+ (SBR+PS).
  3. http://crepedroid.git.sourceforge.net/ I understand this is a clone of the Android. I used this as a workaround to get the newer sources during spring 2012 when the official Android's repository was not accessible for normal browsing (only using repo command). Same quality as in (2).
  4.  http://source.android.com/ - using repo command one is able to retrieve the newest version of OpenCORE. It is in platform/frameworks/base/media/libstagefright . Unfortunately there was still the problem with HE-AAC+ streams (2012/05) - playing mono only. But there is one improvement - when enabling PS feature, the library is no more crashing. This was the starting point to patch the OpenCORE library !


Patching of OpenCORE aacdec

So there was a way how to at least make the library stable. The problem was, that if PS was enabled sometimes the produced sound was very noisy. And sometimes ok, but mono.

I have been trying to find a patch - but there were no patches available anywhere. Even in the Android's source tree there was nothing usable.

It made me to start learning about PS encoding and decoding. Nice mathematics - I can recommend this paper: Parametric Coding of Stereo Audio [PDF]. I spent several evenings reading it. But it made me an overview of the algorithm and pushed me forward.

In order to be able to debug the code I created a tool for converting AAC to WAV - of course reusing the existing native code from the project. I was able to run it directly in my computer (not the Android emulator).

Then snapped some live HE-AAC+ streams and started debugging, tracing and comparing the results. The first hint which I found was the right one! Then I had to create the correct patch suitable for all streams. But this took me less time than to prepare the tools and environments before!

Summary

Here are the summary of versions of the aacdecoder-android library:
  • 2011-05-25 Version 0.5 - initial version - separated from the aacplayer-android project
  • 2011-07-26 Version 0.5.1 - PS crash detected and PS disabled, the first stable version
  • 2012-05-25 Version 0.6 - AAC+ (SBR) is playing, but only mono, not stereo
  • 2012-06-28 Version 0.6.1 - PS patched developed; HE-AAC+ streams can be played in stereo
The challenge for next months is to speed-up the library. Although it is still faster than FAAD2, it consumes a lot of CPU now (for HE-AAC+). It is even impossible to play the streams smoothly on emulator now. So what's next ? To learn ARM Architecture :-)