android下使ffmpeg使用mediacodec硬解

 时间:2026-02-15 12:58:59

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

  • QQ音乐怎么开启或关闭通知栏音乐播放器
  • 激励孩子学习的方法
  • 掏耳朵要将棉签头拽蓬松
  • 肾病综合征可吃的三类食物
  • 圣诞香料热红酒
  • 热门搜索
    ppp项目是什么意思 下巴反复长痘痘是什么原因 什么是安全期 什么减肥产品最有效 fear什么意思 sunshine什么意思 会签是什么意思 棕色是什么颜色 再给我两分钟是什么歌 icp是什么