Please jump to “0. Android NDK” if you want pure technical stuff; please jump to end of the post to download the sample code if you want to figure out everything yourself.
Recently I am doing a project that decodes a video using ffmpeg and render it on Android using Bitmap. At first, I tried to using sws_scale to do color conversion and scaling, it’s very slow (100~300ms).
Then I found from reference 1 that there’s ARM assembly code available to do YUV to RGB/RGBA color conversion. The code downloaded from the website doesn’t compile for Android, so I changed the code a little bit and made it work on Android.
The code also contains C equivalent procedures to do the conversion. It also runs faster than sws_scale. In case the assembly code doesn’t work for your processor, you can use the C equivalent methods.
0. Android NDK
In order to do yuv to rgb color conversion in assembly code, you’ll need to have Android NDK set up. I’m testing using NDK r5b, but other NDK versions should also work.
Note that you’ll need basic NDK knowledge in order to understand the example given. This includes how to pass bitmap, string, and primitive data from Java and C, how to manipulate bitmap object in C and basic JNI stuff.
1. How the Sample Program Work
The sample program consists of both Java and native C code. The java code will copy the test.yuv file from assets folder to /sdcard/test.yuv (main.java), create a bitmap object (RenderView.java), call the native code (also RenderView.java, native method defined in jni/test.c file) to do conversion and render the converted bitmap on screen.
The native code (jni/test.c) will manipulate the bitmap buffer, open the test.yuv file to get the YUV bytes and call the assembly procedure to do yuv2rgb8888 (defined in jni/yuv2rgb/yuv4202rgb8888.s file) conversion.
The assembly procedure is modified based on the code from reference 1. I don’t understand it fully yet. 🙁
2. How to Compile
I’ve created the Android.mk file. So you just go the jni folder, and type “ndk-build” will build the native library for you.
3. Who might Need this Code
The code basically contains the color conversion and also rendering on Android. If you’re developing a video player using ffmpeg, or a video game, you might want to handle color conversion and rendering yourself, then you might find this code useful.
4. Final Note
The sample code only test on yuv420 to rgb8888, but the code actually contains a lot other assembly code. You’ll need to modify the assembly procedure yourself and add them to Android.mk. But it should be straightforward and you can refer the yuv4202rgb8888.s file for reference.
When you call the assembly procedure, you might need to switch the order of u and v if you find the color is wired after conversion.
Note that it is the users’ responsibility to ensure that they are patent free before using the code.
1. YUV2RGB: http://wss.co.uk/pinknoise/yuv2rgb/