How to Build ffmpeg with NDK r9

This is a updated post for a previous post, where we built ffmpeg 0.8 with Android NDK r5 and r6. This post will give instructions of how to build ffmpeg 2.0.1 with Android NDK r9.

0. Download Android NDK

The latest version of Android NDK can be downloaded at Android NDK website. At the time of writing, the newest version is NDK r9. Note that the website provides both current and legacy toolchains. We only need the current toolchain to compile ffmpeg.

After download NDK, simply decompress the archive. Note that we’ll use $NDK to represent the root path of the decompressed NDK.

1. Download ffmpeg source code

FFMPEG source code can be downloaded from the ffmpeg website. The latest stable release is 2.0.1. Download the source code and decompress it to $NDK/sources folder. We’ll discuss about the reason for doing this later.

2. Update configure file

Open ffmpeg-2.0.1/configure file with a text editor, and locate the following lines.

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'

LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'

SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'

SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'

This cause ffmpeg shared libraries to be compiled to libavcodec.so.<version> (e.g. libavcodec.so.55), which is not compatible with Android build system. Therefore we’ll need to replace the above lines with the following lines.

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'

LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'

SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'

SLIB_INSTALL_LINKS='$(SLIBNAME)'

3. Build ffmpeg

Copy the following text to a text editor and save it as build_android.sh.

#!/bin/bash

NDK=$HOME/Desktop/adt/android-ndk-r9

SYSROOT=$NDK/platforms/android-9/arch-arm/

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64

function build_one

{

./configure 

    --prefix=$PREFIX 

    --enable-shared 

    --disable-static 

    --disable-doc 

    --disable-ffmpeg 

    --disable-ffplay 

    --disable-ffprobe 

    --disable-ffserver 

    --disable-avdevice 

    --disable-doc 

    --disable-symver 

    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- 

    --target-os=linux 

    --arch=arm 

    --enable-cross-compile 

    --sysroot=$SYSROOT 

    --extra-cflags="-Os -fpic $ADDI_CFLAGS" 

    --extra-ldflags="$ADDI_LDFLAGS" 

    $ADDITIONAL_CONFIGURE_FLAG

make clean

make

make install

}

CPU=arm

PREFIX=$(pwd)/android/$CPU 

ADDI_CFLAGS="-marm"

build_one

We disabled static library and enabled shared library. Note that the build script is not optimized for a particular CPU. One should refer to ffmpeg documentation for detailed information about available configure options.

Once the file is saved, make sure the script is executable by the command below,

sudo chmod +x build_android.sh

Then execute the script by the command,

./build_android.sh

4. Build Output

The build can take a while to finish depending on your computer speed. Once it’s done, you should be able to find a folder $NDK/sources/ffmpeg-2.0.1/android, which contains arm/lib and arm/include folders.

The arm/lib folder contains the shared libraries, while arm/include folder contains the header files for libavcodec, libavformat, libavfilter, libavutil, libswscale etc.

Note that the arm/lib folder contains both the library files (e.g.: libavcodec-55.so) and symbolic links (e.g.: libavcodec.so) to them. We can remove the symbolic links to avoid confusion.

5. Make ffmpeg Libraries available for Your Projects

Now we’ve compiled the ffmpeg libraries and ready to use them. Android NDK allows us to reuse a compiled module through the import-module build command.

The reason we built our ffmpeg source code under $NDK/sources folder is that NDK build system will search for directories under this path for external modules automatically. To declare the ffmpeg libraries as reusable modules, we’ll need to add a file named $NDK/sources/ffmpeg-2.0.1/android/arm/Android.mk with the following content,

LOCAL_PATH:= $(call my-dir)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libavcodec

LOCAL_SRC_FILES:= lib/libavcodec-55.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libavformat

LOCAL_SRC_FILES:= lib/libavformat-55.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libswscale

LOCAL_SRC_FILES:= lib/libswscale-2.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libavutil

LOCAL_SRC_FILES:= lib/libavutil-52.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libavfilter

LOCAL_SRC_FILES:= lib/libavfilter-3.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

 

include $(CLEAR_VARS)

LOCAL_MODULE:= libwsresample

LOCAL_SRC_FILES:= lib/libswresample-0.so

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

Below is an example of how we can use the libraries in a Android project’s jni/Android.mk file,

LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_MODULE    := tutorial03

LOCAL_SRC_FILES := tutorial03.c

LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid

LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil

 

include $(BUILD_SHARED_LIBRARY)

$(call import-module,ffmpeg-2.0.1/android/arm)

Note that we called import-module with the relative path to $NDK/sources for the build system to locate the reusable ffmpeg libraries.

For real examples to how to use the ffmpeg libraries in Android app, please refer to my github repo of android-ffmpeg-tutorial.

What is Android NDK–a File by File View

Android NDK is a collection of tools and libraries that allow us to develop Android apps in C/C++. This post dissect the latest Android NDK release r8c by providing detailed information about the files and directories.

build: the build tools and scripts

–awk: some awk programs used internally by NDK build system, mainly for parsing various files of an Android NDK project.

–core: mk files used internally by NDK build system.
–gmsl: GNU make standard library.  A collection of functions implemented using native GNU Make functionality that provide list and string manipulation, integer arithmetic, associative arrays, stacks, and debugging facilities.

–tools: a collection of tools (mainly scripts) used for NDK compilation, installation, etc. We don’t need to use these tools as a NDK app developer.

docs: the documentations
–ANDROID-ATOMICS.html: issues about Android atomic operations defined in sys/atomics.h

–ANDROID-MK.html: how Android.mk file works

–APPLICATION-MK.html: how Application.mk file works

–CHANGES.html: the NDK change log for all NDK versions.

–CPLUSPLUS-SUPPORT.html: C++ support on Android. Different runtimes are discussed.

–CPU-ARCH-ABIS.html: native code Application Binary Interface (ABI) management. Supported ABIs include arm, arm-v7a, x86 and mips.

–CPU-ARM-NEON.html: how to use the NEON features available on some arm cpu.

–CPU-FEATURES.html: how to detect CPU families and features using the cpu-features library.

–CPU-MIPS.html: how to enable MIPS support at Android NDK

–CPU-X86.html: how to enable x86 support at Android NDK

–DEVELOPMENT.html: how to modify, compile and generate release packages of NDK

–HOWTO.html: a collection of commonly used tips and tricks.

–IMPORT-MODULE.html: how to import a module outside of project source tree.

–INSTALL.html: how to install Android NDK

–LICENSES.html: license

–NATIVE-ACTIVITY.HTML: how to development and build native activity and application

–NDK-BUILD.html: how ndk-build command works

–NDK-GDB.html: how ndk-debug command works

–NDK-STACK.html: how to use the ndk-stack tool

–openmaxal:

—-index.html: Android specific doc about OpenMAX AL

—-OpenMAX_AL_1_0_1_Specification.pdf: the OpenMAX AL specification 1.0.1

–opensles

—-index.html: Android specific doc about OpenSL ES

—-OpenSL_ES_Specification_1.0.1.pdf: the OpenSL ES specification 1.0.1

–OVERVIEW.html: Android NDK overview

–PREBUILTS.html: How Android prebuilt library works

–sidenav.html: sidebar for the documentation, basically a menu

–STABLE-APIS.html: the list of stable APIs available at different Android API level.

–STANDALONE-TOOLCHAIN.html: how to use the NDK toolchain as a standalone compiler.

–system

—-libc

——CHANGES.html: Android Bionic C change log.

——OVERVIEW.html: Android Bionic C library overview.

——SYSV-IPC.html: explains why Android doesn’t support System V IPCs.

–SYSTEM-ISSUES.html: a list of known issues at Android NDK and Android system images.

documentation.html: the documentation html main page

GNUmakefile: a small script used to detect NDK path. It “includes” /build/core/main.mk. possibly the entry point of NDK build system.

ndk-build: the entry point for building NDK code

ndk-build.cmd: a Windows batch script to invoke NDK-specific GNU Make executables

ndk-gdb: the entry point for debugging NDK code

ndk-stack: a tool that allows us to trace the stack in a shared library with the logcat output. The details of this tool can be found at docs/NDK-STACK.html.

ndk-which: a tool to learn the path of the active toolchain components within the ndk.

platforms: The platform files, the libraries and header files for various Android API level at different platforms.
–android-3:

—-arch-arm: the logical root directory for libraries and headers at Android-3 ARM

–android-4:

—-arch-arm: the logical root directory for libraries and headers at Android-4 ARM

–android-5:

—-arch-arm: the logical root directory for libraries and headers at Android-5 ARM

–android-8:

—-arch-arm: the logical root directory for libraries and headers at Android-8 ARM

–android-9:

—-arch-arm: the logical root directory for libraries and headers at Android-9 ARM

—-arch-mips: the logical root directory for libraries and headers at Android-9 MIPS

—-arch-x86: the logical root directory for libraries and headers at Android-9 x86

–android-14:
—-arch-arm: the logical root directory for libraries and headers at Android-14 ARM
——usr:
——–include:
——–lib:
—-arch-mips: the logical root directory for libraries and headers at Android-14 MIPS
——usr:
——–include:
——–lib:
—-arch-x86: the logical root directory for libraries and headers at Android-14 x86
——usr:
——–include:
——–lib:
prebuilt: contains the prebuilt binaries required by the host and the target platform
–android-arm: some binaries used by NDK on arm target
—-gdbserver
——gdbserver: gdb server
–android-mips: some binaries used by NDK on MIPS target
—-gdbserver
——gdbserver: gdb server
–android-x86: some binaries used by NDK on x86 target
—-gdbserver
——gdbserver: gdb server
–linux-x86: some binaries used by the Android NDK build system
—-bin:
——awk: an interpreted programming language typically used as a data extraction and reporting tool.
——make: a tool which controls the generation of executables and other non-source files of a program from source files.
——sed: stream editor. A utility that parses text and applies transformations to text.

README.TXT: introduction for Android NDK

RELEASE.TXT: contains NDK version.

samples: contains a few sample NDK projects.
–bitmap-plasma: jnigraphics API
–hello-gl2: OpenGL ES v2.
–hello-jni: basic example for JNI
–hello-neon: how to use cpufeatures to detect CPU features and how to use NEON feature of ARM CPU
–module-exports: how to use a module in another module.
–native-activity: how to create nativity actitiy
–native-audio: OpenSL ES audio API
–native-media: OpenMAX AL media API
–native-plasma: native_app_glue
–san-angeles: OpenGL ES v1.
–test-libstdc++: build native executable
–two-libs: two libraries, where the second depends on the first one.

sources: some library modules and their source code
–android:

—-cpufeatures: a library that helps us detecting device CPU type and features. source code available.

—-libportable: Device Shared Library libportable. (???)

—-libthread_db: the sources of the special libthread_db that will be statically linked against the gdbserver binary. These are uses automatically by the build-gdbserver.sh script. This is not an import module.

—-native_app_glue: the android_native_app_glue module, used for creating a native activity.

–cpufeatures: the cpufeatures import module. just a link to android/cpufeatures.

–cxx-stl: various C++ runtime libraries, refer to docs/CPLUSPLUS-SUPPORT.html for more details.
—-gabi++: gabi++ C++ runtime
—-gnu-libstdc++: GNU C++ runtime
—-stlport:  stlport C++ runtime
—-system:  system default C++ runtime=

tests: scripts and sources to perform automated testing for NDK release
–awk: test files for awk
–build: contains tests used to check the NDK build system itself.
–check-release.sh: a few sanity checks on a given NDK release install/package.
–device: contains tests used to check that NDK-generated binaries work properly on an Android device.

–README: description about the folders under tests
–run-tests-all.sh: run all tests
–run-tests.sh: used to run NDK build tests. Without any parameters, this will try to run all standard tests.

–standalone: test programs and scripts for testing a standalone toolchain.

toolchains: toolchains for various platforms, we only show arm-linux-androideabi-4.6 in detail

–arm-linux-androideabi-4.6: toolchain used to compile for arm architecture android ABI on linux with gcc 4.6

—-config.mk: config file for the arm gcc-4.6 toolchain for the Android NDK

—-setup.mk: this file is used to prepare the NDK to build with the arm gcc-4.6 toolchain any number of source files. It defines (or re-defines) templates used to build various sources into target object files, libraries or executables.

—-prebuilt

——linux-x86

——–arm-linux-androideabi

———-lib:

————ldscripts:

———-bin: the tools in this directory is the same as the corresponding binaries (with arm-linux-androideabi- prefix) in the linux-x86/bin directory. including ar, as, c++, g++, gcc, ld, ld.bfd, ld.gold, nm, objcopy, objdump, ranlib, strip

——–bin:

———-arm-linux-androideabi-addr2line: Convert addresses into line number/file name pairs. e.g.: arm-linux-androideabi-addr2line -C -f –e obj/local/armeabi/libnativemaprender.so 0003deb4 (Binutils)

———-arm-linux-androideabi-ar: archiver, used to create modify and extract from libraries. It is normally used to create static libraries. (Binutils)

———-arm-linux-androideabi-as: assembler. (Binutils)

———-arm-linux-androideabi-c++: C++ front end, same as arm-linux-androideabi-g++ (gcc)

———-arm-linux-androideabi-c++filt: Filter to demangle encoded C++ symbols. (Binutils)

———-arm-linux-androideabi-cpp: C preprocessor. The C preprocessor implements the macro language used to transform C, C++, and Objective-C programs before they are compiled. (gcc)

———-arm-linux-androideabi-elfedit: examine and modify ELF metadata within an ELF object. (Binutils)

———-arm-linux-androideabi-g++: GCC compiler C++ front end (gcc)

———-arm-linux-androideabi-gcc: GCC compiler C front end (gcc)

———-arm-linux-androideabi-gcc-4.6: same as above. (gcc)

———-arm-linux-androideabi-gcov: program to test code coverage. (gcc)

———-arm-linux-androideabi-gdb: gdb debugger. (gdb)

———-arm-linux-androideabi-gdbtui: gdb text user interface. (gdb)

———-arm-linux-androideabi-gprof: display profiling info (Binutils)

———-arm-linux-androideabi-ld: linker. same as arm-linux-androideabi-ld.gold (Binutils)

———-arm-linux-androideabi-ld.bfd: linker using BFD, the Binary File Descriptor library.(Binutils)

———-arm-linux-androideabi-ld.gold: a new faster, ELF only linker. (Binutils)

———-arm-linux-androideabi-nm: Lists symbols from object files. (Binutils)

———-arm-linux-androideabi-objcopy: Copy and translates object files. (Binutils)

———-arm-linux-androideabi-objdump: Displays information from object files. (Binutils)

———-arm-linux-androideabi-ranlib: Generates an index to the contents of an archive. The index lists all the symbols defined by archive members that are relocatable object files. (Binutils)

———-arm-linux-androideabi-readelf: Displays information from any ELF format object file. (Binutils)

———-arm-linux-androideabi-run: for manipulating simulators.

———-arm-linux-androideabi-size:  Lists the section sizes of an object or archive file. (Binutils)

———-arm-linux-androideabi-strings: Lists printable strings from files. (Binutils)

———-arm-linux-androideabi-strip: remove symbols. (Binutils)

——–include:

———-lib:

————libiberty.a: contains routines used by various GNU programs, including getopt, obstack, strerror, strtol, and stroul

————libarm-elf-linux-sim.a:

————libarm-linux-android-sim.a:

————gcc:
————–arm-linux-androideabi:
—————-4.6:
——————libgcov.a: a library used by GCC compiler to support code coverage test.
——————libgcc.a: a library used by GCC compiler for some low-level computations.
——————gcov-src: the source code for libgcov
——————crtbegin.o: program initialization code. refer to http://gcc.gnu.org/onlinedocs/gccint/Initialization.html
——————crtbeginS.o: variant of crtbegin.o
——————crtbeginT.o: variant of crtbegin.o
——————crtend.o: program destruction code.
——————crtendS.o: variant of crtend.o
——————arm-v7a: files for arm-v7a ABI
——————thumb: files for thumb code
——–lib32:
———-libbfd.a: the binary file descriptor library. It is a package which allows applications to use the same routines to operate on object files of different object file formats. (Binutils)

———-libbfd.la:  libtool library file for libbfd.a

———-libintl.a: it is a library that provides native language (non-english) support to programs. It is a part of gettext.

———-libexec: some utilities and libraries used by GCC internally
——–gcc:
———-arm-linux-androideabi:
————4.6: some utilities and libraries used by GCC internally, including collect2, cc1, cc1plus etc.
——–SOURCES: description about the sources for the toolchain
——–sysroot: root directory for headers and libraries
———-usr: prefix

————lib: same as content platforms/android-<depends on the sysroot set when compiling the toolchain>/arch-arm/usr/lib/

————include: same as content in platforms/android-<depends on the sysroot set when compiling the toolchain>/arch-arm/usr/include/

–arm-linux-androideabi-4.4.3: toolchain used to compile for arm architecture android ABI on linux with gcc 4.4.3

–arm-linux-androideabi-clang3.1: toolchain used to compile for ARM architecture android ABI on linux with gcc 4.4.3 (contains the config.mk and setup.mk files only)

–llvm-3.1: contains the clang compiler from LLVM

–mipsel-linux-android-4.4.3: toolchain used to compile for MIPS architecture android ABI on linux with gcc 4.4.3

–mipsel-linux-android-4.6: toolchain used to compile for MIPS architecture android ABI on linux with gcc 4.6

–mipsel-linux-android-clang3.1: toolchain used to compile for MIPS architecture android ABI on linux with clang 3.1 (contains the config.mk and setup.mk files only)

–x86-4.4.3: toolchain used to compile for x86 architecture android ABI on linux with gcc 4.4.3

–x86-4.6:  toolchain used to compile for x86 architecture android ABI on linux with gcc 4.6

–x86-clang3.1:  toolchain used to compile for x86 architecture android ABI on linux with clang 3.1 (contains the config.mk and setup.mk files only)

Build Android NDK Toolchain From Source Code

Android NDK comes with a few toolchains under the toolchain directory. We can also build our own toolchain from the source code.

0. Download Latest Android NDK (r8c at the time of writing) from Android NDK website at http://developer.android.com/tools/sdk/ndk/index.html. Extract the downloaded archive.

$ tar xvf android-ndk-r8c-linux-x86.tar.bz2

1. Get into the ndk directory. Download the Android NDK source code to the src directory.

$ cd android-ndk-r8c/
$ ./build/tools/download-toolchain-sources.sh src

2. Install the following libraries

sudo apt-get install libncurses5-dev
sudo apt-get install texinfo
sudo apt-get install bison
sudo apt-get install flex

3. Rebuild the library is just one command. Below are two commands build two different toolchains with different versions of GCC and GDB.

./build/tools/build-gcc.sh –verbose –gdb-version=6.6 $(pwd)/src $(pwd) arm-linux-androideabi-4.6

./build/tools/build-gcc.sh –verbose –gdb-version=7.3.x $(pwd)/src $(pwd) arm-linux-androideabi-4.7

The toolchain built can be found under toolchains directory of the Android NDK folder.

How to Deploy Android NDK Library in Separate APK

There’re times developers want to deploy a NDK library in a separate APK. A typical use case is your library is big and it has different versions for different CPUs/phones. A naive strategy is to put all those libraries in a single huge apk and get lots of user complains. A better approach is to separate NDK library from the main application. This has been done by many video player apps.

Recently I also adopted this approach for my Video Converter Android app. This post gives a simple example of using separate APK for native library.

0. Create the NDK Library

The first step is to create the NDK library. We used the hello-jni code in the NDK sample. Note that when creating this project, uncheck the “Create Activity” box, since we’re going to create a apk contains NDK library only. This is shown in figure below,

Figure 1. Creating a Native Library

You can download the code at the end of this post.

Note that the package name for the library project is roman10.tutorial.nativelib. Once you export the apk and installed it on your device, the ndk library “libhello-jni.so” will be put at /data/data/roman10.tutorial.nativelib/lib/.

Note that the NDK library function’s signature needs to follow the JNI standard in order for the project code described below to call it.

1. Create a Project that Use the NDK Library

Now we create a project that uses the NDK library. To load the library, instead of loadLibrary function, we use load().

private static final String libPath = "/data/data/roman10.tutorial.nativelib/lib/libhello-jni.so";

System.load(libPath);

To call the NDK function, we need to declare the function.

public native String  stringFromJNI();

We can then call the NDK method.

displayText = (TextView) findViewById(R.id.display);        

displayText.setText( stringFromJNI() );

With APKs from both projects installed on my phone, I got the following results.

Figure 2. Execution Results

2. Downloads

You can download the code for the two projects here, from get them from my github here.

How to Compile SQLite for Android using NDK

According to SQLite home page, SQLite is a open source software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine.

Self-contained means SQLite depends little on external libraries; serverless means SQLite doesn’t follow the client-server model that most other SQL database engines follow. SQLite reads and writes directly from the database files on disk. zero-configuraiton means SQLite is easy to deploy and set up; Transactional means all changes and queries are atomic, consistent, isolated and durable. Details of these terms can be found on SQLite home page at reference 0.

This post covers how to compile SQLite for using with native code. Currently Android only provides APIs to access SQLite database on SDK using Java. No NDK interface is publicly available. However, as SQLite is open source and self-contained, it’s possible to build an embedded version of SQLite for using with NDK.

0. Download SQLite Source Code
One can download the SQLite source code here. It’s easier to build the version with all C source code combined into a single file, so download the amalgamation version. Once downloaded, extract the source files to your Android project’s jni folder.

The source code consists of only four files, sqlite3.h, sqlite3.c, sqlite3ext.h, shell.c. If we want to build an embedded version of SQLite, we only need sqlite3.h and sqlite3.c. Shell.c is for building a command line utility to access SQLite database, sqlite3ext.h is for building extension for SQLite.

1. A Simple Example of Using SQLite
For simplicity, we provided a C program modified from SQLite website example, the code is as below,

#include <sqlite3.h>

 

static int callback(void *NotUsed, int argc, char **argv, char **azColName) {

    int i;

    for (i = 0; i < argc; ++i) {

        printf("%s = %sn", azColName[i], argv[i] ? argv[i] : "NULL");

    }

    printf("n");

    return 0;

}

int main(int argc, char **argv) {

    char create_table[100] = "CREATE TABLE IF NOT EXISTS customers (id INTEGER PRIMARY KEY,name TEXT NOT NULL)";

    char insert_value[100] = "INSERT INTO customers VALUES('1', 'roman10')";

    sqlite3 *db;

    char *errMsg;

    int rv;

    if (argc != 2) {

        printf("Usage: %s databasen", argv[0]);

        return 1;

    }

    rv = sqlite3_open(argv[1], &db);

    if (rv) {

        printf("Cannot open database: %sn", sqlite3_errmsg(db));

        sqlite3_close(db);

        return 1;

    }

    rv = sqlite3_exec(db, create_table, callback, 0, &errMsg);

    if (rv != SQLITE_OK) {

        printf("SQLite statement execution error: %sn", errMsg);

    }

    rv = sqlite3_exec(db, insert_value, callback, 0, &errMsg);

    if (rv != SQLITE_OK) {

        printf("SQLite statement execution error: %sn", errMsg);

    }

    sqlite3_close(db);

    return 0;

}

The code accepts a database name as input parameter. It first uses sqlite3_open to open (or create, if the database doesn’t exist) a database. It then execute two SQL query. The first one create a new table “customers” with columns “id” and “name”. The second SQL query insert a record with id = 0, name = “roman10” into the table “customers”.

2. Android.mk to Build the Example
To build the example for Android, you can use the Android.mk file below,

#LOCAL_PATH is used to locate source files in the development tree.

#the macro my-dir provided by the build system, indicates the path of the current directory

LOCAL_PATH:=$(call my-dir)

 

#####################################################################

#            build sqlite3                                            #

#####################################################################

include $(CLEAR_VARS)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/sqlite-amalgamation-3070900

LOCAL_MODULE:=sqlite3

LOCAL_SRC_FILES:=sqlite-amalgamation-3070900/sqlite3.c

include $(BUILD_STATIC_LIBRARY)

#include $(BUILD_SHARED_LIBRARY)

 

 

#####################################################################

#            build our code                    #

#####################################################################

include $(CLEAR_VARS)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/sqlite-amalgamation-3070900

LOCAL_MODULE:=sqlitetest

LOCAL_SRC_FILES:=sqlite_test.c

LOCAL_STATIC_LIBRARIES:=libsqlite3

#LOCAL_SHARED_LIBRARIES:=libsqlite3

LOCAL_LDLIBS:=-llog -lm

#include $(BUILD_SHARED_LIBRARY)

include $(BUILD_EXECUTABLE)

Note that the above build file builds the sqlite as static library, you can also build it as shared library.

Also note that the example illustrates how to build executable using SQLite, you can also call sqlite API in your JNI method, and provide an interface for your Java code to access the SQLite APIs you have embedded.

3. Run the Code
The compiled sqlitetest program should be found under your Android project’s libs/armabi-* folder. You can use adb push to push the executable to your phone. And you might want to change the permission of the sqlitetest to executable. Note that this operation need rooted device.

But root is not required to build SQLite and provide database access through JNI. It’s the limitation of the example provided here. If you don’t have a rooted device, just study the code and build scripts and I believe you can still get the idea.

Below is a screenshot of running sqlitetest program we compiled under Android,

Figure 1. Execution of the Sqlitetest Program

References:
0. SQLite home page: http://www.sqlite.com/
1. An Introduction to SQLite C/C++ Interface: http://www.sqlite.org/cintro.html

How to Build and Use libnetfilter_queue for Android

If you’re looking for general information about how to use libnetfilter_queue for Linux, please refer here.

0. Preparation
First, you’ll need to check if your Android system kernel is compiled with support for libentfilter_queue. Follow the following steps,

  • Connect your android device to your computer.
  • Enter command “adb pull /proc/config.gz” to get the config.gz file from your android device.
  • Extract config.gz file, you’ll get a file named config. This is actually your Android Linux kernel build configuration file.
  • Search for CONFIG_NETFILTER_ADVANCED, CONFIG_NETFITLER_NETLINK and CONFIG_NETFILTER_NETLINK_QUEUE in config file, make sure they’re not commented out.

If your Android build is not compiled with these features, you’ll need to compile customized kernel build to use libnetfilter_queue.

Next you’ll need to root your Android device. This is not the focus of this post, so it’s not covered here. But you can find lots of information online.

Thirdly, make sure your phone has iptables program. iptables program is used to configure the kernel packet filter table. Follow the command below to check,

adb shell

su

iptables –list

If the terminal doens’t complain about program not found, then you have iptables installed. If you don’t have iptables installed on your Android device, you may consider install busybox, or compile your own iptables program. I checked out the Android source code tree, it includes iptables in the external folder. So it should be doable to build on your own.

1. Build the Libraries and Test Executable
libnetfilter_queue depends on libnfnetlink, so we’ll need to download both libraries from here and here. After downloading, extract the libraries to your Android project jni folder.
Copy the nfqnl_test.c file from libnetfilter_queue-1.0.0/utils/ folder to jni folder. And create a Android.mk file with the content below,

#LOCAL_PATH is used to locate source files in the development tree.

#the macro my-dir provided by the build system, indicates the path of the current directory

LOCAL_PATH:=$(call my-dir)

 

#####################################################################

#            build libnflink                    #

#####################################################################

include $(CLEAR_VARS)

LOCAL_MODULE:=nflink

LOCAL_C_INCLUDES := $(LOCAL_PATH)/libnfnetlink-1.0.0/include

LOCAL_SRC_FILES:=

    libnfnetlink-1.0.0/src/iftable.c 

    libnfnetlink-1.0.0/src/rtnl.c 

    libnfnetlink-1.0.0/src/libnfnetlink.c

include $(BUILD_STATIC_LIBRARY)

#include $(BUILD_SHARED_LIBRARY)

 

#####################################################################

#            build libnetfilter_queue            #

#####################################################################

include $(CLEAR_VARS)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/libnfnetlink-1.0.0/include 

    $(LOCAL_PATH)/libnetfilter_queue-1.0.0/include

LOCAL_MODULE:=netfilter_queue

LOCAL_SRC_FILES:=libnetfilter_queue-1.0.0/src/libnetfilter_queue.c

LOCAL_STATIC_LIBRARIES:=libnflink

include $(BUILD_STATIC_LIBRARY)

#include $(BUILD_SHARED_LIBRARY)

 

#####################################################################

#            build our code                    #

#####################################################################

include $(CLEAR_VARS)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/libnfnetlink-1.0.0/include 

    $(LOCAL_PATH)/libnetfilter_queue-1.0.0/include

LOCAL_MODULE:=nfqnltest

LOCAL_SRC_FILES:=nfqnl_test.c

LOCAL_STATIC_LIBRARIES:=libnetfilter_queue

LOCAL_LDLIBS:=-llog -lm

#include $(BUILD_SHARED_LIBRARY)

include $(BUILD_EXECUTABLE)

Then issue “ndk-build” command to build the libraries and executable nfqnltest.

Note that you’ll probably encounter an error “undefined reference to __fswab64”. This is an known issue as indicated here. Just apply the patch (or change according to the patch) to your NDK header file (platforms/android-9/arch-arm/usr/include/linux/byteorder/swab.h, replace “android-9” in the path with your targeted android version). It will resolve the build error.

2. Running the Code on Android
Follow the command below to copy and executable to your Android device and run it,

  • adb shell
  • su
  • mkdir /data/data/nfqnltest
  • chmod 777 /data/data/nfqnltest
  • Open another terminal. Go to libs/<armeabi*> folder of your Android project. Issue command “adb push nfqnltest /data/data/nfqnltest/”
  • Switch back to first terminal, “cd /data/data/nfqnltest”
  • ./nfqnltest

To configure iptables rules, you can open a new terminal, then follow the command below,

adb shell

su

iptables -A OUTPUT -p tcp -j NFQUEUE –queue-num 0

Then in terminal you’re running nfqnltest, you can see the program outputs. If you open browser app on your phone, and try to open google.com. You’ll see some packet information displayed,

pkt received

…….

hw_protocol=0x0000 hook=3 id=0 outdev=12 payload_len=288

entering callback

pkt received

hw_protocol=0x0000 hook=3 id=1 outdev=12 payload_len=869

entering callback

With libnetfilter_queue, you can do a lot of interesting stuff, like user space NATing, packet sniffing/capturing etc.

Effective Color Conversion (YUV->RGB) for Android in Assembly

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.

5. Download
You can download the entire source code package here or from github here.

References:
1. YUV2RGB: http://wss.co.uk/pinknoise/yuv2rgb/