From 086cbf1bfcd00cccb5d0b9e53390eb490d0c78d0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 May 2012 13:17:05 -0500 Subject: [PATCH] FS-4176 --resolve --- .../mod_conference/mod_conference.c | 93 ++++++++++++++++++- 1 file changed, 89 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 89182fa6de..a46437aab3 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -335,6 +335,7 @@ typedef struct conference_obj { switch_time_t end_time; char *log_dir; struct vid_helper vh[2]; + struct vid_helper mh; } conference_obj_t; /* Relationship with another member */ @@ -477,7 +478,8 @@ static switch_status_t chat_send(switch_event_t *message_event); static void launch_conference_record_thread(conference_obj_t *conference, char *path); -static void launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b); +static int launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b); +static void launch_conference_video_mirror_thread(conference_member_t *member_a); typedef switch_status_t (*conf_api_args_cmd_t) (conference_obj_t *, switch_stream_handle_t *, int, char **); typedef switch_status_t (*conf_api_member_cmd_t) (conference_member_t *, switch_stream_handle_t *, void *); @@ -1221,6 +1223,56 @@ static void *SWITCH_THREAD_FUNC conference_video_bridge_thread_run(switch_thread } + +static void *SWITCH_THREAD_FUNC conference_video_mirror_thread_run(switch_thread_t *thread, void *obj) +{ + struct vid_helper *vh = obj; + switch_core_session_t *session_a = vh->member_a->session; + switch_channel_t *channel_a = switch_core_session_get_channel(session_a); + switch_status_t status; + switch_frame_t *read_frame; + conference_obj_t *conference = vh->member_a->conference; + + switch_thread_rwlock_rdlock(conference->rwlock); + switch_thread_rwlock_rdlock(vh->member_a->rwlock); + + /* Acquire locks for both sessions so the helper object and member structures don't get destroyed before we exit */ + switch_core_session_read_lock(session_a); + + vh->up = 1; + while (vh->up > 0 && switch_test_flag(vh->member_a, MFLAG_RUNNING) && + switch_channel_ready(channel_a)) { + + if (vh->up == 1) { + status = switch_core_session_read_video_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } + + if (!switch_test_flag(read_frame, SFF_CNG)) { + if (switch_core_session_write_video_frame(session_a, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { + break; + } + } + } else { + switch_yield(100000); + } + } + + + switch_thread_rwlock_unlock(vh->member_a->rwlock); + + switch_core_session_rwunlock(session_a); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s video mirror thread ended.\n", switch_channel_get_name(channel_a)); + + switch_thread_rwlock_unlock(conference->rwlock); + + vh->up = 0; + return NULL; +} + + /* Main video monitor thread (1 per distinct conference room) */ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thread, void *obj) { @@ -1523,8 +1575,22 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v switch_channel_ready(switch_core_session_get_channel(video_bridge_members[0]->session)) && switch_channel_ready(switch_core_session_get_channel(video_bridge_members[1]->session)) ) { + conference->mh.up = 2; + if (launch_conference_video_bridge_thread(video_bridge_members[0], video_bridge_members[1])) { + conference->mh.up = 1; + } else { + conference->mh.up = -1; + } + } else if (conference->vh[0].up == 0 && + conference->vh[1].up == 0 && + conference->mh.up == 0 && + video_bridge_members[0] && + !video_bridge_members[1] && + switch_test_flag(video_bridge_members[0], MFLAG_RUNNING) && + switch_channel_ready(switch_core_session_get_channel(video_bridge_members[0]->session)) + ) { - launch_conference_video_bridge_thread(video_bridge_members[0], video_bridge_members[1]); + launch_conference_video_mirror_thread(video_bridge_members[0]); } } @@ -6764,11 +6830,11 @@ static void launch_conference_video_thread(conference_obj_t *conference) } /* Create a video thread for the conference and launch it */ -static void launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b) +static int launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b) { conference_obj_t *conference = member_a->conference; switch_memory_pool_t *pool = conference->pool; - int sanity = 10000; + int sanity = 10000, r = 0; memset(conference->vh, 0, sizeof(conference->vh)); @@ -6787,14 +6853,33 @@ static void launch_conference_video_bridge_thread(conference_member_t *member_a, if (conference->vh[0].up == 1 && conference->vh[1].up != 1) { conference->vh[0].up = -1; + r = -1; } if (conference->vh[1].up == 1 && conference->vh[0].up != 1) { conference->vh[1].up = -1; + r = -1; } + + return r; } + + +/* Create a video thread for the conference and launch it */ +static void launch_conference_video_mirror_thread(conference_member_t *member_a) +{ + conference_obj_t *conference = member_a->conference; + switch_memory_pool_t *pool = conference->pool; + + memset(&conference->mh, 0, sizeof(conference->mh)); + + conference->mh.member_a = member_a; + + launch_thread_detached(conference_video_mirror_thread_run, pool, &conference->mh); +} + static void launch_conference_record_thread(conference_obj_t *conference, char *path) { switch_thread_t *thread;