The general idea is to create a static lame build (libmp3lame.a) using NDK, and then use it in the configuration and make scripts of ffmpeg, this way ffmpeg will recognize it a valid coder.
Its a little hackish, but its the only way that I managed to do it, I welcome anyone who can improve the process.
I used Ubuntu (had problems with cygwin) and NDK r5c, so I recommend this environment.
1. Follow the instructions to build ffmpeg using this post from halfninja (Thanks Ninja for the great guide!):
https://github.com/halfninja/android-ffmpeg-x264
2.
2.1 Download Lame version 3.98.4 from here (latest source didn't work for me):
http://sourceforge.net/projects/lame/files/lame/3.98.4/
2.2 Create libmp3lame directory in the jni folder and
2.3 Copy all sources from directory /3.98.4/libmp3lame to jni/libmp3lame directory. Also copy lame.h which is located in include directory of lame sources.
2.4 Edit file
2.6 Copy jni/libmp3lame/*.h to
4. Create Android.mk_lame as follows:
4.1
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mp3lame
LOCAL_SRC_FILES := libmp3lame/bitstream.c libmp3lame/fft.c libmp3lame/id3tag.c libmp3lame/mpglib_interface.c libmp3lame/presets.c libmp3lame/quantize.c libmp3lame/reservoir.c libmp3lame/tables.c libmp3lame/util.c libmp3lame/VbrTag.c libmp3lame/encoder.c libmp3lame/gain_analysis.c libmp3lame/lame.c libmp3lame/newmdct.c libmp3lame/psymodel.c libmp3lame/quantize_pvt.c libmp3lame/set_get.c libmp3lame/takehiro.c libmp3lame/vbrquantize.c libmp3lame/version.c
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := mp3lame_a
LOCAL_STATIC_LIBRARIES := mp3lame
include $(BUILD_EXECUTABLE)
4.2
cp Android.mk_lame Android.mk (rename the original to Android.mk.ffmpeg-x264)
5. call ndk-build to build only lame, this will produce an error, but will also produce libmp3lame.a in the objects directory.
6. copy libmp3lame.a to libmp3lame.
7.
7.1 Edit configure_ffmpeg.sh as follows:
#!/bin/bash
pushd `dirname $0`
. settings.sh
#arm v7n
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi= softfp -mfpu=neon -marm -march=$CPU -mtune=cortex-a8"
PREFIX=./android/$CPU
ADDITIONAL_CONFIGURE_FLAG=-- enable-neon
if [[ $minimal_featureset == 1 ]]; then
echo "Using minimal featureset"
featureflags="--disable- everything \
--enable-decoder=mjpeg --enable-demuxer=mjpeg --enable-parser=mjpeg \
--enable-demuxer=image2 --enable-muxer=mp4 --enable-encoder=libx264 --enable-libx264 \
--enable-decoder=rawvideo \
--enable-protocol=file \
--enable-hwaccels"
fi
if [[ $DEBUG == 1 ]]; then
echo "DEBUG = 1"
DEBUG_FLAG="--disable- stripping"
fi
pushd ffmpeg
./configure $DEBUG_FLAG --enable-cross-compile \
--arch=arm5te \
--enable-armv5te \
--target-os=linux \
--disable-stripping \
--prefix=../output \
--disable-neon \
--enable-version3 \
--disable-shared \
--enable-static \
--enable-gpl \
--enable-memalign-hack \
--cc=arm-linux-androideabi-gcc \
--ld=arm-linux-androideabi-ld \
--extra-cflags="-fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated" \
$featureflags \
--enable-libmp3lame \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-network \
--enable-filter=buffer \
--enable-filter=buffersink \
--disable-demuxer=v4l \
--disable-demuxer=v4l2 \
--disable-indev=v4l \
--disable-indev=v4l2 \
--extra-cflags="-I../x264 -I/home/ehasson/Downloads/ android-ffmpeg-x264/Project/ jni/libmp3lame -Ivideokit" \
--extra-ldflags="-L../x264 -L/home/ehasson/Downloads/ android-ffmpeg-x264/Project/ jni/libmp3lame"
popd; popd
7.2 correct --extra-cflags and --extra-ldflags to your correct full path.
8. call config_make_everything, this should take about 10mins
9. Edit Android.mk.ffmpeg-x264 as follows:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := videokit
# These need to be in the right order
FFMPEG_LIBS := $(addprefix ffmpeg/, \
libavdevice/libavdevice.a \
libavformat/libavformat.a \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswscale/libswscale.a \
libavutil/libavutil.a \
libpostproc/libpostproc.a )
# ffmpeg uses its own deprecated functions liberally, so turn off that annoying noise
LOCAL_CFLAGS += -g -Iffmpeg -Ivideokit -Wno-deprecated-declarations
LOCAL_LDLIBS += -llog -lz $(FFMPEG_LIBS) x264/libx264.a libmp3lame/libmp3lame.a
LOCAL_SRC_FILES := videokit/uk_co_halfninja_ videokit_Videokit.c videokit/ffmpeg.c videokit/cmdutils.c
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
FFMPEG_LIBS := $(addprefix ffmpeg/, \
libavdevice/libavdevice.a \
libavformat/libavformat.a \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswscale/libswscale.a \
libavutil/libavutil.a \
libpostproc/libpostproc.a )
LOCAL_CFLAGS += -g -Iffmpeg -Ivideokit -Wno-deprecated-declarations
LOCAL_LDLIBS += -llog -lz $(FFMPEG_LIBS) x264/libx264.a libmp3lame/libmp3lame.a
LOCAL_SRC_FILES := ffmpeg/ffmpeg.c ffmpeg/cmdutils.c
include $(BUILD_EXECUTABLE)
10. cp Android.mk.ffmpeg-x264 Android.mk
11 call ndk-build
12. the libvideokit.so that contains ffmpeg with libmp3lame should be in the lib directory.
Its a little hackish, but its the only way that I managed to do it, I welcome anyone who can improve the process.
I used Ubuntu (had problems with cygwin) and NDK r5c, so I recommend this environment.
1. Follow the instructions to build ffmpeg using this post from halfninja (Thanks Ninja for the great guide!):
https://github.com/halfninja/android-ffmpeg-x264
2.
2.1 Download Lame version 3.98.4 from here (latest source didn't work for me):
http://sourceforge.net/projects/lame/files/lame/3.98.4/
2.2 Create libmp3lame directory in the jni folder and
2.3 Copy all sources from directory /3.98.4/libmp3lame to jni/libmp3lame directory. Also copy lame.h which is located in include directory of lame sources.
2.4 Edit file
jni/utils.h
, and replace definition extern ieee754_float32_t fast_log2(ieee754_float32_t x);
with this extern float fast_log2(float x);
2.5 Create folder
jni/libmp3lame/lame2.6 Copy jni/libmp3lame/*.h to
jni/libmp3lame/lame4. Create Android.mk_lame as follows:
4.1
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mp3lame
LOCAL_SRC_FILES := libmp3lame/bitstream.c libmp3lame/fft.c libmp3lame/id3tag.c libmp3lame/mpglib_interface.c libmp3lame/presets.c libmp3lame/quantize.c libmp3lame/reservoir.c libmp3lame/tables.c libmp3lame/util.c libmp3lame/VbrTag.c libmp3lame/encoder.c libmp3lame/gain_analysis.c libmp3lame/lame.c libmp3lame/newmdct.c libmp3lame/psymodel.c libmp3lame/quantize_pvt.c libmp3lame/set_get.c libmp3lame/takehiro.c libmp3lame/vbrquantize.c libmp3lame/version.c
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := mp3lame_a
LOCAL_STATIC_LIBRARIES := mp3lame
include $(BUILD_EXECUTABLE)
4.2
cp Android.mk_lame Android.mk (rename the original to Android.mk.ffmpeg-x264)
5. call ndk-build to build only lame, this will produce an error, but will also produce libmp3lame.a in the objects directory.
6. copy libmp3lame.a to libmp3lame.
7.
7.1 Edit configure_ffmpeg.sh as follows:
#!/bin/bash
pushd `dirname $0`
. settings.sh
#arm v7n
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=
PREFIX=./android/$CPU
ADDITIONAL_CONFIGURE_FLAG=--
if [[ $minimal_featureset == 1 ]]; then
echo "Using minimal featureset"
featureflags="--disable-
--enable-decoder=mjpeg --enable-demuxer=mjpeg --enable-parser=mjpeg \
--enable-demuxer=image2 --enable-muxer=mp4 --enable-encoder=libx264 --enable-libx264 \
--enable-decoder=rawvideo \
--enable-protocol=file \
--enable-hwaccels"
fi
if [[ $DEBUG == 1 ]]; then
echo "DEBUG = 1"
DEBUG_FLAG="--disable-
fi
pushd ffmpeg
./configure $DEBUG_FLAG --enable-cross-compile \
--arch=arm5te \
--enable-armv5te \
--target-os=linux \
--disable-stripping \
--prefix=../output \
--disable-neon \
--enable-version3 \
--disable-shared \
--enable-static \
--enable-gpl \
--enable-memalign-hack \
--cc=arm-linux-androideabi-gcc \
--ld=arm-linux-androideabi-ld \
--extra-cflags="-fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated" \
$featureflags \
--enable-libmp3lame \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-network \
--enable-filter=buffer \
--enable-filter=buffersink \
--disable-demuxer=v4l \
--disable-demuxer=v4l2 \
--disable-indev=v4l \
--disable-indev=v4l2 \
--extra-cflags="-I../x264 -I/home/ehasson/Downloads/
--extra-ldflags="-L../x264 -L/home/ehasson/Downloads/
popd; popd
7.2 correct --extra-cflags and --extra-ldflags to your correct full path.
8. call config_make_everything, this should take about 10mins
9. Edit Android.mk.ffmpeg-x264 as follows:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := videokit
# These need to be in the right order
FFMPEG_LIBS := $(addprefix ffmpeg/, \
libavdevice/libavdevice.a \
libavformat/libavformat.a \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswscale/libswscale.a \
libavutil/libavutil.a \
libpostproc/libpostproc.a )
# ffmpeg uses its own deprecated functions liberally, so turn off that annoying noise
LOCAL_CFLAGS += -g -Iffmpeg -Ivideokit -Wno-deprecated-declarations
LOCAL_LDLIBS += -llog -lz $(FFMPEG_LIBS) x264/libx264.a libmp3lame/libmp3lame.a
LOCAL_SRC_FILES := videokit/uk_co_halfninja_
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
FFMPEG_LIBS := $(addprefix ffmpeg/, \
libavdevice/libavdevice.a \
libavformat/libavformat.a \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswscale/libswscale.a \
libavutil/libavutil.a \
libpostproc/libpostproc.a )
LOCAL_CFLAGS += -g -Iffmpeg -Ivideokit -Wno-deprecated-declarations
LOCAL_LDLIBS += -llog -lz $(FFMPEG_LIBS) x264/libx264.a libmp3lame/libmp3lame.a
LOCAL_SRC_FILES := ffmpeg/ffmpeg.c ffmpeg/cmdutils.c
include $(BUILD_EXECUTABLE)
10. cp Android.mk.ffmpeg-x264 Android.mk
11 call ndk-build
12. the libvideokit.so that contains ffmpeg with libmp3lame should be in the lib directory.