Skip to content

Commit e0b785d

Browse files
committed
feat: Add CAPI support.
1 parent 5cf497f commit e0b785d

12 files changed

+369
-5
lines changed

BUILD.gn

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import("../webrtc.gni")
33
declare_args() {
44
libwebrtc_intel_media_sdk = false
55
libwebrtc_desktop_capture = true
6+
libwebrtc_export_capi = true
67
}
78

89
if (is_android) {
@@ -158,6 +159,20 @@ rtc_shared_library("libwebrtc") {
158159
"src/rtc_logging.cc",
159160
]
160161

162+
if(libwebrtc_export_capi) {
163+
sources += [
164+
"include/ref_counted_object_capi.h",
165+
"include/rtc_types_capi.h",
166+
"include/libwebrtc_capi.h",
167+
"include/rtc_peerconnection_factory_capi.h",
168+
169+
170+
"src/capi/libwebrtc_capi.cc",
171+
"src/capi/ref_counted_object_capi.cc",
172+
"src/capi/rtc_peerconnection_factory_capi.cc",
173+
]
174+
}
175+
161176
# intel media sdk
162177
if (is_win && libwebrtc_intel_media_sdk) {
163178
sources += [
@@ -273,3 +288,19 @@ rtc_shared_library("libwebrtc") {
273288
}
274289
}
275290
}
291+
292+
rtc_test("libwebrtc_unittests") {
293+
testonly = true
294+
295+
sources = [
296+
"test/peerconnection.test.cc",
297+
"test/tests.cc",
298+
]
299+
300+
deps = [
301+
":libwebrtc",
302+
"//testing/gtest",
303+
"//test:test_support",
304+
"//test:test_main",
305+
]
306+
}

include/libwebrtc_capi.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef LIB_WEBRTC_HXX_CAPI
2+
#define LIB_WEBRTC_HXX_CAPI
3+
4+
#include "rtc_peerconnection_factory_capi.h"
5+
#include "rtc_types_capi.h"
6+
7+
extern "C" {
8+
/**
9+
* @brief Initializes the WebRTC library.
10+
*
11+
* This function initializes the WebRTC library. It must be called before
12+
* using any other WebRTC functions.
13+
*
14+
* @return rtcBool32 Returns kTrue if initialization is successful, kFalse
15+
* otherwise.
16+
*/
17+
LIB_WEBRTC_CAPI rtcBoolean LibWebRTC_Initialize();
18+
19+
/**
20+
* @brief Creates a new WebRTC PeerConnectionFactory.
21+
*
22+
* This function creates a new WebRTC PeerConnectionFactory. It must be
23+
* called after initializing the WebRTC library using LibWebRTC_Initialize().
24+
*
25+
* @return A pointer to the newly created RTCPeerConnectionFactory.
26+
*/
27+
LIB_WEBRTC_CAPI rtcPeerConnectionFactoryHandle
28+
LibWebRTC_CreatePeerConnectionFactory();
29+
30+
/**
31+
* @brief Terminates the WebRTC PeerConnectionFactory and threads.
32+
*
33+
* Terminates the WebRTC PeerConnectionFactory and threads. This method is
34+
* thread-safe and can be called from any thread. It cleans up SSL and stops
35+
* and destroys the three threads: worker_thread, signaling_thread and
36+
* network_thread.
37+
*
38+
*/
39+
LIB_WEBRTC_CAPI void LibWebRTC_Terminate();
40+
}
41+
42+
#endif // LIB_WEBRTC_HXX_CAPI

include/ref_counted_object_capi.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef LIB_WEBRTC_REF_COUNTED_OBJECT_CAPI
2+
#define LIB_WEBRTC_REF_COUNTED_OBJECT_CAPI
3+
4+
#include "rtc_types_capi.h"
5+
6+
extern "C" {
7+
8+
LIB_WEBRTC_CAPI int RTCRefCountedObject_AddRef(rtcRefCountedObjectHandle handle);
9+
10+
LIB_WEBRTC_CAPI int RTCRefCountedObject_Release(rtcRefCountedObjectHandle handle);
11+
12+
} // extern "C"
13+
14+
#endif // LIB_WEBRTC_REF_COUNTED_OBJECT_CAPI
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef LIB_WEBRTC_RTC_PEERCONNECTION_FACTORY_HXX_CAPI
2+
#define LIB_WEBRTC_RTC_PEERCONNECTION_FACTORY_HXX_CAPI
3+
4+
#include "rtc_types_capi.h"
5+
6+
extern "C" {
7+
8+
typedef rtcRefCountedObjectHandle rtcPeerConnectionFactoryHandle;
9+
10+
LIB_WEBRTC_CAPI rtcBoolean
11+
RTCPeerConnectionFactory_Initialize(rtcPeerConnectionFactoryHandle factory);
12+
13+
LIB_WEBRTC_CAPI rtcBoolean
14+
RTCPeerConnectionFactory_Terminate(rtcPeerConnectionFactoryHandle factory);
15+
16+
LIB_WEBRTC_CAPI rtcResult
17+
RTCPeerConnectionFactory_Create(rtcPeerConnectionFactoryHandle factory,
18+
const void* configuration);
19+
}
20+
21+
#endif // LIB_WEBRTC_RTC_PEERCONNECTION_FACTORY_HXX_CAPI

include/rtc_types_capi.h

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#ifndef LIB_WEBRTC_RTC_TYPES_HXX_CAPI
2+
#define LIB_WEBRTC_RTC_TYPES_HXX_CAPI
3+
4+
#ifdef LIB_WEBRTC_API_EXPORTS
5+
#define LIB_WEBRTC_CAPI __declspec(dllexport)
6+
#elif defined(LIB_WEBRTC_API_DLL)
7+
#define LIB_WEBRTC_CAPI __declspec(dllimport)
8+
#elif !defined(WIN32)
9+
#define LIB_WEBRTC_CAPI __attribute__((visibility("default")))
10+
#else
11+
#define LIB_WEBRTC_CAPI
12+
#endif
13+
14+
#include <stdint.h>
15+
16+
extern "C" {
17+
typedef void* rtcRefCountedObjectHandle;
18+
19+
typedef struct {
20+
const char* message;
21+
} rtcError;
22+
23+
enum class rtcBoolean : int { kFalse = 0, kTrue = 1 };
24+
25+
enum class rtcResult : uint32_t {
26+
kSuccess = 0,
27+
kInvalidPointer = 1,
28+
};
29+
30+
const int kMaxIceServerSize = 8;
31+
32+
enum class MediaSecurityType : int {
33+
kSRTP_None = 0,
34+
kSDES_SRTP = 1,
35+
kDTLS_SRTP = 2
36+
};
37+
38+
enum class RTCMediaType : int {
39+
AUDIO = 0,
40+
VIDEO = 1,
41+
DATA = 2,
42+
UNSUPPORTED = 3
43+
};
44+
45+
struct IceServer {
46+
const char* uri = nullptr;
47+
const char* username = nullptr;
48+
const char* password = nullptr;
49+
};
50+
51+
enum class IceTransportsType { kNone, kRelay, kNoHost, kAll };
52+
53+
enum class TcpCandidatePolicy {
54+
kTcpCandidatePolicyEnabled,
55+
kTcpCandidatePolicyDisabled
56+
};
57+
58+
enum class CandidateNetworkPolicy {
59+
kCandidateNetworkPolicyAll,
60+
kCandidateNetworkPolicyLowCost
61+
};
62+
63+
enum class RtcpMuxPolicy {
64+
kRtcpMuxPolicyNegotiate,
65+
kRtcpMuxPolicyRequire,
66+
};
67+
68+
enum BundlePolicy {
69+
kBundlePolicyBalanced,
70+
kBundlePolicyMaxBundle,
71+
kBundlePolicyMaxCompat
72+
};
73+
74+
enum class SdpSemantics { kPlanB, kUnifiedPlan };
75+
76+
struct RTCConfiguration {
77+
IceServer ice_servers[kMaxIceServerSize];
78+
IceTransportsType type = IceTransportsType::kAll;
79+
BundlePolicy bundle_policy = BundlePolicy::kBundlePolicyBalanced;
80+
RtcpMuxPolicy rtcp_mux_policy = RtcpMuxPolicy::kRtcpMuxPolicyRequire;
81+
CandidateNetworkPolicy candidate_network_policy =
82+
CandidateNetworkPolicy::kCandidateNetworkPolicyAll;
83+
TcpCandidatePolicy tcp_candidate_policy =
84+
TcpCandidatePolicy::kTcpCandidatePolicyEnabled;
85+
86+
int ice_candidate_pool_size = 0;
87+
88+
MediaSecurityType srtp_type = MediaSecurityType::kDTLS_SRTP;
89+
SdpSemantics sdp_semantics = SdpSemantics::kUnifiedPlan;
90+
bool offer_to_receive_audio = true;
91+
bool offer_to_receive_video = true;
92+
93+
bool disable_ipv6 = false;
94+
bool disable_ipv6_on_wifi = false;
95+
int max_ipv6_networks = 5;
96+
bool disable_link_local_networks = false;
97+
int screencast_min_bitrate = -1;
98+
99+
// private
100+
bool use_rtp_mux = true;
101+
uint32_t local_audio_bandwidth = 128;
102+
uint32_t local_video_bandwidth = 512;
103+
};
104+
105+
struct SdpParseError {
106+
// The sdp line that causes the error.
107+
const char* line = nullptr;
108+
// Explains the error.
109+
const char* description = nullptr;
110+
};
111+
112+
enum DesktopType { kScreen, kWindow };
113+
114+
#define CHECK_POINTER_EX(p, r) \
115+
if ((p) == nullptr) { \
116+
return (r); \
117+
}
118+
119+
#define CHECK_POINTER(p) CHECK_POINTER_EX(p, rtcResult::kInvalidPointer)
120+
}
121+
122+
#endif // LIB_WEBRTC_RTC_TYPES_HXX

src/capi/libwebrtc_capi.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "include/libwebrtc_capi.h"
2+
3+
#include "include/libwebrtc.h"
4+
5+
using namespace libwebrtc;
6+
7+
rtcBoolean LibWebRTC_Initialize() {
8+
return LibWebRTC::Initialize() ? rtcBoolean::kTrue : rtcBoolean::kFalse;
9+
}
10+
11+
void LibWebRTC_Terminate() { LibWebRTC::Terminate(); }
12+
13+
rtcPeerConnectionFactoryHandle LibWebRTC_CreatePeerConnectionFactory() {
14+
scoped_refptr<RTCPeerConnectionFactory> p =
15+
LibWebRTC::CreateRTCPeerConnectionFactory();
16+
return static_cast<rtcPeerConnectionFactoryHandle>(p.release());
17+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "include/ref_counted_object_capi.h"
2+
3+
#include "base/refcount.h"
4+
#include "base/scoped_ref_ptr.h"
5+
6+
using namespace libwebrtc;
7+
8+
LIB_WEBRTC_CAPI int RTCRefCountedObject_AddRef(
9+
rtcRefCountedObjectHandle handle) {
10+
if (handle == nullptr) {
11+
return -1;
12+
}
13+
RefCountInterface* p = static_cast<RefCountInterface*>(handle);
14+
return p->AddRef();
15+
}
16+
17+
LIB_WEBRTC_CAPI int RTCRefCountedObject_Release(
18+
rtcRefCountedObjectHandle handle) {
19+
if (handle == nullptr) {
20+
return -1;
21+
}
22+
RefCountInterface* p = static_cast<RefCountInterface*>(handle);
23+
return p->Release();
24+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "include/rtc_peerconnection_factory_capi.h"
2+
3+
#include "include/rtc_peerconnection_factory.h"
4+
5+
using namespace libwebrtc;
6+
7+
rtcBoolean RTCPeerConnectionFactory_Initialize(
8+
rtcPeerConnectionFactoryHandle factory) {
9+
CHECK_POINTER_EX(factory, rtcBoolean::kFalse);
10+
11+
scoped_refptr<RTCPeerConnectionFactory> pFactory =
12+
static_cast<RTCPeerConnectionFactory*>(factory);
13+
return pFactory->Initialize() ? rtcBoolean::kTrue : rtcBoolean::kFalse;
14+
}
15+
16+
rtcBoolean RTCPeerConnectionFactory_Terminate(
17+
rtcPeerConnectionFactoryHandle factory) {
18+
CHECK_POINTER_EX(factory, rtcBoolean::kFalse);
19+
20+
scoped_refptr<RTCPeerConnectionFactory> pFactory =
21+
static_cast<RTCPeerConnectionFactory*>(factory);
22+
return pFactory->Terminate() ? rtcBoolean::kTrue : rtcBoolean::kFalse;
23+
}
24+
25+
LIB_WEBRTC_CAPI rtcResult RTCPeerConnectionFactory_Create(
26+
rtcPeerConnectionFactoryHandle factory, const void* configuration);

src/libwebrtc.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,24 @@ bool LibWebRTC::Initialize() {
1515
if (!g_is_initialized) {
1616
webrtc::InitializeSSL();
1717
g_is_initialized = true;
18+
#ifdef WEBRTC_WIN
19+
WSADATA data;
20+
WSAStartup(MAKEWORD(1, 0), &data);
21+
#endif
1822
}
1923
return g_is_initialized;
2024
}
2125

2226
// Stops and cleans up the threads and SSL.
2327
void LibWebRTC::Terminate() {
28+
if(!g_is_initialized) {
29+
return;
30+
}
2431
webrtc::ThreadManager::Instance()->SetCurrentThread(NULL);
2532
webrtc::CleanupSSL();
26-
33+
#ifdef WEBRTC_WIN
34+
WSACleanup();
35+
#endif
2736
// Resets the static variable g_is_initialized to false.
2837
g_is_initialized = false;
2938
}
@@ -34,7 +43,6 @@ LibWebRTC::CreateRTCPeerConnectionFactory() {
3443
scoped_refptr<RTCPeerConnectionFactory> rtc_peerconnection_factory =
3544
scoped_refptr<RTCPeerConnectionFactory>(
3645
new RefCountedObject<RTCPeerConnectionFactoryImpl>());
37-
rtc_peerconnection_factory->Initialize();
3846
return rtc_peerconnection_factory;
3947
}
4048

src/rtc_peerconnection_factory_impl.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ RTCPeerConnectionFactoryImpl::RTCPeerConnectionFactoryImpl() {}
4747
RTCPeerConnectionFactoryImpl::~RTCPeerConnectionFactoryImpl() {}
4848

4949
bool RTCPeerConnectionFactoryImpl::Initialize() {
50+
51+
task_queue_factory_ = webrtc::CreateDefaultTaskQueueFactory();
52+
5053
worker_thread_ = webrtc::Thread::Create();
5154
worker_thread_->SetName("worker_thread", nullptr);
5255
RTC_CHECK(worker_thread_->Start()) << "Failed to start thread";
@@ -59,7 +62,6 @@ bool RTCPeerConnectionFactoryImpl::Initialize() {
5962
network_thread_->SetName("network_thread", nullptr);
6063
RTC_CHECK(network_thread_->Start()) << "Failed to start thread";
6164
if (!audio_device_module_) {
62-
task_queue_factory_ = webrtc::CreateDefaultTaskQueueFactory();
6365
worker_thread_->BlockingCall([&] { CreateAudioDeviceModule_w(); });
6466
}
6567

@@ -105,11 +107,11 @@ bool RTCPeerConnectionFactoryImpl::Terminate() {
105107
video_device_impl_ = nullptr;
106108
audio_processing_impl_ = nullptr;
107109
});
108-
rtc_peerconnection_factory_ = NULL;
110+
109111
if (audio_device_module_) {
110112
worker_thread_->BlockingCall([this] { DestroyAudioDeviceModule_w(); });
111113
}
112-
114+
rtc_peerconnection_factory_ = nullptr;
113115
return true;
114116
}
115117

0 commit comments

Comments
 (0)