}
switch_mutex_unlock(conference_globals.hash_mutex);
}
+
void conference_video_launch_muxing_thread(conference_obj_t *conference, mcu_canvas_t *canvas, int super)
{
switch_threadattr_t *thd_attr = NULL;
switch_mutex_unlock(conference_globals.hash_mutex);
}
+void *SWITCH_THREAD_FUNC conference_video_layer_thread_run(switch_thread_t *thread, void *obj)
+{
+ conference_member_t *member = (conference_member_t *) obj;
+
+ if (switch_thread_rwlock_tryrdlock(member->rwlock) != SWITCH_STATUS_SUCCESS) {
+ return NULL;
+ }
+
+ //switch_core_autobind_cpu();
+ member->layer_thread_running = 1;
+
+ switch_mutex_lock(member->layer_cond_mutex);
+
+ while(conference_utils_member_test_flag(member, MFLAG_RUNNING) && member->layer_thread_running) {
+ mcu_layer_t *layer = NULL;
+ mcu_canvas_t *canvas = NULL;
+
+ switch_thread_cond_wait(member->layer_cond, member->layer_cond_mutex);
+
+ if (!conference_utils_member_test_flag(member, MFLAG_RUNNING)) {
+ break;
+ }
+
+ switch_mutex_lock(member->conference->canvas_mutex);
+ if (member->video_layer_id > -1 && member->canvas_id > -1) {
+ canvas = member->conference->canvases[member->canvas_id];
+ layer = &canvas->layers[member->video_layer_id];
+
+ if (layer->need_patch && switch_thread_rwlock_tryrdlock(canvas->video_rwlock) == SWITCH_STATUS_SUCCESS) {
+ if (layer->need_patch) {
+ conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE);
+ layer->need_patch = 0;
+ }
+ switch_thread_rwlock_unlock(canvas->video_rwlock);
+ }
+ }
+ switch_mutex_unlock(member->conference->canvas_mutex);
+ }
+
+ switch_mutex_unlock(member->layer_cond_mutex);
+
+ member->layer_thread_running = 0;
+
+ switch_thread_rwlock_unlock(member->rwlock);
+
+ return NULL;
+}
+
+void conference_video_wake_layer_thread(conference_member_t *member)
+{
+ if (member->layer_cond) {
+ if (switch_mutex_trylock(member->layer_cond_mutex) == SWITCH_STATUS_SUCCESS) {
+ switch_thread_cond_signal(member->layer_cond);
+ switch_mutex_unlock(member->layer_cond_mutex);
+ }
+ }
+}
+
+void conference_video_launch_layer_thread(conference_member_t *member)
+{
+ switch_threadattr_t *thd_attr = NULL;
+
+ if (switch_core_cpu_count() < 3) {
+ return;
+ }
+
+ if (!member->layer_cond) {
+ switch_thread_cond_create(&member->layer_cond, member->pool);
+ switch_mutex_init(&member->layer_cond_mutex, SWITCH_MUTEX_NESTED, member->pool);
+ }
+
+ switch_mutex_lock(conference_globals.hash_mutex);
+ if (!member->video_layer_thread) {
+ switch_threadattr_create(&thd_attr, member->pool);
+ //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
+ switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+ switch_thread_create(&member->video_layer_thread, thd_attr, conference_video_layer_thread_run, member, member->pool);
+ }
+ switch_mutex_unlock(conference_globals.hash_mutex);
+}
+
+
+
+
void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_t *thread, void *obj)
{
conference_member_t *member = (conference_member_t *) obj;
void *pop;
switch_frame_t *frame;
- int loops = 0, patched = 0;
+ int loops = 0;
switch_time_t last = 0;
switch_status_t pop_status;
while(conference_utils_member_test_flag(member, MFLAG_RUNNING)) {
- if (patched) {
- pop_status = switch_frame_buffer_trypop(member->fb, &pop);
- } else {
- pop_status = switch_frame_buffer_pop(member->fb, &pop);
- }
+ pop_status = switch_frame_buffer_pop(member->fb, &pop);
if (pop_status == SWITCH_STATUS_SUCCESS) {
- mcu_layer_t *layer = NULL;
- mcu_canvas_t *canvas = NULL;
if (!pop) {
break;
}
last = now;
-
-
}
-
+
switch_frame_buffer_free(member->fb, &frame);
}
-
- canvas = NULL;
- layer = NULL;
- patched = 0;
-
- switch_mutex_lock(member->conference->canvas_mutex);
- if (member->video_layer_id > -1 && member->canvas_id > -1) {
- canvas = member->conference->canvases[member->canvas_id];
- layer = &canvas->layers[member->video_layer_id];
-
- if (layer->need_patch && switch_thread_rwlock_tryrdlock(canvas->video_rwlock) == SWITCH_STATUS_SUCCESS) {
- if (layer->need_patch) {
- conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE);
- patched++;
- layer->need_patch = 0;
- }
- switch_thread_rwlock_unlock(canvas->video_rwlock);
- }
- }
- switch_mutex_unlock(member->conference->canvas_mutex);
- } else {
- patched = 0;
}
}
if (layer->need_patch) {
if (layer->member_id && layer->member && conference_utils_member_test_flag(layer->member, MFLAG_RUNNING) && layer->member->fb) {
- switch_frame_buffer_trypush(layer->member->fb, (void *) 1);
+ conference_video_wake_layer_thread(layer->member);
x++;
} else {
layer->need_patch = 0;
if (layer->cur_img) {
if (layer->member && switch_core_cpu_count() > 2) {
layer->need_patch = 1;
+ conference_video_wake_layer_thread(layer->member);
} else {
conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE);
}
}
if (layer->cur_img) {
- if (layer->member) {
+ if (layer->member && switch_core_cpu_count() > 2) {
layer->need_patch = 1;
+ conference_video_wake_layer_thread(layer->member);
} else {
conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE);
}
if (conference->conference_video_mode == CONF_VIDEO_MODE_MUX) {
conference_video_launch_muxing_write_thread(&member);
+ conference_video_launch_layer_thread(&member);
}
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
switch_core_session_receive_message(session, &msg);
+ conference_utils_member_clear_flag(&member, MFLAG_RUNNING);
+
if (member.video_muxing_write_thread) {
switch_status_t st = SWITCH_STATUS_SUCCESS;
switch_frame_buffer_push(member.fb, NULL);
member.video_muxing_write_thread = NULL;
}
+ if (member.video_layer_thread) {
+ switch_status_t st = SWITCH_STATUS_SUCCESS;
+
+ while(member.layer_thread_running) {
+ conference_video_wake_layer_thread(&member);
+ switch_yield(10000);
+ }
+
+ switch_thread_join(&st, member.video_layer_thread);
+ member.video_layer_thread = NULL;
+ }
+
/* Remove the caller from the conference */
conference_member_del(member.conference, &member);
switch_queue_t *dtmf_queue;
switch_queue_t *video_queue;
switch_thread_t *video_muxing_write_thread;
+ switch_thread_t *video_layer_thread;
+ int layer_thread_running;
switch_thread_t *input_thread;
+ switch_thread_cond_t *layer_cond;
+ switch_mutex_t *layer_cond_mutex;
cJSON *json;
cJSON *status_field;
uint8_t loop_loop;
switch_status_t conference_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);
switch_status_t conference_text_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);
void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_t *thread, void *obj);
+void conference_video_launch_layer_thread(conference_member_t *member);
+void conference_video_wake_layer_thread(conference_member_t *member);
void conference_member_check_agc_levels(conference_member_t *member);
void conference_member_clear_avg(conference_member_t *member);
int conference_member_noise_gate_check(conference_member_t *member);