webrtc 4577版本vs编译

vs版本:2017
操作系统:win10
webrtc版本:4577

成果物要求: x64的可被vs引入的webrtc库

第一:找个
公司有提供客户端工具,工具启动的端口号是10080
第二:webrtc下载
1.首先打开cmd,输入如下内容

		set http_proxy=http://127.0.0.1:10080
		set https_proxy=http://127.0.0.1:10080
		set DEPOT_TOOLS_UPDATE=0
		set DEPOT_TOOLS_WIN_TOOLCHAIN=0
		set GYP_MSVS_OVERRIDE_PATH=D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise
		set GYP_MSVS_VERSON=2017
		set GYP_GENERATORS=msvs-ninja,ninja

注意:代理是一定要设置的,否则webrtc无法下载。
2.下载depot_tools
cmd中输入下面内容:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
下载成功后,设置环境变量PATH,因为这里面有不少的编译需要的工具,比如著名的ninja.exe
设置环境变量后,重启cmd,重新输入以下内容:

		set http_proxy=http://127.0.0.1:10080
		set https_proxy=http://127.0.0.1:10080
		set DEPOT_TOOLS_UPDATE=0
		set DEPOT_TOOLS_WIN_TOOLCHAIN=0
		set GYP_MSVS_OVERRIDE_PATH=D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise
		set GYP_MSVS_VERSON=2017
		set GYP_GENERATORS=msvs-ninja,ninja

3.下载webrtc
在e盘下,新建一个git目录,git目录下建立webrtc目录,webrtc目录下再建立webrtc_wins目录。
cmd中执行cd E:\git\webrtc\webrtc_wins,切换到对应的目录。
然后在cmd中执行fetch --nohooks webrtc,这大概要等一段时间,中途会遇到很多Still working on的提示。
下载完成后,再执行gclient sync
说明下,gclient sync建议多执行几次,主要是内地的原因,一次可能下载的不够彻底,鄙人就遇到过这种情况。
然后cmd中执行下面的命令,定位到4577分支
git checkout -b m4577 refs/remotes/branch-heads/4577
接着继续gclient sync,gclient sync依然建议多执行几次
4.编译webrtc
下载webrtc后,E:\git\webrtc\webrtc_wins下面会多个src目录,cmd中执行cd src,切换到此目录。
然后执行下面命令
gn gen out/Release_h264 --args=“is_clang=false use_lld=false treat_warnings_as_errors=false rtc_include_tests=false is_component_build=false is_debug=false rtc_use_h264=true proprietary_codecs=true ffmpeg_branding=\“Chrome\”” --ide=vs2017
这个会自动生成ninja文件,然后执行下面的命令,进行ninja编译
注意use_lld=false是一定要设置的,早起的webrtc版本只需要设置is_clang=false就行了,此处如果没设置use_lld=false,则最终生成的peerconnection_client.exe无法运行起来。

ninja -C out/Release_h264
这个要等待一段时间,具体要看机器性能,我的台式机,16G的内容,大概要等30多分钟。

相关参数解析:
is_debug 是否是Debug版,默认true,false:表示编译Release版。
target_os: 平台类型,可以取值win、android、ios、linux等,这里取win,表示Windows平台。
target_cpu: cpu类型,Windows下可以取x86、x64
is_component_build :是否使用动态运行期库,这里取false,使用静态运行期库,Release版本将对应MT,Debug版将对应MTd。
proprietary_codecs: 是否使用版权编码,也就是H264,这里取true。
rtc_use_h264: 是否使用H264,这里取true,注意Windows平台编码使用OpenH264,解码使用ffmpeg。
ffmpeg_branding: ffmpeg的分支名,这里采用Chrome的分支。
is_clang: 是否采用clang编译器编译,默认设置为true
rtc_include_tests:自动编译单元测试test文件,默认是true,webrtc的单元测试文件很多,设置为false,可以节省不少编译时间。

5.编译中遇到的问题
编译中会遇到各种各样的问题,下面列举几条
5.1
…/…/modules/audio_processing/agc2/rnn_vad/features_extraction.cc(84): error C2398: 元素“2”: 从“const int”转换到“size_t”需要收缩转换
很明显,vs编译器检查是比较严格的,is_clang如果设置成true,就没这种问题。
我们进行下手动强制转换即可。
5.2
e:\git\webrtc\webrtc_wins\src\third_party\ffmpeg\libavcodec\error_resilience.h(23): fatal error C1083: 无法打开包括文件: “stdatomic.h”: No such file or directory
我们在webrtc目录下搜索stdatomic.h,发现third_party\ffmpeg下面存在几个stdatomic.h,将其中的一个放置于third_party\ffmpeg下即可。
5.3
…/…/third_party/ffmpeg/libavcodec/pcm.c(52): error C2065: “CONFIG_PCM_VIDC_ENCODER”: 未声明的标识符
…/…/third_party/ffmpeg/libavcodec/pcm.c(634): error C2059: 语法错误:“字符串”
直接将对应的行代码注释掉
5.4
E:\git\webrtc\webrtc_wins\src\modules/video_coding/codecs/h264/h264_decoder_impl.h(21): fatal error C1189: #error: “See: bugs.webrtc.org/9213#c13.”
直接注释掉
5.5
ffmpeg_internal.lib(pcm.obj) : error LNK2001: 无法解析的外部符号 avpriv_emms_asm(不影响最终webrtc库的生成)

这个问题是最难解决的,其他的问题跟这相比,有点毛毛雨的感觉,尽管此种情况下webrtc.lib可以生成,但是很多exe都无法生成,比如peerconnection_server.exe,并且将生成的webrtc.lib放置于其他vs工程,会报如下的链接错误:

1>webrtc.lib(pcm.obj) : error LNK2001: 无法解析的外部符号 avpriv_emms_asm
1>webrtc.lib(encode.obj) : error LNK2001: 无法解析的外部符号 avpriv_emms_asm
1>webrtc.lib(h264_picture.obj) : error LNK2001: 无法解析的外部符号 avpriv_emms_asm
1>webrtc.lib(avcodec.obj) : error LNK2001: 无法解析的外部符号 avpriv_emms_asm
1>webrtc.lib(decode.obj) : error LNK2001: 无法解析的外部符号 avpriv_emms_asm
1>webrtc.lib(h264dec.obj) : error LNK2001: 无法解析的外部符号 avpriv_emms_asm
1>webrtc.lib(vp3.obj) : error LNK2001: 无法解析的外部符号 avpriv_emms_asm

所以这个问题必须解决
解决方法:替换ffmpeg文件,x86版本无此问题,x64才会出现,原因是x64不支持大多数汇编指令,ffmpeg里面有汇编代码,用clang就没那个问题,但是clang编译的vc不能引用

现在来讲讲如何替换ffmpeg文件,这里说的ffmpeg指的是third_party\ffmpeg这个目录。

我是这样替换的,我们之前用的webrtc是72版本的,72版本的64位lib库很容易编译通过
编译通过后,我们将72版本的third_party\ffmpeg替换过来,然后接着生成ninja文件,在生成ninja文件的过程中,会出现两个错误。
第一:需要将72版本的third_party\yasm替换过来
第二:需要更改build\config\compiler目录下的BUILD.gn,里面需要在指定位置添加黄色区域的一段内容,这段内容其实是从72版本里面拷贝过来的。

webrtc 4577版本vs编译_第1张图片

除此外,编译的时候,注意用MD而不是MT,为此,我修改了文件
build\config\win下面的BUILD.gn,修改内容如下:
webrtc 4577版本vs编译_第2张图片
这里,我将原来的static_crt改成了dynamic_crt。

6.运行效果
运行的时候,发现peerconnection_client.exe无法播放视频,然后采用is_clang=true的方式进行编译,结果编译出的peerconnection_client.exe依然无法播放视频,故中间有放弃此版本,改用4484版本编译,4484版本的问题解决后,后边又改回到了4577版本,发现4577的成果物放置到自己工程下,发现可以播放视频了。。

7.4484版本编译
4484版本也是比较新的版本,直接编译64位时,最终还是会出现avpriv_emms_asm这样无法识别的符号错误,这里,我并没有采取替换72的ffmpeg的方式,而是事先编译好64位版本的ffmpeg,然后将头文件和lib库替换进去,这样webrtc本身就不需要对ffmpeg进行编译,只需要链接ffmpeg库即可。
64位ffmpeg库的编译,我采取的是以下链接里面的方式:
https://www.cnblogs.com/wanggang123/p/9896564.html

如下图所示,其中ffmpeg_x64_result是编译出的成果物
webrtc 4577版本vs编译_第3张图片

进入到文件夹ffmpeg_x64_result里面,如下图所示:
webrtc 4577版本vs编译_第4张图片
其中bin文件夹里面的内容如下:
webrtc 4577版本vs编译_第5张图片
include文件夹里面的内容如下:
webrtc 4577版本vs编译_第6张图片
将整个ffmpeg_x64(其实只需要拷贝里面的ffmpeg_x64_result)目录拷贝到webrtc下面,拷贝后,webrtc的third_party目录如下图所示:
webrtc 4577版本vs编译_第7张图片
可以看出,对于ffmpeg,我32和64位的都进行编译了下,然后编辑\src\modules\video_coding下的BUILD.gn
webrtc 4577版本vs编译_第8张图片

打开后,进行修改,修改共有两处,第一处如下:
其中左侧是原来的,右侧是修改后的。
webrtc 4577版本vs编译_第9张图片

第二处:注释掉下面这部分。
webrtc 4577版本vs编译_第10张图片
为方便以后粘贴,故将修改的文本放置如下:

rtc_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_x64/ffmpeg_x64_result/include" ]
    libs = [
   # 设置引用库
       "//third_party/ffmpeg_x64/ffmpeg_x64_result/bin/avcodec.lib",
       "//third_party/ffmpeg_x64/ffmpeg_x64_result/bin/avdevice.lib",
       "//third_party/ffmpeg_x64/ffmpeg_x64_result/bin/avfilter.lib",
       "//third_party/ffmpeg_x64/ffmpeg_x64_result/bin/avformat.lib",
       "//third_party/ffmpeg_x64/ffmpeg_x64_result/bin/avutil.lib",
       "//third_party/ffmpeg_x64/ffmpeg_x64_result/bin/swresample.lib",
       "//third_party/ffmpeg_x64/ffmpeg_x64_result/bin/swscale.lib",
    ]
  }
  defines = []
  deps = [
    ":video_codec_interface",
    ":video_coding_utility",
    "../../api/video:video_frame",
    "../../api/video:video_frame_i010",
    "../../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/libyuv",
  ]
  absl_deps = [
    "//third_party/abseil-cpp/absl/strings",
    "//third_party/abseil-cpp/absl/types:optional",
  ]

  if (rtc_use_h264) {
    deps += [
      #"//third_party/ffmpeg",
      "//third_party/openh264:encoder",
    ]

然后开启编译,编译结果比较顺利,peerconnection_client.exe能够播放视频
webrtc 4577版本vs编译_第11张图片
后面将webrtc.lib放到项目中时,碰到一个链接错误,
webrtc.lib(auto_correlation.obj) : error LNK2019: unresolved external symbol __std_reverse_copy_trivially_copyable_4
这个我通过符号__std_reverse_copy_trivially_copyable_4在百度和谷歌上都没搜索到结果,最后采取了微软的bing搜索,此问题已经有人提出,如下网址:
https://github.com/Unity-Technologies/com.unity.webrtc/issues/441

根据里面所说,cmake存在一定的问题,当电脑上安装两个微软编译器的时候。
我电脑上安装有vs2017和vs2019,我卸载了vs2019,重新编译后,就好了。

上面ffmpeg是以动态库的方式提供的,当然也可以以静态库的方式提供,静态库方式编译的好处是最终的成果物里面不需要包含 avcodec-59.dll这样的文件,ffmpeg的静态库编译要比动态库编译麻烦些,为此,本人专门写了一篇博客,如下:
ffmpeg 64位静态库编译

后来我又重新编译了ffmpeg4577,也可以播放视频。

下面给出ffmpeg的静态库和动态库编译成果物,先看下成果物的版本信息
webrtc 4577版本vs编译_第12张图片
静态库成果物
动态库成果物
ffmpeg源码

你可能感兴趣的:(git)