FFmpeg之硬解码

本文介绍了如何在Android上使用FFmpeg进行硬解码,特别是在FFmpeg 5.0.1版本下利用MediaCodec进行硬件加速解码。首先讲述了硬解码相较于软解码的优点和兼容性问题,然后详细阐述了编译支持硬解码FFmpeg的步骤,以及使用FFmpeg API配置和初始化硬解码器的过程。在实践中遇到的两个关键问题——设置JavaJVM和处理非NV12/NV21格式的AVFrame——也给出了解决方案。
摘要由CSDN通过智能技术生成

导读

    众所周知,软解码虽然兼容性一流,但是却非常依赖CPU,所以性能消耗笔记大;硬解码使用内置的DSP芯片进行解码,性能高,但是兼容性一般。

    虽说硬解码兼容性不太好,但是在实际开发中出于对性能的考虑我们依然会采用能硬解则硬解,不能硬解则软解兜底的方案。

    我们知道安卓上可以使用MediaCodec进行硬解码,新版本FFmpeg内部也支持了MediaCodec硬解码,今天我们就使用FFMpeg在安卓上使用MediaCodec进行硬解码。

笔者测试的FFmpeg版本是最新的5.0.1,不同版本之间可以会有差异。

编译支持硬解码的FFmpeg

要编译支持硬解码的FFmpeg,在进行交叉编译时我们只需要打开以下几个属性即可:

--enable-hwaccels \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-decoder=hevc_mediacodec \
--enable-decoder=mpeg4_mediacodec \
--enable-hwaccel=h264_mediacodec \

使用FFMpeg进行硬解码

使用FFmpeg无论是硬解码还是软解码流程都是差不多的,对使用FFmpeg编解码API不熟悉的童鞋们可以回看之前发表的博客文章...

在FFmpeg源文件hwcontext.c中我们可以看出mediacodec对应的type类型是AV_HWDEVICE_TYPE_MEDIACODEC,这个AV_HWDEVICE_TYPE_MEDIACODEC很重要, 在配置硬解码器时都是需要使用到这个type。

static const char *const hw_type_names[] = {
    [AV_HWDEVICE_TYPE_CUDA]   = "cuda",
    [AV_HWDEVICE_TYPE_DRM]    = "drm",
    [AV_HWDEVICE_TYPE_DXVA2]  = "dxva2",
    [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va",
    [AV_HWDEVICE_TYPE_OPENCL] = "opencl",
    [AV_HWDEVICE_TYPE_QSV]    = "qsv",
    [AV_HWDEVICE_TYPE_VAAPI]  = "vaapi",
    [AV_HWDEVICE_TYPE_VDPAU]  = "vdpau",
    [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox",
    [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec",
    [AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
};

下面说说在FFMpeg配置硬解码器的大体步骤:

1、给FFMpeg设置虚拟机环境

首先在库加载函数JNI_OnLoad中调用FFmpeg的函数av_jni_set_java_vm,给FFMpeg设置虚拟机环境:

// 类库加载时自动调用
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reversed) {
    JNIEnv *env = NULL;
    // 初始化JNIEnv
    if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return JNI_FALSE;
    }
​
    // 设置JavaVM,否则无法进行硬解码
    av_jni_set_java_vm(vm, nullptr);
    RegisterNativeMethods(env, "com/fly/ffmpeg/pra
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值