Webrtc+Windows10+VS2017 编译

发布于 2023-04-30 | 作者: klobliu | 来源: CSDN博客 | 转载于: CSDN博客

一、环境及代码获取

1、本机系统环境

系统:Windows Server 2016,Windows10(代码及编译消耗巨大,采用云端服务器编译)
VS版本:VS2017 15.9.38(建议保持这个版本及以上版本)
代码版本: 分支4103 commit 3ed9687558f4fd0271adf5836d4a029df858dc43 6/28/2020
PYTHON: 2.7.17
语言区域:美国英语(系统及IDE都设为英文)

2、代码获取

(1)安装depot_tools工具包

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

(2)设置一下环境变量

DEPOT_TOOLS_WIN_TOOLCHAIN=0
GYP_GENERATORS=msvs-ninja,ninja
GYP_MSVS_VERSION=2017

PATH添加G:\depot_tools在最前面

(3)获取代码

fetch --nohooks webrtc

如果中途断网:

gclient sync

(4)切换分支

git checkout -b (随便命名) refs/remotes/branch-heads/(指定版本号)
gclient sync -D

二、编译

1、将运行时库由MT改为MD(可选,编SDK建议做这一步)

Windows默认不支持is_component_build设置

手动将src/build/config/win/build.gn改为以下内容

config("default_crt") {
  if (is_component_build) {
    # Component mode: dynamic CRT. Since the library is shared, it requires
    # exceptions or will give errors about things not matching, so keep
    # exceptions on.
    configs = [ ":dynamic_crt" ]
  } else {
    if (current_os == "winuwp") {
      # https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great-c-runtime-crt-refactoring/
      # contains a details explanation of what is happening with the Windows
      # CRT in Visual Studio releases related to Windows store applications.
      configs = [ ":dynamic_crt" ]
    } else {
      # Desktop Windows: static CRT.
      configs = [ ":`dynamic_crt`" ]
    }
  }
}

或者

config("static_crt") {
 if (is_debug) {
   # This pulls in the static debug CRT and defines _DEBUG
   cflags = [ `"/MDd" `]
 } else {
   cflags = [ `"/MD"` ]
 }
}

参考https://blog.csdn.net/haowei0926/article/details/78530560

2、在构建目录out\debug 新建args.gn,填入以下内容

is_debug = true // release is_debug=false
rtc_enable_protobuf = false
target_cpu = “x86” // 64bit target_cpu = “x64”
target_os = “win”
is_clang = false
libyuv_include_tests = false
rtc_include_tests = false
rtc_use_h364 = true
is_component_ffmpeg=true
enable_iterator_debugging=true

3、生成工程

32bit
gn args out1/Debug --ide=vs2017 --winsdk=10.0.19041.0
gn args out1/Release --ide=vs2017 --winsdk=10.0.19041.0

64bit
gn args out64/Debug --ide=vs2017  --winsdk=10.0.19041.0
gn args out64/Release --ide=vs2017 --winsdk=10.0.19041.0

sln在Debug/all.sln

4、编译

建议先编 webrtc模块,有问题参考下文三、修正编译问题先解决问题

再编译example中的peerconnection_client和peerconnection_server

三、修正编译问题

1、See: bugs.webrtc.org/9213#c13
首先时,将 modules\video_coding\codecs\h364\目录下的 h364_decoder_impl.h、h364_encoder_impl.h、\h364_color_space.h 几个文件中的#error “See: bugs.webrtc.org/9213#c13.” 注释掉。

根据错误提示,定位到第一个问题件,把这个注释掉:

2、pcm.c 报错
注释掉\third_party\ffmpeg\libavcodec\pcm.c的最后一行,原因是PCM_VIDC这个标志未定义,通过宏定义无法正确生成,导致编译报错 C2059 error “string”。

3、error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”(main.obj 中) 错误
args.gn中写入enable_iterator_debugging=true参数

4、void ThreadManager::RegisterSendAndCheckForCycles(Thread* source,Thread* target) crash

peerconnection_client.exe!rtc::ThreadManager::RegisterSendAndCheckForCycles(rtc::Thread * source, rtc::Thread * target) Line 171	C++
peerconnection_client.exe!rtc::Thread::Send(const rtc::Location & posted_from, rtc::MessageHandler * phandler, unsigned int id, rtc::MessageData * pdata) Line 886	C++
peerconnection_client.exe!rtc::Thread::InvokeInternal(const rtc::Location & posted_from, rtc::FunctionView functor) Line 937	C++
peerconnection_client.exe!rtc::Thread::Invoke(const rtc::Location & posted_from, rtc::FunctionView functor) Line 331	C++
peerconnection_client.exe!cricket::ChannelManager::CreateVideoChannel(webrtc::Call * call, const cricket::MediaConfig & media_config, webrtc::RtpTransportInternal * rtp_transport, const webrtc::MediaTransportConfig & media_transport_config, rtc::Thread * signaling_thread, const std::basic_string,std::allocator > & content_name, bool srtp_required, const webrtc::CryptoOptions & crypto_options, rtc::UniqueRandomIdGenerator * ssrc_generator, const cricket::VideoOptions & options, webrtc::VideoBitrateAllocatorFactory * video_bitrate_allocator_factory) Line 269	C++
peerconnection_client.exe!webrtc::PeerConnection::CreateVideoChannel(const std::basic_string,std::allocator > & mid) Line 6640	C++
peerconnection_client.exe!webrtc::PeerConnection::UpdateTransceiverChannel(rtc::scoped_refptr > transceiver, const cricket::ContentInfo & content, const cricket::ContentGroup * bundle_group) Line 3585	C++
peerconnection_client.exe!webrtc::PeerConnection::UpdateTransceiversAndDataChannels(cricket::ContentSource source, const webrtc::SessionDescriptionInterface & new_session, const webrtc::SessionDescriptionInterface * old_local_description, const webrtc::SessionDescriptionInterface * old_remote_description) Line 3543	C++
peerconnection_client.exe!webrtc::PeerConnection::ApplyLocalDescription(std::unique_ptr > desc) Line 2697	C++
peerconnection_client.exe!webrtc::PeerConnection::DoSetLocalDescription(std::unique_ptr > desc, rtc::scoped_refptr observer) Line 2594	C++
peerconnection_client.exe!webrtc::PeerConnection::SetLocalDescription::__l2::(std::function operations_chain_callback) Line 2474	C++
peerconnection_client.exe!rtc::rtc_operations_chain_internal::OperationWithFunctor(std::function) >::Run() Line 67	C++
peerconnection_client.exe!rtc::OperationsChain::ChainOperation(std::function) >(webrtc::PeerConnection::SetLocalDescription::__l2::void (std::function) && functor) Line 147	C++
peerconnection_client.exe!webrtc::PeerConnection::SetLocalDescription(webrtc::SetSessionDescriptionObserver * observer, webrtc::SessionDescriptionInterface * desc_ptr) Line 2450	C++
peerconnection_client.exe!webrtc::ReturnType::Invoke(webrtc::PeerConnectionInterface * c, void(webrtc::PeerConnectionInterface::*)(webrtc::SetSessionDescriptionObserver *, webrtc::SessionDescriptionInterface *) m, webrtc::SetSessionDescriptionObserver * && , webrtc::SessionDescriptionInterface * && ) Line 93	C++
peerconnection_client.exe!webrtc::MethodCall::Invoke<0,1>(std::integer_sequence __formal) Line 137	C++
peerconnection_client.exe!webrtc::MethodCall::OnMessage(rtc::Message * __formal) Line 132	C++
peerconnection_client.exe!webrtc::internal::SynchronousMethodCall::Invoke(const rtc::Location & posted_from, rtc::Thread * t) Line 25	C++
peerconnection_client.exe!webrtc::MethodCall::Marshal(const rtc::Location & posted_from, rtc::Thread * t) Line 127	C++
peerconnection_client.exe!webrtc::PeerConnectionProxyWithInternal::SetLocalDescription(webrtc::SetSessionDescriptionObserver * a1, webrtc::SessionDescriptionInterface * a2) Line 99	C++
peerconnection_client.exe!Conductor::OnSuccess(webrtc::SessionDescriptionInterface * desc) Line 550	C++
peerconnection_client.exe!webrtc::`anonymous namespace'::CreateSessionDescriptionObserverOperationWrapper::OnSuccess(webrtc::SessionDescriptionInterface * desc) Line 674	C++
peerconnection_client.exe!webrtc::WebRtcSessionDescriptionFactory::OnMessage(rtc::Message * msg) Line 301	C++
peerconnection_client.exe!rtc::Thread::Dispatch(rtc::Message * pmsg) Line 666	C++
peerconnection_client.exe!rtc::Win32SocketServer::Pump() Line 777	C++
peerconnection_client.exe!rtc::Win32SocketServer::MessageWindow::OnMessage(unsigned int wm, unsigned int wp, long lp, long & lr) Line 795	C++
peerconnection_client.exe!rtc::Win32Window::WndProc(HWND__ * hwnd, unsigned int uMsg, unsigned int wParam, long lParam) Line 117	C++


修正为以下代码

void ThreadManager::RegisterSendAndCheckForCycles(Thread* source,Thread* target) {

    CritScope cs(&crit_);
    std::deque all_targets({target});
    // We check the pre-existing who-sends-to-who graph for any path from target
    // to source. This loop is guaranteed to terminate because per the send graph
    // invariant, there are no cycles in the graph.
    for (size_t i = 0; i < all_targets.size(); i++) {
        const auto& targets = send_graph_[all_targets[i]];
        all_targets.insert(all_targets.end(), targets.begin(), targets.end());
    }

    RTC_CHECK_EQ(absl::c_count(all_targets, source), 0)
        << " send loop between " << source->name() << " and " << target->name();

    // We may now insert source -> target without creating a cycle, since there
    // was no path from target to source per the prior CHECK.
    send_graph_[source].insert(target);
}

四、DEMO运行

1、先开peerconnection_client.exe

2、再开两个peerconnection_client.exe

3、双击成员

五、静态库使用

1、头文件获取,建个bash把所有头文件拷贝出来

#!/bin/bash
  src=`find src/ -name "*.h*"`
  echo $src
  for obj in $src
  do
      echo "cp header file $obj"
      cp --parents $obj include/
  done


2、静态库

3、demo cmake
目录结构


project(ApmDemo)
set(PROJECT ApmDemo)
cmake_minimum_required(VERSION 3.6)

set(WEBRTC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")
set(WEBRTC_LIB_DIR WEBRTC_DIR)

set(INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${WEBRTC_LIB_DIR}/include
${WEBRTC_LIB_DIR}/third_party
${WEBRTC_LIB_DIR}/third_party/abseil-cpp
${WEBRTC_LIB_DIR}/rtc_base
)
add_definitions("-std=c++11") 
include_directories(${INCLUDES})

add_executable(${PROJECT} stdafx.cpp apm_test.cpp webrtc_apm.cc)
target_link_libraries(${PROJECT} ${WEBRTC_DIR}/lib/debug/webrtc.lib winmm)
target_include_directories(${PROJECT} PUBLIC ${INCLUDES})

if(ISCI)
   add_compile_definitions(RESOURCE_DIR="")
else()
   add_compile_definitions(RESOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}/resources/")
endif()

add_definitions(
-DNOMINMAX
-DWIN32_LEAN_AND_MEAN
-DWEBRTC_WIN
-D_CRT_SECURE_NO_WARNINGS
)

4、unresolved external symbol __imp__timeGetTime

target_link_libraries(${PROJECT} ${WEBRTC_DIR}/lib/webrtc.lib winmm)

参考文章

1、 error LNK2038: mismatch detected for ‘_ITERATOR_DEBUG_LEVEL’: value ‘2’ doesn’t match value ‘0’

https://blog.csdn.net/u012750702/article/details/52449425

2、WebRTC在windows下编译时 怎么修改RuntimeLibrary类型

https://blog.csdn.net/haowei0926/article/details/78530560

3、Windows平台WebRTC编译-VS2017

https://www.yjf.me/webrtc-build-vs2017.html

4、webrtc c++ (零) webrtc vs2017最新源码编译

https://www.codenong.com/cs106897651/

5、在win10上编译webRTC(问题篇)

https://blog.csdn.net/qq_34732729/article/details/105707104