webrtc-m79-msvc编译H264

0 写在前面

本文主要参考:webrtc 4577版本vs编译_tusong86的博客-CSDN博客

4577也就是m93,由于源码版本的不同,可能存在一定的出入,可根据实际情况进行修改;

感谢作者的付出;

1 编译参数

powershell运行:

// debug 需要编译参数 enable_iterator_debugging=true

gn gen h264-debug-m79 --args='is_debug=true use_lld=false is_clang=false treat_warnings_as_errors=false use_custom_libcxx=false is_component_build=false use_rtti=true rtc_enable_protobuf=false rtc_build_examples=true enable_iterator_debugging=true rtc_use_h264=true use_openh264=true ffmpeg_branding=\"Chrome\" proprietary_codecs=true' --ide=vs2019

查看参数是否生效:

gn args h264-debug-m79 --list=rtc_use_h264

gn args h264-debug-m79 --list=use_openh264

//release 不需要编译参数 enable_iterator_debugging=true

gn gen h264-release-m79 --args='is_debug=false use_lld=false is_clang=false treat_warnings_as_errors=false use_custom_libcxx=false is_component_build=false use_rtti=true rtc_enable_protobuf=false rtc_build_examples=true rtc_use_h264=true use_openh264=true ffmpeg_branding=\"Chrome\" proprietary_codecs=true' --ide=vs2019

查看参数是否生效:

gn args h264-release-m79 --list=rtc_use_h264

gn args h264-release-m79 --list=use_openh264

为了避免下面2.3小节的问题,需要将webrtc的编译参数修改为MD(d),具体修改如下所示:

2 编译错误以及修复

2.1 错误一

解决方案:

注释掉代码:

See: bugs.webrtc.org/9213#c13

具体修改如下图:

2.2 错误二

解决方案:

注释掉\third_party\ffmpeg\libavcodec\pcm.c的最后一行,具体如下图:

2.3 错误三

2.3.1 问题描述

解决此问题需要使用自己MSVC编译的x64 ffmpeg动态库,如何编译ffmpeg的动态库可以采用参考链接[2],自己在尝试的过程中遇到了一些问题:

(1)在编译ffmpeg时采用MT(d)进行编译时出现了很多问题,所以编译ffmpeg还是使用MD(d)方式,但是呢webrtc默认编译的是MT(d),所以需要将webrtc修改为MD(d),修改方式具体见前面;

(2)在使用ffmpeg_deps.sln生成库时,务必选择编译动态库,在使用ffmpeg静态库时则会出现符号重定义的问题,具体如下:

原因就是webrtc所依赖的第三方库中也使用了libvp8(highbd_variance_sse2.obj),而ffmpeg的静态库libavcodec.lib中也包含了highbd_variance_sse2.obj的定义,因此出现了冲突,论据如下:

webrtc中的证据:

2.3.2 解决步骤

假设已经准备好了ffmpeg的动态库,后续的步骤主要如下:

2.3.2.1 拷贝文件

将ffmpeg_deps.sln生成的如下图中的文件拷贝到webrtc的指定目录,具体如下:

D:\webrtc-checkout\src\third_party\ffmpeg_smp_release_x64目录是新创建的,为的就是与之前的ffmpeg区别开来;

拷贝动态库文件

拷贝头文件

2.3.2.2 修改gn文件

修改D:\webrtc-checkout\src\modules\video_coding\BUILD.gn文件

修改内容罗列如下:

rtc_static_library("webrtc_h264") {
  visibility = [ "*" ]
  sources = [
    "codecs/h264/h264.cc",
    "codecs/h264/h264_color_space.cc",
    "codecs/h264/h264_color_space.h",
    "codecs/h264/h264_decoder_impl.cc",
    "codecs/h264/h264_decoder_impl.h",
    "codecs/h264/h264_encoder_impl.cc",
    "codecs/h264/h264_encoder_impl.h",
    "codecs/h264/include/h264.h",
  ]

  if (!is_clang) {
  #设置头文件路径
    include_dirs = [ "//third_party/ffmpeg_smp_release_x64/include" ]
    libs = [
   # 设置引用库
       "//third_party/ffmpeg_smp_release_x64/bin/avcodec.lib",
       "//third_party/ffmpeg_smp_release_x64/bin/avdevice.lib",
       "//third_party/ffmpeg_smp_release_x64/bin/avfilter.lib",
       "//third_party/ffmpeg_smp_release_x64/bin/avformat.lib",
       "//third_party/ffmpeg_smp_release_x64/bin/avutil.lib",
       "//third_party/ffmpeg_smp_release_x64/bin/swresample.lib",
       "//third_party/ffmpeg_smp_release_x64/bin/swscale.lib",
    ]
  }

  defines = []
  deps = [
    ":video_codec_interface",
    ":video_coding_utility",
    "../../api/video:video_frame",
    "../../api/video:video_frame_i010",
    "../../api/video:video_frame_i420",
    "../../api/video:video_rtp_headers",
    "../../api/video_codecs:video_codecs_api",
    "../../common_video",
    "../../media:rtc_h264_profile_id",
    "../../media:rtc_media_base",
    "../../rtc_base",
    "../../rtc_base:checks",
    "../../rtc_base/system:rtc_export",
    "../../system_wrappers:field_trial",
    "../../system_wrappers:metrics",
    "//third_party/abseil-cpp/absl/strings",
    "//third_party/abseil-cpp/absl/types:optional",
    "//third_party/libyuv",
  ]

  if (rtc_use_h264) {
    deps += [
      #"//third_party/ffmpeg",
      "//third_party/openh264:encoder",
    ]
    if (!build_with_mozilla) {
      deps += [ "../../media:rtc_media_base" ]
    }
  }
}

截止到这里虽然可以编译成功了,但是还有其他的问题,虽然这里替换成了自己编译的ffmpeg的x64动态库,但是webrtc的代码中所引用的头文件还是之前的ffmpeg的路径,如果不修改在运行的时候就会出现崩溃,所以还需要修改源码,具体见2.3.2.3小节;

2.3.2.3 修改webrtc源码中对ffmpeg头文件的引用

至此就可以编译通过所有的exe,但是还不可以使用peerconnection_client.exe验证H264的功能,需要修改SDP来提高H264的优先级;

注意:

由于自己所使用的ffmpeg版本问题(相较于webrtc-m79的代码来说ffmpeg的版本太新了),还出现了avcodec_find_decoder的问题,由于avcodec_find_decoder现在返回的是const AVCodec*,而webrtc-m79中没有进行强制类型转换导致编译错误,需要进行一个简单的修改即可:

AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);

修改为:

AVCodec* codec = const_cast<AVCodec*>(avcodec_find_decoder(av_context_->codec_id));

3 提高H264优先级

修改后的代码如下:

std::vector<SdpVideoFormat> InternalEncoderFactory::GetSupportedFormats()const {std::vector<SdpVideoFormat> supported_codecs;for (const webrtc::SdpVideoFormat& format : webrtc::SupportedH264Codecs())supported_codecs.push_back(format);supported_codecs.push_back(SdpVideoFormat(cricket::kVp8CodecName));for (const webrtc::SdpVideoFormat& format : webrtc::SupportedVP9Codecs())supported_codecs.push_back(format);return supported_codecs;
}

4 两个peerconnection_client进行验证

运行peerconnection_client.exe,别忘了拷贝其所依赖的动态库:

测试效果如下:

5 web端与peerconnection_client测试

若使用web与peerconnection_client进行测试,则需要注意,若web端发送offer来启动媒体协商过程,此时传输的仍然是VP8编码,原因是:

web端offer中描述自己最高优先接收的是VP8,接收offer的peerconnection_client端会在WebRtcVideoChannel::GetChangedSendParameters中通过调用SelectSendVideoCodecs来对比自己能提供的编码和offer期望的编码,会优先匹配offer中具有较高优先级的VP8编码,在自己修改的代码中InternalEncoderFactory::GetSupportedFormats中只是将H264的优先级提高了而已(((这个H264优先级的提高在本端作为offer端的时候可以让对端优先匹配该编码))),后面又加上了对VP8和VP9的支持,所以当offer端最高优先级的VP8能在对端被支持的时候,就会优先选择VP8格式来匹配offer端;也正是这个原因在使用两个peerconnection_client进行测试的时候不会出现这个问题,因为二者都是将接收H264设置为最高优先级;

当然若peerconnection_client.exe发送offer来启动媒体协商过程就不存在这个问题了,因为H264就是它的最高优先级接收的视频编码格式。

参考链接

[1] webrtc 4577版本vs编译_tusong86的博客-CSDN博客

[2] 创建ffmpeg vs2019工程_hclbeloved的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/113110.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【git】Idea撤回本地分支、或远程分支提交记录的各种实际场景操作步骤

文章目录 idea撤回本地分支、远程分支场景操作集合场景1&#xff1a;要撤回最后一次本地分支的提交实现效果&#xff1a;操作步骤&#xff1a; 场景2&#xff1a;要撤回最后一次远程分支的提交有撤销记录的&#xff1a;实现效果&#xff1a;操作步骤&#xff1a; 无撤销记录的&…

数据分析基础-数据可视化学习笔记03-可视化的符号与表示-图形符号学

概念 图型符号学&#xff08;Cartographic Symbolization&#xff09;是地图学领域中的一个重要概念&#xff0c;涉及到如何使用不同的符号、颜色、图案和标记来在地图上表示地理信息和数据。图型符号学旨在传达地理信息&#xff0c;使得地图能够清晰、有效地传达各种空间数据…

微信小程序scroll-view隐藏滚动条参数不生效问题

如题&#xff0c;先来看看问题是怎么出现的。 先看文档如何隐藏滚动条&#xff1a; 再根据文档实现wxml文件&#xff1a; <scroll-view show-scrollbar"{{false}}" enhanced><view wx:for"{{1000}}">11111</view> </scroll-view>…

pytorch异常——RuntimeError:Given groups=1, weight of size..., expected of...

文章目录 省流异常报错异常截图异常代码原因解释修正代码执行结果 省流 nn.Conv2d 需要的输入张量格式为 (batch_size, channels, height, width)&#xff0c;但您的示例输入张量 x 是 (batch_size, height, width, channels)。因此&#xff0c;需要对输入张量进行转置。 注意…

探索未知世界:桌面端3D GIS引领地理信息新时代

近年来&#xff0c;桌面端的三维地理信息系统&#xff08;3D GIS&#xff09;在地理信息领域迎来了显著的发展&#xff0c;为我们带来了更深入、更丰富的地理空间认知和数据分析体验。从城市规划到环境保护&#xff0c;从资源管理到应急响应&#xff0c;桌面端的3D GIS正逐渐成…

day 30 动态GDP柱状图绘制

列表.sort(key选择排序依据的函数&#xff0c;reverseTrue|False) 参数key:要求传入一个函数&#xff0c;表示将列表的每一个元素传入函数当中&#xff0c;返回排序的依据&#xff0c; 参数reverse,是否反转排序结果&#xff0c;True降序&#xff0c;False升序 my_list [[&…

【爬虫小知识】如何利用爬虫爬网页——python爬虫

前言 网络时代的到来&#xff0c;给我们提供了海量的信息资源&#xff0c;但是&#xff0c;想要获取这些信息&#xff0c;手动一个一个网页进行查找&#xff0c;无疑是一项繁琐且效率低下的工作。这时&#xff0c;爬虫技术的出现&#xff0c;为我们提供了一种高效的方式去获取…

Android JNI系列详解之生成指定CPU的库文件

一、前提 这次主要了解Android的cpu架构类型&#xff0c;以及在使用CMake工具的时候&#xff0c;如何指定生成哪种类型的库文件。 如上图所示&#xff0c;是我们之前使用CMake工具默认生成的四种cpu架构的动态库文件&#xff1a;arm64-v8a、armeabi-v7a、x86、x86_64&#xff0…

【附安装包】MyEclipse2019安装教程

软件下载 软件&#xff1a;MyEclipse版本&#xff1a;2019语言&#xff1a;简体中文大小&#xff1a;1.86G安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU2.5GHz 内存4G(或更高&#xff09;下载通道①百度网盘丨下载链接&#xff1a;https://pan.baidu.co…

系统架构师---系统规划

目录 前言&#xff1a; 项目的提出与选择 项目立项的目标和动机 进行基础研究并获取技术 进行应用研发并获得产品 提供技术服务 信息技术产品的使用者 项目的选择和确定 选择有核心价值的产品、项目或可开发方向 评估项目风险、收益和代价 评估项目的多种实施方式 平…

app.js和页面.js 实现全局传参

实现全局传参的几个步骤&#xff1a;1. 在页面.js文件中 输入 const appgetApp() 2.便可以在页面中引用app.js中的globalData中的数据。 注意点&#xff1a;app.js中是使用的是this.globalData (调用自身的数据&#xff09; 页面.js中使用的是app.globalData&#xff08;引用ap…

国产系统下开发QT程序总结

国产系统下开发QT程序总结 1. 国产系统简介 开发国产系统客户端的过程中&#xff0c;会出现兼容性问题。以下介绍Kylin和UOS环境下开发QT程序&#xff0c; 首先麒麟和统信这两个系统基于Ubuntu开发的。所以在Ubuntu开发理论上在国产系统上也能运行。芯片架构又分为amd,arm,mi…

vue v-for 例子

vue v-for 例子 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head&…

ArcGIS学习总结(19)——要素转点与空间连接(属性表字段映射)

1.在新创建的面矢量数据的属性表中没有对应的字段信息&#xff0c;为了能够和有属性信息的数据进行匹配&#xff0c;使其具有对应字段的信息。 2.需要匹配的矢量文件属性表信息。 3.对新创建的矢量文件执行要素转点&#xff1a;数据管理工具→要素→要素转点。 4.选择分析工…

AI聊天机器人平台Poe发布更新;自然语言理解课程概要

&#x1f989; AI新闻 &#x1f680; AI聊天机器人平台Poe发布更新 突破功能限制 增加企业级服务 摘要&#xff1a;知名问答网站Quora旗下的AI聊天机器人平台Poe发布了一系列更新&#xff0c;包括推出Mac应用、支持同时进行多个对话、接入Meta的Llama 2模型等功能。用户只需支…

Shell 脚本入门

目录 一、Shell是什么 1.1 我们为什么要学习Shell和使用Shell&#xff1f; 1.2 Shell的分类有哪些&#xff1f; 二、Shell脚本入门知识 2.1 Shell文件命名规范 2.2 Shell解析器 2.3 用Shell 编写hello World 三、Shell的四种变量类型 3.1 系统预定义变量 3.2 自定义变…

(笔记二)利用opencv调用鼠标事件在图像上绘制图形

目录 &#xff08;1&#xff09;查看cv2所支持的鼠标事件&#xff08;2&#xff09;通过鼠标事件在图像上做标记&#xff08;3&#xff09;高级操作&#xff1a;通过移动鼠标在图像绘制图形、曲线 该功能主要创建一个鼠标事件发生时执行的回调函数。鼠标事件可以是任何与鼠标有…

【OpenCV实战】3.OpenCV颜色空间实战

OpenCV颜色空间实战 〇、Coding实战内容一、imread1.1 函数介绍1.2 Flags1.3 Code 二. 色彩空间2.1 获取单色空间2.2. HSV、YUV、RGB2.3. 不同颜色空间应用场景 〇、Coding实战内容 OpenCV imread()方法不同的flags差异性获取单色通道【R通道、G通道、B通道】HSV、YUV、RGB 一…

Prompt GPT推荐社区

大家好&#xff0c;我是荷逸&#xff0c;这次给大家带来的是我日常学习Prompt社区推荐 Snack Prompt 访问地址&#xff1a;http://snackprompt.com Snack Prompt是一个采用的Prompts诱导填空式的社区&#xff0c;它提供了一种简单的prompt修改方式&#xff0c;你只需要输入关…

MindsDB为许多不支持内置机器学习的数据库带来了机器学习功能

选择平台的首要原则是“靠近数据”,让代码靠近数据是保持低延迟的必要条件。 机器学习,特别是深度学习往往会多次遍历所有数据(遍历一次被称为一个epoch)。对于非常大的数据集来说,理想的情况是在存储数据的地方建立模型,这样就不需要大量的数据传输。目前已经有部分数据…