Skip to content

Commit 7e1e310

Browse files
Parallel conference bridge (#4241)
1 parent e5a6c68 commit 7e1e310

File tree

17 files changed

+4284
-19
lines changed

17 files changed

+4284
-19
lines changed

pjmedia/build/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export _LDFLAGS := $(APP_THIRD_PARTY_LIBS) \
5959
export PJMEDIA_SRCDIR = ../src/pjmedia
6060
export PJMEDIA_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
6161
alaw_ulaw.o alaw_ulaw_table.o avi_player.o avi_writer.o av_sync.o \
62-
bidirectional.o clock_thread.o codec.o conference.o \
62+
bidirectional.o clock_thread.o codec.o conference.o conf_thread.o \
6363
conf_switch.o converter.o converter_libswscale.o converter_libyuv.o \
6464
delaybuf.o echo_common.o \
6565
echo_port.o echo_suppress.o echo_webrtc.o echo_webrtc_aec3.o \

pjmedia/build/pjmedia.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@
616616
<ClCompile Include="..\src\pjmedia\clock_thread.c" />
617617
<ClCompile Include="..\src\pjmedia\codec.c" />
618618
<ClCompile Include="..\src\pjmedia\conference.c" />
619+
<ClCompile Include="..\src\pjmedia\conf_thread.c" />
619620
<ClCompile Include="..\src\pjmedia\conf_switch.c" />
620621
<ClCompile Include="..\src\pjmedia\converter.c" />
621622
<ClCompile Include="..\src\pjmedia\converter_libswscale.c" />

pjmedia/build/pjmedia.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
<ClCompile Include="..\src\pjmedia\conference.c">
3939
<Filter>Source Files</Filter>
4040
</ClCompile>
41+
<ClCompile Include="..\src\pjmedia\conf_thread.c">
42+
<Filter>Source Files</Filter>
43+
</ClCompile>
4144
<ClCompile Include="..\src\pjmedia\converter.c">
4245
<Filter>Source Files</Filter>
4346
</ClCompile>
@@ -239,6 +242,9 @@
239242
<ClCompile Include="..\src\pjmedia\av_sync.c">
240243
<Filter>Source Files</Filter>
241244
</ClCompile>
245+
<ClCompile Include="..\src\pjmedia\stream_imp_common.c">
246+
<Filter>Source Files</Filter>
247+
</ClCompile>
242248
</ItemGroup>
243249
<ItemGroup>
244250
<ClInclude Include="..\include\pjmedia\alaw_ulaw.h">

pjmedia/include/pjmedia/conference.h

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,96 @@ enum pjmedia_conf_option
208208
based. */
209209
};
210210

211+
/**
212+
* This structure specifies the conference bridge creation parameters.
213+
*/
214+
typedef struct pjmedia_conf_param
215+
{
216+
/**
217+
* Maximum number of slots/ports to be created in
218+
* the bridge. Note that the bridge internally uses
219+
* one port for the sound device, so the actual
220+
* maximum number of ports will be less one than
221+
* this value.
222+
*/
223+
unsigned max_slots;
224+
225+
/**
226+
* Set the sampling rate of the bridge. This value
227+
* is also used to set the sampling rate of the
228+
* sound device.
229+
*/
230+
unsigned sampling_rate;
231+
232+
/**
233+
* Number of channels in the PCM stream. Normally
234+
* the value will be 1 for mono, but application may
235+
* specify a value of 2 for stereo. Note that all
236+
* ports that will be connected to the bridge MUST
237+
* have the same number of channels as the bridge.
238+
*/
239+
unsigned channel_count;
240+
241+
/**
242+
* Set the number of samples per frame. This value
243+
* is also used to set the sound device.
244+
*/
245+
unsigned samples_per_frame;
246+
247+
/**
248+
* Set the number of bits per sample. This value
249+
* is also used to set the sound device. Currently
250+
* only 16bit per sample is supported.
251+
*/
252+
unsigned bits_per_sample;
253+
254+
/**
255+
* Bitmask options to be set for the bridge. The
256+
* options are constructed from #pjmedia_conf_option
257+
* enumeration.
258+
* The default value is zero.
259+
*/
260+
unsigned options;
261+
262+
/**
263+
* The number of worker threads to use by conference bridge.
264+
* Zero means the operations will be done only by get_frame() thread,
265+
* i.e. conference bridge will be sequential.
266+
* Set this parameter to non-zero value to enable parallel processing.
267+
* The number of worker threads should be less than or equal to the number
268+
* of the processor cores. However, the optimal number of worker threads
269+
* is application and hardware dependent.
270+
* The default value is zero - sequential conference bridge.
271+
* This value is compatible with previous behavior.
272+
* At compile time application developer can change the default value by
273+
* setting #PJMEDIA_CONF_THREADS macro in the config_site.h.
274+
* PJMEDIA_CONF_THREADS is total number of conference bridge threads
275+
* including get_frame() thread. worker_threads is the number of conference
276+
* bridge threads excluding get_frame() thread.
277+
* As a general rule worker_threads is 1 less than PJMEDIA_CONF_THREADS.
278+
* This value is ignored by all conference backends except for the
279+
* multithreaded conference bridge backend
280+
* (PJMEDIA_CONF_PARALLEL_BRIDGE_BACKEND).
281+
*
282+
* The total number of conference bridge threads can be configured at the
283+
* pjsua level using the pjsua_media_config::conf_threads parameter, or at
284+
* the pjsua2 level using the pjsua2::MediaConfig::confThreads parameter.
285+
*/
286+
unsigned worker_threads;
287+
} pjmedia_conf_param;
288+
289+
290+
/**
291+
* Initialize conference bridge creation parameters.
292+
*/
293+
PJ_INLINE(void) pjmedia_conf_param_default(pjmedia_conf_param *param)
294+
{
295+
pj_bzero(param, sizeof(pjmedia_conf_param));
296+
/* Set the default values */
297+
#if defined(PJMEDIA_CONF_THREADS) && PJMEDIA_CONF_THREADS > 1
298+
param->worker_threads = PJMEDIA_CONF_THREADS-1;
299+
#endif
300+
}
211301

212302
/**
213303
* Create conference bridge with the specified parameters. The sampling rate,
@@ -274,6 +364,47 @@ PJ_DECL(pj_status_t) pjmedia_conf_create( pj_pool_t *pool,
274364
unsigned options,
275365
pjmedia_conf **p_conf );
276366

367+
/**
368+
* Create conference bridge with the specified parameters. The sampling rate,
369+
* samples per frame, and bits per sample will be used for the internal
370+
* operation of the bridge (e.g. when mixing audio frames). However, ports
371+
* with different configuration may be connected to the bridge. In this case,
372+
* the bridge is able to perform sampling rate conversion, and buffering in
373+
* case the samples per frame is different.
374+
*
375+
* For this version of PJMEDIA, only 16bits per sample is supported.
376+
*
377+
* For this version of PJMEDIA, the channel count of the ports MUST match
378+
* the channel count of the bridge.
379+
*
380+
* Under normal operation (i.e. when PJMEDIA_CONF_NO_DEVICE option is NOT
381+
* specified), the bridge internally create an instance of sound device
382+
* and connect the sound device to port zero of the bridge.
383+
*
384+
* If PJMEDIA_CONF_NO_DEVICE options is specified, no sound device will
385+
* be created in the conference bridge. Application MUST acquire the port
386+
* interface of the bridge by calling #pjmedia_conf_get_master_port(), and
387+
* connect this port interface to a sound device port by calling
388+
* #pjmedia_snd_port_connect(), or to a master port (pjmedia_master_port)
389+
* if application doesn't want to instantiate any sound devices.
390+
*
391+
* The sound device or master port are crucial for the bridge's operation,
392+
* because it provides the bridge with necessary clock to process the audio
393+
* frames periodically. Internally, the bridge runs when get_frame() to
394+
* port zero is called.
395+
*
396+
* @param pool Pool to use to allocate the bridge and
397+
* additional buffers for the sound device.
398+
* @param param The conference bridge creation parameters.
399+
* See #pjmedia_conf_param for more information.
400+
* @param p_conf Pointer to receive the conference bridge instance.
401+
*
402+
* @return PJ_SUCCESS if conference bridge can be created.
403+
*/
404+
PJ_DECL(pj_status_t) pjmedia_conf_create2(pj_pool_t *pool,
405+
pjmedia_conf_param *param,
406+
pjmedia_conf **p_conf);
407+
277408

278409
/**
279410
* Destroy conference bridge. This will also remove any port, thus application

pjmedia/include/pjmedia/config.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,64 @@
120120
# define PJMEDIA_CONF_USE_AGC 1
121121
#endif
122122

123+
/**
124+
* Conference switch/bridge backend implementations.
125+
* Select one of these implementations in PJMEDIA_CONF_BACKEND.
126+
*/
127+
/** Conference switch board backend */
128+
#define PJMEDIA_CONF_SWITCH_BOARD_BACKEND 0
129+
/** Conference bridge sequential backend */
130+
#define PJMEDIA_CONF_SERIAL_BRIDGE_BACKEND 1
131+
/** Multithreaded conference bridge backend */
132+
#define PJMEDIA_CONF_PARALLEL_BRIDGE_BACKEND 2
133+
134+
/**
135+
* Choose which conference backend implementation to use.
136+
*
137+
* In order to use parallel conference bridge with real parallelism,
138+
* users need to:
139+
* 1. define PJMEDIA_CONF_BACKEND to PJMEDIA_CONF_PARALLEL_BRIDGE_BACKEND
140+
* and at least one of the following:
141+
* 2.1. define PJMEDIA_CONF_THREADS with a value > 1
142+
* This option allows pjmedia_conf_create() to create a parallel conference
143+
* and so convert any existing serial conference to parallel conference
144+
* without changing the code.
145+
* OR
146+
* 2.2. use pjmedia_conf_create2() with pjmedia_conf_param::worker_threads
147+
* initialized to a value > 0.
148+
*
149+
* Default is PJMEDIA_CONF_SERIAL_BRIDGE_BACKEND,
150+
* however
151+
* if PJMEDIA_CONF_USE_SWITCH_BOARD macro was defined, project system
152+
* selects PJMEDIA_CONF_SWITCH_BOARD_BACKEND by default,
153+
* otherwise if PJMEDIA_CONF_THREADS macro was defined, project system
154+
* selects PJMEDIA_CONF_PARALLEL_BRIDGE_BACKEND by default.
155+
*/
156+
#ifndef PJMEDIA_CONF_BACKEND
157+
# if defined(PJMEDIA_CONF_USE_SWITCH_BOARD) && PJMEDIA_CONF_USE_SWITCH_BOARD!=0
158+
# define PJMEDIA_CONF_BACKEND PJMEDIA_CONF_SWITCH_BOARD_BACKEND
159+
# elif defined(PJMEDIA_CONF_THREADS)
160+
# define PJMEDIA_CONF_BACKEND PJMEDIA_CONF_PARALLEL_BRIDGE_BACKEND
161+
# else
162+
# define PJMEDIA_CONF_BACKEND PJMEDIA_CONF_SERIAL_BRIDGE_BACKEND
163+
# endif
164+
#endif //PJMEDIA_CONF_BACKEND
165+
166+
/**
167+
* The default value for the total number of threads, including get_frame()
168+
* thread, that can be used by the conference bridge.
169+
* This value is used to determine if the conference bridge should be
170+
* implemented as a parallel bridge or not.
171+
* If this value is set to 1, the conference bridge will be implemented as a
172+
* serial bridge, otherwise it will be implemented as a parallel bridge.
173+
* PJMEDIA_CONF_THREADS should not be less than 1.
174+
*
175+
* Default value: 1 - serial bridge
176+
*/
177+
#ifndef PJMEDIA_CONF_THREADS
178+
# define PJMEDIA_CONF_THREADS 1
179+
#endif
180+
123181

124182
/*
125183
* Types of sound stream backends.

pjmedia/src/pjmedia/conf_switch.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include <pj/pool.h>
3030
#include <pj/string.h>
3131

32-
#if defined(PJMEDIA_CONF_USE_SWITCH_BOARD) && PJMEDIA_CONF_USE_SWITCH_BOARD!=0
32+
#if PJMEDIA_CONF_BACKEND == PJMEDIA_CONF_SWITCH_BOARD_BACKEND
3333

3434
/* CONF_DEBUG enables detailed operation of the conference bridge.
3535
* Beware that it prints large amounts of logs (several lines per frame).
@@ -209,6 +209,16 @@ static pj_status_t create_sound_port( pj_pool_t *pool,
209209
return PJ_SUCCESS;
210210
}
211211

212+
PJ_DEF(pj_status_t) pjmedia_conf_create2(pj_pool_t *pool,
213+
pjmedia_conf_param *param,
214+
pjmedia_conf **p_conf)
215+
{
216+
return pjmedia_conf_create(pool,
217+
param.max_slots, param.sampling_rate,
218+
param.channel_count, param.samples_per_frame,
219+
param.bits_per_sample, param.options, p_conf);
220+
}
221+
212222
/*
213223
* Create conference bridge.
214224
*/
@@ -1636,4 +1646,4 @@ PJ_DEF(pj_status_t) pjmedia_conf_del_destroy_handler(
16361646
}
16371647

16381648

1639-
#endif
1649+
#endif /* PJMEDIA_CONF_BACKEND == PJMEDIA_CONF_SWITCH_BOARD_BACKEND */

0 commit comments

Comments
 (0)