webrtc android h264 软解

编译

编译的时候可以指定这个参数

gn gen out/Debug --args='target_os="android" target_cpu="arm" rtc_use_h264=true \
ffmpeg_branding="Chrome" proprietary_codecs=true'

查看全部编译选项

gn args out/Debug --list

编译输出

ninja -C out/Debug

代码目录与分析

H264的编解码在这个目录下:

webrtc/modules/video_coding/codecs/h264

H264

h264_decoder_impl.cc

extern "C" {
#include "third_party/ffmpeg/libavcodec/avcodec.h"
#include "third_party/ffmpeg/libavformat/avformat.h"
#include "third_party/ffmpeg/libavutil/imgutils.h"
}  // extern "C"

h264_encoder_impl.cc

#include "third_party/openh264/src/codec/api/svc/codec_api.h"
#include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
#include "third_party/openh264/src/codec/api/svc/codec_def.h"

可以看到解码用了ffmpeg, 编码则是用了openh264。

细节逻辑看这两个文件 h264.cch264_decoder_impl.cc

阅读代码,可以知道,代码都已经集成进去了,没生效一定是那里没设置对。

webrtc-native 增加软解支持

我找到了一下讨论组,发现已经有人提出类似的问题,大概是这样的:

https://groups.google.com/forum/#!topic/discuss-webrtc/PmVjPiewEwM

也有人贴了他的解决办法(base at M67):

enable openh264 by set 'rtc_use_h264 = true ffmpeg_branding = "Chrome" ', after this you need modify  third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/libavcodec/parser_list.c and third_party/ffmpeg//chromium/config/Chrome/android/arm-neon/libavcodec/codec_list.c files, add h264 parse, like:

--- a/chromium/config/Chrome/android/arm-neon/libavcodec/parser_list.c
+++ b/chromium/config/Chrome/android/arm-neon/libavcodec/parser_list.c
@@ -4,4 +4,5 @@ static const AVCodecParser * const parser_list[] = {
     &ff_mpegaudio_parser,
     &ff_opus_parser,
     &ff_vorbis_parser,
+    &ff_h264_parser,
     NULL };

--- a/chromium/config/Chrome/android/arm-neon/libavcodec/codec_list.c
+++ b/chromium/config/Chrome/android/arm-neon/libavcodec/codec_list.c
@@ -13,4 +13,5 @@ static const AVCodec * const codec_list[] = {
     &ff_pcm_s32le_decoder,
     &ff_pcm_u8_decoder,
     &ff_libopus_decoder,
+    &ff_h264_decoder,
     NULL };

但是这个解码器还不能直接用,要给上层接口,所以应该还要通过jni封装到java层。
代码上看到VP8有类似的封装,应该有一点参考价值。

寻找这个思路,找到两篇比较接近问题的博客

  1. https://blog.csdn.net/foruok/article/details/69525039
  2. https://blog.dio.wtf/post/enable-h264-codec-for-webrtc

但是博客中有些信息比较含糊,要修改的parser_list.c codec_list.c config.h 的目录也错了。

webrtc M75 增加H264软解

基于这一篇博客做了修改:
https://blog.dio.wtf/post/enable-h264-codec-for-webrtc

FFmpeg 开启 H.264 软解

为 FFmpeg 开启 H.264 的编译选项,需要修改 third_party/ffmpeg 目录下的几个文件。

  1. third_party/ffmpeg/ffmpeg_generated.gni

可以看到许多编译选项,检查下,把包含H264的开关打开。

  1. third_party/ffmpeg/chromium/config/Chrome/{ABI}/config.h
// #define CONFIG_H264_DECODER 0
// 修改为:
#define CONFIG_H264_DECODER 1
  1. third_party/ffmpeg/chromium/config/Chrome/android/{ABI}/libavcodec/parser_list.c
    &ff_libopus_decoder,
// 增加 ff_h264_decoder
    &ff_h264_decoder,
    NULL };
  1. third_party/ffmpeg/chromium/config/Chrome/android/{ABI}/libavcodec/codec_list.c
     &ff_vorbis_parser,
// 增加 ff_h264_parser
    &ff_h264_parser,
    NULL };
  1. 参考上面的编译小节,重新编译一下。
封装JAVA层接口
  1. 参照 sdk/android/src/java/org/webrtc/VP8Decoder.java 和 sdk/android/src/java/org/webrtc/VP8Encoder.java 实现 H.264 的 Java 层 Wrapper
  2. 参照 sdk/android/jni/vp8codec.cc 实现 H.264 的 native 代码
    举个例子:
#include <jni.h>

#include "modules/video_coding/codecs/h264/include/h264.h"
#include "sdk/android/generated_libvpx_h264_jni/jni/LibvpxH264Decoder_jni.h"
#include "sdk/android/generated_libvpx_h264_jni/jni/LibvpxH264Encoder_jni.h"
#include "sdk/android/src/jni/jni_helpers.h"

namespace webrtc {
namespace jni {

static jlong JNI_LibvpxH264Encoder_CreateEncoder(JNIEnv* jni) {
  return jlongFromPointer(H264Encoder::Create(cricket::VideoCodec(96, "")).release());
}

static jlong JNI_LibvpxH264Decoder_CreateDecoder(JNIEnv* jni) {
  return jlongFromPointer(H264Decoder::Create().release());
}

}  // namespace jni
}  // namespace webrtc
  1. sdk/android/BUILD.gn 中分别添加 generate_jni 和 rtc_static_library 任务,并添加对应的 java 和 cpp 文件
  2. 在 sdk/android/api/org/webrtc/SoftwareVideoDecoderFacoty.java 和 sdk/android/api/org/webrtc/SoftwareVideoEncoderFacoty.java 中分别注册 H.264 并添加创建 codec 的代码

注:WebRTC Android JNI 接口的 C 层函数定义,都是通过 Python 脚本 base/android/jni_generator/jni_generator.py 生成的,生成的代码在 out/{destination}/gen/sdk/android/generated_xxx_jni/jni 目录下。我们需要通过第3步生成 H.264 的 JNI 函数,并在第四步中引用生成的头文件。

另注:我们在将 H.264 的软编(解)码添加到工厂类里时,需要传入一个 Map 作为参数。sdk/android/src/java/org/webrtc/H264Utils.java 提供了这些生成参数的方法。这里的参数会影响协商时生成的 SDP,要根据业务实现。

使用软解
final VideoEncoderFactory encoderFactory =
        new SoftwareVideoEncoderFactory();
        // new DefaultVideoEncoderFactory(eglBase.getEglBaseContext(), /*enableIntelVp8Encoder*/true,/*enableH264HighProfile*/false);
final VideoDecoderFactory decoderFactory =
        // new HardwareVideoDecoderFactory(eglBase.getEglBaseContext());
        new SoftwareVideoDecoderFactory();
        // new PlatformSoftwareVideoDecoderFactory(eglBase.getEglBaseContext());
        //new DefaultVideoDecoderFactory(eglBase.getEglBaseContext());
PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
final AudioDeviceModule adm = JavaAudioDeviceModule.builder(activity.getApplicationContext()
).setUseHardwareAcousticEchoCanceler(false
).setUseHardwareNoiseSuppressor(false
).setAudioRecordErrorCallback(new AudioRecordErrorCallbackAdapter()
).setAudioTrackErrorCallback(new AudioTrackErrorCallbackAdapter()
).createAudioDeviceModule();

参考资料:

  1. https://webrtc.org/native-code/android/
  2. https://blog.csdn.net/foruok/article/details/69525039
  3. https://blog.dio.wtf/post/enable-h264-codec-for-webrtc
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值