* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
if (stream) {
stream->write_function(stream, "Member %d (%s) 0.0:0.0:0.0\n", member->id, switch_channel_get_name(member->channel));
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member %d (%s) 0.0:0.0:0.0\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member %d (%s) 0.0:0.0:0.0\n",
member->id, switch_channel_get_name(member->channel));
}
}
radius = 1.0f;
pos = -90.0f;
-
+
for (member = conference->members; member; member = member->next) {
if (!member->channel || conference_utils_member_test_flag(member, MFLAG_NO_POSITIONAL) || !conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)) {
if (stream) {
stream->write_function(stream, "Member %d (%s) %0.2f:0.0:%0.2f\n", member->id, switch_channel_get_name(member->channel), x, z);
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member %d (%s) %0.2f:0.0:%0.2f\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member %d (%s) %0.2f:0.0:%0.2f\n",
member->id, switch_channel_get_name(member->channel), x, z);
}
pos += offset;
}
-
+
end:
switch_mutex_unlock(conference->member_mutex);
if ((al->device = alcLoopbackOpenDeviceSOFT(NULL))) {
const ALshort silence[16] = { 0 };
float orient[6] = { /*fwd:*/ 0., 0., -1., /*up:*/ 0., 1., 0. };
-
+
al->context = alcCreateContext(al->device, contextAttr);
alcSetThreadContext(al->context);
-
+
/* listener at origin, facing down -z (ears at 0.0m height) */
alListener3f( AL_POSITION, 0. ,0, 0. );
alListener3f( AL_VELOCITY, 0., 0., 0. );
alListenerfv( AL_ORIENTATION, orient );
-
+
alGenSources(1, &al->source);
alSourcef( al->source, AL_PITCH, 1.);
alSourcef( al->source, AL_GAIN, 1.);
if (al->device) {
ALint processed = 0, state = 0;
-
+
//alcSetThreadContext(al->context);
alGetSourcei(al->source, AL_SOURCE_STATE, &state);
alGetSourcei(al->source, AL_BUFFERS_PROCESSED, &processed);
-
+
if (al->setpos) {
al->setpos = 0;
alSource3f(al->source, AL_POSITION, al->pos_x, al->pos_y, al->pos_z);
//alSource3f(al->source, AL_VELOCITY, .01, 0., 0.);
}
-
+
if (processed > 0) {
ALuint bufid;
alSourceUnqueueBuffers(al->source, 1, &bufid);
if (state != AL_PLAYING) {
alSourcePlay(al->source);
}
-
+
alcRenderSamplesSOFT(al->device, data, datalen / 2);
}
}
#endif
#ifndef OPENAL_POSITIONING
-switch_status_t conference_al_parse_position(al_handle_t *al, const char *data)
+switch_status_t conference_al_parse_position(al_handle_t *al, const char *data)
{
return SWITCH_STATUS_FALSE;
}
-#else
-switch_status_t conference_al_parse_position(al_handle_t *al, const char *data)
+#else
+switch_status_t conference_al_parse_position(al_handle_t *al, const char *data)
{
char *args[3];
int num;
char *dup;
-
+
dup = strdup((char *)data);
switch_assert(dup);
-
+
if ((num = switch_split(dup, ':', args)) != 3) {
return SWITCH_STATUS_FALSE;
}
{
if (!al) return;
- switch_mutex_lock(conference_globals.setup_mutex);
+ switch_mutex_lock(conference_globals.setup_mutex);
if (al->source) {
alDeleteSources(1, &al->source);
al->source = 0;
}
#endif
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
} else if (argv[1] && strcasecmp(argv[1], "dial") == 0) {
if (conference_api_sub_dial(NULL, stream, argc, argv) != SWITCH_STATUS_SUCCESS) {
/* command returned error, so show syntax usage */
- stream->write_function(stream, "%s %s", conference_api_sub_commands[CONF_API_COMMAND_DIAL].pcommand,
+ stream->write_function(stream, "%s %s", conference_api_sub_commands[CONF_API_COMMAND_DIAL].pcommand,
conference_api_sub_commands[CONF_API_COMMAND_DIAL].psyntax);
}
} else if (argv[1] && strcasecmp(argv[1], "bgdial") == 0) {
}
}
-
+
switch_safe_free(lbuf);
return status;
}
-switch_status_t conference_api_sub_syntax(char **syntax)
+switch_status_t conference_api_sub_syntax(char **syntax)
{
- /* build api interface help ".syntax" field string */
- uint32_t i;
- size_t nl = 0, ol = 0;
- char cmd_str[256];
- char *tmp = NULL, *p = strdup("");
-
- for (i = 0; i < CONFFUNCAPISIZE; i++) {
- nl = strlen(conference_api_sub_commands[i].pcommand) + strlen(conference_api_sub_commands[i].psyntax) + 5;
-
- switch_snprintf(cmd_str, sizeof(cmd_str), "add conference ::conference::conference_list_conferences %s", conference_api_sub_commands[i].pcommand);
- switch_console_set_complete(cmd_str);
-
- if (p != NULL) {
- ol = strlen(p);
- }
- tmp = realloc(p, ol + nl);
- if (tmp != NULL) {
- p = tmp;
- strcat(p, "\t\t");
- strcat(p, conference_api_sub_commands[i].pcommand);
- if (!zstr(conference_api_sub_commands[i].psyntax)) {
- strcat(p, " ");
- strcat(p, conference_api_sub_commands[i].psyntax);
- }
- if (i < CONFFUNCAPISIZE - 1) {
- strcat(p, "\n");
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't realloc\n");
- return SWITCH_STATUS_TERM;
- }
- }
-
- *syntax = p;
-
- return SWITCH_STATUS_SUCCESS;
+ /* build api interface help ".syntax" field string */
+ uint32_t i;
+ size_t nl = 0, ol = 0;
+ char cmd_str[256];
+ char *tmp = NULL, *p = strdup("");
+
+ for (i = 0; i < CONFFUNCAPISIZE; i++) {
+ nl = strlen(conference_api_sub_commands[i].pcommand) + strlen(conference_api_sub_commands[i].psyntax) + 5;
+
+ switch_snprintf(cmd_str, sizeof(cmd_str), "add conference ::conference::conference_list_conferences %s", conference_api_sub_commands[i].pcommand);
+ switch_console_set_complete(cmd_str);
+
+ if (p != NULL) {
+ ol = strlen(p);
+ }
+ tmp = realloc(p, ol + nl);
+ if (tmp != NULL) {
+ p = tmp;
+ strcat(p, "\t\t");
+ strcat(p, conference_api_sub_commands[i].pcommand);
+ if (!zstr(conference_api_sub_commands[i].psyntax)) {
+ strcat(p, " ");
+ strcat(p, conference_api_sub_commands[i].psyntax);
+ }
+ if (i < CONFFUNCAPISIZE - 1) {
+ strcat(p, "\n");
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't realloc\n");
+ return SWITCH_STATUS_TERM;
+ }
+ }
+
+ *syntax = p;
+
+ return SWITCH_STATUS_SUCCESS;
}
conference->agc_level = 0;
return SWITCH_STATUS_SUCCESS;
}
-
+
if (argc > 3) {
level = atoi(argv[3]);
} else {
if (stream) {
stream->write_function(stream, "OK AGC ENABLED %d\n", conference->agc_level);
}
-
+
} else {
if (stream) {
stream->write_function(stream, "-ERR invalid level\n");
return SWITCH_STATUS_SUCCESS;
-
+
}
switch_status_t conference_api_sub_mute(conference_member_t *member, switch_stream_handle_t *stream, void *data)
}
conference_video_vmute_snap(member, clear);
-
+
return SWITCH_STATUS_SUCCESS;
}
conference_utils_member_clear_flag_locked(member, MFLAG_CAN_BE_SEEN);
conference_video_reset_video_bitrate_counters(member);
-
+
if (member->channel) {
switch_channel_set_flag(member->channel, CF_VIDEO_PAUSE_READ);
switch_core_session_request_video_refresh(member->session);
if (member == NULL)
return SWITCH_STATUS_GENERR;
-
+
if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) {
return SWITCH_STATUS_SUCCESS;
}
if (member == NULL) {
return SWITCH_STATUS_GENERR;
}
-
+
conference_utils_member_clear_flag(member, MFLAG_RUNNING);
if (member->conference && test_eflag(member->conference, EFLAG_HUP_MEMBER)) {
if (member == NULL) {
return SWITCH_STATUS_GENERR;
}
-
+
conference_utils_member_clear_flag(member, MFLAG_RUNNING);
conference_utils_member_set_flag_locked(member, MFLAG_KICKED);
switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK);
for(p = dtmf; p && *p; p++) {
switch_dtmf_t *dt, digit = { *p, SWITCH_DEFAULT_DTMF_DURATION };
-
+
switch_zmalloc(dt, sizeof(*dt));
*dt = digit;
-
+
switch_queue_push(member->dtmf_queue, dt);
switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK);
}
if (switch_is_number(val)) {
index = atoi(val) - 1;
-
+
if (index < 0) {
index = 0;
}
}
stream->write_function(stream, "+OK positioning %s\n", conference_utils_test_flag(conference, CFLAG_POSITIONAL) ? "on" : "off");
-
+
#else
stream->write_function(stream, "-ERR not supported\n");
-
+
#endif
return SWITCH_STATUS_SUCCESS;
conference_utils_member_set_flag(member, MFLAG_POSITIONAL);
member->al = conference_al_create(member->pool);
} else {
-
+
if (stream) {
stream->write_function(stream, "Positional audio not avalilable %d\n", member->conference->channels);
}
return SWITCH_STATUS_FALSE;
}
}
-
+
if (stream != NULL) {
stream->write_function(stream, "Position %u = %0.2f:%0.2f:%0.2f\n", member->id, member->al->pos_x, member->al->pos_y, member->al->pos_z);
}
return SWITCH_STATUS_SUCCESS;
-
+
}
switch_status_t conference_api_sub_write_png(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
int xx = 4;
if ((group_name = strchr(argv[2], ':'))) {
- group_name++;
- xx--;
+ group_name++;
+ xx--;
} else {
- group_name = argv[3];
+ group_name = argv[3];
}
if (!group_name) {
- stream->write_function(stream, "Group name not specified.\n");
- return SWITCH_STATUS_SUCCESS;
+ stream->write_function(stream, "Group name not specified.\n");
+ return SWITCH_STATUS_SUCCESS;
} else {
- if (((lg = switch_core_hash_find(conference->layout_group_hash, group_name)))) {
+ if (((lg = switch_core_hash_find(conference->layout_group_hash, group_name)))) {
vlayout = conference_video_find_best_layout(conference, lg, 0);
}
if (!vlayout) {
- stream->write_function(stream, "Invalid group layout [%s]\n", group_name);
+ stream->write_function(stream, "Invalid group layout [%s]\n", group_name);
return SWITCH_STATUS_SUCCESS;
}
stream->write_function(stream, "Invalid layout [%s]\n", argv[2]);
return SWITCH_STATUS_SUCCESS;
}
-
+
if (idx < 0 || idx > conference->canvas_count - 1) idx = 0;
-
+
stream->write_function(stream, "Change canvas %d to layout [%s]\n", idx + 1, vlayout->name);
switch_mutex_lock(conference->member_mutex);
layer = &member->conference->canvas->layers[member->video_layer_id];
switch_mutex_lock(layer->canvas->mutex);
-
+
if (strcasecmp(text, "clear")) {
member->video_logo = switch_core_strdup(member->pool, text);
}
switch_mutex_lock(member->conference->canvas->mutex);
//layer = &member->conference->canvas->layers[member->video_layer_id];
-
+
if (!strcasecmp(text, "clear") || (member->video_reservation_id && !strcasecmp(text, member->video_reservation_id))) {
member->video_reservation_id = NULL;
stream->write_function(stream, "+OK reservation_id cleared\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s OK video floor auto\n", member->conference->name);
} else {
stream->write_function(stream, "OK floor none\n");
- }
-
+ }
+
} else if (force || member->conference->video_floor_holder == 0) {
conference_utils_set_flag(member->conference, CFLAG_VID_FLOOR_LOCK);
conference_video_set_floor_holder(member->conference, member, SWITCH_TRUE);
if (test_eflag(member->conference, EFLAG_FLOOR_CHANGE)) {
if (stream == NULL) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s OK video floor %d %s\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s OK video floor %d %s\n",
member->conference->name, member->id, switch_channel_get_name(member->channel));
} else {
stream->write_function(stream, "OK floor %u\n", member->id);
}
} else {
if (stream == NULL) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s floor already held by %d %s\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s floor already held by %d %s\n",
member->conference->name, member->id, switch_channel_get_name(member->channel));
} else {
stream->write_function(stream, "ERR floor is held by %u\n", member->conference->video_floor_holder);
switch_mutex_lock(conference->mutex);
conference_fnode_seek(conference->fnode, stream, argv[2]);
switch_mutex_unlock(conference->mutex);
-
+
return SWITCH_STATUS_SUCCESS;
}
uint32_t id = atoi(argv[3]);
conference_member_t *member = conference_member_get(conference, id);
if (member == NULL) {
- stream->write_function(stream, "Member: %u not found.\n", id);
- return SWITCH_STATUS_GENERR;
+ stream->write_function(stream, "Member: %u not found.\n", id);
+ return SWITCH_STATUS_GENERR;
}
-
+
switch_mutex_lock(member->fnode_mutex);
conference_fnode_seek(member->fnode, stream, argv[2]);
switch_mutex_unlock(member->fnode_mutex);
if (conference->fnode && conference->fnode->fh.params) {
switch_event_merge(event, conference->fnode->fh.params);
}
-
+
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", argv[2]);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", async ? "true" : "false");
}
ret_status = SWITCH_STATUS_SUCCESS;
- done:
+ done:
if (member) {
switch_thread_rwlock_unlock(member->rwlock);
for (rel = member->relationships; rel; rel = rel->next) {
stream->write_function(stream, "%d -> %d %s%s%s\n", member->id, rel->id,
- (rel->flags & RFLAG_CAN_SPEAK) ? "SPEAK " : "NOSPEAK ",
- (rel->flags & RFLAG_CAN_HEAR) ? "HEAR " : "NOHEAR ",
- (rel->flags & RFLAG_CAN_SEND_VIDEO) ? "SENDVIDEO " : "NOSENDVIDEO ");
+ (rel->flags & RFLAG_CAN_SPEAK) ? "SPEAK " : "NOSPEAK ",
+ (rel->flags & RFLAG_CAN_HEAR) ? "HEAR " : "NOHEAR ",
+ (rel->flags & RFLAG_CAN_SEND_VIDEO) ? "SENDVIDEO " : "NOSENDVIDEO ");
}
}
} else {
stream->write_function(stream, "relationship %u->%u not found.\n", id, oid);
}
-skip:
+ skip:
if (member) {
switch_thread_rwlock_unlock(member->rwlock);
}
switch_assert(conference != NULL);
switch_assert(stream != NULL);
-
+
if (argc <= 2) {
stream->write_function(stream, "Not enough args\n");
return SWITCH_STATUS_GENERR;
}
-
+
if ( !strcasecmp(argv[2], "on") ) {
conference_utils_set_flag_locked(conference, CFLAG_EXIT_SOUND);
stream->write_function(stream, "OK %s exit sounds on (%s)\n", argv[0], conference->exit_sound);
conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "exit-sounds-off");
switch_event_fire(&event);
- }
+ }
} else if ( !strcasecmp(argv[2], "file") ) {
if (! argv[3]) {
stream->write_function(stream, "No filename specified\n");
conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "exit-sound-file-changed");
switch_event_fire(&event);
- }
+ }
}
} else {
stream->write_function(stream, "Bad args\n");
- return SWITCH_STATUS_GENERR;
+ return SWITCH_STATUS_GENERR;
}
-
+
return 0;
}
switch_assert(conference != NULL);
switch_assert(stream != NULL);
-
+
if (argc <= 2) {
stream->write_function(stream, "Not enough args\n");
return SWITCH_STATUS_GENERR;
}
-
+
if ( !strcasecmp(argv[2], "on") ) {
conference_utils_set_flag_locked(conference, CFLAG_ENTER_SOUND);
stream->write_function(stream, "OK %s enter sounds on (%s)\n", argv[0], conference->enter_sound);
conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "enter-sounds-off");
switch_event_fire(&event);
- }
+ }
} else if ( !strcasecmp(argv[2], "file") ) {
if (! argv[3]) {
stream->write_function(stream, "No filename specified\n");
conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "enter-sound-file-changed");
switch_event_fire(&event);
- }
+ }
}
} else {
stream->write_function(stream, "Bad args\n");
- return SWITCH_STATUS_GENERR;
+ return SWITCH_STATUS_GENERR;
}
-
+
return 0;
}
}
if (conference && argv[2] && strstr(argv[2], "vlc/")) {
- tmp = switch_core_sprintf(conference->pool, "{vlc_rate=%d,vlc_channels=%d,vlc_interval=%d}%s",
+ tmp = switch_core_sprintf(conference->pool, "{vlc_rate=%d,vlc_channels=%d,vlc_interval=%d}%s",
conference->rate, conference->channels, conference->interval, argv[2]);
argv[2] = tmp;
}
switch_assert(conference != NULL);
switch_assert(stream != NULL);
-
+
if (argc > 3 && !zstr(argv[2])) {
int x;
switch_channel_t *channel;
switch_event_t *event;
char *xdest = NULL;
-
+
if (!id || !(member = conference_member_get(conference, id))) {
stream->write_function(stream, "No Member %u in conference %s.\n", id, conference->name);
continue;
channel = switch_core_session_get_channel(member->session);
xdest = switch_core_session_sprintf(member->session, "conference:%s@%s", conference_name, profile_name);
switch_ivr_session_transfer(member->session, xdest, "inline", NULL);
-
+
switch_channel_set_variable(channel, "last_transfered_conference", conference_name);
stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]);
-
+
/* tell them what happened */
if (test_eflag(conference, EFLAG_TRANSFER) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "non-existant recording '%s'\n", argv[2]);
} else {
if (test_eflag(conference, EFLAG_RECORD) &&
- switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+ switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-recording");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", all ? "all" : argv[2]);
return SWITCH_STATUS_GENERR;
}
stream->write_function(stream, "%s recording file %s\n",
- action == REC_ACTION_PAUSE ? "Pause" : "Resume", argv[2]);
+ action == REC_ACTION_PAUSE ? "Pause" : "Resume", argv[2]);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s recording file %s\n",
- action == REC_ACTION_PAUSE ? "Pause" : "Resume", argv[2]);
+ action == REC_ACTION_PAUSE ? "Pause" : "Resume", argv[2]);
if (!conference_record_action(conference, argv[2], action)) {
stream->write_function(stream, "non-existant recording '%s'\n", argv[2]);
} else {
if (test_eflag(conference, EFLAG_RECORD) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS)
- {
- conference_event_add_data(conference, event);
- if (action == REC_ACTION_PAUSE) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "pause-recording");
- } else {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "resume-recording");
+ {
+ conference_event_add_data(conference, event);
+ if (action == REC_ACTION_PAUSE) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "pause-recording");
+ } else {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "resume-recording");
+ }
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", argv[2]);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Recordings", conference->record_count ? "true" : "false");
+ switch_event_fire(&event);
}
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", argv[2]);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Recordings", conference->record_count ? "true" : "false");
- switch_event_fire(&event);
- }
}
return SWITCH_STATUS_SUCCESS;
ok = 1;
}
switch_mutex_unlock(conference->mutex);
-
+
if (ok) {
stream->write_function(stream, "volume changed\n");
}
switch_status_t conference_api_sub_get(conference_obj_t *conference,
- switch_stream_handle_t *stream, int argc, char **argv) {
+ switch_stream_handle_t *stream, int argc, char **argv) {
int ret_status = SWITCH_STATUS_GENERR;
if (argc != 3) {
ret_status = SWITCH_STATUS_SUCCESS;
if (strcasecmp(argv[2], "run_time") == 0) {
stream->write_function(stream, "%ld",
- switch_epoch_time_now(NULL) - conference->run_time);
+ switch_epoch_time_now(NULL) - conference->run_time);
} else if (strcasecmp(argv[2], "count") == 0) {
stream->write_function(stream, "%d",
- conference->count);
+ conference->count);
} else if (strcasecmp(argv[2], "count_ghosts") == 0) {
stream->write_function(stream, "%d",
- conference->count_ghosts);
+ conference->count_ghosts);
} else if (strcasecmp(argv[2], "max_members") == 0) {
stream->write_function(stream, "%d",
- conference->max_members);
+ conference->max_members);
} else if (strcasecmp(argv[2], "rate") == 0) {
stream->write_function(stream, "%d",
- conference->rate);
+ conference->rate);
} else if (strcasecmp(argv[2], "profile_name") == 0) {
stream->write_function(stream, "%s",
- conference->profile_name);
+ conference->profile_name);
} else if (strcasecmp(argv[2], "sound_prefix") == 0) {
stream->write_function(stream, "%s",
- conference->sound_prefix);
+ conference->sound_prefix);
} else if (strcasecmp(argv[2], "caller_id_name") == 0) {
stream->write_function(stream, "%s",
- conference->caller_id_name);
+ conference->caller_id_name);
} else if (strcasecmp(argv[2], "caller_id_number") == 0) {
stream->write_function(stream, "%s",
- conference->caller_id_number);
+ conference->caller_id_number);
} else if (strcasecmp(argv[2], "is_locked") == 0) {
stream->write_function(stream, "%s",
- conference_utils_test_flag(conference, CFLAG_LOCKED) ? "locked" : "");
+ conference_utils_test_flag(conference, CFLAG_LOCKED) ? "locked" : "");
} else if (strcasecmp(argv[2], "endconference_grace_time") == 0) {
stream->write_function(stream, "%d",
- conference->endconference_grace_time);
+ conference->endconference_grace_time);
} else if (strcasecmp(argv[2], "uuid") == 0) {
stream->write_function(stream, "%s",
- conference->uuid_str);
+ conference->uuid_str);
} else if (strcasecmp(argv[2], "wait_mod") == 0) {
stream->write_function(stream, "%s",
- conference_utils_test_flag(conference, CFLAG_WAIT_MOD) ? "true" : "");
+ conference_utils_test_flag(conference, CFLAG_WAIT_MOD) ? "true" : "");
} else {
ret_status = SWITCH_STATUS_FALSE;
}
}
switch_status_t conference_api_sub_set(conference_obj_t *conference,
- switch_stream_handle_t *stream, int argc, char **argv) {
+ switch_stream_handle_t *stream, int argc, char **argv) {
int ret_status = SWITCH_STATUS_GENERR;
if (argc != 4 || zstr(argv[3])) {
} else {
ret_status = SWITCH_STATUS_FALSE;
}
- } else if (strcasecmp(argv[2], "sound_prefix") == 0) {
+ } else if (strcasecmp(argv[2], "sound_prefix") == 0) {
stream->write_function(stream, "%s",conference->sound_prefix);
conference->sound_prefix = switch_core_strdup(conference->pool, argv[3]);
- } else if (strcasecmp(argv[2], "caller_id_name") == 0) {
+ } else if (strcasecmp(argv[2], "caller_id_name") == 0) {
stream->write_function(stream, "%s",conference->caller_id_name);
conference->caller_id_name = switch_core_strdup(conference->pool, argv[3]);
- } else if (strcasecmp(argv[2], "caller_id_number") == 0) {
+ } else if (strcasecmp(argv[2], "caller_id_number") == 0) {
stream->write_function(stream, "%s",conference->caller_id_number);
conference->caller_id_number = switch_core_strdup(conference->pool, argv[3]);
} else if (strcasecmp(argv[2], "endconference_grace_time") == 0) {
- int new_gt = atoi(argv[3]);
- if (new_gt >= 0) {
- stream->write_function(stream, "%d", conference->endconference_grace_time);
- conference->endconference_grace_time = new_gt;
- } else {
- ret_status = SWITCH_STATUS_FALSE;
- }
+ int new_gt = atoi(argv[3]);
+ if (new_gt >= 0) {
+ stream->write_function(stream, "%d", conference->endconference_grace_time);
+ conference->endconference_grace_time = new_gt;
+ } else {
+ ret_status = SWITCH_STATUS_FALSE;
+ }
} else {
ret_status = SWITCH_STATUS_FALSE;
}
return status;
}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
if (!(xml = switch_xml_new("conference-info"))) {
abort();
}
-
+
switch_mutex_lock(conference->mutex);
switch_snprintf(tmp, sizeof(tmp), "%u", conference->doc_version);
conference->doc_version++;
}
}
}
-
+
switch_xml_set_attr_d(xml, "version", tmpp);
switch_xml_set_attr_d(xml, "state", "full");
switch_xml_set_attr_d(xml, "xmlns", "urn:ietf:params:xml:ns:conference-info");
-
+
uri = switch_mprintf("sip:%s@%s", name, domain);
switch_xml_set_attr_d(xml, "entity", uri);
if (!(x_tag = switch_xml_add_child_d(xml, "conference-description", off++))) {
abort();
}
-
+
if (!(x_tag1 = switch_xml_add_child_d(x_tag, "display-text", off1++))) {
abort();
}
abort();
}
switch_snprintf(tmp, sizeof(tmp), "%u", conference->count);
- switch_xml_set_txt_d(x_tag1, tmpp);
+ switch_xml_set_txt_d(x_tag1, tmpp);
#if 0
if (conference->count == 0) {
if (!(x_tag1 = switch_xml_add_child_d(x_tag, "active", off1++))) {
abort();
}
- switch_xml_set_txt_d(x_tag1, "true");
-
+ switch_xml_set_txt_d(x_tag1, "true");
+
off1 = off2 = off3 = off4 = 0;
if (!(x_tag = switch_xml_add_child_d(xml, "users", off++))) {
abort();
}
-
+
switch_mutex_lock(conference->member_mutex);
-
+
for (np = conference->cdr_nodes; np; np = np->next) {
char *user_uri = NULL;
switch_channel_t *channel = NULL;
-
+
if (!np->cp || (np->member && !np->member->session) || np->leave_time) { /* for now we'll remove participants when the leave */
continue;
}
user_uri = strdup(uri);
}
}
-
+
if (!user_uri) {
user_uri = switch_mprintf("sip:%s@%s", np->cp->caller_id_number, domain);
}
-
-
+
+
switch_xml_set_attr_d(x_tag1, "state", "full");
switch_xml_set_attr_d(x_tag1, "entity", user_uri);
abort();
}
switch_xml_set_txt_d(x_tag2, np->cp->caller_id_name);
-
+
if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "endpoint", off2++))) {
abort();
}
switch_xml_set_attr_d(x_tag2, "entity", user_uri);
-
+
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "display-text", off3++))) {
abort();
}
char *p;
switch_time_exp_lt(&tm, (switch_time_t) conference->start_time * 1000000);
- switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm);
+ switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm);
p = end_of_p(tmpp) -1;
snprintf(p, 4, ":00");
}
-
- /** ok so this is in the rfc but not the xsd
- if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "joining-method", off3++))) {
+
+ /** ok so this is in the rfc but not the xsd
+ if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "joining-method", off3++))) {
abort();
- }
- switch_xml_set_txt_d(x_tag3, np->cp->direction == SWITCH_CALL_DIRECTION_INBOUND ? "dialed-in" : "dialed-out");
+ }
+ switch_xml_set_txt_d(x_tag3, np->cp->direction == SWITCH_CALL_DIRECTION_INBOUND ? "dialed-in" : "dialed-out");
*/
if (np->member) {
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "media", off3++))) {
abort();
}
-
+
snprintf(tmp, sizeof(tmp), "%ua", np->member->id);
switch_xml_set_attr_d(x_tag3, "id", tmpp);
}
switch_xml_set_txt_d(x_tag4, var);
}
-
+
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "status", off4++))) {
abort();
}
switch_xml_set_txt_d(x_tag4, conference_cdr_audio_flow(np->member));
-
-
+
+
if (switch_channel_test_flag(channel, CF_VIDEO)) {
off4 = 0;
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "media", off3++))) {
abort();
}
-
+
snprintf(tmp, sizeof(tmp), "%uv", np->member->id);
switch_xml_set_attr_d(x_tag3, "id", tmpp);
}
switch_xml_set_txt_d(x_tag4, var);
}
-
+
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "status", off4++))) {
abort();
}
switch_xml_set_txt_d(x_tag4, switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv");
-
+
}
}
-
+
switch_safe_free(user_uri);
}
xml_text = switch_xml_toxml(xml, SWITCH_TRUE);
switch_xml_free(xml);
-
+
switch_safe_free(dup_domain);
- switch_safe_free(uri);
+ switch_safe_free(uri);
return xml_text;
}
cJSON *json = cJSON_CreateObject(), *jusers = NULL, *jold_users = NULL, *juser = NULL, *jvars = NULL;
switch_assert(json);
-
+
switch_mutex_lock(conference->mutex);
switch_snprintf(tmp, sizeof(tmp), "%u", conference->doc_version);
conference->doc_version++;
domain = "cluecon.com";
}
}
-
+
uri = switch_mprintf("%s@%s", name, domain);
- json_add_child_string(json, "entity", uri);
- json_add_child_string(json, "conferenceDescription", conference->desc ? conference->desc : "FreeSWITCH Conference");
- json_add_child_string(json, "conferenceState", "active");
+ json_add_child_string(json, "entity", uri);
+ json_add_child_string(json, "conferenceDescription", conference->desc ? conference->desc : "FreeSWITCH Conference");
+ json_add_child_string(json, "conferenceState", "active");
switch_snprintf(tmp, sizeof(tmp), "%u", conference->count);
- json_add_child_string(json, "userCount", tmp);
-
+ json_add_child_string(json, "userCount", tmp);
+
jusers = json_add_child_array(json, "users");
jold_users = json_add_child_array(json, "oldUsers");
-
+
switch_mutex_lock(conference->member_mutex);
-
+
for (np = conference->cdr_nodes; np; np = np->next) {
char *user_uri = NULL;
switch_channel_t *channel = NULL;
switch_size_t retsize;
const char *fmt = "%Y-%m-%dT%H:%M:%S%z";
char *p;
-
+
if (np->record_path || !np->cp) {
continue;
}
user_uri = strdup(uri);
}
}
-
+
if (np->cp) {
if (!user_uri) {
user_uri = switch_mprintf("%s@%s", np->cp->caller_id_number, domain);
}
-
+
json_add_child_string(juser, "entity", user_uri);
json_add_child_string(juser, "displayText", np->cp->caller_id_name);
}
//if (np->record_path) {
- //json_add_child_string(juser, "recordingPATH", np->record_path);
+ //json_add_child_string(juser, "recordingPATH", np->record_path);
//}
json_add_child_string(juser, "status", np->leave_time ? "disconnected" : "connected");
switch_time_exp_lt(&tm, (switch_time_t) conference->start_time * 1000000);
- switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm);
+ switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm);
p = end_of_p(tmpp) -1;
snprintf(p, 4, ":00");
json_add_child_string(jvars, hp->name, hp->value);
}
}
-
+
switch_json_add_presence_data_cols(var_event, jvars, "PD-");
switch_event_destroy(&var_event);
if ((var = switch_channel_get_variable(channel, "rtp_use_ssrc"))) {
json_add_child_string(juser, "rtpAudioSSRC", var);
}
-
+
json_add_child_string(juser, "rtpAudioDirection", conference_cdr_audio_flow(np->member));
-
-
+
+
if (switch_channel_test_flag(channel, CF_VIDEO)) {
if ((var = switch_channel_get_variable(channel, "rtp_use_video_ssrc"))) {
json_add_child_string(juser, "rtpVideoSSRC", var);
}
-
+
json_add_child_string(juser, "rtpVideoDirection", switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv");
}
}
}
cJSON_AddItemToArray(np->leave_time ? jold_users : jusers, juser);
-
+
switch_safe_free(user_uri);
}
switch_mutex_unlock(conference->member_mutex);
switch_safe_free(dup_domain);
- switch_safe_free(uri);
+ switch_safe_free(uri);
return json;
}
member->cdr_node->cp = switch_caller_profile_dup(member->conference->pool, cp);
member->cdr_node->id = member->id;
-
-
+
+
}
void conference_cdr_rejected(conference_obj_t *conference, switch_channel_t *channel, cdr_reject_reason_t reason)
if (!(x_conference = switch_xml_add_child_d(cdr, "conference", cdr_off++))) {
abort();
}
-
+
if (!(x_ptr = switch_xml_add_child_d(x_conference, "name", conference_off++))) {
abort();
}
switch_xml_set_txt_d(x_ptr, conference->name);
-
+
if (!(x_ptr = switch_xml_add_child_d(x_conference, "hostname", conference_off++))) {
abort();
}
switch_xml_set_txt_d(x_ptr, switch_core_get_hostname());
-
+
if (!(x_ptr = switch_xml_add_child_d(x_conference, "rate", conference_off++))) {
abort();
}
switch_snprintf(str, sizeof(str), "%d", conference->rate);
switch_xml_set_txt_d(x_ptr, str);
-
+
if (!(x_ptr = switch_xml_add_child_d(x_conference, "interval", conference_off++))) {
abort();
}
switch_snprintf(str, sizeof(str), "%d", conference->interval);
switch_xml_set_txt_d(x_ptr, str);
-
-
+
+
if (!(x_ptr = switch_xml_add_child_d(x_conference, "start_time", conference_off++))) {
abort();
}
switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch");
switch_snprintf(str, sizeof(str), "%ld", (long)conference->start_time);
switch_xml_set_txt_d(x_ptr, str);
-
-
+
+
if (!(x_ptr = switch_xml_add_child_d(x_conference, "end_time", conference_off++))) {
abort();
}
}
switch_xml_set_attr_d(x_member, "type", np->cp ? "caller" : "recording_node");
-
+
if (!(x_ptr = switch_xml_add_child_d(x_member, "join_time", member_off++))) {
abort();
}
switch_xml_set_txt_d(x_ptr, "conference_locked");
} else if (rp->reason == CDRR_MAXMEMBERS) {
switch_xml_set_txt_d(x_ptr, "max_members_reached");
- } else if (rp->reason == CDRR_PIN) {
+ } else if (rp->reason == CDRR_PIN) {
switch_xml_set_txt_d(x_ptr, "invalid_pin");
}
switch_ivr_set_xml_profile_data(x_cp, rp->cp, 0);
}
}
-
+
xml_text = switch_xml_toxml(cdr, SWITCH_TRUE);
-
+
if (!zstr(conference->log_dir)) {
path = switch_mprintf("%s%s%s.cdr.xml", conference->log_dir, SWITCH_PATH_SEPARATOR, conference->uuid_str);
-
+
#ifdef _MSC_VER
if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
#else
- if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) {
+ if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) {
#endif
- int wrote;
- wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
- wrote++;
- close(fd);
- fd = -1;
- } else {
- char ebuf[512] = { 0 };
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n",
- path, switch_strerror_r(errno, ebuf, sizeof(ebuf)));
- }
-
- if (conference->cdr_event_mode != CDRE_NONE) {
- switch_event_t *event;
-
- if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_CDR) == SWITCH_STATUS_SUCCESS)
- // if (switch_event_create(&event, SWITCH_EVENT_CDR) == SWITCH_STATUS_SUCCESS)
- {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Source", CONF_EVENT_CDR);
- if (conference->cdr_event_mode == CDRE_AS_CONTENT) {
- switch_event_set_body(event, xml_text);
- } else {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Path", path);
- }
- switch_event_fire(&event);
+ int wrote;
+ wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
+ wrote++;
+ close(fd);
+ fd = -1;
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not create CDR event");
+ char ebuf[512] = { 0 };
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n",
+ path, switch_strerror_r(errno, ebuf, sizeof(ebuf)));
+ }
+
+ if (conference->cdr_event_mode != CDRE_NONE) {
+ switch_event_t *event;
+
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_CDR) == SWITCH_STATUS_SUCCESS)
+ // if (switch_event_create(&event, SWITCH_EVENT_CDR) == SWITCH_STATUS_SUCCESS)
+ {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Source", CONF_EVENT_CDR);
+ if (conference->cdr_event_mode == CDRE_AS_CONTENT) {
+ switch_event_set_body(event, xml_text);
+ } else {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Path", path);
+ }
+ switch_event_fire(&event);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not create CDR event");
+ }
}
}
+
+ switch_safe_free(path);
+ switch_safe_free(xml_text);
+ switch_xml_free(cdr);
}
- switch_safe_free(path);
- switch_safe_free(xml_text);
- switch_xml_free(cdr);
-}
+ /* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
void conference_event_mod_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id)
{
- cJSON *data, *addobj = NULL;
+ cJSON *data, *addobj = NULL;
const char *action = NULL;
char *value = NULL;
cJSON *jid = 0;
argv[i] = str->valuestring;
}
}
- } else if (jvalue->type == cJSON_String) {
+ } else if (jvalue->type == cJSON_String) {
value = jvalue->valuestring;
argv[argc++] = value;
}
}
SWITCH_STANDARD_STREAM(stream);
-
- if (!strcasecmp(action, "kick") ||
- !strcasecmp(action, "mute") ||
- !strcasecmp(action, "unmute") ||
+
+ if (!strcasecmp(action, "kick") ||
+ !strcasecmp(action, "mute") ||
+ !strcasecmp(action, "unmute") ||
!strcasecmp(action, "tmute") ||
- !strcasecmp(action, "vmute") ||
- !strcasecmp(action, "unvmute") ||
- !strcasecmp(action, "tvmute")
+ !strcasecmp(action, "vmute") ||
+ !strcasecmp(action, "unvmute") ||
+ !strcasecmp(action, "tvmute")
) {
exec = switch_mprintf("%s %s %d", conference_name, action, cid);
- } else if (!strcasecmp(action, "volume_in") ||
- !strcasecmp(action, "volume_out") ||
- !strcasecmp(action, "vid-res-id") ||
- !strcasecmp(action, "vid-floor") ||
+ } else if (!strcasecmp(action, "volume_in") ||
+ !strcasecmp(action, "volume_out") ||
+ !strcasecmp(action, "vid-res-id") ||
+ !strcasecmp(action, "vid-floor") ||
!strcasecmp(action, "vid-layer") ||
!strcasecmp(action, "vid-canvas") ||
!strcasecmp(action, "vid-watching-canvas") ||
switch_ivr_session_transfer(member->session, argv[0], argv[1], argv[2]);
switch_thread_rwlock_unlock(member->rwlock);
}
- switch_thread_rwlock_unlock(conference->rwlock);
+ switch_thread_rwlock_unlock(conference->rwlock);
}
goto end;
} else if (!strcasecmp(action, "list-videoLayouts")) {
}
if (conference->layout_group_hash) {
- for (hi = switch_core_hash_first(conference->layout_group_hash); hi; hi = switch_core_hash_next(&hi)) {
- char *name;
- switch_core_hash_this(hi, &vvar, NULL, &val);
- name = switch_mprintf("group:%s", (char *)vvar);
- cJSON_AddItemToArray(array, cJSON_CreateString(name));
- free(name);
- }
+ for (hi = switch_core_hash_first(conference->layout_group_hash); hi; hi = switch_core_hash_next(&hi)) {
+ char *name;
+ switch_core_hash_this(hi, &vvar, NULL, &val);
+ name = switch_mprintf("group:%s", (char *)vvar);
+ cJSON_AddItemToArray(array, cJSON_CreateString(name));
+ free(name);
+ }
}
switch_mutex_unlock(conference_globals.setup_mutex);
cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(event_channel));
cJSON_AddItemToObject(jdata, "action", cJSON_CreateString("response"));
-
+
if (addobj) {
cJSON_AddItemToObject(jdata, "conf-command", cJSON_CreateString(action));
cJSON_AddItemToObject(jdata, "response", cJSON_CreateString("OK"));
*domain++ = '\0';
}
}
-
+
if (!strcasecmp(action, "bootstrap")) {
- if (!zstr(name) && (conference = conference_find(name, domain))) {
+ if (!zstr(name) && (conference = conference_find(name, domain))) {
conference_desc = conference_cdr_json_render(conference, json);
} else {
conference_desc = cJSON_CreateObject();
}
json_add_child_string(conference_desc, "action", "conferenceDescription");
-
+
cJSON_AddItemToObject(reply, "data", conference_desc);
switch_safe_free(dup);
event = cJSON_CreateObject();
- json_add_child_string(event, "eventChannel", event_channel);
+ json_add_child_string(event, "eventChannel", event_channel);
cJSON_AddItemToObject(event, "data", conference_desc);
-
+
switch_event_channel_broadcast(event_channel, &event, "mod_conference", conference_globals.event_channel_id);
switch_safe_free(dup_domain);
//if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) {
switch_channel_set_flag(member->channel, CF_VIDEO_REFRESH_REQ);
switch_core_media_gen_key_frame(member->session);
- //}
+ //}
- if (conference && conference->la && member->session &&
+ if (conference && conference->la && member->session &&
!switch_channel_test_flag(member->channel, CF_VIDEO_ONLY)) {
cJSON *msg, *data;
const char *uuid = switch_core_session_get_uuid(member->session);
cJSON_AddItemToObject(data, "role", cJSON_CreateString(conference_utils_member_test_flag(member, MFLAG_MOD) ? "moderator" : "participant"));
cJSON_AddItemToObject(data, "chatID", cJSON_CreateString(conference->chat_id));
cJSON_AddItemToObject(data, "canvasCount", cJSON_CreateNumber(conference->canvas_count));
-
+
if (conference_utils_member_test_flag(member, MFLAG_SECOND_SCREEN)) {
cJSON_AddItemToObject(data, "secondScreen", cJSON_CreateTrue());
}
-
+
if (conference_utils_member_test_flag(member, MFLAG_MOD)) {
cJSON_AddItemToObject(data, "modChannel", cJSON_CreateString(conference->mod_event_channel));
}
-
- switch_core_get_variables(&variables);
+
+ switch_core_get_variables(&variables);
for (hp = variables->headers; hp; hp = hp->next) {
if (!strncasecmp(hp->name, "conference_verto_", 11)) {
char *var = hp->name + 11;
switch_event_t *event;
char *body;
char *name = NULL, *domain = NULL, *dup_domain = NULL;
-
+
if (!conference_utils_test_flag(conference, CFLAG_RFC4579)) {
return;
}
const char *presence_id = switch_channel_get_variable(member->channel, "presence_id");
const char *chat_proto = switch_channel_get_variable(member->channel, "chat_proto");
switch_event_t *reply = NULL;
-
+
if (presence_id && chat_proto) {
if (switch_event_get_header(processed, presence_id)) {
continue;
switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "to", presence_id);
switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "conference_name", conference->name);
switch_event_add_header_string(reply, SWITCH_STACK_BOTTOM, "conference_domain", conference->domain);
-
+
switch_event_set_body(reply, switch_event_get_body(event));
-
+
switch_core_chat_deliver(chat_proto, &reply);
switch_event_add_header_string(processed, SWITCH_STACK_BOTTOM, presence_id, "true");
}
if (conference_utils_test_flag(conference, CFLAG_RFC4579)) {
char *key = switch_mprintf("conference_%s_%s_%s_%s", conference->name, conference->domain, ext, ext_domain);
char *expanded = NULL, *ostr = dial_str;;
-
+
if (!strcasecmp(action, "call")) {
if((conference->max_members > 0) && (conference->count >= conference->max_members)) {
// Conference member limit has been reached; do not proceed with setup request
switch_safe_free(expanded);
}
}
-
+
} else if (!strcasecmp(action, "end")) {
if (switch_core_session_hupall_matching_var("conference_call_key", key, SWITCH_CAUSE_NORMAL_CLEARING)) {
conference_send_notify(conference, "SIP/2.0 200 OK\r\n", call_id, SWITCH_TRUE);
switch_event_fire(&event);
}
}
-
+
}
void conference_data_event_handler(switch_event_t *event)
if (!(dup_to = strdup(to))) {
return;
}
-
+
conference_name = dup_to + 5;
}
dup_conference_name = switch_mprintf("%q@%q", conference_name, domain_name);
-
+
if ((conference = conference_find(conference_name, NULL)) || (conference = conference_find(dup_conference_name, NULL))) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
conference_obj_t *conference = NULL;
switch_stream_handle_t stream = { 0 };
const char *proto;
- const char *from;
+ const char *from;
const char *to;
//const char *subject;
const char *body;
}
if (!(conference = conference_find(name, NULL))) {
- switch_core_chat_send_args(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "",
+ switch_core_chat_send_args(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "",
"Conference not active.", NULL, NULL, SWITCH_FALSE);
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
if (test_eflag(conference, EFLAG_PLAY_FILE_DONE) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
-
+
conference_event_add_data(conference, event);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "seconds", "%ld", (long) node->fh.samples_in / node->fh.native_rate);
if (node->member_id) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done");
-
+
if ((member = conference_member_get(conference, node->member_id))) {
conference_member_add_event_data(member, event);
switch_thread_rwlock_unlock(member->rwlock);
switch_event_fire(&event);
}
-#ifdef OPENAL_POSITIONING
+#ifdef OPENAL_POSITIONING
if (node->al && node->al->device) {
conference_al_close(node->al);
}
/* positional requires mono input */
fnode->fh.channels = channels = 1;
}
-
+
retry:
flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT;
if (test_eflag(conference, EFLAG_PLAY_FILE) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_event_add_data(conference, event);
-
+
if (fnode->fh.params) {
switch_event_merge(event, conference->fnode->fh.params);
}
-
+
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", file);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", async ? "true" : "false");
fnode->pool = pool;
fnode->async = async;
fnode->file = switch_core_strdup(fnode->pool, file);
-
+
if (!conference->fnode || (async && !conference->async_fnode)) {
conference_video_fnode_check(fnode);
}
switch_mutex_unlock(conference->mutex);
- done:
+ done:
switch_safe_free(expanded);
switch_safe_free(dfile);
/* Play a file */
switch_status_t conference_file_local_play(conference_obj_t *conference, switch_core_session_t *session, char *path, uint32_t leadin, void *buf,
- uint32_t buflen)
+ uint32_t buflen)
{
uint32_t x = 0;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_safe_free(dpath);
}
- done:
+ done:
switch_safe_free(expanded);
return status;
}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
#include <mod_conference.h>
struct _mapping control_mappings[] = {
- {"mute", conference_loop_mute_toggle},
- {"mute on", conference_loop_mute_on},
- {"mute off", conference_loop_mute_off},
- {"vmute", conference_loop_vmute_toggle},
- {"vmute on", conference_loop_vmute_on},
- {"vmute off", conference_loop_vmute_off},
- {"vmute snap", conference_loop_conference_video_vmute_snap},
- {"vmute snapoff", conference_loop_conference_video_vmute_snapoff},
- {"deaf mute", conference_loop_deafmute_toggle},
- {"energy up", conference_loop_energy_up},
- {"energy equ", conference_loop_energy_equ_conf},
- {"energy dn", conference_loop_energy_dn},
- {"vol talk up", conference_loop_volume_talk_up},
- {"vol talk zero", conference_loop_volume_talk_zero},
- {"vol talk dn", conference_loop_volume_talk_dn},
- {"vol listen up", conference_loop_volume_listen_up},
- {"vol listen zero", conference_loop_volume_listen_zero},
- {"vol listen dn", conference_loop_volume_listen_dn},
- {"hangup", conference_loop_hangup},
- {"event", conference_loop_event},
- {"lock", conference_loop_lock_toggle},
- {"transfer", conference_loop_transfer},
- {"execute_application", conference_loop_exec_app},
- {"floor", conference_loop_floor_toggle},
- {"vid-floor", conference_loop_vid_floor_toggle},
- {"vid-floor-force", conference_loop_vid_floor_force}
+ {"mute", conference_loop_mute_toggle},
+ {"mute on", conference_loop_mute_on},
+ {"mute off", conference_loop_mute_off},
+ {"vmute", conference_loop_vmute_toggle},
+ {"vmute on", conference_loop_vmute_on},
+ {"vmute off", conference_loop_vmute_off},
+ {"vmute snap", conference_loop_conference_video_vmute_snap},
+ {"vmute snapoff", conference_loop_conference_video_vmute_snapoff},
+ {"deaf mute", conference_loop_deafmute_toggle},
+ {"energy up", conference_loop_energy_up},
+ {"energy equ", conference_loop_energy_equ_conf},
+ {"energy dn", conference_loop_energy_dn},
+ {"vol talk up", conference_loop_volume_talk_up},
+ {"vol talk zero", conference_loop_volume_talk_zero},
+ {"vol talk dn", conference_loop_volume_talk_dn},
+ {"vol listen up", conference_loop_volume_listen_up},
+ {"vol listen zero", conference_loop_volume_listen_zero},
+ {"vol listen dn", conference_loop_volume_listen_dn},
+ {"hangup", conference_loop_hangup},
+ {"event", conference_loop_event},
+ {"lock", conference_loop_lock_toggle},
+ {"transfer", conference_loop_transfer},
+ {"execute_application", conference_loop_exec_app},
+ {"floor", conference_loop_floor_toggle},
+ {"vid-floor", conference_loop_vid_floor_toggle},
+ {"vid-floor-force", conference_loop_vid_floor_force}
};
int conference_loop_mapping_len()
{
- return (sizeof(control_mappings)/sizeof(control_mappings[0]));
+ return (sizeof(control_mappings)/sizeof(control_mappings[0]));
}
switch_status_t conference_loop_dmachine_dispatcher(switch_ivr_dmachine_match_t *match)
return;
if (conference_utils_test_flag(member->conference, CFLAG_WAIT_MOD) && !conference_utils_member_test_flag(member, MFLAG_MOD) )
- return;
+ return;
if (!conference_utils_test_flag(member->conference, CFLAG_LOCKED)) {
if (member->conference->is_locked_sound) {
}
-
+
}
switch_snprintf(msg, sizeof(msg), "digits/%c.wav", *p);
conference_member_play_file(member, msg, 0, SWITCH_TRUE);
}
-
+
}
void conference_loop_energy_dn(conference_member_t *member, caller_control_action_t *action)
switch_snprintf(msg, sizeof(msg), "digits/%c.wav", *p);
conference_member_play_file(member, msg, 0, SWITCH_TRUE);
}
-
+
}
void conference_loop_volume_talk_up(conference_member_t *member, caller_control_action_t *action)
switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level));
conference_member_play_file(member, msg, 0, SWITCH_TRUE);
-
+
}
void conference_loop_volume_listen_dn(conference_member_t *member, caller_control_action_t *action)
conference_member_play_file(member, msg, 0, SWITCH_TRUE);
}
- switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level));
- conference_member_play_file(member, msg, 0, SWITCH_TRUE);
+ switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level));
+ conference_member_play_file(member, msg, 0, SWITCH_TRUE);
}
void conference_loop_event(conference_member_t *member, caller_control_action_t *action)
switch_ivr_session_transfer(member->session, exten, dialplan, context);
- done:
+ done:
return;
}
}
} else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Empty execute app string [%s]\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Empty execute app string [%s]\n",
(char *) action->expanded_data);
goto done;
}
switch_core_session_set_read_codec(member->session, &member->read_codec);
switch_channel_clear_app_flag(channel, CF_APP_TAGGED);
- done:
+ done:
switch_safe_free(mydata);
/* marshall frames from the call leg to the conference thread for muxing to other call legs */
void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *obj)
{
- switch_event_t *event;
+ switch_event_t *event;
conference_member_t *member = obj;
switch_channel_t *channel;
switch_status_t status;
flush_len = switch_samples_per_packet(member->conference->rate, member->conference->interval) * 2 * member->conference->channels * (500 / member->conference->interval);
- /* As long as we have a valid read, feed that data into an input buffer where the conference thread will take it
+ /* As long as we have a valid read, feed that data into an input buffer where the conference thread will take it
and mux it with any audio from other channels. */
while (conference_utils_member_test_flag(member, MFLAG_RUNNING) && switch_channel_ready(channel)) {
/* if we have caller digits, feed them to the parser to find an action */
if (switch_channel_has_dtmf(channel)) {
char dtmf[128] = "";
-
+
switch_channel_dequeue_dtmf_string(channel, dtmf, sizeof(dtmf));
if (conference_utils_member_test_flag(member, MFLAG_DIST_DTMF)) {
} else if (member->dmachine) {
switch_ivr_dmachine_ping(member->dmachine, NULL);
}
-
+
if (switch_queue_size(member->dtmf_queue)) {
switch_dtmf_t *dt;
void *pop;
-
+
if (switch_queue_trypop(member->dtmf_queue, &pop) == SWITCH_STATUS_SUCCESS) {
dt = (switch_dtmf_t *) pop;
switch_core_session_send_dtmf(member->session, dt);
free(dt);
}
}
-
+
if (switch_test_flag(read_frame, SFF_CNG)) {
if (member->conference->agc_level) {
member->nt_tally++;
member->conference->agc_level = 0;
conference_member_clear_avg(member);
}
-
+
/* if the member can speak, compute the audio energy level and */
/* generate events when the level crosses the threshold */
uint32_t energy = 0, i = 0, samples = 0, j = 0;
int16_t *data;
int agc_period = (member->read_impl.actual_samples_per_second / member->read_impl.samples_per_packet) / 4;
-
+
data = read_frame->data;
member->score = 0;
if (member->volume_in_level) {
switch_change_sln_volume(read_frame->data, (read_frame->datalen / 2) * member->conference->channels, member->volume_in_level);
}
-
+
if (member->agc_volume_in_level) {
switch_change_sln_volume_granular(read_frame->data, (read_frame->datalen / 2) * member->conference->channels, member->agc_volume_in_level);
}
-
+
if ((samples = read_frame->datalen / sizeof(*data) / member->read_impl.number_of_channels)) {
for (i = 0; i < samples; i++) {
energy += abs(data[j]);
j += member->read_impl.number_of_channels;
}
-
+
member->score = energy / samples;
}
if (member->vol_period) {
member->vol_period--;
}
-
- if (member->conference->agc_level && member->score &&
+
+ if (member->conference->agc_level && member->score &&
conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) &&
conference_member_noise_gate_check(member)
) {
int last_shift = abs((int)(member->last_score - member->score));
-
+
if (member->score && member->last_score && last_shift > 900) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7,
- "AGC %s:%d drop anomalous shift of %d\n",
+ "AGC %s:%d drop anomalous shift of %d\n",
member->conference->name,
member->id, last_shift);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7,
- "AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d\n",
+ "AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d\n",
member->conference->name,
- member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level,
+ member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level,
member->score, member->avg_score, member->agc_volume_in_level);
-
+
if (++member->agc_concur >= agc_period) {
if (!member->vol_period) {
conference_member_check_agc_levels(member);
if (member->score_iir > SCORE_MAX_IIR) {
member->score_iir = SCORE_MAX_IIR;
}
-
+
if (conference_member_noise_gate_check(member)) {
uint32_t diff = member->score - member->energy_level;
if (hangover_hits) {
member->floor_packets++;
}
- if (diff >= diff_level || ++hangunder_hits >= hangunder) {
+ if (diff >= diff_level || ++hangunder_hits >= hangunder) {
hangover_hits = hangunder_hits = 0;
member->last_talking = switch_epoch_time_now(NULL);
conference_member_update_status_field(member);
conference_member_check_agc_levels(member);
conference_member_clear_avg(member);
-
+
if (test_eflag(member->conference, EFLAG_STOP_TALKING) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_member_add_event_data(member, event);
member->last_score = member->score;
if (member == member->conference->floor_holder) {
- if (member->id != member->conference->video_floor_holder &&
+ if (member->id != member->conference->video_floor_holder &&
(member->floor_packets > member->conference->video_floor_packets || member->energy_level == 0)) {
conference_video_set_floor_holder(member->conference, member, SWITCH_FALSE);
}
}
/* skip frames that are not actual media or when we are muted or silent */
- if ((conference_utils_member_test_flag(member, MFLAG_TALKING) || member->energy_level == 0 || conference_utils_test_flag(member->conference, CFLAG_AUDIO_ALWAYS))
+ if ((conference_utils_member_test_flag(member, MFLAG_TALKING) || member->energy_level == 0 || conference_utils_test_flag(member->conference, CFLAG_AUDIO_ALWAYS))
&& conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK) && !conference_utils_test_flag(member->conference, CFLAG_WAIT_MOD)
&& (member->conference->count > 1 || (member->conference->record_count && member->conference->count >= member->conference->min_recording_participants))) {
switch_audio_resampler_t *read_resampler = member->read_resampler;
tmp_frame.datalen = datalen;
tmp_frame.rate = member->conference->rate;
conference_member_check_channels(&tmp_frame, member, SWITCH_TRUE);
-
+
if (datalen) {
switch_size_t ok = 1;
}
}
- do_continue:
+ do_continue:
switch_mutex_unlock(member->read_mutex);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Setup timer %s success interval: %u samples: %u\n",
member->conference->timer_name, interval, tsamples);
-
+
write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE);
write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
for (x = 0; x < argc; x++) {
char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]);
switch_assert(dial_str);
- conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL,
+ conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL,
profile, &member->conference->cancel_cause, NULL);
switch_safe_free(dial_str);
}
loops = wait_sec * 10;
-
+
switch_channel_set_app_flag(channel, CF_APP_TAGGED);
do {
switch_ivr_sleep(member->session, 100, SWITCH_TRUE, NULL);
member->conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
goto end;
}
-
+
conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE);
}
-
+
if (!conference_utils_test_flag(member->conference, CFLAG_ANSWERED)) {
switch_channel_answer(channel);
}
switch_mutex_lock(member->write_mutex);
-
+
if (switch_channel_test_flag(member->channel, CF_CONFERENCE_ADV)) {
if (member->conference->la) {
conference_event_adv_la(member->conference, member, SWITCH_TRUE);
char *from = switch_event_get_header(event, "from");
char *to = switch_event_get_header(event, "to");
char *body = switch_event_get_body(event);
-
+
if (to && from && body) {
if (strchr(to, '+') && strncmp(to, CONF_CHAT_PROTO, strlen(CONF_CHAT_PROTO))) {
switch_event_del_header(event, "to");
use_buffer = NULL;
mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer);
-
+
use_timer = 1;
if (mux_used) {
if ((write_frame.datalen = (uint32_t) switch_buffer_read(use_buffer, write_frame.data, bytes))) {
if (write_frame.datalen) {
write_frame.samples = write_frame.datalen / 2 / member->conference->channels;
-
- if( !conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) {
- memset(write_frame.data, 255, write_frame.datalen);
- } else if (member->volume_out_level) { /* Check for output volume adjustments */
- switch_change_sln_volume(write_frame.data, write_frame.samples * member->conference->channels, member->volume_out_level);
- }
-
- write_frame.timestamp = timer.samplecount;
-
- if (member->fnode) {
- conference_member_add_file_data(member, write_frame.data, write_frame.datalen);
- }
-
- conference_member_check_channels(&write_frame, member, SWITCH_FALSE);
-
- if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
- switch_mutex_unlock(member->audio_out_mutex);
- break;
- }
+
+ if( !conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) {
+ memset(write_frame.data, 255, write_frame.datalen);
+ } else if (member->volume_out_level) { /* Check for output volume adjustments */
+ switch_change_sln_volume(write_frame.data, write_frame.samples * member->conference->channels, member->volume_out_level);
+ }
+
+ write_frame.timestamp = timer.samplecount;
+
+ if (member->fnode) {
+ conference_member_add_file_data(member, write_frame.data, write_frame.datalen);
+ }
+
+ conference_member_check_channels(&write_frame, member, SWITCH_FALSE);
+
+ if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
+ switch_mutex_unlock(member->audio_out_mutex);
+ break;
+ }
}
}
conference_member_play_file(member, member->conference->muted_sound, 0, SWITCH_TRUE);
} else {
char msg[512];
-
+
switch_snprintf(msg, sizeof(msg), "Muted");
conference_member_say(member, msg, 0);
}
conference_member_play_file(member, member->conference->mute_detect_sound, 0, SWITCH_TRUE);
} else {
char msg[512];
-
+
switch_snprintf(msg, sizeof(msg), "Currently Muted");
conference_member_say(member, msg, 0);
}
conference_utils_member_clear_flag(member, MFLAG_INDICATE_MUTE_DETECT);
}
-
+
if (conference_utils_member_test_flag(member, MFLAG_INDICATE_UNMUTE)) {
if (!zstr(member->conference->unmuted_sound)) {
conference_member_play_file(member, member->conference->unmuted_sound, 0, SWITCH_TRUE);
} else {
char msg[512];
-
+
switch_snprintf(msg, sizeof(msg), "Un-Muted");
conference_member_say(member, msg, 0);
}
}
}
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
if (target_score < 0) target_score = 0;
r = (int)member->score > target_score;
-
+
} else {
r = (int32_t)member->score > member->energy_level;
}
binding->handler = handler;
switch_ivr_dmachine_bind(member->dmachine, "conf", digits, 0, conference_loop_dmachine_dispatcher, binding);
-
+
}
void conference_member_bind_controls(conference_member_t *member, const char *controls)
for (xcontrol = switch_xml_child(xgroups, "control"); xcontrol; xcontrol = xcontrol->next) {
- const char *key = switch_xml_attr(xcontrol, "action");
- const char *digits = switch_xml_attr(xcontrol, "digits");
- const char *data = switch_xml_attr_soft(xcontrol, "data");
+ const char *key = switch_xml_attr(xcontrol, "action");
+ const char *digits = switch_xml_attr(xcontrol, "digits");
+ const char *data = switch_xml_attr_soft(xcontrol, "data");
if (zstr(key) || zstr(digits)) continue;
for(i = 0; i < conference_loop_mapping_len(); i++) {
if (!strcasecmp(key, control_mappings[i].name)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s binding '%s' to '%s'\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s binding '%s' to '%s'\n",
switch_core_session_get_name(member->session), digits, key);
conference_member_do_binding(member, control_mappings[i].handler, digits, data);
switch_xml_free(cxml);
cxml = NULL;
}
-
+
if (params) switch_event_destroy(¶ms);
-
+
}
void conference_member_update_status_field(conference_member_t *member)
char *str, *vstr = "", display[128] = "", *json_display = NULL;
cJSON *json, *audio, *video;
- if (!member->conference->la || !member->json ||
+ if (!member->conference->la || !member->json ||
!member->status_field || switch_channel_test_flag(member->channel, CF_VIDEO_ONLY) || conference_utils_member_test_flag(member, MFLAG_SECOND_SCREEN)) {
return;
}
if (conference_utils_test_flag(member->conference, CFLAG_JSON_STATUS)) {
json = cJSON_CreateObject();
audio = cJSON_CreateObject();
- cJSON_AddItemToObject(audio, "muted", cJSON_CreateBool(!conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)));
- cJSON_AddItemToObject(audio, "onHold", cJSON_CreateBool(switch_channel_test_flag(member->channel, CF_HOLD)));
+ cJSON_AddItemToObject(audio, "muted", cJSON_CreateBool(!conference_utils_member_test_flag(member, MFLAG_CAN_SPEAK)));
+ cJSON_AddItemToObject(audio, "onHold", cJSON_CreateBool(switch_channel_test_flag(member->channel, CF_HOLD)));
cJSON_AddItemToObject(audio, "talking", cJSON_CreateBool(conference_utils_member_test_flag(member, MFLAG_TALKING)));
cJSON_AddItemToObject(audio, "floor", cJSON_CreateBool(member == member->conference->floor_holder));
cJSON_AddItemToObject(audio, "energyScore", cJSON_CreateNumber(member->score));
cJSON_AddItemToObject(json, "audio", audio);
-
+
if (switch_channel_test_flag(member->channel, CF_VIDEO) || member->avatar_png_img) {
video = cJSON_CreateObject();
cJSON_AddItemToObject(video, "avatarPresented", cJSON_CreateBool(!!member->avatar_png_img));
if (member && member->id == member->conference->video_floor_holder && conference_utils_test_flag(member->conference, CFLAG_VID_FLOOR_LOCK)) {
cJSON_AddItemToObject(video, "floorLocked", cJSON_CreateTrue());
}
- cJSON_AddItemToObject(video, "reservationID", member->video_reservation_id ?
+ cJSON_AddItemToObject(video, "reservationID", member->video_reservation_id ?
cJSON_CreateString(member->video_reservation_id) : cJSON_CreateNull());
cJSON_AddItemToObject(video, "videoLayerID", cJSON_CreateNumber(member->video_layer_id));
-
+
cJSON_AddItemToObject(json, "video", video);
} else {
cJSON_AddItemToObject(json, "video", cJSON_CreateFalse());
} else {
str = "ACTIVE";
}
-
+
if (switch_channel_test_flag(member->channel, CF_VIDEO)) {
if (!conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) {
vstr = " VIDEO (BLIND)";
}
return status;
-
+
}
#endif
}
if (member) {
- if (!conference_utils_member_test_flag(member, MFLAG_INTREE) ||
- conference_utils_member_test_flag(member, MFLAG_KICKED) ||
+ if (!conference_utils_member_test_flag(member, MFLAG_INTREE) ||
+ conference_utils_member_test_flag(member, MFLAG_KICKED) ||
(member->session && !switch_channel_up(switch_core_session_get_channel(member->session)))) {
/* member is kicked or hanging up so forget it */
int x = 0;
if (!member->avg_score) return;
-
+
if ((int)member->avg_score < member->conference->agc_level - 100) {
member->agc_volume_in_level++;
switch_normalize_volume_granular(member->agc_volume_in_level);
if (x) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7,
- "AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d %s\n",
+ "AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d %s\n",
member->conference->name,
- member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level,
+ member->id, member->conference->agc_level - member->avg_score, member->conference->agc_level,
member->score, member->avg_score, member->agc_volume_in_level, x > 0 ? "+++" : "---");
-
+
conference_member_clear_avg(member);
}
}
to = member->read_impl.number_of_channels;
}
- rlen = frame->datalen / 2 / from;
+ rlen = frame->datalen / 2 / from;
if (in && frame->rate == 48000 && ((from == 1 && to == 2) || (from == 2 && to == 2)) && conference_utils_member_test_flag(member, MFLAG_POSITIONAL)) {
if (from == 2 && to == 2) {
frame->datalen /= 2;
rlen = frame->datalen / 2;
}
-
+
conference_al_process(member->al, frame->data, frame->datalen, frame->rate);
} else {
switch_mux_channels((int16_t *) frame->data, rlen, from, to);
}
-
+
frame->datalen = rlen * 2 * to;
-
+
}
}
if (member->fnode->al) {
speech_len /= 2;
}
-
+
if (switch_core_speech_read_tts(member->fnode->sh, file_frame, &speech_len, &flags) == SWITCH_STATUS_SUCCESS) {
- file_sample_len = file_data_len / 2 / member->conference->channels;
+ file_sample_len = file_data_len / 2 / member->conference->channels;
} else {
file_sample_len = file_data_len = 0;
}
lock_member(member);
for (rel = member->relationships; rel; rel = rel->next) {
if (id == 0 || rel->id == id) {
- /* we just forget about rel here cos it was allocated by the member's pool
+ /* we just forget about rel here cos it was allocated by the member's pool
it will be freed when the member is */
conference_member_t *omember;
switch_mutex_unlock(conference->member_mutex);
conference_cdr_add(member);
-
+
if (!conference_utils_member_test_flag(member, MFLAG_NOCHANNEL)) {
if (conference_utils_member_test_flag(member, MFLAG_GHOST)) {
conference->count_ghosts++;
}
if (!switch_channel_get_variable(channel, "conference_call_key")) {
- char *key = switch_core_session_sprintf(member->session, "conference_%s_%s_%s",
+ char *key = switch_core_session_sprintf(member->session, "conference_%s_%s_%s",
conference->name, conference->domain, switch_channel_get_variable(channel, "caller_id_number"));
switch_channel_set_variable(channel, "conference_call_key", key);
}
if (conference->count > 1) {
if ((conference->moh_sound && !conference_utils_test_flag(conference, CFLAG_WAIT_MOD)) ||
- (conference_utils_test_flag(conference, CFLAG_WAIT_MOD) && !switch_true(switch_channel_get_variable(channel, "conference_permanent_wait_mod_moh")))) {
+ (conference_utils_test_flag(conference, CFLAG_WAIT_MOD) && !switch_true(switch_channel_get_variable(channel, "conference_permanent_wait_mod_moh")))) {
/* stop MoH if any */
conference_file_stop(conference, FILE_STOP_ASYNC);
}
const char * enter_sound = switch_channel_get_variable(channel, "conference_enter_sound");
if (conference_utils_test_flag(conference, CFLAG_ENTER_SOUND) && !conference_utils_member_test_flag(member, MFLAG_SILENT)) {
if (!zstr(enter_sound)) {
- conference_file_play(conference, (char *)enter_sound, CONF_DEFAULT_LEADIN,
- switch_core_session_get_channel(member->session), 0);
- } else {
+ conference_file_play(conference, (char *)enter_sound, CONF_DEFAULT_LEADIN,
+ switch_core_session_get_channel(member->session), 0);
+ } else {
conference_file_play(conference, conference->enter_sound, CONF_DEFAULT_LEADIN, switch_core_session_get_channel(member->session), 0);
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"%s has positional audio blocked.\n", switch_channel_get_name(channel));
} else {
- if (conference_member_parse_position(member, position) != SWITCH_STATUS_SUCCESS) {
+ if (conference_member_parse_position(member, position) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s invalid position data\n", switch_channel_get_name(channel));
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s position data set\n", switch_channel_get_name(channel));
}
-
+
conference_utils_member_set_flag(member, MFLAG_POSITIONAL);
member->al = conference_al_create(member->pool);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s cannot set position data on mono conference.\n", switch_channel_get_name(channel));
}
}
-
-
+
+
controls = switch_channel_get_variable(channel, "conference_controls");
}
if (strcasecmp(controls, "none")) {
- switch_ivr_dmachine_create(&member->dmachine, "mod_conference", NULL,
+ switch_ivr_dmachine_create(&member->dmachine, "mod_conference", NULL,
conference->ivr_dtmf_timeout, conference->ivr_input_timeout, NULL, NULL, NULL);
conference_member_bind_controls(member, controls);
}
-
+
}
unlock_member(member);
cJSON_AddItemToArray(member->json, cJSON_CreateStringPrintf("%0.4d", member->id));
cJSON_AddItemToArray(member->json, cJSON_CreateString(switch_channel_get_variable(member->channel, "caller_id_number")));
cJSON_AddItemToArray(member->json, cJSON_CreateString(switch_channel_get_variable(member->channel, "caller_id_name")));
-
+
cJSON_AddItemToArray(member->json, cJSON_CreateStringPrintf("%s@%s",
switch_channel_get_variable(member->channel, "original_read_codec"),
switch_channel_get_variable(member->channel, "original_read_rate")
-
+
member->status_field = cJSON_CreateString("");
cJSON_AddItemToArray(member->json, member->status_field);
-
+
cJSON_AddItemToArray(member->json, cJSON_CreateNull());
-
+
conference_member_update_status_field(member);
//switch_live_array_add_alias(conference->la, switch_core_session_get_uuid(member->session), "conference");
}
conference_event_adv_la(conference, member, SWITCH_TRUE);
- if (!conference_utils_member_test_flag(member, MFLAG_SECOND_SCREEN)) {
+ if (!conference_utils_member_test_flag(member, MFLAG_SECOND_SCREEN)) {
switch_live_array_add(conference->la, switch_core_session_get_uuid(member->session), -1, &member->json, SWITCH_FALSE);
}
}
return;
} else {
old_member = conference->floor_holder;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping floor %s\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping floor %s\n",
switch_channel_get_name(old_member->channel));
}
switch_mutex_lock(conference->mutex);
if (member) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Adding floor %s\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Adding floor %s\n",
switch_channel_get_name(member->channel));
conference->floor_holder = member;
}
if (conference->floor_holder) {
- conference_member_add_event_data(conference->floor_holder, event);
+ conference_member_add_event_data(conference->floor_holder, event);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", conference->floor_holder->id);
} else {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "New-ID", "none");
conference_cdr_del(member);
-#ifdef OPENAL_POSITIONING
+#ifdef OPENAL_POSITIONING
if (member->al && member->al->device) {
conference_al_close(member->al);
}
if (member->rec) {
conference->recording_members--;
}
-
+
for (imember = conference->members; imember; imember = imember->next) {
if (imember == member) {
if (last) {
}
switch_thread_rwlock_unlock(member->rwlock);
-
+
/* Close Unused Handles */
if (member_fnode) {
conference_file_node_t *fnode, *cur;
const char *p;
for (p = dtmf; p && *p; p++) {
switch_dtmf_t *dt, digit = { *p, SWITCH_DEFAULT_DTMF_DURATION };
-
+
switch_zmalloc(dt, sizeof(*dt));
*dt = digit;
switch_queue_push(imember->dtmf_queue, dt);
if (fnode->fh.params) {
const char *position = switch_event_get_header(fnode->fh.params, "position");
-
+
if (!bad_params && !zstr(position) && member->conference->channels == 2) {
fnode->al = conference_al_create(pool);
if (conference_al_parse_position(fnode->al, position) != SWITCH_STATUS_SUCCESS) {
switch_mutex_unlock(member->fnode_mutex);
status = SWITCH_STATUS_SUCCESS;
- done:
+ done:
switch_safe_free(expanded);
switch_safe_free(dfile);
if (*text == '{') {
char *new_fp;
-
+
fp = switch_core_strdup(pool, text);
switch_assert(fp);
}
} else {
stream->write_function(stream, "Skipping moderator (member id %d).\n", member->id);
- }
+ }
}
switch_mutex_unlock(conference->member_mutex);
}
{
int index = -1;
int cur;
-
+
if (watching) {
cur = member->watching_canvas_id;
} else {
if (switch_is_number(val)) {
index = atoi(val) - 1;
-
+
if (index < 0) {
index = 0;
}
index--;
}
}
-
+
if (watching) {
if (index > member->conference->canvas_count || !member->conference->canvases[index]) {
index = 0;
index = member->conference->canvas_count;
}
}
-
+
if (index > MAX_CANVASES || index < 0) {
return -1;
}
-
+
if (member->conference->canvas_count > 1) {
if (index > member->conference->canvas_count) {
return -1;
if (switch_core_codec_init(&member->read_codec,
"L16",
NULL, NULL, read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000,
- read_impl.number_of_channels,
+ read_impl.number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member->pool) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG,
"Raw Codec Activation Success L16@%uhz %d channel %dms\n",
NULL,
conference->rate,
read_impl.microseconds_per_packet / 1000,
- read_impl.number_of_channels,
+ read_impl.number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, member->pool) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG,
- "Raw Codec Activation Success L16@%uhz %d channel %dms\n",
+ "Raw Codec Activation Success L16@%uhz %d channel %dms\n",
conference->rate, conference->channels, read_impl.microseconds_per_packet / 1000);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz %d channel %dms\n",
return 0;
- codec_done1:
+ codec_done1:
switch_core_codec_destroy(&member->read_codec);
- codec_done2:
+ codec_done2:
switch_core_codec_destroy(&member->write_codec);
- done:
+ done:
switch_mutex_unlock(member->audio_out_mutex);
}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
switch_assert(conference != NULL);
switch_mutex_lock(conference->member_mutex);
for (member = conference->members; member; member = member->next)
- {
- if (conference_utils_member_test_flag(member, MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path)))
{
- //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Action: %d\n", action);
- switch (action)
- {
- case REC_ACTION_STOP:
- conference_utils_member_clear_flag_locked(member, MFLAG_RUNNING);
- count++;
- break;
- case REC_ACTION_PAUSE:
- conference_utils_member_set_flag_locked(member, MFLAG_PAUSE_RECORDING);
- count = 1;
- break;
- case REC_ACTION_RESUME:
- conference_utils_member_clear_flag_locked(member, MFLAG_PAUSE_RECORDING);
- count = 1;
- break;
- }
+ if (conference_utils_member_test_flag(member, MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path)))
+ {
+ //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Action: %d\n", action);
+ switch (action)
+ {
+ case REC_ACTION_STOP:
+ conference_utils_member_clear_flag_locked(member, MFLAG_RUNNING);
+ count++;
+ break;
+ case REC_ACTION_PAUSE:
+ conference_utils_member_set_flag_locked(member, MFLAG_PAUSE_RECORDING);
+ count = 1;
+ break;
+ case REC_ACTION_RESUME:
+ conference_utils_member_clear_flag_locked(member, MFLAG_PAUSE_RECORDING);
+ count = 1;
+ break;
+ }
}
- }
+ }
switch_mutex_unlock(conference->member_mutex);
return count;
}
flags |= SWITCH_FILE_FLAG_VIDEO;
if (conference->canvas) {
char *orig_path = rec->path;
- rec->path = switch_core_sprintf(rec->pool, "{channels=%d,samplerate=%d,vw=%d,vh=%d,fps=%0.2f}%s",
+ rec->path = switch_core_sprintf(rec->pool, "{channels=%d,samplerate=%d,vw=%d,vh=%d,fps=%0.2f}%s",
conference->channels,
conference->rate,
conference->canvas->width,
switch_core_file_set_string(&member->rec->fh, SWITCH_AUDIO_COL_STR_ARTIST, "FreeSWITCH mod_conference Software Conference Module");
if (test_eflag(conference, EFLAG_RECORD) &&
- switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+ switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "start-recording");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", rec->path);
if (len == 0) {
mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer);
-
+
if (mux_used >= data_buf_len) {
goto again;
}
switch_core_timer_next(&timer);
} /* Rinse ... Repeat */
- end:
-
+ end:
+
for(;;) {
switch_mutex_lock(member->audio_out_mutex);
rlen = (uint32_t) switch_buffer_read(member->mux_buffer, data_buf, data_buf_len);
switch_mutex_unlock(member->audio_out_mutex);
-
+
if (rlen > 0) {
len = (switch_size_t) rlen / sizeof(int16_t)/ conference->channels;
- switch_core_file_write(&member->rec->fh, data_buf, &len);
+ switch_core_file_write(&member->rec->fh, data_buf, &len);
} else {
break;
}
conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-recording");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", rec->path);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Samples-Out", "%ld", (long) member->rec->fh.samples_out);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Samplerate", "%ld", (long) member->rec->fh.samplerate);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Milliseconds-Elapsed", "%ld", (long) member->rec->fh.samples_out / (member->rec->fh.samplerate / 1000));
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Samples-Out", "%ld", (long) member->rec->fh.samples_out);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Samplerate", "%ld", (long) member->rec->fh.samplerate);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Milliseconds-Elapsed", "%ld", (long) member->rec->fh.samples_out / (member->rec->fh.samplerate / 1000));
switch_event_fire(&event);
}
return NULL;
}
-
-
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
*/
#include <mod_conference.h>
-const char *conference_utils_combine_flag_var(switch_core_session_t *session, const char *var_name)
+const char *conference_utils_combine_flag_var(switch_core_session_t *session, const char *var_name)
{
switch_event_header_t *hp;
switch_event_t *event, *cevent;
switch_channel_get_variables(channel, &cevent);
switch_event_merge(event, cevent);
-
+
for (hp = event->headers; hp; hp = hp->next) {
char *var = hp->name;
char *val = hp->value;
}
}
}
-
+
switch_event_destroy(&event);
switch_event_destroy(&cevent);
} else if (!strcasecmp(argv[i], "video-muxing-personal-canvas")) {
f[CFLAG_PERSONAL_CANVAS] = 1;
}
- }
+ }
free(dup);
}
return !!member->flags[flag];
}
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
*/
#include <mod_conference.h>
-static struct conference_fps FPS_VALS[] = {
+static struct conference_fps FPS_VALS[] = {
{1.0f, 1000, 90},
{5.0f, 200, 450},
{10.0f, 100, 900},
switch_event_create(¶ms, SWITCH_EVENT_COMMAND);
switch_assert(params);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conference_name", conference->name);
-
+
if (!(cxml = switch_xml_open_cfg("conference_layouts.conf", &cfg, params))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", "conference_layouts.conf");
goto done;
video_layout_t *vlayout;
const char *val = NULL, *name = NULL;
switch_bool_t auto_3d = SWITCH_FALSE;
-
+
if ((val = switch_xml_attr(x_layout, "name"))) {
name = val;
}
}
auto_3d = switch_true(switch_xml_attr(x_layout, "auto-3d-position"));
-
+
vlayout = switch_core_alloc(conference->pool, sizeof(*vlayout));
vlayout->name = switch_core_strdup(conference->pool, name);
if ((val = switch_xml_attr(x_image, "x"))) {
x = atoi(val);
}
-
+
if ((val = switch_xml_attr(x_image, "y"))) {
y = atoi(val);
}
-
+
if ((val = switch_xml_attr(x_image, "scale"))) {
scale = atoi(val);
}
-
+
if ((val = switch_xml_attr(x_image, "floor"))) {
floor = switch_true(val);
}
if ((val = switch_xml_attr(x_image, "overlap"))) {
overlap = switch_true(val);
}
-
+
if ((val = switch_xml_attr(x_image, "reservation_id"))) {
res_id = val;
}
continue;
}
-
+
vlayout->images[vlayout->layers].x = x;
vlayout->images[vlayout->layers].y = y;
vlayout->images[vlayout->layers].scale = scale;
vlayout->images[vlayout->layers].flooronly = flooronly;
vlayout->images[vlayout->layers].fileonly = fileonly;
vlayout->images[vlayout->layers].overlap = overlap;
-
+
if (res_id) {
vlayout->images[vlayout->layers].res_id = switch_core_strdup(conference->pool, res_id);
}
switch_snprintf(cmd_str, sizeof(cmd_str), "add conference ::conference::conference_list_conferences vid-layout %s", name);
switch_console_set_complete(cmd_str);
}
-
+
}
if ((x_groups = switch_xml_child(x_layout_settings, "groups"))) {
video_layout_node_t *last_vlnode = NULL;
x_layout = switch_xml_child(x_group, "layout");
-
+
if (!name || !x_group || !x_layout) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid group\n");
continue;
cxml = NULL;
}
- switch_event_destroy(¶ms);
+ switch_event_destroy(¶ms);
}
layer->mute_patched = 0;
layer->banner_patched = 0;
layer->is_avatar = 0;
-
+
if (layer->geometry.overlap) {
layer->canvas->refresh = 1;
}
double screen_aspect = 0, img_aspect = 0;
int x_pos = layer->x_pos;
int y_pos = layer->y_pos;
-
+
img_w = layer->screen_w = IMG->d_w * layer->geometry.scale / VIDEO_LAYOUT_SCALE;
img_h = layer->screen_h = IMG->d_h * layer->geometry.scale / VIDEO_LAYOUT_SCALE;
if (freeze) {
switch_img_free(&layer->img);
}
-
+
if (screen_aspect > img_aspect) {
img_w = img_aspect * layer->screen_h;
x_pos += (layer->screen_w - img_w) / 2;
if (!layer->img) {
layer->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, img_w, img_h, 1);
}
-
+
if (layer->banner_img && !layer->banner_patched) {
switch_img_fill(layer->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h, &layer->canvas->letterbox_bgcolor);
switch_img_patch(IMG, layer->banner_img, layer->x_pos, layer->y_pos + (layer->screen_h - layer->banner_img->d_h));
switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex, layer->y_pos + ey);
if (layer->logo_text_img) {
int tx = 0, ty = 0;
- switch_img_find_position(POS_LEFT_BOT,
+ switch_img_find_position(POS_LEFT_BOT,
layer->logo_img->d_w, layer->logo_img->d_h, layer->logo_text_img->d_w, layer->logo_text_img->d_h, &tx, &ty);
switch_img_patch(IMG, layer->logo_text_img, layer->x_pos + ex + tx, layer->y_pos + ey + ty);
}
mcu_canvas_t *canvas = NULL;
switch_mutex_lock(member->conference->canvas_mutex);
-
+
if (member->canvas_id < 0) goto end;
canvas = member->conference->canvases[member->canvas_id];
if (!path) {
path = member->video_logo;
}
-
+
if (!path) {
goto end;
}
}
- if (zstr(path) || !strcasecmp(path, "reset")) {
+ if (zstr(path) || !strcasecmp(path, "reset")) {
path = switch_channel_get_variable_dup(member->channel, "video_logo_path", SWITCH_FALSE, -1);
}
-
+
if (zstr(path) || !strcasecmp(path, "clear")) {
switch_img_free(&layer->banner_img);
layer->banner_patched = 0;
-
- switch_img_fill(member->conference->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h,
+
+ switch_img_fill(member->conference->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h,
&member->conference->canvas->letterbox_bgcolor);
goto end;
}
}
}
-
+
if (params) switch_event_destroy(¶ms);
switch_safe_free(dup);
const char *font_face = NULL;
const char *var, *tmp = NULL;
char *dup = NULL;
-
+
switch_mutex_lock(layer->canvas->mutex);
if (!text) {
text = member->video_banner_text;
}
-
+
if (!text) {
goto end;
}
}
}
- if (zstr(text) || !strcasecmp(text, "reset")) {
+ if (zstr(text) || !strcasecmp(text, "reset")) {
text = switch_channel_get_variable_dup(member->channel, "video_banner_text", SWITCH_FALSE, -1);
}
-
+
if (zstr(text) || !strcasecmp(text, "clear")) {
switch_img_free(&layer->banner_img);
layer->banner_patched = 0;
-
- switch_img_fill(member->conference->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h,
+
+ switch_img_fill(member->conference->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h,
&member->conference->canvas->letterbox_bgcolor);
goto end;
switch_channel_t *channel = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS;
const char *var = NULL;
-
+
if (!member->session) abort();
channel = switch_core_session_get_channel(member->session);
member->video_layer_id = idx;
switch_goto_status(SWITCH_STATUS_BREAK, end);
}
-
+
if (layer->geometry.res_id || member->video_reservation_id) {
if (!layer->geometry.res_id || !member->video_reservation_id || strcmp(layer->geometry.res_id, member->video_reservation_id)) {
switch_goto_status(SWITCH_STATUS_FALSE, end);
}
}
-
+
if (member->video_layer_id > -1) {
conference_video_detach_video_layer(member);
}
switch_img_free(&layer->mute_img);
member->avatar_patched = 0;
-
+
if (member->avatar_png_img) {
layer->is_avatar = 1;
}
-
+
var = NULL;
if (member->video_banner_text || (var = switch_channel_get_variable_dup(channel, "video_banner_text", SWITCH_FALSE, -1))) {
conference_video_layer_set_banner(member, layer, var);
void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout)
{
- int i = 0;
+ int i = 0;
if (!canvas) return;
- switch_mutex_lock(canvas->mutex);
+ switch_mutex_lock(canvas->mutex);
canvas->layout_floor_id = -1;
if (!vlayout) {
}
canvas->vlayout = vlayout;
-
+
for (i = 0; i < vlayout->layers; i++) {
mcu_layer_t *layer = &canvas->layers[i];
layer->geometry.x = vlayout->images[i].x;
canvas->total_layers = vlayout->layers;
canvas->send_keyframe = 1;
- switch_mutex_unlock(canvas->mutex);
+ switch_mutex_unlock(canvas->mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Canvas position %d applied layout %s\n", canvas->canvas_id, vlayout->name);
}
if (!super) {
conference->canvas_count++;
-
+
if (!conference->canvas) {
conference->canvas = canvas;
}
}
-
+
conference->canvases[canvas->canvas_id] = canvas;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Canvas attached to position %d\n", canvas->canvas_id);
canvas->width = conference->canvas_width;
canvas->height = conference->canvas_height;
-
+
canvas->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, canvas->width, canvas->height, 0);
switch_queue_create(&canvas->video_queue, 200, canvas->pool);
}
void conference_video_write_canvas_image_to_codec_group(conference_obj_t *conference, mcu_canvas_t *canvas, codec_set_t *codec_set,
- int codec_index, uint32_t timestamp, switch_bool_t need_refresh,
- switch_bool_t need_keyframe, switch_bool_t need_reset)
+ int codec_index, uint32_t timestamp, switch_bool_t need_refresh,
+ switch_bool_t need_keyframe, switch_bool_t need_reset)
{
conference_member_t *imember;
}
do {
-
+
frame->data = ((unsigned char *)frame->packet) + 12;
frame->datalen = SWITCH_DEFAULT_VIDEO_SIZE;
if (conference_utils_member_test_flag(imember, MFLAG_NO_MINIMIZE_ENCODING)) {
continue;
}
-
+
if (imember->video_codec_index != codec_index) {
continue;
}
//if (need_refresh) {
// switch_core_session_request_video_refresh(imember->session);
//}
-
+
//switch_core_session_write_encoded_video_frame(imember->session, frame, 0, 0);
switch_set_flag(frame, SFF_ENCODED);
-
+
if (switch_frame_buffer_dup(imember->fb, frame, &dupframe) == SWITCH_STATUS_SUCCESS) {
switch_queue_push(imember->mux_out_queue, dupframe);
dupframe = NULL;
switch_img_copy(layer->cur_img, &layer->mute_img);
}
- switch_mutex_unlock(canvas->mutex);
+ switch_mutex_unlock(canvas->mutex);
}
}
void conference_video_canvas_del_fnode_layer(conference_obj_t *conference, conference_file_node_t *fnode)
{
mcu_canvas_t *canvas = conference->canvases[fnode->canvas_id];
-
+
switch_mutex_lock(canvas->mutex);
if (fnode->layer_id > -1) {
mcu_layer_t *xlayer = &canvas->layers[fnode->layer_id];
-
+
fnode->layer_id = -1;
fnode->canvas_id = -1;
xlayer->fnode = NULL;
if (xlayer->fnode || xlayer->geometry.res_id || xlayer->member_id) {
continue;
}
-
+
idx = i;
break;
}
}
if (idx < 0) goto end;
-
+
layer = &canvas->layers[idx];
layer->fnode = fnode;
switch_thread_rwlock_unlock(member->rwlock);
}
}
-
+
end:
switch_mutex_unlock(canvas->mutex);
{
switch_threadattr_t *thd_attr = NULL;
switch_mutex_lock(conference_globals.hash_mutex);
- if (!member->video_muxing_write_thread) {
+ if (!member->video_muxing_write_thread) {
switch_threadattr_create(&thd_attr, member->pool);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&member->video_muxing_write_thread, thd_attr, conference_video_muxing_write_thread_run, member, member->pool);
switch_threadattr_t *thd_attr = NULL;
switch_mutex_lock(conference_globals.hash_mutex);
- if (!canvas->video_muxing_thread) {
+ if (!canvas->video_muxing_thread) {
switch_threadattr_create(&thd_attr, conference->pool);
switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
conference_utils_set_flag(conference, CFLAG_VIDEO_MUXING);
- switch_thread_create(&canvas->video_muxing_thread, thd_attr,
+ switch_thread_create(&canvas->video_muxing_thread, thd_attr,
super ? conference_video_super_muxing_thread_run : conference_video_muxing_thread_run, canvas, conference->pool);
}
switch_mutex_unlock(conference_globals.hash_mutex);
}
loops++;
-
+
frame = (switch_frame_t *) pop;
if (switch_test_flag(frame, SFF_ENCODED)) {
void conference_video_check_recording(conference_obj_t *conference, switch_frame_t *frame)
{
conference_member_t *imember;
-
+
if (!conference->recording_members) {
return;
}
switch_mutex_lock(conference->member_mutex);
-
+
for (imember = conference->members; imember; imember = imember->next) {
if (!imember->rec) {
continue;
- }
+ }
if (switch_test_flag((&imember->rec->fh), SWITCH_FILE_OPEN) && switch_core_file_has_video(&imember->rec->fh)) {
switch_core_file_write_video(&imember->rec->fh, frame);
}
canvas = member->conference->canvases[member->canvas_id];
- if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) &&
+ if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) &&
(!switch_channel_test_flag(member->channel, CF_VIDEO) || member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY)) {
return;
}
}
member->avatar_patched = 0;
-
+
if (!force && switch_channel_test_flag(member->channel, CF_VIDEO) && member->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
conference_utils_member_set_flag_locked(member, MFLAG_ACK_VIDEO);
} else {
if (member->conference->no_video_avatar) {
avatar = member->conference->no_video_avatar;
}
-
+
if ((var = switch_channel_get_variable_dup(member->channel, "video_no_video_avatar_png", SWITCH_FALSE, -1))) {
avatar = var;
}
}
-
+
if ((var = switch_channel_get_variable_dup(member->channel, "video_avatar_png", SWITCH_FALSE, -1))) {
avatar = var;
}
-
+
switch_img_free(&member->avatar_png_img);
-
+
if (avatar) {
member->avatar_png_img = switch_img_read_png(avatar, SWITCH_IMG_FMT_I420);
}
if (force && !member->avatar_png_img && member->video_mute_img) {
switch_img_copy(member->video_mute_img, &member->avatar_png_img);
}
-
+
if (canvas) {
switch_mutex_unlock(canvas->mutex);
}
if (!member->channel || !switch_channel_test_flag(member->channel, CF_VIDEO)) {
return;
}
-
+
flushed = conference_video_flush_queue(member->video_queue);
-
+
if (flushed && member->auto_avatar) {
switch_channel_video_sync(member->channel);
-
+
switch_img_free(&member->avatar_png_img);
member->avatar_patched = 0;
conference_video_reset_video_bitrate_counters(member);
void conference_video_fnode_check(conference_file_node_t *fnode) {
mcu_canvas_t *canvas = fnode->conference->canvases[fnode->canvas_id];
-
+
if (switch_core_file_has_video(&fnode->fh) && switch_core_file_read_video(&fnode->fh, NULL, SVR_CHECK) == SWITCH_STATUS_BREAK) {
int full_screen = 0;
if (fnode->fh.params && fnode->conference->canvas_count == 1) {
full_screen = switch_true(switch_event_get_header(fnode->fh.params, "full-screen"));
}
-
+
if (full_screen) {
canvas->play_file = 1;
canvas->conference->playing_video_file = 1;
for (i = 0; i < canvas->total_layers; i++) {
mcu_layer_t *xlayer = &canvas->layers[i];
-
+
if (xlayer->is_avatar && xlayer->member_id != conference->video_floor_holder) {
avatar_layers++;
}
}
- if (!layer &&
- (canvas->layers_used < canvas->total_layers ||
+ if (!layer &&
+ (canvas->layers_used < canvas->total_layers ||
(avatar_layers && !member->avatar_png_img) || conference_utils_member_test_flag(member, MFLAG_MOD)) &&
(member->avatar_png_img || member->video_flow != SWITCH_MEDIA_FLOW_SENDONLY)) {
/* find an empty layer */
conference_video_attach_video_layer(member, canvas, i);
break;
}
- } else if ((!xlayer->member_id || (!member->avatar_png_img &&
- xlayer->is_avatar &&
+ } else if ((!xlayer->member_id || (!member->avatar_png_img &&
+ xlayer->is_avatar &&
xlayer->member_id != conference->video_floor_holder)) &&
!xlayer->fnode && !xlayer->geometry.fileonly) {
switch_status_t lstatus;
}
size = switch_queue_size(member->video_queue);
} while(size > member->conference->video_fps.fps / 2);
-
+
if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && member->video_layer_id > -1 && member->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
if (img) {
member->good_img++;
} else {
member->blanks++;
member->good_img = 0;
-
+
if (member->blanks == member->conference->video_fps.fps || (member->blanks % (int)(member->conference->video_fps.fps * 10)) == 0) {
member->managed_kps = 0;
switch_core_session_request_video_refresh(member->session);
}
-
+
if (member->blanks == member->conference->video_fps.fps * 5) {
member->blackouts++;
conference_video_check_avatar(member, SWITCH_TRUE);
member->managed_kps = 0;
-
+
if (member->avatar_png_img) {
//if (layer) {
//layer->is_avatar = 1;
//}
-
+
member->auto_avatar = 1;
}
}
int kps;
int w = 320;
int h = 240;
-
+
if (layer) {
if (layer->screen_w > 320 && layer->screen_h > 240) {
w = layer->screen_w;
h = layer->screen_h;
}
}
-
+
if (!layer || !conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) || member->avatar_png_img) {
kps = 200;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps because user's image is not visible\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps because user's image is not visible\n",
switch_channel_get_name(member->channel), kps);
} else {
kps = switch_calc_bitrate(w, h, 2, member->conference->video_fps.fps);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps to accomodate %dx%d resolution\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps to accomodate %dx%d resolution\n",
switch_channel_get_name(member->channel), kps, layer->screen_w, layer->screen_h);
}
-
+
msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
msg.numeric_arg = kps * 1024;
msg.from = __FILE__;
-
+
switch_core_session_receive_message(member->session, &msg);
member->managed_kps = kps;
}
int last_file_count = 0;
canvas->video_timer_reset = 1;
-
+
packet = switch_core_alloc(conference->pool, SWITCH_RTP_MAX_BUF_LEN);
while (conference_globals.running && !conference_utils_test_flag(conference, CFLAG_DESTRUCT) && conference_utils_test_flag(conference, CFLAG_VIDEO_MUXING)) {
if (canvas->timer.interval) {
switch_core_timer_destroy(&canvas->timer);
}
-
+
switch_core_timer_init(&canvas->timer, "soft", conference->video_fps.ms, conference->video_fps.samples, NULL);
canvas->send_keyframe = 1;
}
}
now = switch_micro_time_now();
-
+
if (members_with_video != conference->members_with_video) {
do_refresh = 100;
count_changed = 1;
}
-
+
if (members_with_avatar != conference->members_with_avatar) {
count_changed = 1;
}
layout_group_t *lg = NULL;
video_layout_t *vlayout = NULL;
int canvas_count = 0;
-
+
switch_mutex_lock(conference->member_mutex);
for (imember = conference->members; imember; imember = imember->next) {
if (imember->canvas_id == canvas->canvas_id || imember->canvas_id == -1) {
}
}
switch_mutex_unlock(conference->member_mutex);
-
+
if (conference->video_layout_group && (lg = switch_core_hash_find(conference->layout_group_hash, conference->video_layout_group))) {
if ((vlayout = conference_video_find_best_layout(conference, lg, canvas_count))) {
switch_mutex_lock(conference->member_mutex);
}
}
}
-
+
if (count_changed) {
need_refresh = 1;
need_keyframe = 1;
do_refresh = 100;
}
-
+
if (conference->async_fnode && switch_core_file_has_video(&conference->async_fnode->fh)) {
check_async_file = 1;
file_count++;
}
-
+
if (conference->fnode && switch_core_file_has_video(&conference->fnode->fh)) {
check_file = 1;
file_count++;
}
last_file_count = file_count;
-
+
if (do_refresh) {
if ((do_refresh % 50) == 0) {
switch_mutex_lock(conference->member_mutex);
-
- for (imember = conference->members; imember; imember = imember->next) {
+
+ for (imember = conference->members; imember; imember = imember->next) {
if (imember->canvas_id != canvas->canvas_id) continue;
if (imember->session && switch_channel_test_flag(imember->channel, CF_VIDEO)) {
}
do_refresh--;
}
-
+
members_with_video = conference->members_with_video;
members_with_avatar = conference->members_with_avatar;
}
switch_mutex_lock(conference->member_mutex);
-
+
for (imember = conference->members; imember; imember = imember->next) {
switch_image_t *img = NULL;
int i;
-
- if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO) && !imember->avatar_png_img) ||
+
+ if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO) && !imember->avatar_png_img) ||
conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
continue;
- }
+ }
if (imember->watching_canvas_id == canvas->canvas_id && switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) {
switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ);
}
if (conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING) &&
- imember->watching_canvas_id > -1 && imember->watching_canvas_id == canvas->canvas_id &&
+ imember->watching_canvas_id > -1 && imember->watching_canvas_id == canvas->canvas_id &&
!conference_utils_member_test_flag(imember, MFLAG_NO_MINIMIZE_ENCODING)) {
min_members++;
-
- if (switch_channel_test_flag(imember->channel, CF_VIDEO)) {
+
+ if (switch_channel_test_flag(imember->channel, CF_VIDEO)) {
if (imember->video_codec_index < 0 && (check_codec = switch_core_session_get_video_write_codec(imember->session))) {
for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) {
if (check_codec->implementation->codec_id == write_codecs[i]->codec.implementation->codec_id) {
if (imember->video_codec_index < 0) {
write_codecs[i] = switch_core_alloc(conference->pool, sizeof(codec_set_t));
-
- if (switch_core_codec_copy(check_codec, &write_codecs[i]->codec,
+
+ if (switch_core_codec_copy(check_codec, &write_codecs[i]->codec,
&conference->video_codec_settings, conference->pool) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Setting up video write codec %s at slot %d\n", write_codecs[i]->codec.implementation->iananame, i);
continue;
}
- //VIDFLOOR
- if (conference->canvas_count == 1 && canvas->layout_floor_id > -1 && imember->id == conference->video_floor_holder &&
+ //VIDFLOOR
+ if (conference->canvas_count == 1 && canvas->layout_floor_id > -1 && imember->id == conference->video_floor_holder &&
imember->video_layer_id != canvas->layout_floor_id) {
conference_video_attach_video_layer(imember, canvas, canvas->layout_floor_id);
}
-
+
conference_video_pop_next_image(imember, &img);
layer = NULL;
switch_mutex_lock(canvas->mutex);
//printf("MEMBER %d layer_id %d canvas: %d/%d\n", imember->id, imember->video_layer_id,
// canvas->layers_used, canvas->total_layers);
-
+
if (imember->video_layer_id > -1) {
layer = &canvas->layers[imember->video_layer_id];
if (layer->member_id != imember->id) {
}
if (!layer) {
- if (conference_video_find_layer(conference, canvas, imember, &layer) == SWITCH_STATUS_SUCCESS) {
- imember->layer_timeout = 0;
- } else {
- if (--imember->layer_timeout <= 0) {
- conference_video_next_canvas(imember);
- }
- }
+ if (conference_video_find_layer(conference, canvas, imember, &layer) == SWITCH_STATUS_SUCCESS) {
+ imember->layer_timeout = 0;
+ } else {
+ if (--imember->layer_timeout <= 0) {
+ conference_video_next_canvas(imember);
+ }
+ }
}
conference_video_check_auto_bitrate(imember, layer);
if (layer) {
-
+
//if (layer->cur_img && layer->cur_img != imember->avatar_png_img) {
// switch_img_free(&layer->cur_img);
//}
if (img && img != imember->avatar_png_img) {
switch_img_free(&img);
}
-
+
if (!layer->mute_patched) {
if (imember->video_mute_img || layer->mute_img) {
conference_video_clear_layer(layer);
-
+
if (!layer->mute_img && imember->video_mute_img) {
//layer->mute_img = switch_img_read_png(imember->video_mute_png, SWITCH_IMG_FMT_I420);
switch_img_copy(imember->video_mute_img, &layer->mute_img);
if (layer->mute_img) {
conference_video_scale_and_patch(layer, layer->mute_img, SWITCH_FALSE);
}
- }
+ }
+
-
tmp = switch_img_write_text_img(layer->screen_w, layer->screen_h, SWITCH_TRUE, "VIDEO MUTED");
switch_img_patch(canvas->img, tmp, layer->x_pos, layer->y_pos);
switch_img_free(&tmp);
layer->cur_img = img;
}
-
+
img = NULL;
layer->tagged = 1;
if (switch_core_media_bug_count(imember->session, "patch:video")) {
layer->bugged = 1;
}
- }
+ }
}
switch_mutex_unlock(canvas->mutex);
if (img && img != imember->avatar_png_img) {
switch_img_free(&img);
}
-
+
if (imember->session) {
switch_core_session_rwunlock(imember->session);
}
}
-
+
switch_mutex_unlock(conference->member_mutex);
if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) {
layout_group_t *lg = NULL;
video_layout_t *vlayout = NULL;
conference_member_t *omember;
-
+
if (video_key_freq && (now - last_key_time) > video_key_freq) {
need_keyframe = SWITCH_TRUE;
last_key_time = now;
switch_mutex_lock(conference->member_mutex);
for (imember = conference->members; imember; imember = imember->next) {
-
+
if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) ||
switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
continue;
switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ);
need_keyframe = SWITCH_TRUE;
}
-
+
if (count_changed) {
int total = conference->members_with_video;
if (!conference_utils_test_flag(conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS)) {
total += conference->members_with_avatar;
}
-
+
if (imember->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
total--;
}
}
}
}
-
+
if (check_file) {
if (switch_core_file_read_video(&conference->fnode->fh, &file_frame, SVR_BLOCK | SVR_FLUSH) == SWITCH_STATUS_SUCCESS) {
if ((normal_file_img = file_frame.img)) {
file_imgs[j++] = normal_file_img;
}
}
- }
+ }
for (imember = conference->members; imember; imember = imember->next) {
int i = 0;
-
+
if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO || imember->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) ||
switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
continue;
}
-
+
for (omember = conference->members; omember; omember = omember->next) {
mcu_layer_t *layer = NULL;
switch_image_t *use_img = NULL;
if (conference->members_with_video + conference->members_with_avatar != 1 && imember == omember) {
continue;
}
-
+
if (i < imember->canvas->total_layers) {
layer = &imember->canvas->layers[i++];
if (layer->member_id != omember->id) {
const char *var = NULL;
-
+
layer->mute_patched = 0;
layer->avatar_patched = 0;
switch_img_free(&layer->banner_img);
switch_img_free(&layer->logo_img);
-
+
if (layer->geometry.audio_position) {
conference_api_sub_position(omember, NULL, layer->geometry.audio_position);
}
-
+
var = NULL;
- if (omember->video_banner_text ||
+ if (omember->video_banner_text ||
(var = switch_channel_get_variable_dup(omember->channel, "video_banner_text", SWITCH_FALSE, -1))) {
conference_video_layer_set_banner(omember, layer, var);
}
-
+
var = NULL;
- if (omember->video_logo ||
+ if (omember->video_logo ||
(var = switch_channel_get_variable_dup(omember->channel, "video_logo_path", SWITCH_FALSE, -1))) {
conference_video_layer_set_logo(omember, layer, var);
}
layer->member_id = omember->id;
}
-
+
if (!layer && omember->al) {
conference_api_sub_position(omember, NULL, "0:0:0");
}
-
+
use_img = omember->pcanvas_img;
-
+
if (layer) {
-
+
if (use_img && !omember->avatar_png_img) {
layer->avatar_patched = 0;
} else {
switch_img_free(&tmp);
layer->mute_patched = 1;
}
-
+
use_img = NULL;
layer = NULL;
}
}
-
+
if (layer && use_img) {
conference_video_scale_and_patch(layer, use_img, SWITCH_FALSE);
}
conference_video_scale_and_patch(layer, img, SWITCH_FALSE);
}
}
-
+
switch_core_session_rwunlock(imember->session);
}
for (imember = conference->members; imember; imember = imember->next) {
switch_frame_t *dupframe;
-
+
if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) ||
switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
continue;
write_frame.datalen = 0;
write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12;
write_frame.packetlen = 0;
-
+
if (switch_frame_buffer_dup(imember->fb, &write_frame, &dupframe) == SWITCH_STATUS_SUCCESS) {
switch_queue_push(imember->mux_out_queue, dupframe);
dupframe = NULL;
switch_core_session_rwunlock(imember->session);
}
-
+
switch_mutex_unlock(conference->member_mutex);
} else {
if (canvas->canvas_id == 0) {
if (conference->async_fnode) {
- if (conference->async_fnode->layer_id > -1) {
+ if (conference->async_fnode->layer_id > -1) {
conference_video_patch_fnode(canvas, conference->async_fnode);
} else {
conference_video_fnode_check(conference->async_fnode);
}
}
-
+
if (conference->fnode) {
if (conference->fnode->layer_id > -1) {
conference_video_patch_fnode(canvas, conference->fnode);
}
}
}
-
+
if (!conference->playing_video_file) {
for (i = 0; i < canvas->total_layers; i++) {
mcu_layer_t *layer = &canvas->layers[i];
if (layer->cur_img) {
conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE);
}
-
+
layer->tagged = 0;
}
-
+
layer->bugged = 0;
}
}
need_keyframe = SWITCH_TRUE;
last_key_time = now;
}
-
+
write_img = canvas->img;
timestamp = canvas->timer.samplecount;
if (canvas->play_file) {
canvas->send_keyframe = 1;
canvas->play_file = 0;
-
+
canvas->timer.interval = 1;
canvas->timer.samples = 90;
}
}
write_frame.img = write_img;
-
+
if (conference->canvas_count == 1) {
conference_video_check_recording(conference, &write_frame);
}
if (min_members && conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING)) {
for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) {
write_codecs[i]->frame.img = write_img;
- conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i,
- timestamp, need_refresh, need_keyframe, need_reset);
+ conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i,
+ timestamp, need_refresh, need_keyframe, need_reset);
if (canvas->video_write_bandwidth) {
switch_core_codec_control(&write_codecs[i]->codec, SCC_VIDEO_BANDWIDTH, SCCT_INT, &canvas->video_write_bandwidth, NULL, NULL);
write_frame.datalen = 0;
write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12;
write_frame.packetlen = 0;
-
+
//switch_core_session_write_video_frame(imember->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
-
+
if (switch_frame_buffer_dup(imember->fb, &write_frame, &dupframe) == SWITCH_STATUS_SUCCESS) {
switch_queue_push(imember->mux_out_queue, dupframe);
dupframe = NULL;
}
if (imember->session) {
- switch_core_session_rwunlock(imember->session);
+ switch_core_session_rwunlock(imember->session);
}
}
canvas->video_timer_reset = 1;
-
+
packet = switch_core_alloc(conference->pool, SWITCH_RTP_MAX_BUF_LEN);
while (conference_globals.running && !conference_utils_test_flag(conference, CFLAG_DESTRUCT) && conference_utils_test_flag(conference, CFLAG_VIDEO_MUXING)) {
conference_video_init_canvas_layers(conference, canvas, NULL);
}
switch_mutex_unlock(canvas->mutex);
-
+
if (canvas->video_timer_reset) {
canvas->video_timer_reset = 0;
if (canvas->timer.interval) {
switch_core_timer_destroy(&canvas->timer);
}
-
+
switch_core_timer_init(&canvas->timer, "soft", conference->video_fps.ms, conference->video_fps.samples, NULL);
canvas->send_keyframe = 1;
}
if (jcanvas->layers_used != last_used_canvases[j]) {
count_changed++;
}
-
+
last_used_canvases[j] = jcanvas->layers_used;
}
-
+
if (count_changed) {
int total = used_canvases;
layout_group_t *lg = NULL;
}
switch_mutex_lock(conference->member_mutex);
-
+
for (imember = conference->members; imember; imember = imember->next) {
int i;
-
- if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO) && !imember->avatar_png_img) ||
+
+ if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO) && !imember->avatar_png_img) ||
conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
continue;
- }
+ }
if (imember->watching_canvas_id == canvas->canvas_id && switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) {
switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ);
need_keyframe = SWITCH_TRUE;
}
-
+
if (conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING) &&
- imember->watching_canvas_id > -1 && imember->watching_canvas_id == canvas->canvas_id &&
+ imember->watching_canvas_id > -1 && imember->watching_canvas_id == canvas->canvas_id &&
!conference_utils_member_test_flag(imember, MFLAG_NO_MINIMIZE_ENCODING)) {
min_members++;
-
- if (switch_channel_test_flag(imember->channel, CF_VIDEO)) {
+
+ if (switch_channel_test_flag(imember->channel, CF_VIDEO)) {
if (imember->video_codec_index < 0 && (check_codec = switch_core_session_get_video_write_codec(imember->session))) {
for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) {
if (check_codec->implementation->codec_id == write_codecs[i]->codec.implementation->codec_id) {
if (imember->video_codec_index < 0) {
write_codecs[i] = switch_core_alloc(conference->pool, sizeof(codec_set_t));
-
- if (switch_core_codec_copy(check_codec, &write_codecs[i]->codec,
+
+ if (switch_core_codec_copy(check_codec, &write_codecs[i]->codec,
&conference->video_codec_settings, conference->pool) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Setting up video write codec %s at slot %d\n", write_codecs[i]->codec.implementation->iananame, i);
switch_core_session_rwunlock(imember->session);
}
-
+
switch_mutex_unlock(conference->member_mutex);
layer_idx = 0;
for (j = 0; j < conference->canvas_count; j++) {
mcu_canvas_t *jcanvas = (mcu_canvas_t *) conference->canvases[j];
-
+
pop_conference_video_next_canvas_image(jcanvas, &img);
if (!jcanvas->layers_used && !conference->super_canvas_show_all_layers) {
switch_img_free(&img);
continue;
}
-
+
if (layer_idx < canvas->total_layers) {
layer = &canvas->layers[layer_idx++];
layer->member_id = jcanvas->canvas_id;
switch_img_free(&layer->cur_img);
}
-
+
if (canvas->refresh) {
layer->refresh = 1;
canvas->refresh++;
char str[80] = "";
switch_image_t *tmp;
const char *format = "#cccccc:#142e55:FreeSans.ttf:4%:";
-
+
switch_snprintf(str, sizeof(str), "%sCanvas %d", format, jcanvas->canvas_id + 1);
tmp = switch_img_write_text_img(img->d_w, img->d_h, SWITCH_TRUE, str);
switch_img_patch(img, tmp, 0, 0);
switch_img_free(&img);
}
-
+
if (canvas->refresh > 1) {
canvas->refresh = 0;
}
for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) {
write_codecs[i]->frame.img = write_img;
conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i, timestamp, need_refresh, need_keyframe, need_reset);
-
+
if (canvas->video_write_bandwidth) {
switch_core_codec_control(&write_codecs[i]->codec, SCC_VIDEO_BANDWIDTH, SCCT_INT, &canvas->video_write_bandwidth, NULL, NULL);
canvas->video_write_bandwidth = 0;
}
}
}
-
+
switch_mutex_lock(conference->member_mutex);
for (imember = conference->members; imember; imember = imember->next) {
switch_frame_t *dupframe;
write_frame.datalen = 0;
write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12;
write_frame.packetlen = 0;
-
+
//switch_core_session_write_video_frame(imember->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
-
+
if (switch_frame_buffer_dup(imember->fb, &write_frame, &dupframe) == SWITCH_STATUS_SUCCESS) {
switch_queue_push(imember->mux_out_queue, dupframe);
dupframe = NULL;
}
if (imember->session) {
- switch_core_session_rwunlock(imember->session);
+ switch_core_session_rwunlock(imember->session);
}
}
}
}
- switch_mutex_lock(conference->member_mutex);
+ switch_mutex_lock(conference->member_mutex);
for (imember = conference->members; imember; imember = imember->next) {
if (!(imember->session)) {
}
}
- switch_mutex_unlock(conference->member_mutex);
+ switch_mutex_unlock(conference->member_mutex);
if (conference->last_video_floor_holder == conference->video_floor_holder) {
conference->last_video_floor_holder = 0;
if ((!force && conference_utils_test_flag(conference, CFLAG_VID_FLOOR_LOCK))) {
return;
}
-
+
if (member && member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) {
return;
}
if (conference->video_floor_holder) {
if (member && conference->video_floor_holder == member->id) {
return;
- } else {
+ } else {
if (member) {
conference->last_video_floor_holder = conference->video_floor_holder;
}
-
+
if (conference->last_video_floor_holder && (imember = conference_member_get(conference, conference->last_video_floor_holder))) {
switch_core_session_request_video_refresh(imember->session);
if (conference_utils_member_test_flag(imember, MFLAG_VIDEO_BRIDGE)) {
conference_utils_set_flag(conference, CFLAG_VID_FLOOR_LOCK);
- }
+ }
switch_thread_rwlock_unlock(imember->rwlock);
imember = NULL;
}
-
+
old_member = conference->video_floor_holder;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping video floor %d\n", old_member);
}
if (switch_test_flag(vid_frame, SFF_CNG) || !vid_frame->packet) {
return;
}
-
+
if (conference_utils_test_flag(conference, CFLAG_FLOOR_CHANGE)) {
conference_utils_clear_flag(conference, CFLAG_FLOOR_CHANGE);
}
}
- switch_mutex_lock(conference->member_mutex);
+ switch_mutex_lock(conference->member_mutex);
for (imember = conference->members; imember; imember = imember->next) {
switch_core_session_t *isession = imember->session;
-
+
if (!isession || switch_core_session_read_lock(isession) != SWITCH_STATUS_SUCCESS) {
continue;
}
-
+
if (switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) {
want_refresh++;
switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ);
}
-
+
if (isession && switch_channel_test_flag(imember->channel, CF_VIDEO)) {
int send_frame = 0;
if (switch_channel_test_flag(imember->channel, CF_VIDEO) && (conference->members_with_video == 1 || imember != floor_holder)) {
send_frame = 1;
}
- } else if (!conference_utils_member_test_flag(imember, MFLAG_RECEIVING_VIDEO) &&
- (conference_utils_test_flag(conference, CFLAG_VID_FLOOR_LOCK) ||
- !(imember->id == imember->conference->video_floor_holder && imember->conference->last_video_floor_holder))) {
+ } else if (!conference_utils_member_test_flag(imember, MFLAG_RECEIVING_VIDEO) &&
+ (conference_utils_test_flag(conference, CFLAG_VID_FLOOR_LOCK) ||
+ !(imember->id == imember->conference->video_floor_holder && imember->conference->last_video_floor_holder))) {
send_frame = 1;
}
}
}
}
-
+
switch_core_session_rwunlock(isession);
}
switch_mutex_unlock(conference->member_mutex);
if (switch_test_flag(frame, SFF_CNG) || !frame->packet) {
return SWITCH_STATUS_SUCCESS;
}
-
-
+
+
if (switch_thread_rwlock_tryrdlock(member->conference->rwlock) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
conference_video_write_frame(member->conference, member, frame);
conference_video_check_recording(member->conference, frame);
switch_thread_rwlock_unlock(member->conference->rwlock);
- return SWITCH_STATUS_SUCCESS;
+ return SWITCH_STATUS_SUCCESS;
}
}
last->next = rel->next;
} else {
member->relationships = rel->next;
- }
+ }
switch_mutex_lock(member->conference->member_mutex);
member->conference->relationship_total--;
return SWITCH_STATUS_SUCCESS;
}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
}
stream->write_function(stream, "%s%d%s%d%s%d%s%d\n", delim,
- member->volume_in_level,
+ member->volume_in_level,
delim,
member->agc_volume_in_level,
delim, member->volume_out_level, delim, member->energy_level);
{
switch_event_t *event;
char *name = NULL, *domain = NULL, *dup_domain = NULL;
-
+
if (!conference_utils_test_flag(conference, CFLAG_RFC4579)) {
return;
}
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT);
- conference_event_add_data(conference, event);
+ conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create");
switch_event_fire(&event);
has_file_data = ready = total = 0;
floor_holder = conference->floor_holder;
-
+
/* 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;
//(!conference_utils_test_flag(conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) {
floor_holder = imember;
}
-
+
if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_VIDEO) && imember->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
members_with_video++;
}
}
switch_mutex_unlock(imember->audio_in_mutex);
}
-
+
conference->members_with_video = members_with_video;
conference->members_with_avatar = members_with_avatar;
if (conference->perpetual_sound && !conference->async_fnode) {
conference_file_play(conference, conference->perpetual_sound, CONF_DEFAULT_LEADIN, NULL, 1);
- } else if (conference->moh_sound && ((nomoh == 0 && conference->count == 1)
- || conference_utils_test_flag(conference, CFLAG_WAIT_MOD)) && !conference->async_fnode && !conference->fnode) {
+ } else if (conference->moh_sound && ((nomoh == 0 && conference->count == 1)
+ || conference_utils_test_flag(conference, CFLAG_WAIT_MOD)) && !conference->async_fnode && !conference->fnode) {
conference_file_play(conference, conference->moh_sound, CONF_DEFAULT_LEADIN, NULL, 1);
}
conference->fnode->leadin--;
} else if (!conference->fnode->done) {
file_sample_len = samples;
-
+
if (conference->fnode->type == NODE_TYPE_SPEECH) {
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_BLOCKING;
switch_size_t speech_len = file_data_len;
-
+
if (conference->fnode->al) {
speech_len /= 2;
}
-
+
if (switch_core_speech_read_tts(conference->fnode->sh, file_frame, &speech_len, &flags) == SWITCH_STATUS_SUCCESS) {
-
+
if (conference->fnode->al) {
conference_al_process(conference->fnode->al, file_frame, speech_len, conference->rate);
}
file_sample_len = file_data_len / 2 / conference->fnode->sh->channels;
-
+
} else {
file_sample_len = file_data_len = 0;
}
} else if (conference->fnode->type == NODE_TYPE_FILE) {
switch_core_file_read(&conference->fnode->fh, file_frame, &file_sample_len);
if (conference->fnode->fh.vol) {
- switch_change_sln_volume_granular((void *)file_frame, (uint32_t)file_sample_len * conference->fnode->fh.channels,
+ switch_change_sln_volume_granular((void *)file_frame, (uint32_t)file_sample_len * conference->fnode->fh.channels,
conference->fnode->fh.vol);
}
if (conference->fnode->al) {
}
}
}
-
+
if (ready || has_file_data) {
/* Use more bits in the main_frame to preserve the exact sum of the audio samples. */
int main_frame[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
/* Copy audio from every member known to be producing audio into the main frame. */
for (omember = conference->members; omember; omember = omember->next) {
conference->member_loop_count++;
-
+
if (!(conference_utils_member_test_flag(omember, MFLAG_RUNNING) && conference_utils_member_test_flag(omember, MFLAG_HAS_AUDIO))) {
continue;
}
conference->mux_loop_count++;
}
}
-
+
bptr = (int16_t *) omember->frame;
for (x = 0; x < omember->read / 2; x++) {
main_frame[x] += (int32_t) bptr[x];
if (conference->agc_level && conference->member_loop_count) {
conference_energy = 0;
-
+
for (x = 0; x < bytes / 2; x++) {
z = abs(main_frame[x]);
switch_normalize_to_16bit(z);
conference_energy += (int16_t) z;
}
-
+
conference->score = conference_energy / ((bytes / 2) / divisor) / conference->member_loop_count;
conference->avg_tally += conference->score;
conference->avg_score = conference->avg_tally / ++conference->avg_itt;
if (!conference->avg_itt) conference->avg_tally = conference->score;
}
-
+
/* Create write frame once per member who is not deaf for each sample in the main frame
check if our audio is involved and if so, subtract it from the sample so we don't hear ourselves.
Since main frame was 32 bit int, we did not lose any detail, now that we have to convert to 16 bit we can
cut it off at the min and max range if need be and write the frame to the output buffer.
- */
+ */
for (omember = conference->members; omember; omember = omember->next) {
switch_size_t ok = 1;
}
bptr = (int16_t *) omember->frame;
-
+
for (x = 0; x < bytes / 2 ; x++) {
z = main_frame[x];
z -= (int32_t) bptr[x];
}
- /* when there are relationships, we have to do more work by scouring all the members to see if there are any
+ /* when there are relationships, we have to do more work by scouring all the members to see if there are any
reasons why we should not be hearing a paticular member, and if not, delete their samples as well.
- */
+ */
if (conference->relationship_total) {
for (imember = conference->members; imember; imember = imember->next) {
if (imember != omember && conference_utils_member_test_flag(imember, MFLAG_HAS_AUDIO)) {
switch_normalize_to_16bit(z);
write_frame[x] = (int16_t) z;
}
-
+
switch_mutex_lock(omember->audio_out_mutex);
ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes);
switch_mutex_unlock(omember->audio_out_mutex);
} else {
memset(write_frame, 255, bytes);
}
-
+
for (omember = conference->members; omember; omember = omember->next) {
switch_size_t ok = 1;
-
+
if (!conference_utils_member_test_flag(omember, MFLAG_RUNNING)) {
continue;
}
-
+
switch_mutex_lock(omember->audio_out_mutex);
ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes);
switch_mutex_unlock(omember->audio_out_mutex);
if (conference->canvas && conference->fnode->layer_id > -1 ) {
conference_video_canvas_del_fnode_layer(conference, conference->fnode);
}
-
+
if (conference->fnode->type != NODE_TYPE_SPEECH) {
conference_file_close(conference, conference->fnode);
}
}
if (!conference->end_count && conference->endconference_time &&
- switch_epoch_time_now(NULL) - conference->endconference_time > conference->endconference_grace_time) {
+ switch_epoch_time_now(NULL) - conference->endconference_time > conference->endconference_grace_time) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Conference %s: endconf grace time exceeded (%u)\n",
- conference->name, conference->endconference_grace_time);
+ conference->name, conference->endconference_grace_time);
conference_utils_set_flag(conference, CFLAG_DESTRUCT | CFLAG_ENDCONF_FORCED);
}
switch_mutex_unlock(conference->mutex);
}
/* Rinse ... Repeat */
- end:
+ end:
if (conference_utils_test_flag(conference, CFLAG_OUTCALL)) {
conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL;
switch_mutex_lock(conference->mutex);
conference_file_stop(conference, FILE_STOP_ASYNC);
conference_file_stop(conference, FILE_STOP_ALL);
-
+
for (np = conference->cdr_nodes; np; np = np->next) {
if (np->var_event) {
switch_event_destroy(&np->var_event);
if (conference->vh[1].up == 1) {
conference->vh[1].up = -1;
}
-
+
while (conference->vh[0].up || conference->vh[1].up) {
switch_cond_next();
}
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT);
- conference_event_add_data(conference, event);
+ conference_event_add_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-destroy");
switch_event_fire(&event);
-
+
switch_core_timer_destroy(&timer);
switch_mutex_lock(conference_globals.hash_mutex);
if (conference_utils_test_flag(conference, CFLAG_INHASH)) {
if (*text == '{') {
char *new_fp;
-
+
fp = switch_core_strdup(pool, text);
switch_assert(fp);
switch_mutex_lock(conference_globals.hash_mutex);
for (hi = switch_core_hash_first(conference_globals.conference_hash); hi; hi = switch_core_hash_next(&hi)) {
switch_core_hash_this(hi, &vvar, NULL, &val);
- switch_console_push_match(&my_matches, (const char *) vvar);
+ switch_console_push_match(&my_matches, (const char *) vvar);
}
switch_mutex_unlock(conference_globals.hash_mutex);
-
+
if (my_matches) {
*matches = my_matches;
status = SWITCH_STATUS_SUCCESS;
switch_snprintf(i, sizeof(i), "%u", conference->rate);
switch_xml_set_attr_d(x_conference, "rate", ival);
switch_xml_set_attr_d(x_conference, "uuid", conference->uuid_str);
-
+
if (conference_utils_test_flag(conference, CFLAG_LOCKED)) {
switch_xml_set_attr_d(x_conference, "locked", "true");
}
if (conference_utils_test_flag(conference, CFLAG_EXIT_SOUND)) {
switch_xml_set_attr_d(x_conference, "exit_sound", "true");
}
-
+
if (conference_utils_test_flag(conference, CFLAG_ENTER_SOUND)) {
switch_xml_set_attr_d(x_conference, "enter_sound", "true");
}
-
+
if (conference->max_members > 0) {
switch_snprintf(i, sizeof(i), "%d", conference->max_members);
switch_xml_set_attr_d(x_conference, "max_members", ival);
switch_assert(x_member);
switch_xml_set_attr_d(x_member, "type", "recording_node");
/* or:
- x_member = switch_xml_add_child_d(x_members, "recording_node", moff++);
+ x_member = switch_xml_add_child_d(x_members, "recording_node", moff++);
*/
x_tag = switch_xml_add_child_d(x_member, "record_path", count++);
switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL) - member->join_time);
add_x_tag(x_member, "join_time", i, toff++);
-
+
switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL) - member->last_talking);
add_x_tag(x_member, "last_talking", member->last_talking ? i : "N/A", toff++);
switch_snprintf(i, sizeof(i), "%d", member->volume_out_level);
add_x_tag(x_member, "volume_out", i, toff++);
-
+
x_flags = switch_xml_add_child_d(x_member, "flags", count++);
switch_assert(x_flags);
void conference_fnode_toggle_pause(conference_file_node_t *fnode, switch_stream_handle_t *stream)
{
- if (fnode) {
+ if (fnode) {
if (switch_test_flag(fnode, NFLAG_PAUSE)) {
- stream->write_function(stream, "+OK Resume\n");
+ stream->write_function(stream, "+OK Resume\n");
switch_clear_flag(fnode, NFLAG_PAUSE);
- } else {
- stream->write_function(stream, "+OK Pause\n");
+ } else {
+ stream->write_function(stream, "+OK Pause\n");
switch_set_flag(fnode, NFLAG_PAUSE);
- }
}
+ }
}
void conference_fnode_seek(conference_file_node_t *fnode, switch_stream_handle_t *stream, char *arg)
{
- if (fnode && fnode->type == NODE_TYPE_FILE) {
+ if (fnode && fnode->type == NODE_TYPE_FILE) {
unsigned int samps = 0;
unsigned int pos = 0;
-
+
if (*arg == '+' || *arg == '-') {
- int step;
- int32_t target;
+ int step;
+ int32_t target;
if (!(step = atoi(arg))) {
- step = 1000;
- }
-
+ step = 1000;
+ }
+
samps = step * (fnode->fh.native_rate / 1000);
target = (int32_t)fnode->fh.pos + samps;
-
- if (target < 0) {
- target = 0;
- }
-
- stream->write_function(stream, "+OK seek to position %d\n", target);
+
+ if (target < 0) {
+ target = 0;
+ }
+
+ stream->write_function(stream, "+OK seek to position %d\n", target);
switch_core_file_seek(&fnode->fh, &pos, target, SEEK_SET);
-
- } else {
+
+ } else {
samps = switch_atoui(arg) * (fnode->fh.native_rate / 1000);
- stream->write_function(stream, "+OK seek to position %d\n", samps);
+ stream->write_function(stream, "+OK seek to position %d\n", samps);
switch_core_file_seek(&fnode->fh, &pos, samps, SEEK_SET);
- }
}
+ }
}
/* generate an outbound call from the conference */
switch_status_t conference_outcall(conference_obj_t *conference,
- char *conference_name,
- switch_core_session_t *session,
- char *bridgeto, uint32_t timeout,
- char *flags, char *cid_name,
- char *cid_num,
- char *profile,
- switch_call_cause_t *cause,
- switch_call_cause_t *cancel_cause, switch_event_t *var_event)
+ char *conference_name,
+ switch_core_session_t *session,
+ char *bridgeto, uint32_t timeout,
+ char *flags, char *cid_name,
+ char *cid_num,
+ char *profile,
+ switch_call_cause_t *cause,
+ switch_call_cause_t *cancel_cause, switch_event_t *var_event)
{
switch_core_session_t *peer_session = NULL;
switch_channel_t *peer_channel;
switch_channel_answer(caller_channel);
}
- callup:
+ callup:
/* if the outbound call leg is ready */
if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
/* add them to the conference */
switch_snprintf(appdata, sizeof(appdata), "%s%s%s%s%s%s", conference_name,
- profile?"@":"", profile?profile:"",
- have_flags?"+flags{":"", have_flags?flags:"", have_flags?"}":"");
+ profile?"@":"", profile?profile:"",
+ have_flags?"+flags{":"", have_flags?flags:"", have_flags?"}":"");
switch_caller_extension_add_application(peer_session, extension, (char *) mod_conference_app_name, appdata);
switch_channel_set_caller_extension(peer_channel, extension);
goto done;
}
- done:
+ done:
if (conference) {
switch_thread_rwlock_unlock(conference->rwlock);
}
conference_outcall(call->conference, call->conference_name,
- call->session, call->bridgeto, call->timeout,
+ call->session, call->bridgeto, call->timeout,
call->flags, call->cid_name, call->cid_num, call->profile, &cause, call->cancel_cause, call->var_event);
if (call->conference && test_eflag(call->conference, EFLAG_BGDIAL_RESULT) &&
}
switch_status_t conference_outcall_bg(conference_obj_t *conference,
- char *conference_name,
- switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name,
- const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause, switch_event_t **var_event)
+ char *conference_name,
+ switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name,
+ const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause, switch_event_t **var_event)
{
struct bg_call *call = NULL;
switch_thread_t *thread;
if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Channel answer failed.\n");
- goto end;
+ goto end;
}
/* Save the original read codec. */
}
}
- cflags_str = flags_str;
+ cflags_str = flags_str;
//if ((v_cflags_str = switch_channel_get_variable(channel, "conference_flags"))) {
if ((v_cflags_str = conference_utils_combine_flag_var(session, "conference_flags"))) {
if (switch_channel_test_flag(channel, CF_RECOVERED)) {
const char *check = switch_channel_get_variable(channel, "last_transfered_conference");
-
+
if (!zstr(check)) {
conference_name = (char *) check;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Cannot create a conference since join-only flag is set\n");
jos_xml = switch_xml_find_child(xml_cfg.profile, "param", "name", "join-only-sound");
if (jos_xml && (val = (char *) switch_xml_attr_soft(jos_xml, "value"))) {
- switch_channel_answer(channel);
- switch_ivr_play_file(session, NULL, val, NULL);
+ switch_channel_answer(channel);
+ switch_ivr_play_file(session, NULL, val, NULL);
}
if (!switch_false(switch_channel_get_variable(channel, "hangup_after_conference"))) {
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
}
rl++;
-
+
/* Start the conference thread for this conference */
conference_launch_thread(conference);
} else { /* setup user variable */
/* Install our Signed Linear codec so we get the audio in that format */
switch_core_session_set_read_codec(member.session, &member.read_codec);
-
+
memcpy(mflags, conference->mflags, sizeof(mflags));
-
+
conference_utils_set_mflags(flags_str, mflags);
mflags[MFLAG_RUNNING] = 1;
switch_queue_create(&member.mux_out_queue, 200, member.pool);
switch_frame_buffer_create(&member.fb);
}
-
+
/* Add the caller to the conference */
if (conference_member_add(conference, &member) != SWITCH_STATUS_SUCCESS) {
switch_core_codec_destroy(&member.read_codec);
if (conference->conference_video_mode == CONF_VIDEO_MODE_MUX) {
conference_video_launch_muxing_write_thread(&member);
}
-
+
msg.from = __FILE__;
/* Tell the channel we are going to be in a bridge */
switch_channel_set_flag(channel, CF_VIDEO_DECODED_READ);
switch_core_media_gen_key_frame(session);
}
-
+
/* Chime in the core video thread */
switch_core_session_set_video_read_callback(session, conference_video_thread_callback, (void *)&member);
/* Clean Up. */
- done:
+ done:
if (member.video_muxing_write_thread) {
switch_status_t st = SWITCH_STATUS_SUCCESS;
member.video_muxing_write_thread = NULL;
}
-
+
if (locked) {
switch_mutex_unlock(conference_globals.setup_mutex);
}
toplay = expanded;
} else {
expanded = NULL;
- toplay = src;
+ toplay = src;
}
if (!switch_is_file_path(toplay) && conference->sound_prefix) {
switch_core_session_get_read_impl(session, &read_impl);
channel = switch_core_session_get_channel(session);
-
+
presence_id = switch_channel_get_variable(channel, "presence_id");
if ((force_rate = switch_channel_get_variable(channel, "conference_force_rate"))) {
force_interval_i = read_impl.microseconds_per_packet / 1000;
} else {
tmp = atoi(force_interval);
-
+
if (SWITCH_ACCEPTABLE_INTERVAL(tmp)) {
force_interval_i = interval = tmp;
}
caller_id_number = val;
} else if (!strcasecmp(var, "caller-controls") && !zstr(val)) {
caller_controls = val;
- } else if (!strcasecmp(var, "ivr-dtmf-timeout") && !zstr(val)) {
- ivr_dtmf_timeout = atoi(val);
- if (ivr_dtmf_timeout < 500) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "not very smart value for ivr-dtmf-timeout found (%d), defaulting to 500ms\n", ivr_dtmf_timeout);
- ivr_dtmf_timeout = 500;
- }
- } else if (!strcasecmp(var, "ivr-input-timeout") && !zstr(val)) {
- ivr_input_timeout = atoi(val);
- if (ivr_input_timeout != 0 && ivr_input_timeout < 500) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "not very smart value for ivr-input-timeout found (%d), defaulting to 500ms\n", ivr_input_timeout);
- ivr_input_timeout = 5000;
- }
+ } else if (!strcasecmp(var, "ivr-dtmf-timeout") && !zstr(val)) {
+ ivr_dtmf_timeout = atoi(val);
+ if (ivr_dtmf_timeout < 500) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "not very smart value for ivr-dtmf-timeout found (%d), defaulting to 500ms\n", ivr_dtmf_timeout);
+ ivr_dtmf_timeout = 500;
+ }
+ } else if (!strcasecmp(var, "ivr-input-timeout") && !zstr(val)) {
+ ivr_input_timeout = atoi(val);
+ if (ivr_input_timeout != 0 && ivr_input_timeout < 500) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "not very smart value for ivr-input-timeout found (%d), defaulting to 500ms\n", ivr_input_timeout);
+ ivr_input_timeout = 5000;
+ }
} else if (!strcasecmp(var, "moderator-controls") && !zstr(val)) {
moderator_controls = val;
} else if (!strcasecmp(var, "broadcast-chat-messages") && !zstr(val)) {
errno = 0; /* sanity first */
max_members = strtol(val, NULL, 0); /* base 0 lets 0x... for hex 0... for octal and base 10 otherwise through */
if (errno == ERANGE || errno == EINVAL || (int32_t) max_members < 0 || max_members == 1) {
- /* a negative wont work well, and its foolish to have a conference limited to 1 person unless the outbound
+ /* a negative wont work well, and its foolish to have a conference limited to 1 person unless the outbound
* stuff is added, see comments above
*/
max_members = 0; /* set to 0 to disable max counts */
conference->moderator_controls = switch_core_strdup(conference->pool, moderator_controls);
conference->broadcast_chat_messages = broadcast_chat_messages;
-
+
conference->conference_video_mode = conference_video_mode;
if (!switch_core_has_video() && (conference->conference_video_mode == CONF_VIDEO_MODE_MUX || conference->conference_video_mode == CONF_VIDEO_MODE_TRANSCODE)) {
conference->conference_video_mode = CONF_VIDEO_MODE_PASSTHROUGH;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "video-mode invalid, only valid setting is 'passthrough' due to no video capabilities\n");
}
-
+
if (conference->conference_video_mode == CONF_VIDEO_MODE_MUX) {
int canvas_w = 0, canvas_h = 0;
if (video_canvas_size) {
char *p;
-
+
if ((canvas_w = atoi(video_canvas_size))) {
if ((p = strchr(video_canvas_size, 'x'))) {
p++;
canvas_w = CONFERENCE_CANVAS_DEFAULT_WIDTH;
canvas_h = CONFERENCE_CANVAS_DEFAULT_HIGHT;
}
-
-
+
+
conference_video_parse_layouts(conference, canvas_w, canvas_h);
-
+
if (!video_canvas_bgcolor) {
video_canvas_bgcolor = "#333333";
}
conference->video_codec_settings.video.bandwidth = switch_parse_bandwidth_string(video_codec_bandwidth);
}
}
-
+
if (zstr(video_layout_name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No video-layout-name specified, using " CONFERENCE_MUX_DEFAULT_LAYOUT "\n");
video_layout_name = CONFERENCE_MUX_DEFAULT_LAYOUT;
conference->log_dir = path;
}
-
+
if (!zstr(cdr_event_mode)) {
if (!strcmp(cdr_event_mode, "content")) {
conference->cdr_event_mode = CDRE_AS_CONTENT;
/* Set enter sound and exit sound flags so that default is on */
conference_utils_set_flag(conference, CFLAG_ENTER_SOUND);
conference_utils_set_flag(conference, CFLAG_EXIT_SOUND);
-
+
/* Activate the conference mutex for exclusivity */
switch_mutex_init(&conference->mutex, SWITCH_MUTEX_NESTED, conference->pool);
switch_mutex_init(&conference->flag_mutex, SWITCH_MUTEX_NESTED, conference->pool);
conference->super_canvas_show_all_layers = video_super_canvas_show_all_layers;
if (video_canvas_count < 1) video_canvas_count = 1;
-
+
if (conference->conference_video_mode == CONF_VIDEO_MODE_MUX) {
video_layout_t *vlayout = conference_video_get_layout(conference, conference->video_layout_name, conference->video_layout_group);
-
+
if (!vlayout) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot find layout\n");
conference->video_layout_name = conference->video_layout_group = NULL;
}
}
- end:
+ end:
switch_mutex_unlock(conference_globals.hash_mutex);
switch_event_fire(&event);
}
-
+
}
#if 0
uint32_t conference_kickall_matching_var(conference_obj_t *conference, const char *var, const char *val)
continue;
}
- channel = switch_core_session_get_channel(member->session);
+ channel = switch_core_session_get_channel(member->session);
vval = switch_channel_get_variable(channel, var);
if (vval && !strcmp(vval, val)) {
r++;
}
- }
+ }
switch_mutex_unlock(conference->member_mutex);
switch_mutex_unlock(conference->mutex);
}
}
- done:
+ done:
switch_event_destroy(¶ms);
/* Release the config registry handle */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_console_add_complete_func("::conference::conference_list_conferences", conference_list_conferences);
-
+
switch_event_channel_bind("conference", conference_event_channel_handler, &conference_globals.event_channel_id);
switch_event_channel_bind("conference-liveArray", conference_event_la_channel_handler, &conference_globals.event_channel_id);
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
- * Software distributed under the License is distributed on an "AS IS" basis,
+ * Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- *
+ *
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter at 0xdecafbad dot com>
#define ALC_HRTF_SOFT 0x1992
-#define validate_pin(buf, pin, mpin) \
- pin_valid = (!zstr(pin) && strcmp(buf, pin) == 0); \
- if (!pin_valid && !zstr(mpin) && strcmp(buf, mpin) == 0) { \
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Moderator PIN found!\n"); \
- pin_valid = 1; \
- mpin_matched = 1; \
- }
+#define validate_pin(buf, pin, mpin) \
+ pin_valid = (!zstr(pin) && strcmp(buf, pin) == 0); \
+ if (!pin_valid && !zstr(mpin) && strcmp(buf, mpin) == 0) { \
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Moderator PIN found!\n"); \
+ pin_valid = 1; \
+ mpin_matched = 1; \
+ }
/* STRUCTS */
struct conference_fps {
- float fps;
- int ms;
- int samples;
+ float fps;
+ int ms;
+ int samples;
};
typedef enum {
- CONF_SILENT_REQ = (1 << 0),
- CONF_SILENT_DONE = (1 << 1)
+ CONF_SILENT_REQ = (1 << 0),
+ CONF_SILENT_DONE = (1 << 1)
} conference_app_flag_t;
extern char *mod_conference_cf_name;
extern int EC;
typedef enum {
- FILE_STOP_CURRENT,
- FILE_STOP_ALL,
- FILE_STOP_ASYNC
+ FILE_STOP_CURRENT,
+ FILE_STOP_ALL,
+ FILE_STOP_ASYNC
} file_stop_t;
/* Global Values */
typedef struct conference_globals_s {
- switch_memory_pool_t *conference_pool;
- switch_mutex_t *conference_mutex;
- switch_hash_t *conference_hash;
- switch_mutex_t *id_mutex;
- switch_mutex_t *hash_mutex;
- switch_mutex_t *setup_mutex;
- uint32_t id_pool;
- int32_t running;
- uint32_t threads;
- switch_event_channel_id_t event_channel_id;
+ switch_memory_pool_t *conference_pool;
+ switch_mutex_t *conference_mutex;
+ switch_hash_t *conference_hash;
+ switch_mutex_t *id_mutex;
+ switch_mutex_t *hash_mutex;
+ switch_mutex_t *setup_mutex;
+ uint32_t id_pool;
+ int32_t running;
+ uint32_t threads;
+ switch_event_channel_id_t event_channel_id;
} conference_globals_t;
extern conference_globals_t conference_globals;
struct caller_control_actions;
typedef struct caller_control_actions {
- char *binded_dtmf;
- char *data;
- char *expanded_data;
+ char *binded_dtmf;
+ char *data;
+ char *expanded_data;
} caller_control_action_t;
typedef struct caller_control_menu_info {
- switch_ivr_menu_t *stack;
- char *name;
+ switch_ivr_menu_t *stack;
+ char *name;
} caller_control_menu_info_t;
typedef enum {
- MFLAG_RUNNING,
- MFLAG_CAN_SPEAK,
- MFLAG_CAN_HEAR,
- MFLAG_KICKED,
- MFLAG_ITHREAD,
- MFLAG_NOCHANNEL,
- MFLAG_INTREE,
- MFLAG_NO_MINIMIZE_ENCODING,
- MFLAG_FLUSH_BUFFER,
- MFLAG_ENDCONF,
- MFLAG_HAS_AUDIO,
- MFLAG_TALKING,
- MFLAG_RESTART,
- MFLAG_MINTWO,
- MFLAG_MUTE_DETECT,
- MFLAG_DIST_DTMF,
- MFLAG_MOD,
- MFLAG_INDICATE_MUTE,
- MFLAG_INDICATE_UNMUTE,
- MFLAG_NOMOH,
- MFLAG_VIDEO_BRIDGE,
- MFLAG_INDICATE_MUTE_DETECT,
- MFLAG_PAUSE_RECORDING,
- MFLAG_ACK_VIDEO,
- MFLAG_GHOST,
- MFLAG_JOIN_ONLY,
- MFLAG_POSITIONAL,
- MFLAG_NO_POSITIONAL,
- MFLAG_JOIN_VID_FLOOR,
- MFLAG_RECEIVING_VIDEO,
- MFLAG_CAN_BE_SEEN,
- MFLAG_SECOND_SCREEN,
- MFLAG_SILENT,
- ///////////////////////////
- MFLAG_MAX
+ MFLAG_RUNNING,
+ MFLAG_CAN_SPEAK,
+ MFLAG_CAN_HEAR,
+ MFLAG_KICKED,
+ MFLAG_ITHREAD,
+ MFLAG_NOCHANNEL,
+ MFLAG_INTREE,
+ MFLAG_NO_MINIMIZE_ENCODING,
+ MFLAG_FLUSH_BUFFER,
+ MFLAG_ENDCONF,
+ MFLAG_HAS_AUDIO,
+ MFLAG_TALKING,
+ MFLAG_RESTART,
+ MFLAG_MINTWO,
+ MFLAG_MUTE_DETECT,
+ MFLAG_DIST_DTMF,
+ MFLAG_MOD,
+ MFLAG_INDICATE_MUTE,
+ MFLAG_INDICATE_UNMUTE,
+ MFLAG_NOMOH,
+ MFLAG_VIDEO_BRIDGE,
+ MFLAG_INDICATE_MUTE_DETECT,
+ MFLAG_PAUSE_RECORDING,
+ MFLAG_ACK_VIDEO,
+ MFLAG_GHOST,
+ MFLAG_JOIN_ONLY,
+ MFLAG_POSITIONAL,
+ MFLAG_NO_POSITIONAL,
+ MFLAG_JOIN_VID_FLOOR,
+ MFLAG_RECEIVING_VIDEO,
+ MFLAG_CAN_BE_SEEN,
+ MFLAG_SECOND_SCREEN,
+ MFLAG_SILENT,
+ ///////////////////////////
+ MFLAG_MAX
} member_flag_t;
typedef enum {
- CFLAG_RUNNING,
- CFLAG_DYNAMIC,
- CFLAG_ENFORCE_MIN,
- CFLAG_DESTRUCT,
- CFLAG_LOCKED,
- CFLAG_ANSWERED,
- CFLAG_BRIDGE_TO,
- CFLAG_WAIT_MOD,
- CFLAG_VID_FLOOR,
- CFLAG_WASTE_FLAG,
- CFLAG_OUTCALL,
- CFLAG_INHASH,
- CFLAG_EXIT_SOUND,
- CFLAG_ENTER_SOUND,
- CFLAG_USE_ME,
- CFLAG_AUDIO_ALWAYS,
- CFLAG_ENDCONF_FORCED,
- CFLAG_RFC4579,
- CFLAG_FLOOR_CHANGE,
- CFLAG_VID_FLOOR_LOCK,
- CFLAG_JSON_EVENTS,
- CFLAG_LIVEARRAY_SYNC,
- CFLAG_CONF_RESTART_AUTO_RECORD,
- CFLAG_POSITIONAL,
- CFLAG_TRANSCODE_VIDEO,
- CFLAG_VIDEO_MUXING,
- CFLAG_MINIMIZE_VIDEO_ENCODING,
- CFLAG_MANAGE_INBOUND_VIDEO_BITRATE,
- CFLAG_JSON_STATUS,
- CFLAG_VIDEO_BRIDGE_FIRST_TWO,
- CFLAG_VIDEO_REQUIRED_FOR_CANVAS,
- CFLAG_PERSONAL_CANVAS,
- /////////////////////////////////
- CFLAG_MAX
+ CFLAG_RUNNING,
+ CFLAG_DYNAMIC,
+ CFLAG_ENFORCE_MIN,
+ CFLAG_DESTRUCT,
+ CFLAG_LOCKED,
+ CFLAG_ANSWERED,
+ CFLAG_BRIDGE_TO,
+ CFLAG_WAIT_MOD,
+ CFLAG_VID_FLOOR,
+ CFLAG_WASTE_FLAG,
+ CFLAG_OUTCALL,
+ CFLAG_INHASH,
+ CFLAG_EXIT_SOUND,
+ CFLAG_ENTER_SOUND,
+ CFLAG_USE_ME,
+ CFLAG_AUDIO_ALWAYS,
+ CFLAG_ENDCONF_FORCED,
+ CFLAG_RFC4579,
+ CFLAG_FLOOR_CHANGE,
+ CFLAG_VID_FLOOR_LOCK,
+ CFLAG_JSON_EVENTS,
+ CFLAG_LIVEARRAY_SYNC,
+ CFLAG_CONF_RESTART_AUTO_RECORD,
+ CFLAG_POSITIONAL,
+ CFLAG_TRANSCODE_VIDEO,
+ CFLAG_VIDEO_MUXING,
+ CFLAG_MINIMIZE_VIDEO_ENCODING,
+ CFLAG_MANAGE_INBOUND_VIDEO_BITRATE,
+ CFLAG_JSON_STATUS,
+ CFLAG_VIDEO_BRIDGE_FIRST_TWO,
+ CFLAG_VIDEO_REQUIRED_FOR_CANVAS,
+ CFLAG_PERSONAL_CANVAS,
+ /////////////////////////////////
+ CFLAG_MAX
} conference_flag_t;
typedef struct conference_cdr_node_s {
- switch_caller_profile_t *cp;
- char *record_path;
- switch_time_t join_time;
- switch_time_t leave_time;
- member_flag_t mflags[MFLAG_MAX];
- uint32_t id;
- conference_member_t *member;
- switch_event_t *var_event;
- struct conference_cdr_node_s *next;
+ switch_caller_profile_t *cp;
+ char *record_path;
+ switch_time_t join_time;
+ switch_time_t leave_time;
+ member_flag_t mflags[MFLAG_MAX];
+ uint32_t id;
+ conference_member_t *member;
+ switch_event_t *var_event;
+ struct conference_cdr_node_s *next;
} conference_cdr_node_t;
typedef enum {
- CDRR_LOCKED = 1,
- CDRR_PIN,
- CDRR_MAXMEMBERS
+ CDRR_LOCKED = 1,
+ CDRR_PIN,
+ CDRR_MAXMEMBERS
} cdr_reject_reason_t;
typedef struct conference_cdr_reject_s {
- switch_caller_profile_t *cp;
- switch_time_t reject_time;
- cdr_reject_reason_t reason;
- struct conference_cdr_reject_s *next;
+ switch_caller_profile_t *cp;
+ switch_time_t reject_time;
+ cdr_reject_reason_t reason;
+ struct conference_cdr_reject_s *next;
} conference_cdr_reject_t;
typedef enum {
- CDRE_NONE,
- CDRE_AS_CONTENT,
- CDRE_AS_FILE
+ CDRE_NONE,
+ CDRE_AS_CONTENT,
+ CDRE_AS_FILE
} cdr_event_mode_t;
struct call_list {
- char *string;
- int iteration;
- struct call_list *next;
+ char *string;
+ int iteration;
+ struct call_list *next;
};
typedef struct call_list call_list_t;
typedef enum {
- RFLAG_CAN_SPEAK = (1 << 0),
- RFLAG_CAN_HEAR = (1 << 1),
- RFLAG_CAN_SEND_VIDEO = (1 << 2)
+ RFLAG_CAN_SPEAK = (1 << 0),
+ RFLAG_CAN_HEAR = (1 << 1),
+ RFLAG_CAN_SEND_VIDEO = (1 << 2)
} relation_flag_t;
typedef enum {
- NODE_TYPE_FILE,
- NODE_TYPE_SPEECH
+ NODE_TYPE_FILE,
+ NODE_TYPE_SPEECH
} node_type_t;
typedef enum {
- NFLAG_NONE = (1 << 0),
- NFLAG_PAUSE = (1 << 1)
+ NFLAG_NONE = (1 << 0),
+ NFLAG_PAUSE = (1 << 1)
} node_flag_t;
typedef enum {
- EFLAG_ADD_MEMBER = (1 << 0),
- EFLAG_DEL_MEMBER = (1 << 1),
- EFLAG_ENERGY_LEVEL = (1 << 2),
- EFLAG_VOLUME_LEVEL = (1 << 3),
- EFLAG_GAIN_LEVEL = (1 << 4),
- EFLAG_DTMF = (1 << 5),
- EFLAG_STOP_TALKING = (1 << 6),
- EFLAG_START_TALKING = (1 << 7),
- EFLAG_MUTE_MEMBER = (1 << 8),
- EFLAG_UNMUTE_MEMBER = (1 << 9),
- EFLAG_DEAF_MEMBER = (1 << 10),
- EFLAG_UNDEAF_MEMBER = (1 << 11),
- EFLAG_KICK_MEMBER = (1 << 12),
- EFLAG_DTMF_MEMBER = (1 << 13),
- EFLAG_ENERGY_LEVEL_MEMBER = (1 << 14),
- EFLAG_VOLUME_IN_MEMBER = (1 << 15),
- EFLAG_VOLUME_OUT_MEMBER = (1 << 16),
- EFLAG_PLAY_FILE = (1 << 17),
- EFLAG_PLAY_FILE_MEMBER = (1 << 18),
- EFLAG_SPEAK_TEXT = (1 << 19),
- EFLAG_SPEAK_TEXT_MEMBER = (1 << 20),
- EFLAG_LOCK = (1 << 21),
- EFLAG_UNLOCK = (1 << 22),
- EFLAG_TRANSFER = (1 << 23),
- EFLAG_BGDIAL_RESULT = (1 << 24),
- EFLAG_FLOOR_CHANGE = (1 << 25),
- EFLAG_MUTE_DETECT = (1 << 26),
- EFLAG_RECORD = (1 << 27),
- EFLAG_HUP_MEMBER = (1 << 28),
- EFLAG_PLAY_FILE_DONE = (1 << 29),
- EFLAG_SET_POSITION_MEMBER = (1 << 30)
+ EFLAG_ADD_MEMBER = (1 << 0),
+ EFLAG_DEL_MEMBER = (1 << 1),
+ EFLAG_ENERGY_LEVEL = (1 << 2),
+ EFLAG_VOLUME_LEVEL = (1 << 3),
+ EFLAG_GAIN_LEVEL = (1 << 4),
+ EFLAG_DTMF = (1 << 5),
+ EFLAG_STOP_TALKING = (1 << 6),
+ EFLAG_START_TALKING = (1 << 7),
+ EFLAG_MUTE_MEMBER = (1 << 8),
+ EFLAG_UNMUTE_MEMBER = (1 << 9),
+ EFLAG_DEAF_MEMBER = (1 << 10),
+ EFLAG_UNDEAF_MEMBER = (1 << 11),
+ EFLAG_KICK_MEMBER = (1 << 12),
+ EFLAG_DTMF_MEMBER = (1 << 13),
+ EFLAG_ENERGY_LEVEL_MEMBER = (1 << 14),
+ EFLAG_VOLUME_IN_MEMBER = (1 << 15),
+ EFLAG_VOLUME_OUT_MEMBER = (1 << 16),
+ EFLAG_PLAY_FILE = (1 << 17),
+ EFLAG_PLAY_FILE_MEMBER = (1 << 18),
+ EFLAG_SPEAK_TEXT = (1 << 19),
+ EFLAG_SPEAK_TEXT_MEMBER = (1 << 20),
+ EFLAG_LOCK = (1 << 21),
+ EFLAG_UNLOCK = (1 << 22),
+ EFLAG_TRANSFER = (1 << 23),
+ EFLAG_BGDIAL_RESULT = (1 << 24),
+ EFLAG_FLOOR_CHANGE = (1 << 25),
+ EFLAG_MUTE_DETECT = (1 << 26),
+ EFLAG_RECORD = (1 << 27),
+ EFLAG_HUP_MEMBER = (1 << 28),
+ EFLAG_PLAY_FILE_DONE = (1 << 29),
+ EFLAG_SET_POSITION_MEMBER = (1 << 30)
} event_type_t;
#ifdef OPENAL_POSITIONING
typedef struct al_handle_s {
- switch_mutex_t *mutex;
- ALCdevice *device;
- ALCcontext *context;
- ALuint source;
- ALuint buffer_in[2];
- int setpos;
- ALfloat pos_x;
- ALfloat pos_y;
- ALfloat pos_z;
+ switch_mutex_t *mutex;
+ ALCdevice *device;
+ ALCcontext *context;
+ ALuint source;
+ ALuint buffer_in[2];
+ int setpos;
+ ALfloat pos_x;
+ ALfloat pos_y;
+ ALfloat pos_z;
} al_handle_t;
void conference_al_close(al_handle_t *al);
-#else
+#else
typedef struct al_handle_s {
- int unsupported;
- switch_mutex_t *mutex;
+ int unsupported;
+ switch_mutex_t *mutex;
} al_handle_t;
#endif
struct conference_obj;
typedef struct conference_file_node {
- switch_file_handle_t fh;
- switch_speech_handle_t *sh;
- node_flag_t flags;
- node_type_t type;
- uint8_t done;
- uint8_t async;
- switch_memory_pool_t *pool;
- uint32_t leadin;
- struct conference_file_node *next;
- char *file;
- switch_bool_t mux;
- uint32_t member_id;
- al_handle_t *al;
- int layer_id;
- int canvas_id;
- struct conference_obj *conference;
+ switch_file_handle_t fh;
+ switch_speech_handle_t *sh;
+ node_flag_t flags;
+ node_type_t type;
+ uint8_t done;
+ uint8_t async;
+ switch_memory_pool_t *pool;
+ uint32_t leadin;
+ struct conference_file_node *next;
+ char *file;
+ switch_bool_t mux;
+ uint32_t member_id;
+ al_handle_t *al;
+ int layer_id;
+ int canvas_id;
+ struct conference_obj *conference;
} conference_file_node_t;
typedef enum {
- REC_ACTION_STOP = 1,
- REC_ACTION_PAUSE,
- REC_ACTION_RESUME
+ REC_ACTION_STOP = 1,
+ REC_ACTION_PAUSE,
+ REC_ACTION_RESUME
} recording_action_type_t;
/* conference xml config sections */
typedef struct conference_xml_cfg {
- switch_xml_t profile;
- switch_xml_t controls;
+ switch_xml_t profile;
+ switch_xml_t controls;
} conference_xml_cfg_t;
struct vid_helper {
- conference_member_t *member_a;
- conference_member_t *member_b;
- int up;
+ conference_member_t *member_a;
+ conference_member_t *member_b;
+ int up;
};
typedef struct mcu_layer_geometry_s {
- int x;
- int y;
- int scale;
- int floor;
- int flooronly;
- int fileonly;
- int overlap;
- char *res_id;
- char *audio_position;
+ int x;
+ int y;
+ int scale;
+ int floor;
+ int flooronly;
+ int fileonly;
+ int overlap;
+ char *res_id;
+ char *audio_position;
} mcu_layer_geometry_t;
typedef struct mcu_layer_def_s {
- char *name;
- mcu_layer_geometry_t layers[MCU_MAX_LAYERS];
+ char *name;
+ mcu_layer_geometry_t layers[MCU_MAX_LAYERS];
} mcu_layer_def_t;
struct mcu_canvas_s;
typedef struct mcu_layer_s {
- mcu_layer_geometry_t geometry;
- int member_id;
- int idx;
- int tagged;
- int bugged;
- int screen_w;
- int screen_h;
- int x_pos;
- int y_pos;
- int banner_patched;
- int mute_patched;
- int avatar_patched;
- int refresh;
- int is_avatar;
- switch_img_position_t logo_pos;
- switch_image_t *img;
- switch_image_t *cur_img;
- switch_image_t *banner_img;
- switch_image_t *logo_img;
- switch_image_t *logo_text_img;
- switch_image_t *mute_img;
- switch_img_txt_handle_t *txthandle;
- conference_file_node_t *fnode;
- struct mcu_canvas_s *canvas;
+ mcu_layer_geometry_t geometry;
+ int member_id;
+ int idx;
+ int tagged;
+ int bugged;
+ int screen_w;
+ int screen_h;
+ int x_pos;
+ int y_pos;
+ int banner_patched;
+ int mute_patched;
+ int avatar_patched;
+ int refresh;
+ int is_avatar;
+ switch_img_position_t logo_pos;
+ switch_image_t *img;
+ switch_image_t *cur_img;
+ switch_image_t *banner_img;
+ switch_image_t *logo_img;
+ switch_image_t *logo_text_img;
+ switch_image_t *mute_img;
+ switch_img_txt_handle_t *txthandle;
+ conference_file_node_t *fnode;
+ struct mcu_canvas_s *canvas;
} mcu_layer_t;
typedef struct video_layout_s {
- char *name;
- char *audio_position;
- mcu_layer_geometry_t images[MCU_MAX_LAYERS];
- int layers;
+ char *name;
+ char *audio_position;
+ mcu_layer_geometry_t images[MCU_MAX_LAYERS];
+ int layers;
} video_layout_t;
typedef struct video_layout_node_s {
- video_layout_t *vlayout;
- struct video_layout_node_s *next;
+ video_layout_t *vlayout;
+ struct video_layout_node_s *next;
} video_layout_node_t;
typedef struct layout_group_s {
- video_layout_node_t *layouts;
+ video_layout_node_t *layouts;
} layout_group_t;
typedef struct mcu_canvas_s {
- int width;
- int height;
- switch_image_t *img;
- mcu_layer_t layers[MCU_MAX_LAYERS];
- int total_layers;
- int layers_used;
- int layout_floor_id;
- int refresh;
- int send_keyframe;
- int play_file;
- switch_rgb_color_t bgcolor;
- switch_rgb_color_t letterbox_bgcolor;
- switch_mutex_t *mutex;
- switch_timer_t timer;
- switch_memory_pool_t *pool;
- video_layout_t *vlayout;
- video_layout_t *new_vlayout;
- int canvas_id;
- struct conference_obj *conference;
- switch_thread_t *video_muxing_thread;
- int video_timer_reset;
- switch_queue_t *video_queue;
- int32_t video_write_bandwidth;
+ int width;
+ int height;
+ switch_image_t *img;
+ mcu_layer_t layers[MCU_MAX_LAYERS];
+ int total_layers;
+ int layers_used;
+ int layout_floor_id;
+ int refresh;
+ int send_keyframe;
+ int play_file;
+ switch_rgb_color_t bgcolor;
+ switch_rgb_color_t letterbox_bgcolor;
+ switch_mutex_t *mutex;
+ switch_timer_t timer;
+ switch_memory_pool_t *pool;
+ video_layout_t *vlayout;
+ video_layout_t *new_vlayout;
+ int canvas_id;
+ struct conference_obj *conference;
+ switch_thread_t *video_muxing_thread;
+ int video_timer_reset;
+ switch_queue_t *video_queue;
+ int32_t video_write_bandwidth;
} mcu_canvas_t;
/* Record Node */
typedef struct conference_record {
- struct conference_obj *conference;
- char *path;
- switch_memory_pool_t *pool;
- switch_bool_t autorec;
- struct conference_record *next;
- switch_file_handle_t fh;
+ struct conference_obj *conference;
+ char *path;
+ switch_memory_pool_t *pool;
+ switch_bool_t autorec;
+ struct conference_record *next;
+ switch_file_handle_t fh;
} conference_record_t;
typedef enum {
- CONF_VIDEO_MODE_PASSTHROUGH,
- CONF_VIDEO_MODE_TRANSCODE,
- CONF_VIDEO_MODE_MUX
+ CONF_VIDEO_MODE_PASSTHROUGH,
+ CONF_VIDEO_MODE_TRANSCODE,
+ CONF_VIDEO_MODE_MUX
} conference_video_mode_t;
/* Conference Object */
typedef struct conference_obj {
- char *name;
- char *la_name;
- char *la_event_channel;
- char *mod_event_channel;
- char *desc;
- char *timer_name;
- char *tts_engine;
- char *tts_voice;
- char *enter_sound;
- char *exit_sound;
- char *alone_sound;
- char *perpetual_sound;
- char *moh_sound;
- char *muted_sound;
- char *mute_detect_sound;
- char *unmuted_sound;
- char *locked_sound;
- char *is_locked_sound;
- char *is_unlocked_sound;
- char *kicked_sound;
- char *join_only_sound;
- char *caller_id_name;
- char *caller_id_number;
- char *sound_prefix;
- char *special_announce;
- char *auto_record;
- char *record_filename;
- char *outcall_templ;
- char *video_layout_name;
- char *video_layout_group;
- char *video_canvas_bgcolor;
- char *video_super_canvas_bgcolor;
- char *video_letterbox_bgcolor;
- char *no_video_avatar;
- conference_video_mode_t conference_video_mode;
- int members_with_video;
- int members_with_avatar;
- switch_codec_settings_t video_codec_settings;
- uint32_t canvas_width;
- uint32_t canvas_height;
- uint32_t terminate_on_silence;
- uint32_t max_members;
- uint32_t doc_version;
- char *maxmember_sound;
- uint32_t announce_count;
- char *pin;
- char *mpin;
- char *pin_sound;
- char *bad_pin_sound;
- char *profile_name;
- char *domain;
- char *chat_id;
- char *caller_controls;
- char *moderator_controls;
- switch_live_array_t *la;
- conference_flag_t flags[CFLAG_MAX];
- member_flag_t mflags[MFLAG_MAX];
- switch_call_cause_t bridge_hangup_cause;
- switch_mutex_t *flag_mutex;
- uint32_t rate;
- uint32_t interval;
- uint32_t channels;
- switch_mutex_t *mutex;
- conference_member_t *members;
- conference_member_t *floor_holder;
- uint32_t video_floor_holder;
- uint32_t last_video_floor_holder;
- switch_mutex_t *member_mutex;
- conference_file_node_t *fnode;
- conference_file_node_t *async_fnode;
- switch_memory_pool_t *pool;
- switch_thread_rwlock_t *rwlock;
- uint32_t count;
- int32_t energy_level;
- uint8_t min;
- switch_speech_handle_t lsh;
- switch_speech_handle_t *sh;
- switch_byte_t *not_talking_buf;
- uint32_t not_talking_buf_len;
- int pin_retries;
- int broadcast_chat_messages;
- int comfort_noise_level;
- int auto_recording;
- int record_count;
- uint32_t min_recording_participants;
- int ivr_dtmf_timeout;
- int ivr_input_timeout;
- uint32_t eflags;
- uint32_t verbose_events;
- int end_count;
- uint32_t count_ghosts;
- /* allow extra time after 'endconf' member leaves */
- switch_time_t endconference_time;
- int endconference_grace_time;
-
- uint32_t relationship_total;
- uint32_t score;
- int mux_loop_count;
- int member_loop_count;
- int agc_level;
-
- uint32_t avg_score;
- uint32_t avg_itt;
- uint32_t avg_tally;
- switch_time_t run_time;
- char *uuid_str;
- uint32_t originating;
- switch_call_cause_t cancel_cause;
- conference_cdr_node_t *cdr_nodes;
- conference_cdr_reject_t *cdr_rejected;
- switch_time_t start_time;
- switch_time_t end_time;
- char *log_dir;
- cdr_event_mode_t cdr_event_mode;
- struct vid_helper vh[2];
- struct vid_helper mh;
- conference_record_t *rec_node_head;
- int last_speech_channels;
- mcu_canvas_t *canvas;
- mcu_canvas_t *canvases[MAX_CANVASES+1];
- int canvas_count;
- int super_canvas_label_layers;
- int super_canvas_show_all_layers;
- int canvas_running_count;
- switch_mutex_t *canvas_mutex;
- switch_hash_t *layout_hash;
- switch_hash_t *layout_group_hash;
- struct conference_fps video_fps;
- int playing_video_file;
- int recording_members;
- uint32_t video_floor_packets;
+ char *name;
+ char *la_name;
+ char *la_event_channel;
+ char *mod_event_channel;
+ char *desc;
+ char *timer_name;
+ char *tts_engine;
+ char *tts_voice;
+ char *enter_sound;
+ char *exit_sound;
+ char *alone_sound;
+ char *perpetual_sound;
+ char *moh_sound;
+ char *muted_sound;
+ char *mute_detect_sound;
+ char *unmuted_sound;
+ char *locked_sound;
+ char *is_locked_sound;
+ char *is_unlocked_sound;
+ char *kicked_sound;
+ char *join_only_sound;
+ char *caller_id_name;
+ char *caller_id_number;
+ char *sound_prefix;
+ char *special_announce;
+ char *auto_record;
+ char *record_filename;
+ char *outcall_templ;
+ char *video_layout_name;
+ char *video_layout_group;
+ char *video_canvas_bgcolor;
+ char *video_super_canvas_bgcolor;
+ char *video_letterbox_bgcolor;
+ char *no_video_avatar;
+ conference_video_mode_t conference_video_mode;
+ int members_with_video;
+ int members_with_avatar;
+ switch_codec_settings_t video_codec_settings;
+ uint32_t canvas_width;
+ uint32_t canvas_height;
+ uint32_t terminate_on_silence;
+ uint32_t max_members;
+ uint32_t doc_version;
+ char *maxmember_sound;
+ uint32_t announce_count;
+ char *pin;
+ char *mpin;
+ char *pin_sound;
+ char *bad_pin_sound;
+ char *profile_name;
+ char *domain;
+ char *chat_id;
+ char *caller_controls;
+ char *moderator_controls;
+ switch_live_array_t *la;
+ conference_flag_t flags[CFLAG_MAX];
+ member_flag_t mflags[MFLAG_MAX];
+ switch_call_cause_t bridge_hangup_cause;
+ switch_mutex_t *flag_mutex;
+ uint32_t rate;
+ uint32_t interval;
+ uint32_t channels;
+ switch_mutex_t *mutex;
+ conference_member_t *members;
+ conference_member_t *floor_holder;
+ uint32_t video_floor_holder;
+ uint32_t last_video_floor_holder;
+ switch_mutex_t *member_mutex;
+ conference_file_node_t *fnode;
+ conference_file_node_t *async_fnode;
+ switch_memory_pool_t *pool;
+ switch_thread_rwlock_t *rwlock;
+ uint32_t count;
+ int32_t energy_level;
+ uint8_t min;
+ switch_speech_handle_t lsh;
+ switch_speech_handle_t *sh;
+ switch_byte_t *not_talking_buf;
+ uint32_t not_talking_buf_len;
+ int pin_retries;
+ int broadcast_chat_messages;
+ int comfort_noise_level;
+ int auto_recording;
+ int record_count;
+ uint32_t min_recording_participants;
+ int ivr_dtmf_timeout;
+ int ivr_input_timeout;
+ uint32_t eflags;
+ uint32_t verbose_events;
+ int end_count;
+ uint32_t count_ghosts;
+ /* allow extra time after 'endconf' member leaves */
+ switch_time_t endconference_time;
+ int endconference_grace_time;
+
+ uint32_t relationship_total;
+ uint32_t score;
+ int mux_loop_count;
+ int member_loop_count;
+ int agc_level;
+
+ uint32_t avg_score;
+ uint32_t avg_itt;
+ uint32_t avg_tally;
+ switch_time_t run_time;
+ char *uuid_str;
+ uint32_t originating;
+ switch_call_cause_t cancel_cause;
+ conference_cdr_node_t *cdr_nodes;
+ conference_cdr_reject_t *cdr_rejected;
+ switch_time_t start_time;
+ switch_time_t end_time;
+ char *log_dir;
+ cdr_event_mode_t cdr_event_mode;
+ struct vid_helper vh[2];
+ struct vid_helper mh;
+ conference_record_t *rec_node_head;
+ int last_speech_channels;
+ mcu_canvas_t *canvas;
+ mcu_canvas_t *canvases[MAX_CANVASES+1];
+ int canvas_count;
+ int super_canvas_label_layers;
+ int super_canvas_show_all_layers;
+ int canvas_running_count;
+ switch_mutex_t *canvas_mutex;
+ switch_hash_t *layout_hash;
+ switch_hash_t *layout_group_hash;
+ struct conference_fps video_fps;
+ int playing_video_file;
+ int recording_members;
+ uint32_t video_floor_packets;
} conference_obj_t;
/* Relationship with another member */
typedef struct conference_relationship {
- uint32_t id;
- uint32_t flags;
- struct conference_relationship *next;
+ uint32_t id;
+ uint32_t flags;
+ struct conference_relationship *next;
} conference_relationship_t;
/* Conference Member Object */
struct conference_member {
- uint32_t id;
- switch_core_session_t *session;
- switch_channel_t *channel;
- conference_obj_t *conference;
- switch_memory_pool_t *pool;
- switch_buffer_t *audio_buffer;
- switch_buffer_t *mux_buffer;
- switch_buffer_t *resample_buffer;
- member_flag_t flags[MFLAG_MAX];
- uint32_t score;
- uint32_t last_score;
- uint32_t score_iir;
- switch_mutex_t *flag_mutex;
- switch_mutex_t *write_mutex;
- switch_mutex_t *audio_in_mutex;
- switch_mutex_t *audio_out_mutex;
- switch_mutex_t *read_mutex;
- switch_mutex_t *fnode_mutex;
- switch_thread_rwlock_t *rwlock;
- switch_codec_implementation_t read_impl;
- switch_codec_implementation_t orig_read_impl;
- switch_codec_t read_codec;
- switch_codec_t write_codec;
- char *rec_path;
- switch_time_t rec_time;
- conference_record_t *rec;
- uint8_t *frame;
- uint8_t *last_frame;
- uint32_t frame_size;
- uint8_t *mux_frame;
- uint32_t read;
- uint32_t vol_period;
- int32_t energy_level;
- int32_t agc_volume_in_level;
- int32_t volume_in_level;
- int32_t volume_out_level;
- int32_t agc_concur;
- int32_t nt_tally;
- switch_time_t join_time;
- switch_time_t last_talking;
- uint32_t native_rate;
- switch_audio_resampler_t *read_resampler;
- int16_t *resample_out;
- uint32_t resample_out_len;
- conference_file_node_t *fnode;
- conference_relationship_t *relationships;
- switch_speech_handle_t lsh;
- switch_speech_handle_t *sh;
- uint32_t verbose_events;
- uint32_t avg_score;
- uint32_t avg_itt;
- uint32_t avg_tally;
- struct conference_member *next;
- switch_ivr_dmachine_t *dmachine;
- conference_cdr_node_t *cdr_node;
- char *kicked_sound;
- switch_queue_t *dtmf_queue;
- switch_queue_t *video_queue;
- switch_queue_t *mux_out_queue;
- switch_thread_t *video_muxing_write_thread;
- switch_thread_t *input_thread;
- cJSON *json;
- cJSON *status_field;
- uint8_t loop_loop;
- al_handle_t *al;
- int last_speech_channels;
- int video_layer_id;
- int canvas_id;
- int watching_canvas_id;
- int layer_timeout;
- int video_codec_index;
- int video_codec_id;
- char *video_banner_text;
- char *video_logo;
- char *video_mute_png;
- char *video_reservation_id;
- switch_media_flow_t video_flow;
- switch_frame_buffer_t *fb;
- switch_image_t *avatar_png_img;
- switch_image_t *video_mute_img;
- uint32_t floor_packets;
- int blanks;
- int managed_kps;
- int blackouts;
- int good_img;
- int auto_avatar;
- int avatar_patched;
- mcu_canvas_t *canvas;
- switch_image_t *pcanvas_img;
+ uint32_t id;
+ switch_core_session_t *session;
+ switch_channel_t *channel;
+ conference_obj_t *conference;
+ switch_memory_pool_t *pool;
+ switch_buffer_t *audio_buffer;
+ switch_buffer_t *mux_buffer;
+ switch_buffer_t *resample_buffer;
+ member_flag_t flags[MFLAG_MAX];
+ uint32_t score;
+ uint32_t last_score;
+ uint32_t score_iir;
+ switch_mutex_t *flag_mutex;
+ switch_mutex_t *write_mutex;
+ switch_mutex_t *audio_in_mutex;
+ switch_mutex_t *audio_out_mutex;
+ switch_mutex_t *read_mutex;
+ switch_mutex_t *fnode_mutex;
+ switch_thread_rwlock_t *rwlock;
+ switch_codec_implementation_t read_impl;
+ switch_codec_implementation_t orig_read_impl;
+ switch_codec_t read_codec;
+ switch_codec_t write_codec;
+ char *rec_path;
+ switch_time_t rec_time;
+ conference_record_t *rec;
+ uint8_t *frame;
+ uint8_t *last_frame;
+ uint32_t frame_size;
+ uint8_t *mux_frame;
+ uint32_t read;
+ uint32_t vol_period;
+ int32_t energy_level;
+ int32_t agc_volume_in_level;
+ int32_t volume_in_level;
+ int32_t volume_out_level;
+ int32_t agc_concur;
+ int32_t nt_tally;
+ switch_time_t join_time;
+ switch_time_t last_talking;
+ uint32_t native_rate;
+ switch_audio_resampler_t *read_resampler;
+ int16_t *resample_out;
+ uint32_t resample_out_len;
+ conference_file_node_t *fnode;
+ conference_relationship_t *relationships;
+ switch_speech_handle_t lsh;
+ switch_speech_handle_t *sh;
+ uint32_t verbose_events;
+ uint32_t avg_score;
+ uint32_t avg_itt;
+ uint32_t avg_tally;
+ struct conference_member *next;
+ switch_ivr_dmachine_t *dmachine;
+ conference_cdr_node_t *cdr_node;
+ char *kicked_sound;
+ switch_queue_t *dtmf_queue;
+ switch_queue_t *video_queue;
+ switch_queue_t *mux_out_queue;
+ switch_thread_t *video_muxing_write_thread;
+ switch_thread_t *input_thread;
+ cJSON *json;
+ cJSON *status_field;
+ uint8_t loop_loop;
+ al_handle_t *al;
+ int last_speech_channels;
+ int video_layer_id;
+ int canvas_id;
+ int watching_canvas_id;
+ int layer_timeout;
+ int video_codec_index;
+ int video_codec_id;
+ char *video_banner_text;
+ char *video_logo;
+ char *video_mute_png;
+ char *video_reservation_id;
+ switch_media_flow_t video_flow;
+ switch_frame_buffer_t *fb;
+ switch_image_t *avatar_png_img;
+ switch_image_t *video_mute_img;
+ uint32_t floor_packets;
+ int blanks;
+ int managed_kps;
+ int blackouts;
+ int good_img;
+ int auto_avatar;
+ int avatar_patched;
+ mcu_canvas_t *canvas;
+ switch_image_t *pcanvas_img;
};
typedef enum {
- CONF_API_SUB_ARGS_SPLIT,
- CONF_API_SUB_MEMBER_TARGET,
- CONF_API_SUB_ARGS_AS_ONE
+ CONF_API_SUB_ARGS_SPLIT,
+ CONF_API_SUB_MEMBER_TARGET,
+ CONF_API_SUB_ARGS_AS_ONE
} conference_fntype_t;
typedef void (*void_fn_t) (void);
/* API command parser */
typedef struct api_command {
- char *pname;
- void_fn_t pfnapicmd;
- conference_fntype_t fntype;
- char *pcommand;
- char *psyntax;
+ char *pname;
+ void_fn_t pfnapicmd;
+ conference_fntype_t fntype;
+ char *pcommand;
+ char *psyntax;
} api_command_t;
typedef struct codec_set_s {
- switch_codec_t codec;
- switch_frame_t frame;
- uint8_t *packet;
+ switch_codec_t codec;
+ switch_frame_t frame;
+ uint8_t *packet;
} codec_set_t;
typedef void (*conference_key_callback_t) (conference_member_t *, struct caller_control_actions *);
typedef struct {
- conference_member_t *member;
- caller_control_action_t action;
- conference_key_callback_t handler;
+ conference_member_t *member;
+ caller_control_action_t action;
+ conference_key_callback_t handler;
} key_binding_t;
struct _mapping {
- const char *name;
- conference_key_callback_t handler;
+ const char *name;
+ conference_key_callback_t handler;
};
typedef enum {
- CONF_API_COMMAND_LIST = 0,
- CONF_API_COMMAND_ENERGY,
- CONF_API_COMMAND_VOLUME_IN,
- CONF_API_COMMAND_VOLUME_OUT,
- CONF_API_COMMAND_PLAY,
- CONF_API_COMMAND_SAY,
- CONF_API_COMMAND_SAYMEMBER,
- CONF_API_COMMAND_STOP,
- CONF_API_COMMAND_DTMF,
- CONF_API_COMMAND_KICK,
- CONF_API_COMMAND_MUTE,
- CONF_API_COMMAND_UNMUTE,
- CONF_API_COMMAND_DEAF,
- CONF_API_COMMAND_UNDEAF,
- CONF_API_COMMAND_RELATE,
- CONF_API_COMMAND_LOCK,
- CONF_API_COMMAND_UNLOCK,
- CONF_API_COMMAND_DIAL,
- CONF_API_COMMAND_BGDIAL,
- CONF_API_COMMAND_TRANSFER,
- CONF_API_COMMAND_RECORD,
- CONF_API_COMMAND_NORECORD,
- CONF_API_COMMAND_EXIT_SOUND,
- CONF_API_COMMAND_ENTER_SOUND,
- CONF_API_COMMAND_PIN,
- CONF_API_COMMAND_NOPIN,
- CONF_API_COMMAND_GET,
- CONF_API_COMMAND_SET,
+ CONF_API_COMMAND_LIST = 0,
+ CONF_API_COMMAND_ENERGY,
+ CONF_API_COMMAND_VOLUME_IN,
+ CONF_API_COMMAND_VOLUME_OUT,
+ CONF_API_COMMAND_PLAY,
+ CONF_API_COMMAND_SAY,
+ CONF_API_COMMAND_SAYMEMBER,
+ CONF_API_COMMAND_STOP,
+ CONF_API_COMMAND_DTMF,
+ CONF_API_COMMAND_KICK,
+ CONF_API_COMMAND_MUTE,
+ CONF_API_COMMAND_UNMUTE,
+ CONF_API_COMMAND_DEAF,
+ CONF_API_COMMAND_UNDEAF,
+ CONF_API_COMMAND_RELATE,
+ CONF_API_COMMAND_LOCK,
+ CONF_API_COMMAND_UNLOCK,
+ CONF_API_COMMAND_DIAL,
+ CONF_API_COMMAND_BGDIAL,
+ CONF_API_COMMAND_TRANSFER,
+ CONF_API_COMMAND_RECORD,
+ CONF_API_COMMAND_NORECORD,
+ CONF_API_COMMAND_EXIT_SOUND,
+ CONF_API_COMMAND_ENTER_SOUND,
+ CONF_API_COMMAND_PIN,
+ CONF_API_COMMAND_NOPIN,
+ CONF_API_COMMAND_GET,
+ CONF_API_COMMAND_SET,
} api_command_type_t;
struct bg_call {
- conference_obj_t *conference;
- switch_core_session_t *session;
- char *bridgeto;
- uint32_t timeout;
- char *flags;
- char *cid_name;
- char *cid_num;
- char *conference_name;
- char *uuid;
- char *profile;
- switch_call_cause_t *cancel_cause;
- switch_event_t *var_event;
- switch_memory_pool_t *pool;
+ conference_obj_t *conference;
+ switch_core_session_t *session;
+ char *bridgeto;
+ uint32_t timeout;
+ char *flags;
+ char *cid_name;
+ char *cid_num;
+ char *conference_name;
+ char *uuid;
+ char *profile;
+ switch_call_cause_t *cancel_cause;
+ switch_event_t *var_event;
+ switch_memory_pool_t *pool;
};
/* FUNCTION DEFINITIONS */
switch_status_t conference_outcall(conference_obj_t *conference,
char *conference_name,
switch_core_session_t *session,
- char *bridgeto, uint32_t timeout,
- char *flags,
- char *cid_name,
+ char *bridgeto, uint32_t timeout,
+ char *flags,
+ char *cid_name,
char *cid_num,
char *profile,
switch_call_cause_t *cause,
switch_status_t conference_outcall_bg(conference_obj_t *conference,
char *conference_name,
switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name,
- const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause,
+ const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause,
switch_event_t **var_event);
void conference_video_launch_muxing_thread(conference_obj_t *conference, mcu_canvas_t *canvas, int super);
void conference_video_launch_muxing_write_thread(conference_member_t *member);
void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *obj);
switch_status_t conference_file_local_play(conference_obj_t *conference, switch_core_session_t *session, char *path, uint32_t leadin, void *buf,
- uint32_t buflen);
+ uint32_t buflen);
switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin, switch_bool_t mux);
switch_status_t conference_member_say(conference_member_t *member, char *text, uint32_t leadin);
uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop);
conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_core_session_t *session, switch_memory_pool_t *pool);
switch_status_t chat_send(switch_event_t *message_event);
-
+
void conference_record_launch_thread(conference_obj_t *conference, char *path, switch_bool_t autorec);