Compile ffmpeg using ndk in linux

Source: Internet
Author: User

My environment:
OS: ubuntu 12.10
Android-ndk-r7 ffmpeg: 0.8

The compilation steps are as follows:
Step 1:
Install and configure ndk
Run ndk-build. If the following information is displayed, the installation is successful.

Specify the project directory by setting the macro NDK_PROJECT_PATH
Export NDK_PROJECT_PATH =/home/robin/Desktop/wshare/jni

Step 2: Download ffmpeg source code

Step 3:
Create a folder jni and decompress the ffmpeg source code to the jni directory. The jni directory is required when ndk is used for compiling. Otherwise, an error occurs during compilation.
The directory structure after this step is as follows:

Ndk-build compiles the file in jni by default. If it cannot find the directory, it should be notified by setting NDK_PROJECT_PATH.
If the current working directory is in the jni directory or in the direct parent directory of jni, you do not need to set this macro.

Step 4:
Create the config_android.sh file in the ffmpeg directory and set the content as follows. You need to make changes based on the ndk directory of the local machine. Some parameters are required, and some parameters can be set as needed according to the application environment.

NDK_ROOT=/home/robin/Desktop/android-ndk-r7PREBUILT=${NDK_ROOT}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86PLATFORM=${NDK_ROOT}/platforms/android-14/arch-arm./configure --target-os=linux \--arch=arm \--enable-small \--enable-static \--disable-asm \--enable-armv5te \--enable-cross-compile \--disable-debug \--disable-doc \--disable-stripping \--disable-ffmpeg \--disable-ffplay \--disable-ffprobe \--disable-ffserver \--disable-encoders \--disable-muxers \--disable-devices \--disable-hwaccels \--disable-bsfs \--disable-protocols \--disable-avdevice \--disable-shared \--disable-filters \--disable-postproc \--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \--nm=$PREBUILT/bin/arm-linux-androideabi-nm \--extra-cflags="-fPIC -DANDROID" \--extra-ldflags='-L$PLATFORM/usr/lib -nostdlib' \echo "#undef restrict" >> config.hecho "#define restrict __restrict__" >> config.hecho "#undef HAVE_LRINT" >> config.hecho "#define HAVE_LRINT 1" >> config.hecho "#undef HAVE_LRINTF" >> config.hecho "#define HAVE_LRINTF 1" >> config.hecho "#undef HAVE_ROUND" >> config.hecho "#define HAVE_ROUND 1" >> config.hecho "#undef HAVE_ROUNDF" >> config.hecho "#define HAVE_ROUNDF 1" >> config.hecho "#undef HAVE_TRUNCF" >> config.hecho "#define HAVE_TRUNCF 1" >> config.h

 

Step 5:
Run./config_android.sh to start configuration.
If an error occurs during running, you can refer to config. log to learn the specific cause of the Error. Generally, the error occurs because the related directory is not correctly configured.
After configure is complete, edit the generated config. h and find this sentence.
# Define restrict
The GCC of Android does not support the restrict keyword, so it is changed to the following:
# Define restrict
Edit libavutil/libm. h and delete all static methods.
Available
# If 0
...
# Endif comment out

Step 6:
Modify Makefile in libavcodec, libavfilter, libavformat, libavutil, libpostproc, and libswscale, delete or comment out the following two sentences in each Makefile.
Include $ (SUBDIR) ../config. mak
Include $ (SRC_PATH)/subdir. mak

Step 7:
Add an av. mk file under ffmpeg. The content is as follows:

# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).makinclude $(LOCAL_PATH)/../config.makOBJS :=OBJS-yes :=MMX-OBJS-yes :=include $(LOCAL_PATH)/Makefile# collect objectsOBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)OBJS += $(OBJS-yes)FFNAME := lib$(NAME)FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))FFCFLAGS  = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-signFFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\"ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))ifneq ($(ALL_S_FILES),)ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))elseC_OBJS := $(OBJS)S_OBJS :=endifC_FILES := $(patsubst %.o,%.c,$(C_OBJS))S_FILES := $(patsubst %.o,%.S,$(S_OBJS))FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))

Step 8:
Add a series of Android. mk files in the jni directory as follows:
Include $ (all-subdir-makefiles)
In the ffmpeg directory, Android. mk contains the following content:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscaleLOCAL_MODULE := ffmpeginclude $(BUILD_SHARED_LIBRARY)include $(call all-makefiles-under,$(LOCAL_PATH))

Libavformat/Android. mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindexLOCAL_LDLIBS := -lzLOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

Libavcodec/Android. mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_LDLIBS := -lzLOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

The content of Android. mk in libavfilter, libavutil, libpostproc, and libswscale is as follows:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include $(LOCAL_PATH)/../av.mkLOCAL_SRC_FILES := $(FFFILES)LOCAL_C_INCLUDES :=        \    $(LOCAL_PATH)        \    $(LOCAL_PATH)/..LOCAL_CFLAGS += $(FFCFLAGS)LOCAL_STATIC_LIBRARIES := $(FFLIBS)LOCAL_MODULE := $(FFNAME)include $(BUILD_STATIC_LIBRARY)

Step 9:
Run ndk-build
After compilation, the compiler will create two folders libs and obj in the same directory of jni. The compilation output will be placed in these two folders.

Description of some Macros in Android. mk:
LOCAL_PATH: = $ (call my-dir)

The LOCAL_PATH variable must be defined in an Android. mk file. It is used to search for source files in the Development tree. In this example, the macro function 'my-dir ',
Provided by the compilation system, used to return the current path (that is, the directory containing the Android. mk file ).

Include $ (CLEAR_VARS)

CLEAR_VARS is provided by the compilation system, specifying that gnu makefile can clear many LOCAL_XXX variables for you (such as LOCAL_MODULE, LOCAL_SRC_FILES,
LOCAL_STATIC_LIBRARIES, etc ...),
Except LOCAL_PATH. This is necessary because all the compilation control files are in the same gnu make execution environment, and all the variables are global.

LOCAL_MODULE: = hello-jni

The target object to be compiled. The LOCAL_MODULE variable must be defined to identify each module you describe in the Android. mk file. The name must be unique and contain no spaces.

Note: The compilation system automatically generates the appropriate prefix and suffix. In other words, a shared library module named 'hello-jni 'will generate 'libello-jni. so 'file.

Important Notes:

If you name the library 'libello-jni ', the compilation system will not add any lib prefix or generate 'libello-jni. so' to support the library from the Android platform.
The Android. mk file in the source code, if you do need to do so.

LOCAL_SRC_FILES: = hello-jni.c

The LOCAL_SRC_FILES variable must contain the C or C ++ source code files to be compiled and packaged into the module. Note that you do not need to list header files and contained files here, because
The translation system will automatically find the dependent files for you; just list the source code files directly passed to the compiler.

Note: The default C ++ source code file extension is '. cpp'. It is also possible to specify a different extension, as long as the LOCAL_DEFAULT_CPP_EXTENSION variable is defined,
Do not forget the starting dot (that is, '. cxx', rather than 'cxx ')

Include $ (BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY indicates compiling and generating shared libraries. It is a variable provided by the compilation system and points to a GNU Makefile script to collect
Since 'include $ (CLEAR_VARS) ', it defines all information in the LOCAL_XXX variable and determines what to compile and how to do it correctly. And
BUILD_STATIC_LIBRARY variable indicates generating static library: lib $ (LOCAL_MODULE). a, BUILD_EXECUTABLE indicates generating executable files.

Refer:
Http://www.cnblogs.com/qq78292959/archive/2011/01/12/2076982.html
Http://www.cnblogs.com/hibraincol/archive/2011/05/30/2063847.html

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.