移植ffplay媒体播放器和sdl2到Android平台

前言

前述博文《基于FFmpeg和Android的音视频同步播放实现》中,我们按照自己的方法实现了一个简单的媒体播放器,并做了音视频同步。但是这个程序在播放更多码流时,遇到了一些问题,包括视频解码问题,同步时视频卡顿等。我们在博文《在ubuntu16.04下测试ffplay程序》中也测试过ffplay这个强大的播放器,而我们也知道SDL基于Android平台也有支持,所以我们可以将ffplay和sdl移植到Android平台上来。

主要工作

  1. 编译FFmpeg的Android平台动态库,以实现视频解码;
  2. 编译SDL2的Android平台动态库,以支持对视频显示和音频播放的芯片支持;
  3. 移植ffplay程序到Android平台,以实现一个基本的媒体播放器;
    FFmpeg和ffplay都在native层实现或编译,SDL2一部分在native层编译,另一部分平台依赖需要在java层实现,当然,SDL2均提供了参考代码。

源代码版本

FFmpeg基于当前最新的4.0.1版本;
SDL2基于当前最新的SDL2-2.0.8版本;
ffplay也是基于FFmpeg4.0.1附带的源码;

编译libffmpeg.so

FFmpeg库的编译基于android-ndk-r14b在Ubuntu下编译,注意采用standalone_toolchain的编译链,可以参考https://blog.csdn.net/ericbar/article/details/80229592 , ndk采用r14b而没有采用最新的版本,因为从r15b版本开始,FFmpeg代码中引用stderr等标准输入输出函数会找不到。
config.sh和make.sh需要做些修改,分别参考如下,

#!/bin/bash

FFMPEG_SRC_PATH=$(cd `dirname $0`; pwd)


SYSROOT=/home/ffmpeg/work/toolchain/android/linux-x86_64/ndk-r14/android-19/arm/sysroot
LIBPATH=/home/ffmpeg/work/toolchain/android/linux-x86_64/ndk-r14/android-19/arm/sysroot/usr/lib
TOOLCHAIN=/home/ffmpeg/work/toolchain/android/linux-x86_64/ndk-r14/android-19/arm


export PATH=$TOOLCHAIN/bin:$PATH
export CROSS_PREFIX=arm-linux-androideabi-
export CC="${CROSS_PREFIX}gcc "
export CXX=${CROSS_PREFIX}g++
export LD=${CROSS_PREFIX}ld
export AR=${CROSS_PREFIX}ar
export STRIP=${CROSS_PREFIX}strip

LDFLAGS="-lm -lz -Wl,-soname=libffmpeg.so,-z,noexecstack"


PREFIX=ffout
ADDI_CFLAGS="-marm"

echo " "
echo "please wait..."
echo " "

#cd $FFMPEG_SRC_PATH
rm ./$PREFIX -rf
make clean

echo " "
echo "preparing to configure..."
echo " "

./configure \
    --prefix=$PREFIX \
    --enable-shared \
    --disable-static \
    --disable-doc \
    --disable-ffmpeg \
    --disable-ffprobe \
    --disable-doc \
    --disable-symver \
    --disable-programs \
    --disable-w32threads \
    --disable-os2threads \
    --disable-sdl2 \
    --tempprefix=$FFMPEG_SRC_PATH \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --target-os=linux  \
    --arch=arm \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG

#   --sysinclude=$SYSROOT \

下面make.sh里,需要把avdevice下的.o库链接添加进来,

#!/bin/bash

FFMPEG_SRC_PATH=$(cd `dirname $0`; pwd)

SYSROOT=/home/ffmpeg/work/toolchain/android/linux-x86_64/ndk-r14/android-19/arm/sysroot
LIBPATH=/home/ffmpeg/work/toolchain/android/linux-x86_64/ndk-r14/android-19/arm/sysroot/usr/lib
TOOLCHAIN=/home/ffmpeg/work/toolchain/android/linux-x86_64/ndk-r14/android-19/arm

export TMPDIR=$FFMPEG_SRC_PATH
export PATH=$TOOLCHAIN/bin:$PATH
export CROSS_PREFIX=arm-linux-androideabi-
export CC="$CCACHE ${CROSS_PREFIX}gcc "
export CXX=${CROSS_PREFIX}g++
export LD=${CROSS_PREFIX}ld
export AR=${CROSS_PREFIX}ar
export STRIP=${CROSS_PREFIX}strip

LDFLAGS="-lm -lz -Wl,-soname=libffmpeg.so,-z,noexecstack"

CPU=arm
PREFIX=ffout
ADDI_CFLAGS="-marm"

#make -j${NUMBER_OF_CORES} && make install || exit 1
make -j4 && make install || exit 1

rm  libavcodec/reverse.o libavcodec/log2_tab.o libavformat/log2_tab.o libavformat/golomb_tab.o \
    libswresample/log2_tab.o libavfilter/log2_tab.o libswscale/log2_tab.o libavdevice/reverse.o

$CC -o $PREFIX/libffmpeg.so -shared $LDFLAGS $EXTRA_LDFLAGS --sysroot=$SYSROOT -L $LIBPATH \
    libavutil/*.o libavutil/arm/*.o libavcodec/*.o libavcodec/arm/*.o  \
    libavformat/*.o libavfilter/*.o libswresample/*.o libswresample/arm/*.o \
    libswscale/*.o libswscale/arm/*.o compat/*.o libavdevice/*.o

cp $PREFIX/libffmpeg.so $PREFIX/libffmpeg-debug.so
${STRIP} --strip-unneeded $PREFIX/libffmpeg.so

编译SDL2库

我们下载SDL2-2.0.8源码后,解压缩,直接进入SDL2-2.0.8目录,首先需要设置NDK的环境变量,这里注意NDK不要采用类似FFmpeg编译的standalone_toolchain方式,采用从Google官网下载的原始版本解压缩即可,版本的话,使用android-ndk-r16b即可,参考下述命令即可启动编译,

export ANDROID_NDK_HOME=/home/ffmpeg/work/android-ndk-r16b
export PATH=$ANDROID_NDK_HOME:$PATH
ndk-build -B NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk

最后在SDL2-2.0.8\libs\armeabi-v7a下会生成libSDL2.so库。

移植ffplay

ffplay程序基于eclipse来编译,其中eclipse的ndk版本采用android-ndk-r13b;主要是一些头文件依赖和编译警告,需要做一些适当的调整和修正。

SDL2的java层适配

SDL2的源码里提供了相关参考,我们直接搬过来就行,代码路径位于,
SDL2-2.0.8\android-project\app\src\main\java\org\libsdl\app
当然,我们需要做一点修改,主要有如下几点:
1. SDLActivity.java中,主程序(main函数)所在的so库名是libfflay.so而不是libmain.so,这个是我在创建工程时选的so名字,所以要修改过来,大家可以根据自己实际名字修改。
2. SDLActivity.java中,加载的so库,由main修改成ffmpeg和ffplay;
3. SDLActivity.java中,native层启动的主程序名由SDL_main改成start,注意我们这里把ffplay源码里的main函数改成了start函数;

GitHub源码

代码修改部分比较琐碎,这里不一一讲述,媒体播放url在ffplay.c的input_filename全局变量初始化时直接赋值。

请参考完整的源码路径:
https://github.com/ericbars/ffplay

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值