基于FFmpeg的经过Neon加速的可显示转码进度的安卓视频转码器

相关介绍

    之前因为项目需要做一个安卓视频转码器,之后在网上搜了很多相关的资料,之后找到雷神的相关博客,里面有一篇博客上就实现了安卓视频转码器,因此就拿来用了,但是由于里面有些功能没符合项目需求,所以我在其基础上进行了修改,主要添加了两项功能:转换过程中可显示转码进度;视频转码加速;下面就这两项功能实现过程作具体描述,顺便说句题外话,在这里非常感谢雷神所做的贡献。

转码进度功能实现

    在工程jni目录ffmpeg.h中添加添加typedef struct FFMFCContext {
long progress;
long media_duration;
long media_cur_time;
} FFMFCContext;结构体用来保存进度值,然后在jni下的ffmpeg_mod.c中的transcode_init函数中插入如下代码,计算转码估计总用时。基于FFmpeg的经过Neon加速的可显示转码进度的安卓视频转码器_第1张图片
    再在print_report函数下插入如下红色代码,最后ffmfcctx.progress中保存的就是
基于FFmpeg的经过Neon加速的可显示转码进度的安卓视频转码器_第2张图片基于FFmpeg的经过Neon加速的可显示转码进度的安卓视频转码器_第3张图片
    然后写好相关jni调用接口函数将该参数在安卓进度条中显示出来,具体见附件源代码。

Neon加速

    neon加速功能的实现其实就是一个编译ffmpeg库的过程,对于neon技术有疑问的同学可以自行在网上查找,有很多相关介绍。

编译环境说明

    相关软件:Ubuntu 15.10 + android-ndk-r9d-linux-x86_64+ ffmpeg 2.6.9+libfaac-1.28 +libx264

    下载地址:ffmpeg:https://ffmpeg.org/download.html

            Libfaac:http://www.audiocoding.com/downloads.html

              Libx264http://www.videolan.org/developers/x264.html

编译libx264

在linux下切换到libx264库文件目录下建立一个bash批处理文件内容如下,然后执行。
export NDK="/home/joechiang/android-ndk-r9d" 
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt  
export PLATFORM=$NDK/platforms/android-8/arch-arm  
export PREFIX=../android-lib  
./configure --prefix=$PREFIX --enable-static --enable-strip --enable-pic --disable-cli --host=arm-linux --cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi- --sysroot=$PLATFORM --extra-cflags="-march=armv7-a -mtune=cortex-a8 -mfloat-abi=softfp -mfpu=neon -D__ARM_ARCH_7__-D__ARM_ARCH_7A__" 
make
make install
其中NDK是指Android NDK软件解压所在目录,PREFIX是编译后目标文件所在目录,enable-static表示生成静态库,如果想打开neon功能必须有-march=armv7-a -mtune=cortex-a8 -mfloat-abi=softfp -mfpu=neon。

编译libfaac

在linux下切换到libfaac库文件目录下建立一个bash批处理文件内容如下,然后执行。
export NDK="/home/joechiang/android-ndk-r9d"  
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt  
export PLATFORM=$NDK/platforms/android-8/arch-arm  
CFLAGS="-fpic -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_7__ -Wno-psabi -march=armv7 -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,--noexecstack -MMD -MP "  
#CFLAGS="-fpic -DANDROID -fpic -mthumb-interwork -D__ARM_ARCH_7__ -Wno-psabi -march=armv7-a -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa, -MMD -MP "  
CROSS_COMPILE=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi-  
export CPPFLAGS="$CFLAGS"  
export CFLAGS="$CFLAGS"  
export CXXFLAGS="$CFLAGS"  
export CXX="${CROSS_COMPILE}g++ --sysroot=${PLATFORM}"  
export LDFLAGS="$LDFLAGS"  
export CC="${CROSS_COMPILE}gcc --sysroot=${PLATFORM}"  
export NM="${CROSS_COMPILE}nm"  
export STRIP="${CROSS_COMPILE}strip"  
export RANLIB="${CROSS_COMPILE}ranlib"  
export AR="${CROSS_COMPILE}ar"   
./configure --without-mp4v2 --host=arm-linux --enable-static 
make
make test
sudo make install  
cp -rf /usr/local/include/faac.h ../android-lib/include  
cp -rf /usr/local/include/faaccfg.h ../android-lib/include  
cp -rf /usr/local/lib/libfaac.a ../android-lib/lib

编译ffmpeg

(1)下载FFmpeg源代码之后,首先需要对源代码中的configure文件进行修改。由于编译出来的动态库文件名的版本号在.so之后(例如“libavcodec.so.5.100.1”),而android平台不能识别这样文件名,所以需要修改这种文件名。在ffmpeg库文件下的configure文件中找到下面几行代码:

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)'  
替换为下面内容
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'  
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'  
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'  
SLIB_INSTALL_LINKS='$(SLIBNAME)'

(2)linux下切换到到ffmpeg所在目录下建立一个bash批处理文件将libx264和libfaac一起编译到ffmpeg中
export NDK=/home/joechiang/android-ndk-r9d  
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt  
export PLATFORM=$NDK/platforms/android-8/arch-arm  
export PREFIX=../264fflib-fmeg2.6.9
 ./configure --target-os=linux --prefix=$PREFIX --arch=arm --cpu=armv7-a --enable-cross-compile --enable-runtime-cpudetect --arch=arm --cc=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi-gcc --cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi- --disable-stripping --nm=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi-nm --sysroot=$PLATFORM --enable-gpl --enable-shared --disable-static --enable-nonfree --enable-version3 --enable-small --disable-vda --disable-iconv --enable-libx264 --enable-libfaac --enable-encoder=libx264 --enable-encoder=libfaac --enable-zlib --disable-ffprobe --disable-ffplay --disable-ffmpeg --disable-ffserver --disable-debug --extra-cflags='-I ../android-lib/include -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a -mfpu=neon' --extra-ldflags='-L ../android-lib/lib'
make
make install
注意一下指令中../android-lib/就是libfaac和libx264编译后生成文件所在目录。
    至此,整个编译完毕,本文的编译指令仅供参考,如需缩减或增加ffmpeg的相关功能还需修改编译指令,编译完后只需将编译好的.so文件和头文件替换原工程中的相应.so和头文件,其余地方不用修改。

测试

  在华为荣耀3C上将同一视频转码成h264编码格式加速前的时间:5min,加速后需要的时间:1min 43seconds,可见加速效果还是很明显的。

附:

雷神博客:http://blog.csdn.net/leixiaohua1020/article/details/47056365
实现后的工程源码:http://download.csdn.net/detail/jiangzhuo18273176294/9822325

你可能感兴趣的:(基于FFmpeg的经过Neon加速的可显示转码进度的安卓视频转码器)