android webrtc学习三(开启ffmpeg解码和openH264编码)

   日期:2020-07-18     浏览:117    评论:0    
核心提示:相信大家伙在看其他开启ffmpeg或者开启webrtcH264软解的相关文档当中,基本都会看到这句话:打开third_party/ffmpeg/ffmpeg_generated.gni文件,把包含H264的开关打开基本上所有文章说了这句话之后就没然后了,开关打开怎么开也没有说明,甚至没有例子,对初学者非常不友好。在上一篇文章android webrtc学习二当中已经修改了硬编解码的白名单;而对于软编解码,android webrtc编码采用openh264,解码则使用ffmpeg,这两块的代码都在

相信大家伙在看其他开启ffmpeg或者开启webrtcH264软解的相关文档当中,基本都会看到这句话:

打开third_party/ffmpeg/ffmpeg_generated.gni文件,把包含H264的开关打开

基本上所有文章说了这句话之后就没然后了,开关打开怎么开也没有说明,甚至没有例子,对初学者非常不友好。

在上一篇文章android webrtc学习二当中已经修改了硬编解码的白名单;而对于软编解码,android webrtc编码采用openh264,解码则使用ffmpeg,这两块的代码都在webrtc源码src/third_party当中;开启步骤如下:

1、使rtc_use_h264最终返回值为true

打开src/webrtc.gni文件,搜索rtc_use_h264,可以看到原本是这么写的

rtc_use_h264 = proprietary_codecs && !is_android && !is_ios && !(is_win && !is_clang)

想要让rtc_use_h264最终返回true,就将!is_android去掉或者直接将rtc_use_h264值改为true;当只去掉!is_android判断后,那么这时候返回的值就取决于proprietary_codecs,而这个值通过全局搜索可以发现在 src/build/config/features.gni 文件当中定义了

proprietary_codecs = is_chrome_branded || is_chromecast

该值默认返回false,那么我们可以直接改为true,但考虑到该文件藏得有点深,并且也不太想改动这两个平台的判断,那么最终对该值的改动则在编译过程中添加 args="proprietary_codecs=true"进行设置即可。

2、修改src/third_party/ffmpeg/ffmpeg_generated.gni文件

找到并打开src/third_party/ffmpeg/ffmpeg_generated.gni,把包含H264的开关打开,大多的文章坑就在这里,以下则是我不断尝试最终实现效果的改法,搜索H264。

  • 修改1

if ((is_mac) || (is_win) || (use_linux_config)) {
ffmpeg_c_sources += [
“libavcodec/autorename_libavcodec_hpeldsp.c”,
“libavcodec/autorename_libavcodec_videodsp.c”,
“libavcodec/autorename_libavcodec_vp3dsp.c”,
“libavcodec/autorename_libavcodec_vp8dsp.c”,
“libavcodec/h264pred.c”,
“libavcodec/vp3.c”,
“libavcodec/vp3_parser.c”,
“libavcodec/vp56rac.c”,
“libavcodec/vp8.c”,
“libavcodec/vp8_parser.c”,
]
}

在判断条件当中添加|| (is_android)判断,如下:

if ((is_mac) || (is_win) || (use_linux_config) || (is_android)) {
ffmpeg_c_sources += [
“libavcodec/autorename_libavcodec_hpeldsp.c”,
“libavcodec/autorename_libavcodec_videodsp.c”,
“libavcodec/autorename_libavcodec_vp3dsp.c”,
“libavcodec/autorename_libavcodec_vp8dsp.c”,
“libavcodec/h264pred.c”,
“libavcodec/vp3.c”,
“libavcodec/vp3_parser.c”,
“libavcodec/vp56rac.c”,
“libavcodec/vp8.c”,
“libavcodec/vp8_parser.c”,
]
}

  • 修改2

if ((is_mac && ffmpeg_branding == “Chrome”) || (is_win && ffmpeg_branding == “Chrome”) || (use_linux_config && ffmpeg_branding == “Chrome”) || (use_linux_config && ffmpeg_branding == “ChromeOS”)) {
ffmpeg_c_sources += [
“libavcodec/cabac.c”,
“libavcodec/h2645_parse.c”,
“libavcodec/h264_cabac.c”,
“libavcodec/h264_cavlc.c”,
“libavcodec/h264_direct.c”,
“libavcodec/h264_loopfilter.c”,
“libavcodec/h264_mb.c”,
“libavcodec/h264_parse.c”,
“libavcodec/h264_parser.c”,
“libavcodec/h264_picture.c”,
“libavcodec/h264_ps.c”,
“libavcodec/h264_refs.c”,
“libavcodec/h264_sei.c”,
“libavcodec/h264_slice.c”,
“libavcodec/h264chroma.c”,
“libavcodec/h264data.c”,
“libavcodec/h264dec.c”,
“libavcodec/h264dsp.c”,
“libavcodec/h264idct.c”,
“libavcodec/h264qpel.c”,
“libavcodec/startcode.c”,
]
}

同理,在if条件里添加|| (is_android)判断

  • 修改3

if ((is_mac) || (is_win && current_cpu == “x64”) || (is_win && current_cpu == “x86”) || (use_linux_config && current_cpu == “x64”) || (use_linux_config && current_cpu == “x86”) || (is_android && current_cpu==“x86”)) {
ffmpeg_c_sources += [
“libavcodec/x86/autorename_libavcodec_x86_videodsp_init.c”,
“libavcodec/x86/h264_intrapred_init.c”,
“libavcodec/x86/hpeldsp_init.c”,
“libavcodec/x86/hpeldsp_vp3_init.c”,
“libavcodec/x86/vp3dsp_init.c”,
“libavcodec/x86/vp8dsp_init.c”,
]
ffmpeg_asm_sources += [
“libavcodec/x86/autorename_libavcodec_x86_videodsp.asm”,
“libavcodec/x86/fpel.asm”,
“libavcodec/x86/h264_intrapred.asm”,
“libavcodec/x86/h264_intrapred_10bit.asm”,
“libavcodec/x86/hpeldsp.asm”,
“libavcodec/x86/hpeldsp_vp3.asm”,
“libavcodec/x86/vp3dsp.asm”,
“libavcodec/x86/vp8dsp.asm”,
“libavcodec/x86/vp8dsp_loopfilter.asm”,
]
}

在if条件里添加:|| (is_android && current_cpu==“x64”)

  • 修改4

if ((use_linux_config && current_cpu == “arm” && arm_use_neon) || (use_linux_config && current_cpu == “arm”)) {
ffmpeg_c_sources += [
“libavcodec/arm/h264pred_init_arm.c”,
“libavcodec/arm/hpeldsp_init_arm.c”,
“libavcodec/arm/hpeldsp_init_armv6.c”,
“libavcodec/arm/videodsp_init_arm.c”,
“libavcodec/arm/videodsp_init_armv5te.c”,
“libavcodec/arm/vp3dsp_init_arm.c”,
“libavcodec/arm/vp8dsp_init_arm.c”,
“libavcodec/arm/vp8dsp_init_armv6.c”,
]
ffmpeg_gas_sources += [
“libavcodec/arm/hpeldsp_arm.S”,
“libavcodec/arm/hpeldsp_armv6.S”,
“libavcodec/arm/videodsp_armv5te.S”,
“libavcodec/arm/vp8_armv6.S”,
“libavcodec/arm/vp8dsp_armv6.S”,
]
}

在if条件里添加:|| (is_android && current_cpu == “arm”)

  • 修改5

if ((use_linux_config && current_cpu == “mips64el”) || (use_linux_config && current_cpu == “mipsel”)) {
ffmpeg_c_sources += [
“libavcodec/mips/autorename_libavcodec_mips_videodsp_init.c”,
“libavcodec/mips/h264pred_init_mips.c”,
“libavcodec/mips/hpeldsp_init_mips.c”,
“libavcodec/mips/vp3dsp_init_mips.c”,
“libavcodec/mips/vp8dsp_init_mips.c”,
]
}

在if条件里添加:|| (is_android && current_cpu == “mips64el”)

  • 修改6

if ((is_android && current_cpu == “arm64”) || (is_win && current_cpu == “arm64”) || (use_linux_config && current_cpu == “arm64”)) {
ffmpeg_c_sources += [
“libavcodec/aarch64/fft_init_aarch64.c”,
“libavcodec/aarch64/mpegaudiodsp_init.c”,
“libavcodec/aarch64/vorbisdsp_init.c”,
“libavutil/aarch64/cpu.c”,
“libavutil/aarch64/float_dsp_init.c”,
]
ffmpeg_gas_sources += [
“libavcodec/aarch64/autorename_libavcodec_aarch64_fft_neon.S”,
“libavcodec/aarch64/autorename_libavcodec_aarch64_mdct_neon.S”,
“libavcodec/aarch64/autorename_libavcodec_aarch64_vorbisdsp_neon.S”,
“libavcodec/aarch64/mpegaudiodsp_neon.S”,
“libavutil/aarch64/autorename_libavutil_aarch64_float_dsp_neon.S”,
]
}

在if条件里添加:|| (is_android && current_cpu == “arm64”)

  • 修改7

if ((is_win && current_cpu == “arm64”) || (use_linux_config && current_cpu == “arm64”)) {
ffmpeg_c_sources += [
“libavcodec/aarch64/h264pred_init.c”,
“libavcodec/aarch64/hpeldsp_init_aarch64.c”,
“libavcodec/aarch64/videodsp_init.c”,
“libavcodec/aarch64/vp8dsp_init_aarch64.c”,
]
ffmpeg_gas_sources += [
“libavcodec/aarch64/autorename_libavcodec_aarch64_h264pred_neon.S”,
“libavcodec/aarch64/autorename_libavcodec_aarch64_hpeldsp_neon.S”,
“libavcodec/aarch64/autorename_libavcodec_aarch64_vp8dsp_neon.S”,
“libavcodec/aarch64/videodsp.S”,
]
}

在if条件里添加:|| (is_android && current_cpu == “arm64”)

  • 修改8

if ((use_linux_config && current_cpu == “arm” && arm_use_neon && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “arm” && arm_use_neon && ffmpeg_branding == “ChromeOS”) || (use_linux_config && current_cpu == “arm” && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “arm” && ffmpeg_branding == “ChromeOS”)) {
ffmpeg_c_sources += [
“libavcodec/arm/h264chroma_init_arm.c”,
“libavcodec/arm/h264dsp_init_arm.c”,
“libavcodec/arm/h264qpel_init_arm.c”,
]
ffmpeg_gas_sources += [
“libavcodec/arm/startcode_armv6.S”,
]
}

在if条件里添加:|| (is_android && current_cpu == “arm” && arm_use_neon)

  • 修改9

if ((is_mac && ffmpeg_branding == “Chrome”) || (is_win && current_cpu == “x64” && ffmpeg_branding == “Chrome”) || (is_win && current_cpu == “x86” && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “x64” && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “x64” && ffmpeg_branding == “ChromeOS”) || (use_linux_config && current_cpu == “x86” && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “x86” && ffmpeg_branding == “ChromeOS”)) {
ffmpeg_c_sources += [
“libavcodec/x86/h264_qpel.c”,
“libavcodec/x86/h264chroma_init.c”,
“libavcodec/x86/h264dsp_init.c”,
]
ffmpeg_asm_sources += [
“libavcodec/x86/h264_chromamc.asm”,
“libavcodec/x86/h264_chromamc_10bit.asm”,
“libavcodec/x86/h264_deblock.asm”,
“libavcodec/x86/h264_deblock_10bit.asm”,
“libavcodec/x86/h264_idct.asm”,
“libavcodec/x86/h264_idct_10bit.asm”,
“libavcodec/x86/h264_qpel_10bit.asm”,
“libavcodec/x86/h264_qpel_8bit.asm”,
“libavcodec/x86/h264_weight.asm”,
“libavcodec/x86/h264_weight_10bit.asm”,
“libavcodec/x86/qpel.asm”,
]
}

在if条件里添加:|| (is_android && current_cpu == “x64”) || (is_android && current_cpu == “x86”)

  • 修改10

if ((use_linux_config && current_cpu == “mips64el” && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “mips64el” && ffmpeg_branding == “ChromeOS”) || (use_linux_config && current_cpu == “mipsel” && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “mipsel” && ffmpeg_branding == “ChromeOS”)) {
ffmpeg_c_sources += [
“libavcodec/mips/h264chroma_init_mips.c”,
“libavcodec/mips/h264dsp_init_mips.c”,
“libavcodec/mips/h264qpel_init_mips.c”,
]
}

在if条件里添加:|| (is_android && current_cpu == “mips64el”) || (is_android && current_cpu == “mipsel”)

  • 修改11

if ((is_win && current_cpu == “arm64” && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “arm64” && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “arm64” && ffmpeg_branding == “ChromeOS”)) {
ffmpeg_c_sources += [
“libavcodec/aarch64/h264chroma_init_aarch64.c”,
“libavcodec/aarch64/h264dsp_init_aarch64.c”,
“libavcodec/aarch64/h264qpel_init_aarch64.c”,
]
ffmpeg_gas_sources += [
“libavcodec/aarch64/autorename_libavcodec_aarch64_h264cmc_neon.S”,
“libavcodec/aarch64/autorename_libavcodec_aarch64_h264dsp_neon.S”,
“libavcodec/aarch64/autorename_libavcodec_aarch64_h264idct_neon.S”,
“libavcodec/aarch64/autorename_libavcodec_aarch64_h264qpel_neon.S”,
]
}

在if条件里添加: || (is_android && current_cpu == “arm64”)

-修改12

if (use_linux_config && current_cpu == “arm” && arm_use_neon) {
ffmpeg_c_sources += [
“libavcodec/arm/hpeldsp_init_neon.c”,
“libavcodec/arm/vp8dsp_init_neon.c”,
]
ffmpeg_gas_sources += [
“libavcodec/arm/h264pred_neon.S”,
“libavcodec/arm/hpeldsp_neon.S”,
“libavcodec/arm/vp3dsp_neon.S”,
“libavcodec/arm/vp8dsp_neon.S”,
]
}

在if条件里添加:|| (is_android && current_cpu == “arm” && arm_use_neon)

  • 修改13

if ((use_linux_config && current_cpu == “arm” && arm_use_neon && ffmpeg_branding == “Chrome”) || (use_linux_config && current_cpu == “arm” && arm_use_neon && ffmpeg_branding == “ChromeOS”)) {
ffmpeg_gas_sources += [
“libavcodec/arm/h264cmc_neon.S”,
“libavcodec/arm/h264dsp_neon.S”,
“libavcodec/arm/h264idct_neon.S”,
“libavcodec/arm/h264qpel_neon.S”,
]
}

在if条件里添加:|| (is_android && current_cpu == “arm” && arm_use_neon)

3、添加静态编译

找到src/third_party/ffmpeg/chromium/config/Chromium/android/{ABI}/libavcodec/codec_list.c和
src/third_party/ffmpeg/chromium/config/Chromium/android/{ABI}/libavcodec/parser_list.c;分别添加&ff_h264_decoder,和&ff_h264_parser,,如下:

4、修改宏定义

打开文件src/third_party/ffmpeg/chromium/config/Chromium/android/{ABI}/config.h,搜索CONFIG_H264_DECODER,将该值改成1

5、添加licenses

打开src/tools_webrtc/libs/generate_licences,找到LIB_TO_LICENSES_DICT节点,添加
‘openh264’:[‘third_party/openh264/src/LICENSE’],
‘ffmpeg’:[‘third_party/ffmpeg/LICENSE.md’],

6、实现jni和java层

以上四大步骤操作完毕之后,已经将h264编解码器集成到webrtc当中了,接下来模仿vp8或者vp9实现jni和java层
进入src/sdk/android/jni文件夹,创建h264_codec.cc文件

#include <jni.h>
#include “modules/video_coding/codecs/h264/include/h264.h”
#include “sdk/android/generated_h264_jni/H264Decoder_jni.h”
#include “sdk/android/generated_h264_jni/H264Encoder_jni.h”
#include “sdk/android/src/jni/jni_helpers.h”
namespace webrtc {
namespace jni {
static jlong JNI_H264Encoder_CreateEncoder(JNIEnv* jni) {
return jlongFromPointer(H264Encoder::Create(cricket::VideoCodec(cricket::kH264CodecName)).release());
}
static jboolean JNI_H264Encoder_IsSupported(JNIEnv* jni) {
return !SupportedH264Codecs().empty();
}
static jlong JNI_H264Decoder_CreateDecoder(JNIEnv* jni) {
return jlongFromPointer(H264Decoder::Create().release());
}
static jboolean JNI_H264Decoder_IsSupported(JNIEnv* jni) {
return !SupportedH264Codecs().empty();
}
}
}

进入src/sdk/android/api/org/webrtc文件夹,模仿LibvpxVp9Decoder.java和LibvpxVp9Encoder.java编写H264Decoder.java和H264Encoder.java类

7、添加H264编译脚本

打开src/sdk/android/BUILD.gn文件,搜索vp9,模仿vp9写出h264的编译脚本,如下





8、编译

  • 编译jar和so包

gn gen out/release/arm64-v8a --args=‘target_os=“android” target_cpu=“arm64” proprietary_codecs=true use_openh264=true’

ninja -C out/release/arm64-v8a

  • 编译aar包,将rtc_use_h264直接改为true
    在src目录下执行

./tools_webrtc/android/build_aar.py --build-dir out --arch “armeabi-v7a”

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服