多语言展示
当前在线:674今日阅读:113今日分享:31

android下使ffmpeg使用mediacodec硬解

ffmpeg是一个开源的编码库,集成了许多优秀的编解码器,但是本身是基于C语言开发的,在android平台也想使用的话,需要花费多一些精力,如何在安卓下使用这个强大的编码库,让自己的APP拥有强大的视频编解码能力呢?以下将自己在编译的过程中所碰到的问题并分享给大家,可能不全,但希望可以帮到一些人
工具/原料

linux, ffmpeg, ndk

方法/步骤
1

准备工作从ffmpeg官网下载(http://ffmpeg.org/)源码(版本最好>3.1),这里介绍只使用ffmpeg提供的基本编解码功能,不外加其它需要单独编译的第三方库,但依然很强大,可以满足一般正常的使用

2

准备好交叉编译工具链和编译脚本在编译之前需要做一些修改,让生成的库可能让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)'参考脚本,具体编译链可以换成自己电脑的,编译选项也可以按实际自己要求去修改#!/bin/bashNDK=/root/android/android-ndk-r10/platforms/android-9/arch-arm/ SYSROOT=$NDK/platforms/android-16/arch-arm/ TOOLCHAIN=/root/android/android-ndk-r10/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 CPU=arm PREFIX=/root/ffmpeg-3.x.xADDI_CFLAGS='-marm' function build_one { ./configure \ --prefix=$PREFIX \--enable-shared \--disable-static \--disable-doc \--disable-ffmpeg \--disable-ffplay \--disable-ffprobe \--disable-ffserver \--disable-doc \--disable-symver \--enable-small \--enable-memalign-hack \--enable-jni \--enable-mediacodec \--enable-jni \--enable-mediacodec \--enable-decoder=h264_mediacodec \--enable-hwaccel=h264_mediacodec \--enable-decoder=hevc_mediacodec \--enable-decoder=mpeg4_mediacodec \--enable-decoder=vp8_mediacodec \--enable-decoder=vp9_mediacodec \--enable-gpl \--enable-nonfree \--enable-version3 \--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 make clean make -j8make install } build_one由于编解码库没作删减,编译时间可能要等一段时间,等待编译完成吧编译成功后,ffmpeg将会包含硬解功能,但要使用硬解还差几步

3

如何在android中使用视频硬解第一步:据官方文档介绍,需要在android的JNI_OnLoad()函数中调用extern 'C'{ #include  }av_jni_set_java_vm(vm, NULL);//初始化ffmpeg的jni代码第二步:当ffmpeg在获取到文件的流信息后,可以解析出视频所使用的解码器ID,根据这个解码器ID,将解码器直接换成'**_mediacode' 即可,如switch (pVideoCtx->codec_id) { case AV_CODEC_ID_H264: { pCodec = avcodec_find_decoder_by_name('h264_mediacodec'); break; } case AV_CODEC_ID_MPEG4: { pCodec = avcodec_find_decoder_by_name('mpeg4_mediacodec'); break; } } default: break; }至此,ffmpeg的使用跟普通场合的使用已经没有差别了第三步:据文档介绍,对安桌系统的版本也有要求,android自4.0推出mediacodec,但使用ffmpeg的mediacodec硬解要5.0以上的android才行,我在4.2和4.4的手机测试过,都不能硬解视频,最好找一个5.0以上的安卓设备测试

4

总结安卓的mediacodec的硬解在ffmpeg这种方式的使用下,虽然可以硬解,但是感觉这种传输机制还是太过于浪费资源,毕竟jni要这么频繁的传输这么多的视频数据,期间不但要传输数据、还要做视频转码、显示等操作,如果是实时显示的话,还是不太现实,最好还是直接在安卓直接实现好

注意事项
1

细节的地方可能会因为编译环境的不同,而有所区别

2

该经验方法仅供学习参考

推荐信息