FFmpeg Android platform porting-Compilation

Source: Internet
Author: User

FFmpeg Android platform porting-Compilation

Dennis Hu March 28, 2014

Abstract:This article mainly introduces the compilation and basic testing process of porting FFmpeg audio/video codec library to Android platform.

Environment preparation:

Ubuntu12.04 TLS

Android-ndk-r9d-linux-x86_64.tar.bz2

Adt-bundle-windows-x86_64-20131030.zip


Step 1: Download the source code

Go to the FFmpeg official website http://www.ffmpeg.org/to download the source code. The downloaded source code is the most accurate. After entering the official website, select "Download" to go To the Download page. As of January 1, March 28, 2014, the latest stable version is FFmpeg2.2, codenamed "Muybridge ". Click "Downloadgzip tarball.pdf" below to download the file. The file name is ffmpeg-2.2.tar.gz, which is about 8.3 MB.

Step 2: Compile FFmpeg in Linux

You can install ubuntu on a VMplayer Virtual Machine on Windows.

This document describes how to use/home/dennis as the root directory:

Copy ffmpeg-2.2.tar.gz to the root directory, and then run the following command to decompress it:

$ Tar zxf ffmpeg-2.2.tar.gz

Decompress the package and you will get the/home/dennis/ffmpeg-2.2 directory.

Modifying the ffmpeg-2.2/configure file

If you compile the file directly according to the unmodified configuration, the resulting so file is similar to libavcodec. so.55.39.101. The version number is after so, and Android does not seem to be able to load the file. Therefore, modify the settings as follows:

Put the following four lines in the file:

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 )'

Replace:

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

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

SLIB_INSTALL_NAME = '$ (SLIBNAME_WITH_MAJOR )'

SLIB_INSTALL_LINKS = '$ (SLIBNAME )'

Compile the build_android.sh script file

FFmpeg can be said to be a super bully with an audio/video envelope encoding/decoding and format. Therefore, you usually need to configure and set the corresponding environment variables before compilation.

All configuration options are in the ffmpeg-2.2/configure script file and you can view all configuration options by executing the following command:

$./Configure-help

There are many configuration options and they are complicated. Here we will first figure out what I need and then take a look at it later.

We will write the required configuration items and environment variable settings into a sh script file to compile the so file required by the Android platform.

The content of build_android.sh is as follows:

#! /Bin/bash

NDK =/home/dennis/android-ndk-r9d

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-ffserver \

-- Enable-cross-compile \

-- Cross-prefix = $ TOOLCHAIN/bin/arm-linux-androideabi -\

-- Target-OS = linux \

-- Arch = arm \

-- Sysroot = $ SYSROOT \

-- Extra-cflags = "-OS-fpic $ ADDI_CFLAGS "\

-- Extra-ldflags = "$ ADDI_LDFLAGS "\

$ ADDITIONAL_CONFIGURE_FLAG

}

CPU = arm

PREFIX = $ (pwd)/android/$ CPU

ADDI_CFLAGS = "-marm"

Build_one


Note the following points in this script file:

(1) The three environment variables NDK, SYSROOT, and TOOLCHAIN must be replaced with those on your own machine.

(2) ensure that the path pointed to by the cross-prefix variable exists.

Add the executable permission to build_android.sh:

$ Chmod + x build_android.sh

Run build_android.sh.

$./Build_android.sh

After configuring this script to configure ffmpeg, configuration files such as config. h will be generated and will be used in subsequent compilation. If compilation is performed without configuration, the system will prompt that the config. h file and other errors cannot be found.

$ Make

$ Make install

At this point, an android directory is generated under the/home/dennis/ffmpeg-2.2 directory, where the so library file under the/home/dennis/ffmpeg-2.2/android/arm/lib directory is as follows:

-Rwxr-xr-x 1 dennisdennis 55208 Mar 29 16: 26libavdevice-55.so

-Rwxr-xr-x 1 dennisdennis 632476 Mar 29 libavfilter-4.so

-Rwxr-xr-x 1 dennisdennis 1442948 Mar 29 libavformat-55.so

-Rwxr-xr-x 1 dennisdennis 7985396 Mar 29 libavcodec-55.so

-Rwxr-xr-x 1 dennisdennis 83356 Mar 29 16: 26libswresample-0.so

-Rwxr-xr-x 1 dennisdennis 308636 Mar 29 libswscale-2.so

-Rwxr-xr-x 1 dennisdennis 300580 Mar 29 16: 26libavutil-52.so

Note: The above list removes the symbolic link file and the pkgconfig directory.

Step 3: create a common Android Project

    Create a new Android project FFmpeg4Android, create the jni folder under the root directory of the project, create the prebuilt directory under jni, and then:

    (1) Put the seven so files compiled above into this directory;

    (2) Copy all the header folders under/home/dennis/ffmpeg-2.2/android/arm/include to the directory.

      Create a class that contains the native method. First create the cn. dennishucd package under src, and then create the FFmpegNative. java class file. It mainly includes loading the so library file and a native test method. The content is as follows:

      package cn.dennishucd;public class FFmpegNative {                static{                                System.loadLibrary("avutil-52");                                System.loadLibrary("avcodec-55");                                System.loadLibrary("swresample-0");                                System.loadLibrary("avformat-55");                                System.loadLibrary("swscale-2");                                System.loadLibrary("avfilter-3");                                System.loadLibrary("ffmpeg_codec");                }                publicnative int avcodec_find_decoder(int codecID);}

        Use javah to create a. header file:

        Go to the bin/classes directory and run javah-jni cn. dennishucd. FFmpegNative.

        The C header file of cn_dennishucd_FFmpegNative.h will be generated in the current directory;

          Based on the header file name, the same name is created for the C source file cn_dennishucd_FFmpegNative.c

          The core part of the code is as follows:

          JNIEXPORT jint JNICALLJava_cn_dennishucd_FFmpegNative_avcodec_1find_1decoder

          (JNIEnv * env, jobject obj, jint codecID)

          {

          AVCodec * codec = NULL;

          /* Register all formats and codecs */

          Av_register_all ();

          Codec = avcodec_find_decoder (codecID );

          If (codec! = NULL)

          {

          Return0;

          }

          Else

          {

          Return-1;

          }

          }

            Compile Android. mk with the following content:

            LOCAL_PATH: = $ (callmy-dir)

            Include $ (CLEAR_VARS)

            LOCAL_MODULE: = avcodec-55-prebuilt

            LOCAL_SRC_FILES: = prebuilt/libavcodec-55.so

            Include $ (PREBUILT_SHARED_LIBRARY)

            Include $ (CLEAR_VARS)

            LOCAL_MODULE: = avdevice-55-prebuilt

            LOCAL_SRC_FILES: = prebuilt/libavdevice-55.so

            Include $ (PREBUILT_SHARED_LIBRARY)

            Include $ (CLEAR_VARS)

            LOCAL_MODULE: = avfilter-4-prebuilt

            LOCAL_SRC_FILES: = prebuilt/libavfilter-4.so

            Include $ (PREBUILT_SHARED_LIBRARY)

            Include $ (CLEAR_VARS)

            LOCAL_MODULE: = avformat-55-prebuilt

            LOCAL_SRC_FILES: = prebuilt/libavformat-55.so

            Include $ (PREBUILT_SHARED_LIBRARY)

            Include $ (CLEAR_VARS)

            LOCAL_MODULE: = avutil-52-prebuilt

            LOCAL_SRC_FILES: = prebuilt/libavutil-52.so

            Include $ (PREBUILT_SHARED_LIBRARY)

            Include $ (CLEAR_VARS)

            LOCAL_MODULE: = avswresample-0-prebuilt

            LOCAL_SRC_FILES: = prebuilt/libswresample-0.so

            Include $ (PREBUILT_SHARED_LIBRARY)

            Include $ (CLEAR_VARS)

            LOCAL_MODULE: = swscale-2-prebuilt

            LOCAL_SRC_FILES: = prebuilt/libswscale-2.so

            Include $ (PREBUILT_SHARED_LIBRARY)

            Include $ (CLEAR_VARS)

            LOCAL_MODULE: = ffmpeg_codec

            LOCAL_SRC_FILES: = cn_dennishucd_FFmpegNative.c

            LOCAL_LDLIBS: =-llog-ljnigraphics-lz-landroid

            LOCAL_SHARED_LIBRARIES: = avcodec-55-prebuilt avdevice-55-prebuilt avfilter-4-prebuiltavformat-55-prebuilt avutil-52-prebuilt

            Include $ (BUILD_SHARED_LIBRARY)

              Compile Application. mk [can be omitted] to compile the so file

              Open the cmd command line, go to the FFmpeg4Android \ jni directory, and execute the following command:

              Ndk-build

              By the end of this step, the libs \ armeabi directory will be generated under the FFmpeg4Android root directory. In addition to the above seven so directories, The libffmpeg_codec.so file will also be generated.

                How to add a library

                Add the following code to the FFmpegNative class to load the so Library:

                Static {

                System. loadLibrary ("avutil-52 ");

                System. loadLibrary ("avcodec-55 ");

                System. loadLibrary ("swresample-0 ");

                System. loadLibrary ("avformat-55 ");

                System. loadLibrary ("swscale-2 ");

                System. loadLibrary ("avfilter-3 ");

                System. loadLibrary ("avdevice-55 ");

                System. loadLibrary ("ffmpeg_codec ");

                }

                  Modify layout/main. xml and add an id to TextView to operate on it in code.
                           
                             
                            
                           

                  Add an Activity implementation class FFmpeg4AndroidActivity. Call the native function in the OnCreate method to pass the value to the TextView control and package it for running. The FFmpeg4AndroidActivity code is as follows:

                  Package cn. dennishucd;

                  Import android. app. Activity;

                  Import android. OS. Bundle;

                  Import android. widget. TextView;

                  Public class FFmpeg4AndroidActivity extends Activity {

                  @ Override

                  Protectedvoid onCreate (Bundle savedInstanceState ){

                  Super. onCreate (savedInstanceState );

                  SetContentView (R. layout. main );

                  TextViewtv = (TextView) this. findViewById (R. id. textview_hello );

                  FFmpegNativeffmpeg = new FFmpegNative ();

                  IntcodecID = 28; // 28 is the H264 Codec ID

                  Intres = ffmpeg. avcodec_find_decoder (codecID );

                  If (res = 0 ){

                  TV. setText ("Success! ");

                  }

                  Else {

                  TV. setText ("Failed! ");

                  }

                  }

                  }

                  28 in the Code is the ID of the H264 codec. It can be found in the source code of ffmpeg, which is defined by the enumeration type. In C, it can be converted to an integer value. Test whether H264 encoding/decoding can be found here. If it can be found, it indicates that the function of calling the ffmpeg library is successful, which also indicates that the so file we compiled is basically available.


                  Note:

                  [1] The compilation methods in this article mainly refer to the ideas in reference [1]. I would like to thank the author for his contribution;

                  [2] The subsequent testing process is referring to the decoding_encoding.c example in ffmpeg-2.1.4;

                  [3] For more information about how to use pre-built, see [2;

                  [4] This is only the first step in the porting process. The ffmpeg interface will be further analyzed later to call its codec library.

                  [5] The Android. mk file should be fine-tuned. This is the next step.

                  [6] it took me a lot of effort to complete the entire process. If you have any reposted information, please indicate the source. Thank you. The full source code for this article can be downloaded in my CSDN resources (http://download.csdn.net/detail/gobitan/7132037), the latest version can be tracked my github (https://github.com/dennishucd/FFmpeg4Android ).

                  References:

                    Http://www.roman10.net/how-to-build-ffmpeg-with-ndk-r9/http://www.ciaranmccormack.com/creating-a-prebuilt-shared-library-on-android-using-the-ndk/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.