From 718142bb12785d6293483c2c575dc45477300d36 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 20 May 2016 11:12:08 -0500 Subject: [PATCH] FS-9144 #resolve [Implement video-mute-exit-canvas and recording in personal-canvas mode.] --- .../mod_conference/conference_api.c | 9 -- .../mod_conference/conference_record.c | 20 ++-- .../mod_conference/conference_video.c | 107 +++++++++++------- 3 files changed, 77 insertions(+), 59 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 11a2efadcb..fe93d42ce9 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -1079,10 +1079,6 @@ switch_status_t conference_api_sub_vid_personal(conference_obj_t *conference, sw if (argv[2]) { on = switch_true(argv[2]); if (on) { - if (conference->record_count > 0) { - stream->write_function(stream, "-ERR conference is recording, not enabling vid-personal.\n"); - return SWITCH_STATUS_SUCCESS; - } conference_utils_set_flag(conference, CFLAG_PERSONAL_CANVAS); } else { conference_utils_clear_flag(conference, CFLAG_PERSONAL_CANVAS); @@ -2515,11 +2511,6 @@ switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_s return SWITCH_STATUS_SUCCESS; } - if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) { - stream->write_function(stream, "-ERR Personal Canvas enabled, recording not permitted.\n"); - return SWITCH_STATUS_SUCCESS; - } - if (argv[3]) { if (argv[3]) { diff --git a/src/mod/applications/mod_conference/conference_record.c b/src/mod/applications/mod_conference/conference_record.c index 7eb8fd0a18..89afeab14b 100644 --- a/src/mod/applications/mod_conference/conference_record.c +++ b/src/mod/applications/mod_conference/conference_record.c @@ -65,11 +65,6 @@ void conference_record_launch_thread(conference_obj_t *conference, char *path, i return; } - if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Personal Canvas enabled, recording not permitted.\n"); - return; - } - rec->conference = conference; rec->path = switch_core_strdup(pool, path); rec->pool = pool; @@ -235,9 +230,10 @@ void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *thread, v flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; if (conference_utils_test_flag(conference, CFLAG_TRANSCODE_VIDEO)) { + char *orig_path = rec->path; flags |= SWITCH_FILE_FLAG_VIDEO; + if (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", conference->channels, conference->rate, @@ -245,9 +241,18 @@ void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *thread, v canvas->height, conference->video_fps.fps, orig_path); + } else { + 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, + conference->canvas_height, + conference->video_fps.fps, + orig_path); + } } - + if (switch_core_file_open(&member->rec->fh, rec->path, (uint8_t) conference->channels, conference->rate, flags, rec->pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s]\n", rec->path); @@ -390,6 +395,7 @@ void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *thread, v switch_mutex_unlock(conference->mutex); switch_core_file_close(&member->rec->fh); } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Recording of %s Stopped\n", rec->path); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_event_add_data(conference, event); diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 5fc896407b..1e5d1cc10d 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1613,8 +1613,8 @@ void conference_video_check_recording(conference_obj_t *conference, mcu_canvas_t if (!imember->rec) { continue; } - - if (canvas && imember->canvas_id != canvas->canvas_id) { + + if (!conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) && canvas && imember->canvas_id != canvas->canvas_id) { continue; } @@ -2123,16 +2123,18 @@ static void personal_attach(mcu_layer_t *layer, conference_member_t *member) conference_api_sub_position(member, NULL, layer->geometry.audio_position); } - var = NULL; - if (member->video_banner_text || - (var = switch_channel_get_variable_dup(member->channel, "video_banner_text", SWITCH_FALSE, -1))) { - conference_video_layer_set_banner(member, layer, var); - } - - var = NULL; - if (member->video_logo || - (var = switch_channel_get_variable_dup(member->channel, "video_logo_path", SWITCH_FALSE, -1))) { - conference_video_layer_set_logo(member, layer, var); + if (member->channel) { + var = NULL; + if (member->video_banner_text || + (var = switch_channel_get_variable_dup(member->channel, "video_banner_text", SWITCH_FALSE, -1))) { + conference_video_layer_set_banner(member, layer, var); + } + + var = NULL; + if (member->video_logo || + (var = switch_channel_get_variable_dup(member->channel, "video_logo_path", SWITCH_FALSE, -1))) { + conference_video_layer_set_logo(member, layer, var); + } } } @@ -2163,6 +2165,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr int layout_applied = 0; int files_playing = 0; int last_personal = conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) ? 1 : 0; + int last_video_count = 0; canvas->video_timer_reset = 1; canvas->video_layout_group = conference->video_layout_group; @@ -2230,11 +2233,12 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } - if (video_count != canvas->video_count) { + + if (video_count != canvas->video_count || video_count != last_video_count) { count_changed = 1; } - canvas->video_count = video_count; + canvas->video_count = last_video_count = video_count; switch_mutex_unlock(conference->member_mutex); switch_core_timer_next(&canvas->timer); @@ -2562,7 +2566,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr 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) { send_keyframe = SWITCH_TRUE; last_key_time = now; @@ -2571,9 +2575,10 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr 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_READY) || - switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { + + if (!imember->rec && + (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || + switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) { continue; } @@ -2591,13 +2596,13 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr layout_applied++; } - if (switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { + if (imember->channel && switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); send_keyframe = SWITCH_TRUE; } if (count_changed) { - int total = conference->members_with_video; + int total = last_video_count; int kps; switch_vid_params_t vid_params = { 0 }; @@ -2605,7 +2610,10 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr total += conference->members_with_avatar; } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + if (total > 0 && + (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) || + conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN)) && + imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { total--; } @@ -2621,7 +2629,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } } - if (!switch_channel_test_flag(imember->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && + if (imember->channel && !switch_channel_test_flag(imember->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && conference_utils_test_flag(conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE)) { switch_core_media_get_vid_params(imember->session, &vid_params); kps = switch_calc_bitrate(vid_params.width, vid_params.height, conference->video_quality, (int)(imember->conference->video_fps.fps)); @@ -2629,11 +2637,13 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + if (imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { conference_video_pop_next_image(imember, &imember->pcanvas_img); } - switch_core_session_rwunlock(imember->session); + if (imember->session) { + switch_core_session_rwunlock(imember->session); + } } if (conference->new_personal_vlayout && layout_applied) { @@ -2671,9 +2681,10 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr int i = 0; mcu_layer_t *floor_layer = NULL; - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || !imember->canvas || - (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) || - (switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) { + if (!imember->rec && + (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || !imember->canvas || + (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) || + (switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS))) { continue; } @@ -2762,7 +2773,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (layer) { if (conference_utils_member_test_flag(omember, MFLAG_CAN_BE_SEEN)) { layer->mute_patched = 0; - } else { + } else if (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) { if (!layer->mute_patched) { switch_image_t *tmp; conference_video_scale_and_patch(layer, omember->video_mute_img ? omember->video_mute_img : omember->pcanvas_img, SWITCH_FALSE); @@ -2795,7 +2806,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } } - switch_core_session_rwunlock(imember->session); + if (imember->session) { + switch_core_session_rwunlock(imember->session); + } } if (files_playing && !file_count) { @@ -2807,33 +2820,41 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr for (imember = conference->members; imember; imember = imember->next) { switch_frame_t *dupframe; - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || - switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { + if (!imember->rec && + (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || + switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) { continue; } - if (need_refresh) { + if (need_refresh && imember->session) { switch_core_session_request_video_refresh(imember->session); } - if (send_keyframe) { + if (send_keyframe && imember->session) { switch_core_media_gen_key_frame(imember->session); } - switch_set_flag(&write_frame, SFF_RAW_RTP); write_frame.img = imember->canvas->img; - write_frame.packet = packet; - write_frame.data = ((uint8_t *)packet) + 12; - write_frame.datalen = 0; - write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12; - write_frame.packetlen = 0; + + if (imember->rec) { + switch_core_file_write_video(&imember->rec->fh, &write_frame); + } else { + switch_set_flag(&write_frame, SFF_RAW_RTP); + write_frame.packet = packet; + write_frame.data = ((uint8_t *)packet) + 12; + 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; + 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); + if (imember->session) { + switch_core_session_rwunlock(imember->session); + } } switch_mutex_unlock(conference->member_mutex);