@[toc]

安卓 webrtc 开启 h264 软编解码

本文首发地址 https://blog.csdn.net/CSqingchen/article/details/120199702
最新更新地址 https://gitee.com/chenjim/chenjimblog
本文基于libmediasoupclient 3.2.0 和 webrtc branch-heads/4147(m84)
本文得熟悉相关基础,参考 文1文2
除了需要加编译参数 rtc_use_h264=true, 还需要以下修改以支持h264软编解码
网络搜索到的有很多复制、粘贴,缺少部分内容的,或者版本环境不匹配,很让人头疼。。。。
  1. 修改 ffmpeg_generated.gni 开启 openh264 编解码
    安卓平台默认未支持 h264 解码,会显示黑屏
    third_party/ffmpeg/ffmpeg_generated.gni 中我们可以开到,默认未支持安卓平台
    修改 ffmpeg_generated.gniuse_linux_config,添加 || is_android以支持,结果如下
    use_linux_config = is_linux || is_fuchsia || is_android
    参考自 https://www.codeleading.com/article/3215969775
    而对于软编解码,android webrtc采用openh264 +ffmpeg,这两块的代码都在webrtc源码src/third_party当中
  2. 增加 codec_list parser_list h264 支持
    third_party/ffmpeg/chromium/config/Chrome/android/arm64/libavcodec/parser_list.c 中添加 &ff_h264_parser,
    third_party/ffmpeg/chromium/config/Chrome/android/arm64/libavcodec/codec_list.c 中添加 &ff_h264_decoder,
    third_party/ffmpeg/chromium/config/下有 Chrome ChromeOS Chromium,这里用的是 Chrome,(其它可能有问题。。。)
    需要在编译参数添加 ffmpeg_branding="Chrome"
    这里路径 android/arm64 是需要配合参数 --arch "arm64-v8a",
    如果是 armeabi-v7a 需要同步修改目录 android/arm-neon/libavcodec下内容,
    最终编译参数参考:
    ./tools_webrtc/android/build_aar.py --extra-gn-args 'rtc_use_h264=true ffmpeg_branding="Chrome" rtc_enable_protobuf=false use_rtti=true use_custom_libcxx=false' --arch "arm64-v8a"
  3. 增加文件 LibH264Decoder.java
    复制 sdk/android/api/org/webrtc/LibvpxVp8Decoder.java为同目录 LibH264Decoder.java,修改后如下:

    package org.webrtc;
    public class LibH264Decoder extends WrappedNativeVideoDecoder {
      @Override
      public long createNativeVideoDecoder() {
     return nativeCreateDecoder();
      }
      static native long nativeCreateDecoder();
    }
  4. 增加文件 LibH264Encoder.java
    复制 sdk/android/api/org/webrtc/LibvpxVp8Encoder.java 为同目录 LibH264Encoder.java,修改后如下:

    package org.webrtc;
    public class LibH264Encoder extends WrappedNativeVideoEncoder {
      @Override
      public long createNativeVideoEncoder() {
     return nativeCreateEncoder();
      }
      static native long nativeCreateEncoder();
      @Override
      public boolean isHardwareEncoder() {return false;}
    }
    
  5. 增加 h264_codec.cc
    复制 sdk/android/src/jni/vp8_codec.cc 为同目录 h264_codec.cc,修改后如下:

    #include <jni.h>
    #include "modules/video_coding/codecs/h264/include/h264.h"
    #include "sdk/android/generated_libH264_jni/LibH264Decoder_jni.h"
    #include "sdk/android/generated_libH264_jni/LibH264Encoder_jni.h"
    #include "sdk/android/src/jni/jni_helpers.h"
    namespace webrtc {
    namespace jni {
    static jlong JNI_LibH264Encoder_CreateEncoder(JNIEnv* jni) {
      return jlongFromPointer(H264Encoder::Create().release());
    }
    static jlong JNI_LibH264Decoder_CreateDecoder(JNIEnv* jni) {
      return jlongFromPointer(H264Decoder::Create().release());
    }
    }  // namespace jni
    }  // namespace webrtc
  6. 修改H264 Create()
    添加上面要用到的 H264Encoder::Create(),修改 diff 如下:

    --- a/modules/video_coding/codecs/h264/h264.cc
    +++ b/modules/video_coding/codecs/h264/h264.cc
    @@ -84,6 +84,16 @@ std::vector<SdpVideoFormat> SupportedH264Codecs() {
                         "0")};
     }
    
    +std::unique_ptr<H264Encoder> H264Encoder::Create() {
  7. RTC_LOG(LS_INFO) << "Creating H264EncoderImpl.";
  8. return std::make_unique(cricket::VideoCodec("H264"));
    +#else
  9. RTC_NOTREACHED();
  10. return nullptr;
    +#endif
  11. }
    +
    std::unique_ptr H264Encoder::Create(
    const cricket::VideoCodec& codec) {
    RTC_DCHECK(H264Encoder::IsSupported());

    --- a/modules/video_coding/codecs/h264/include/h264.h
    +++ b/modules/video_coding/codecs/h264/include/h264.h
    @@ -43,6 +43,7 @@ std::vector SupportedH264Codecs();

    class RTC_EXPORT H264Encoder : public VideoEncoder {
    public:

  12. static std::unique_ptr Create();
    static std::unique_ptr Create(const cricket::VideoCodec& codec);
    // If H.264 is supported (any implementation).
    static bool IsSupported();

  13. 修改 sdk/android/BUILD.gn
    将其中 vp8 相关地方复制添加 h264 相关,我的一份修改 diff 如下,若编译有问题或者无效,需仔细核对此处。。。

    @@ -45,6 +45,7 @@ if (is_android) {
        ":java_audio_device_module_java",
        ":libjingle_peerconnection_java",
  14. ":libH264_java",

    ":libvpx_vp8_java",
    ":libvpx_vp9_java",
    ":logging_java",

    @@ -489,6 +490,20 @@ if (is_android) {
    ]
    }

  15. rtc_android_library("libH264_java") {
  16. visibility = [ "*" ]
  17. sources = [
  18. "api/org/webrtc/LibH264Decoder.java",
  19. "api/org/webrtc/LibH264Encoder.java",
  20. ]
  21. deps = [
  22. ":base_java",
  23. ":video_api_java",
  24. ":video_java",
  25. "//rtc_base:base_java",
  26. ]
  27. }
    +
    rtc_android_library("libvpx_vp9_java") {
    visibility = [ "*" ]
    sources = [
    @@ -512,6 +527,7 @@ if (is_android) {

    deps = [

    ":base_java",
  28. ":libH264_java",

    ":libvpx_vp8_java",
    ":libvpx_vp9_java",
    ":video_api_java",

    @@ -783,6 +799,18 @@ if (current_os == "linux" || is_android) {
    ]
    }

  29. rtc_library("libH264_jni") {
  30. visibility = [ "*" ]
  31. allow_poison = [ "software_video_codecs" ]
  32. sources = [ "src/jni/h264_codec.cc" ]
  33. deps = [
  34. ":base_jni",
  35. ":generated_libH264_jni",
  36. ":video_jni",
  37. "../../modules/video_coding:webrtc_h264",
  38. ]
  39. }
    +
    rtc_library("libvpx_vp9_jni") {
    visibility = [ "*" ]
    allow_poison = [ "software_video_codecs" ]
    @@ -799,6 +827,7 @@ if (current_os == "linux" || is_android) {
    visibility = [ "*" ]
    allow_poison = [ "software_video_codecs" ]
    deps = [
  40. ":libH264_jni",

    ":libvpx_vp8_jni",
    ":libvpx_vp9_jni",

    ]
    @@ -1203,6 +1232,16 @@ if (current_os == "linux" || is_android) {
    jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
    }

  41. generate_jni("generated_libH264_jni") {
  42. sources = [
  43. "api/org/webrtc/LibH264Decoder.java",
  44. "api/org/webrtc/LibH264Encoder.java",
  45. ]
    +
  46. namespace = "webrtc::jni"
  47. jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
  48. }
    +
    generate_jni("generated_libvpx_vp9_jni") {
    sources = [

    "api/org/webrtc/LibvpxVp9Decoder.java",
  49. 修改 SoftwareVideoDecoderFacoty.java 和 SoftwareVideoEncoderFacoty.java
    需要 分别注册 H.264 并添加创建 codec 的代码, 我的修改 DIFF 如下

    --- a/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java
    +++ b/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java
    @@ -26,6 +26,10 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory {
    @Nullable
    @Override
  50. if (codecType.getName().equalsIgnoreCase("H264")) {
  51. return new LibH264Decoder();
  52. }
    +
    if (codecType.getName().equalsIgnoreCase("VP8")) {

    return new LibvpxVp8Decoder();

    }
    @@ -45,6 +49,9 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory {
    List codecs = new ArrayList();

    codecs.add(new VideoCodecInfo("VP8", new HashMap<>()));
    +

  53. codecs.add(new VideoCodecInfo("H264", new HashMap<>()));
    +
    if (LibvpxVp9Decoder.nativeIsSupported()) {

    codecs.add(new VideoCodecInfo("VP9", new HashMap<>()));

    }

    --- a/sdk/android/api/org/webrtc/SoftwareVideoEncoderFactory.java
    +++ b/sdk/android/api/org/webrtc/SoftwareVideoEncoderFactory.java
    @@ -19,6 +19,9 @@ public class SoftwareVideoEncoderFactory implements VideoEncoderFactory {
    @Nullable
    @Override
    public VideoEncoder createEncoder(VideoCodecInfo info) {

  54. if (info.name.equalsIgnoreCase("H264")) {
  55. return new LibH264Encoder();
  56. }
    if (info.name.equalsIgnoreCase("VP8")) {

    return new LibvpxVp8Encoder();

    }
    @@ -38,6 +41,9 @@ public class SoftwareVideoEncoderFactory implements VideoEncoderFactory {
    List codecs = new ArrayList();

    codecs.add(new VideoCodecInfo("VP8", new HashMap<>()));
    +

  57. codecs.add(new VideoCodecInfo("H264", new HashMap<>()));
    +
    if (LibvpxVp9Encoder.nativeIsSupported()) {

    codecs.add(new VideoCodecInfo("VP9", new HashMap<>()));

    }

  58. 编译使用吧,祝好运。。。

本文参考自 webrtc M75支持android安卓H264软编解遇到的一些坑
在其基础补充、完善部分说明和详细修改结果,如有问题欢迎反馈


其它相关文档

标签: none

添加新评论