Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/mod/applications/mod_conference/conference_member.c
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,11 @@ int conference_member_setup_media(conference_member_t *member, conference_obj_t
goto codec_done1;
}

switch_mutex_lock(member->audio_in_mutex);
switch_buffer_zero(member->audio_buffer);
member->audio_buffer_primed = SWITCH_FALSE;
switch_mutex_unlock(member->audio_in_mutex);

/* Setup an audio buffer for the outgoing audio */
if (!member->mux_buffer && switch_buffer_create_dynamic(&member->mux_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n");
Expand Down
53 changes: 45 additions & 8 deletions src/mod/applications/mod_conference/mod_conference.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,50 @@ void conference_send_notify(conference_obj_t *conference, const char *status, co

}

static switch_bool_t conference_member_read_audio_frame(conference_member_t *member, uint32_t bytes)
{
switch_size_t inuse = 0;
switch_size_t min_bytes = bytes * CONF_AUDIO_BUFFER_MIN_FRAMES;
uint32_t buf_read = 0;
switch_bool_t have_audio = SWITCH_FALSE;

if (!member->audio_buffer || !member->frame) {
return SWITCH_FALSE;
}

switch_mutex_lock(member->audio_in_mutex);
inuse = switch_buffer_inuse(member->audio_buffer);
if (!member->audio_buffer_primed && inuse >= min_bytes) {
member->audio_buffer_primed = SWITCH_TRUE;
}
if (member->audio_buffer_primed && inuse < bytes) {
switch_mutex_unlock(member->audio_in_mutex);
switch_yield(CONF_AUDIO_BUFFER_RETRY_USEC);
switch_mutex_lock(member->audio_in_mutex);
inuse = switch_buffer_inuse(member->audio_buffer);
if (!member->audio_buffer_primed && inuse >= min_bytes) {
member->audio_buffer_primed = SWITCH_TRUE;
}
}

if (member->audio_buffer_primed && inuse >= bytes
&& (buf_read = (uint32_t) switch_buffer_read(member->audio_buffer, member->frame, bytes))) {
member->read = buf_read;

if (buf_read < bytes) {
memset(member->frame + buf_read, 0, bytes - buf_read);
member->audio_buffer_primed = SWITCH_FALSE;
}

conference_utils_member_set_flag_locked(member, MFLAG_HAS_AUDIO);
have_audio = SWITCH_TRUE;
} else if (member->audio_buffer_primed && inuse < bytes) {
member->audio_buffer_primed = SWITCH_FALSE;
}
switch_mutex_unlock(member->audio_in_mutex);

return have_audio;
}

/* Main monitor thread (1 per distinct conference room) */
void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *obj)
Expand Down Expand Up @@ -306,7 +350,6 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob

/* Read one frame of audio from each member channel and save it for redistribution */
for (imember = conference->members; imember; imember = imember->next) {
uint32_t buf_read = 0;
total++;
imember->read = 0;

Expand Down Expand Up @@ -370,15 +413,9 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
}

conference_utils_member_clear_flag_locked(imember, MFLAG_HAS_AUDIO);
switch_mutex_lock(imember->audio_in_mutex);

if (switch_buffer_inuse(imember->audio_buffer) >= bytes
&& (buf_read = (uint32_t) switch_buffer_read(imember->audio_buffer, imember->frame, bytes))) {
imember->read = buf_read;
conference_utils_member_set_flag_locked(imember, MFLAG_HAS_AUDIO);
if (conference_member_read_audio_frame(imember, bytes)) {
ready++;
}
switch_mutex_unlock(imember->audio_in_mutex);
}

conference->members_with_video = members_with_video;
Expand Down
5 changes: 5 additions & 0 deletions src/mod/applications/mod_conference/mod_conference.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
#define SCORE_IIR_SPEAKING_MAX 300
/* the threshold below which you cede the floor to someone loud (see above value). */
#define SCORE_IIR_SPEAKING_MIN 100
/* Keep a small input cushion so the mixer is not phase-locked to the input thread. */
#define CONF_AUDIO_BUFFER_MIN_FRAMES 2
/* Give a primed input thread a short grace period to deliver the next real frame. */
#define CONF_AUDIO_BUFFER_RETRY_USEC 1000
/* the FPS of the conference canvas */
#define FPS 30
/* max supported layers in one mcu */
Expand Down Expand Up @@ -803,6 +807,7 @@ struct conference_member {
conference_record_t *rec;
uint8_t *frame;
uint8_t *last_frame;
switch_bool_t audio_buffer_primed;
uint32_t frame_size;
uint8_t *mux_frame;
uint32_t read;
Expand Down