android下使ffmpeg使用mediacodec硬解

2025-10-09 06:07:00

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/bash

NDK=/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.x

ADDI_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 -j8

make install 

build_one

由于编解码库没作删减,编译时间可能要等一段时间,等待编译完成吧

编译成功后,ffmpeg将会包含硬解功能,但要使用硬解还差几步

3、如何在android中使用视频硬解

第一步:据官方文档介绍,需要在android的JNI_OnLoad()函数中调用

extern "C"{ 

#include <libavcodec/jni.h> 

}

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要这么频繁的传输这么多的视频数据,期间不但要传输数据、还要做视频转码、显示等操作,如果是实时显示的话,还是不太现实,最好还是直接在安卓直接实现好

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢