Skip to content

WebRTC:NativeCode

Categories

How to install

우선 depot_tools를 설치하고 PATH환경변수를 설정한다. git clone명령으로 코드를 받지 말고 아래와 같이 진행한다.

$ mkdir webrtc-checkout
$ cd webrtc-checkout
$ fetch --nohooks webrtc

생성된 src 디렉토리로 이동한다.

$ cd src

원하는 branch로 이동한다.

$ git branch --remote
$ git checkout branch-heads/70

Sync:

$ gclient sync

만약 macOS일 경우 gn을 실행할 경우 python webrtc-checkout/src/build/mac/find_sdk.py --print_sdk_path 10.12와 같은 SDK 경로를 검색하는 명령에서 실패할 수 있다. 이 경우 아래와 같은 명령을 우선 실행해야 한다.

## Install Xcode, launch it, accept the license agreement, and run
$ sudo xcode-select -s /Applications/Xcode.app

ninja프로젝트를 생성한다.

## Generating Ninja project files
$ gn gen out/Default

## or Release mode:
$ gn gen out/Default --args='is_debug=false'

## clean:
$ gn clean out/Default

Compiling:

$ ninja -C out/Default

Diagram

Block Diagram

WebRTCNativeAPIsDocument_-_Block_Diagram.png

Set up a call

WebRTCNativeAPIsDocument_-_Set_up_a_call.png

Receive a Call

WebRTCNativeAPIsDocument_-_Receive_a_Call.png

Close Down a Call

WebRTCNativeAPIsDocument_-_Close_Down_a_Call.png

gn arguments

gn gen out/Default --args='is_debug=false'와 같이 gn에서 적용할 수 있는 변수에 대하여 설명한다.

전체 목록은 gn args out/Default --list로 확인 할 수 있다. WebRTC:NativeCode:GnArgumentList에서 확인 가능.

enable_nacl=false
Disable Native Client.
Most developers don't normally need to test Native Client capabilities and can speed up the build by disabling it.
blink_symbol_level=0
Remove WebCore symbols
WebCore has lots of templates that account for a large portion of the debugging symbols. If you're not debugging WebCore, you can skip these symbols to make the build smaller and faster.
is_debug=false
릴리즈 빌드시 적용한다.
rtc_use_h264=true
Enable this to build OpenH264 encoder/FFmpeg decoder. This is supported on all platforms except Android and iOS. Because FFmpeg can be built with/without H.264 support, |ffmpeg_branding| has to separately be set to a value that includes H.264, for example "Chrome". If FFmpeg is built without H.264, compilation succeeds but |H264DecoderImpl| fails to initialize.
CHECK THE OPENH264, FFMPEG AND H.264 LICENSES/PATENTS BEFORE BUILDING.
ffmpeg_branding
Controls whether we build the Chromium or Google Chrome version of FFmpeg. The Google Chrome version contains additional codecs. Typical values are Chromium, Chrome, and ChromeOS.
symbol_level
How many symbols to include in the build. This affects the performance of the build since the symbols are large and dealing with them is slow.
  • 2: means regular build with symbols.
  • 1: means minimal symbols, usually enough for backtraces only. Symbols with internal linkage (static functions or those in anonymous namespaces) may not appear when using this level.
  • 0: means no symbols.
  • -1: means auto-set according to debug/release and platform.
use_rtti
Build with C++ RTTI enabled. Chromium builds without RTTI by default, but some sanitizers are known to require it, like CFI diagnostics and UBsan variants.

Target visibility and the native API

The WebRTC-specific GN templates declare build targets whose default visibility allows all other targets in the WebRTC tree (and no targets outside the tree) to depend on them.

Prefer to restrict the visibility if possible:

  • If a target is used by only one or a tiny number of other targets, prefer to list them explicitly: visibility = [ ":foo", ":bar" ]
  • If a target is used only by targets in the same BUILD.gn file: visibility = [ ":*" ].

Setting visibility = [ "*" ] means that targets outside the WebRTC tree can depend on this target; use this only for build targets whose headers are part of the native API.

H264 encode/decode support

gn Argument를 아래와 같이 적용하면 된다.

$ gn gen out/release --args='ffmpeg_branding="Chrome" rtc_use_h264=true is_debug=false'

Sample program

WebRTC 동작 테스트를 위한 샘플 프로그램. branch-heads/72에서 테스트 되었다.

cmake build script.

# libsourcey WebRTC Video Server

cmake_minimum_required (VERSION 2.8)

set (PROJECT_NAME sourecy)
project (${PROJECT_NAME})

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set (SOURCE_FILES main.cpp)
add_executable (${PROJECT_NAME} ${SOURCE_FILES})

set (WEBRTC_PREFIX /usr/local/c2core/webrtc)

set (WEBRTC_INCLUDE_DIRS
        ${WEBRTC_PREFIX}/include
        ${WEBRTC_PREFIX}/include/third_party/abseil-cpp)
set (WEBRTC_INCLUDE_LIBS
        -Wl,-force_load,${WEBRTC_PREFIX}/lib/libwebrtc.a
        "-framework Foundation"
        "-framework AVFoundation"
        "-framework CoreAudio"
        "-framework AudioToolbox"
        "-framework CoreFoundation"
        "-framework CoreGraphics"
        "-framework CoreMedia"
        "-framework CoreVideo"
        "-framework IOSurface"
        "-framework Cocoa")

#"-framework IOKit"
#"-framework Security"
#"-framework SystemConfiguration"
#"-framework ApplicationServices"
#"-framework OpenGL"
#"-framework VideoToolbox"

target_compile_definitions (${PROJECT_NAME} PRIVATE WEBRTC_MAC WEBRTC_POSIX)
target_include_directories (${PROJECT_NAME} PRIVATE ${WEBRTC_INCLUDE_DIRS})
target_link_libraries (${PROJECT_NAME} PRIVATE ${WEBRTC_INCLUDE_LIBS})

C/C++ main source:

#include <iostream>
#include <rtc_base/ssladapter.h>

int main()
{
    rtc::InitializeSSL();

    using namespace std;
    cout << "Hello, World!" << endl;

    rtc::CleanupSSL();
    return 0;
}

MediaStream

Troubleshooting

Direct access to weak symbols

ld: warning: direct access in function 'webrtc::AudioEncoderIlbc::QueryAudioEncoder(webrtc::AudioEncoderIlbcConfig const&)' from file '/usr/local/c2core/webrtc/lib/libwebrtc.a(audio_encoder_ilbc.o)' to global weak symbol 'void rtc::webrtc_checks_impl::LogStreamer<>::Call<>(char const*, int, char const*)::t' from file 'CMakeFiles/c2media.dir/libc2media/temp/webrtc-streamer/rtspaudiocapturer.cpp.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.

rtc::Thread::Current() is nullptr

메인 스레드가 아닌 별도의 스레드에서 rtc::Thread::Current()의 반환값이 nullptr로 반환될 경우 아래와 같이 초기화가 필요하다.

webrtc_thread = rtc::Thread::CreateWithSocketServer();
assert(static_cast<bool>(webrtc_thread));

auto * thread_manger = rtc::ThreadManager::Instance();
assert(thread_manger != nullptr);
thread_manger->SetCurrentThread(webrtc_thread.get());

manager = std::make_unique<WrxPcManager>();
manager->setCallback(this);
if (!manager->existsPeerConnection()) {
    throw ErrException(E_INIT);
}

auto * thread = rtc::Thread::Current();
assert(webrtc_thread.get() == thread);

See also

Favorite site

Native Build

Example