How to build ffmpeg with hardware accelerated codecs for Android x86

In order to build a complete ffmpeg with hardware acceleration for Intel platform (XXX lake + Atom), we need a complete Android x86 build, the cross-compilation doesn't work well with NDK or anything else.

Steps are below.

 Install Ubuntu 16.04 LTS x86-64, install the all Ubuntu dependencies as here.

sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev libxml2-utils xsltproc unzip

Install Python Mako by pip, which the build system uses to generate the i18n files during compilation.

sudo apt-get install python-pip

pip install mako

Get the source code of Android x86, here make sure you have large enough space.

mkdir android-x86
cd android-x86
repo init -u git:// -b $branch
repo sync --no-tags --no-clone-bundle

The variable $branch is the name of specific Android branch.

  • oreo-x86
    • Android 8.0
  • nougat-x86
    • Android 7.1
  • marshmallow-x86
    • Android 6.0
  • lollipop-x86
    • Android 5.1
  • kitkat-x86
    • Android 4.4
  • jb-x86
    • Android 4.3
  • ics-x86
    • Android 4.0
  • honeycomb-x86
    • Android 3.2
  • gingerbread-x86
    • Android 2.3
  • froyo-x86
    • Android 2.2
  • eclair-x86
    • Android 2.1
  • donut-x86
    • Android 1.6
  • cupcake-x86 (aka android-x86-v0.9)
    • Android 1.5

Once the code base was checked out, use lunch command to build the system for once.

Enter the folder of checked out folder.

Source the build environement setup.

. build/

Select the build target and type of build


The $TARGET_PRODUCT could be one of android_x86 android_x86_64 .

The $TARGET_BUILD_VARIANT could be one of eng user userdebug .

So if we want to make a debug version of Android x86-64, we type

lunch android_x86_64-userdebug

Now type

m -jX iso_img

to make the system image.

When there is the error about, open the file


 and append a line


to it.

If everything goes okay, the Android system image would be build.

 Now we start to build a better ffmpeg with hardware acceleration API, vaapi, cuvid etc. The system already offer the possibilty but didn't supply the correct configuration as the default.

Copy the file




If you want to build the command line of ffmpeg, create a new file under external/tools folder, fill it with content

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

  -DTARGET_CONFIG=\"config-x86_64-x86_64.h\" \

    ../ffmpeg.c \
    ../ffmpeg_filter.c \
    ../ffmpeg_opt.c \
    ../ffmpeg_cuvid.c \
    ../ffmpeg_vaapi.c \
    ../cmdutils.c \

  $(LOCAL_PATH)/android/include \
  $(LOCAL_PATH)/.. \

LOCAL_SHARED_LIBRARIES := libavutil libavcodec libswscale libswresample libswscale libavformat libavfilter

LOCAL_MODULE := ffmpeg


Then that's it, you would have the ffmpeg command line under /system/bin/ffmpeg !

Do not touch the script gen-android-configs and configure with ffmpeg.

Now let's add more dependency to the system, such as libva-utils for the Intel platform to detect the video codec capability of the system.

Under the folder external, clone the repository at branch 1.8.3

git clone -b 1.8.3

Enter the libva-utils folder, change a bit the source code. The system's libva under driver is 1.1.0, it's not very compatible with the libva-utils, which is a new program.

diff --git a/vainfo/vainfo.c b/vainfo/vainfo.c
index 4405073..5d9f055 100644
--- a/vainfo/vainfo.c
+++ b/vainfo/vainfo.c
@@ -97,7 +97,8 @@ int main(int argc, const char* argv[])
   const char *name = strrchr(argv[0], '/'); 
   VAProfile profile, *profile_list = NULL;
   int num_profiles, max_num_profiles, i;
-  VAEntrypoint entrypoint, entrypoints[10];
+  VAEntrypoint entrypoints[10];
+  int entrypoint_index;
   int num_entrypoint;
   int ret_val = 0;
@@ -118,8 +119,8 @@ int main(int argc, const char* argv[])
   va_status = vaInitialize(va_dpy, &major_version, &minor_version);
   CHECK_VASTATUS(va_status, "vaInitialize", 3);
-  printf("%s: VA-API version: %d.%d (libva %s)\n",
-         name, major_version, minor_version, LIBVA_VERSION_S);
+  printf("%s: VA-API version: %d.%d\n",
+         name, major_version, minor_version);
   driver = vaQueryVendorString(va_dpy);
   printf("%s: Driver version: %s\n", name, driver ? driver : "<unknown>");
@@ -149,8 +150,8 @@ int main(int argc, const char* argv[])
       CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints", 4);
       profile_str = profile_string(profile);
-      for (entrypoint = 0; entrypoint < num_entrypoint; entrypoint++)
-          printf("      %-32s: %s\n", profile_str, entrypoint_string(entrypoints[entrypoint]));
+      for (entrypoint_index = 0; entrypoint_index < num_entrypoint; entrypoint_index++)
+          printf("      %-32s: %s\n", profile_str, entrypoint_string(entrypoints[entrypoint_index]));

Just make the vainfo.c is able to be compiled with system libva.

Back to the folder android-x86, type

mmm external/libva-utils

to just build the specific module. That's it, now the /system/bin/vainfo would be there !


posted on 2019-03-22 16:14  Bo Schwarzstein  阅读(714)  评论(0编辑  收藏  举报