From 0fc2c54b11673a8d4b8df32c22cb22c3e94be6e8 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 27 Mar 2015 14:27:11 -0400 Subject: [PATCH] FS-7513: Add new conference profile param video-mode (mux,transcode,passthrough) with passthrough as default remove transcode-video, decode-video, mix-video flags --- .../autoload_configs/conference.conf.xml | 4 +- .../mod_conference/mod_conference.c | 171 +++++++++++------- 2 files changed, 109 insertions(+), 66 deletions(-) diff --git a/conf/vanilla/autoload_configs/conference.conf.xml b/conf/vanilla/autoload_configs/conference.conf.xml index 210950d056..f45e0a4984 100644 --- a/conf/vanilla/autoload_configs/conference.conf.xml +++ b/conf/vanilla/autoload_configs/conference.conf.xml @@ -177,6 +177,7 @@ + @@ -212,8 +213,9 @@ - + + diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index aeb8aacf66..dcd5825019 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -114,6 +114,10 @@ static int EC = 0; /* max supported layers in one mcu */ #define MCU_MAX_LAYERS 64 +#define CONFERENCE_MUX_DEFAULT_LAYOUT "group:grid" +#define CONFERENCE_CANVAS_DEFAULT_WIDTH 1280 +#define CONFERENCE_CANVAS_DEFAULT_HIGHT 720 + #define test_eflag(conference, flag) ((conference)->eflags & flag) typedef enum { @@ -444,6 +448,12 @@ typedef struct conference_record { struct conference_record *next; } conference_record_t; +typedef enum { + CONF_VIDEO_MODE_PASSTHROUGH, + CONF_VIDEO_MODE_TRANSCODE, + CONF_VIDEO_MODE_MUX +} conf_video_mode_t; + /* Conference Object */ typedef struct conference_obj { char *name; @@ -478,6 +488,7 @@ typedef struct conference_obj { char *video_layout_group; char *video_canvas_bgcolor; char *video_layout_bgcolor; + conf_video_mode_t conf_video_mode; int members_with_video; int video_timer_reset; int32_t video_write_bandwidth; @@ -1586,6 +1597,21 @@ static video_layout_t *find_best_layout(conference_obj_t *conference, layout_gro return vlnode? vlnode->vlayout : last ? last->vlayout : NULL; } +static video_layout_t *get_layout(conference_obj_t *conference) +{ + layout_group_t *lg = NULL; + video_layout_t *vlayout = NULL; + + if (conference->video_layout_group) { + lg = switch_core_hash_find(conference->layout_group_hash, conference->video_layout_group); + vlayout = find_best_layout(conference, lg); + } else { + vlayout = switch_core_hash_find(conference->layout_hash, conference->video_layout_name); + } + + return vlayout; +} + static void vmute_snap(conference_member_t *member, switch_bool_t clear) { if (member->conference->canvas && member->video_layer_id > -1) { @@ -1647,7 +1673,6 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread { conference_obj_t *conference = (conference_obj_t *) obj; conference_member_t *imember; - video_layout_t *vlayout = NULL; switch_codec_t *check_codec = NULL; codec_set_t *write_codecs[MAX_MUX_CODECS] = { 0 }; int buflen = SWITCH_RTP_MAX_BUF_LEN; @@ -1658,17 +1683,9 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread mcu_layer_t *layer = NULL; switch_frame_t write_frame = { 0 }; uint8_t *packet = NULL; - layout_group_t *lg = NULL; switch_image_t *write_img = NULL, *file_img = NULL; uint32_t timestamp = 0; - - - if (conference->video_layout_group) { - lg = switch_core_hash_find(conference->layout_group_hash, conference->video_layout_group); - vlayout = find_best_layout(conference, lg); - } else { - vlayout = switch_core_hash_find(conference->layout_hash, conference->video_layout_name); - } + video_layout_t *vlayout = get_layout(conference); if (!vlayout) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot find layout\n"); @@ -10902,12 +10919,8 @@ static void set_cflags(const char *flags, uint32_t *f) *f |= CFLAG_RFC4579; } else if (!strcasecmp(argv[i], "auto-3d-position")) { *f |= CFLAG_POSITIONAL; - } else if (!strcasecmp(argv[i], "decode-video") || !strcasecmp(argv[i], "transcode-video")) { - *f |= CFLAG_TRANSCODE_VIDEO; } else if (!strcasecmp(argv[i], "minimize-video-encoding")) { *f |= CFLAG_MINIMIZE_VIDEO_ENCODING; - } else if (!strcasecmp(argv[i], "mix-video")) { - *f |= CFLAG_VIDEO_MUXING; } @@ -11688,7 +11701,7 @@ SWITCH_STANDARD_APP(conference_function) conference->min = 2; } - if (conference->video_layout_name) { + if (conference->conf_video_mode == CONF_VIDEO_MODE_MUX) { switch_queue_create(&member.video_queue, 2000, member.pool); switch_queue_create(&member.mux_out_queue, 2000, member.pool); switch_frame_buffer_create(&member.fb); @@ -12031,6 +12044,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c char *video_canvas_bgcolor = NULL; char *video_layout_bgcolor = NULL; char *video_codec_bandwidth = NULL; + conf_video_mode_t conf_video_mode = CONF_VIDEO_MODE_PASSTHROUGH; float fps = 15.0f; uint32_t max_members = 0; uint32_t announce_count = 0; @@ -12310,6 +12324,16 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c terminate_on_silence = val; } else if (!strcasecmp(var, "endconf-grace-time") && !zstr(val)) { endconf_grace_time = val; + } else if (!strcasecmp(var, "video-mode") && !zstr(val)) { + if (!strcasecmp(val, "passthrough")) { + conf_video_mode = CONF_VIDEO_MODE_PASSTHROUGH; + } else if (!strcasecmp(val, "transcode")) { + conf_video_mode = CONF_VIDEO_MODE_TRANSCODE; + } else if (!strcasecmp(val, "mux")) { + conf_video_mode = CONF_VIDEO_MODE_MUX; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "video-mode invalid, valid settings are 'passthrough', 'transcode' and 'mux'\n"); + } } } @@ -12374,67 +12398,84 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c conference->video_codec_settings.video.bandwidth = switch_parse_bandwidth_string(video_codec_bandwidth); } - if (video_layout_name) { - if (!strncasecmp(video_layout_name, "group:", 6)) { - if (!switch_core_hash_find(conference->layout_group_hash, video_layout_name + 6)) { - video_layout_name = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid conference layout group settings\n"); - } else { - video_layout_group = video_layout_name + 6; - } - } else if (!switch_core_hash_find(conference->layout_hash, video_layout_name)) { - video_layout_name = NULL; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid conference layout settings\n"); + conference->conf_video_mode = conf_video_mode; + + if (conference->conf_video_mode == CONF_VIDEO_MODE_MUX) { + if (!video_canvas_bgcolor) { + video_canvas_bgcolor = "#333333"; } - } - - if (!video_canvas_bgcolor) { - video_canvas_bgcolor = "#333333"; - } - if (!video_layout_bgcolor) { - video_layout_bgcolor = "#000000"; - } + if (!video_layout_bgcolor) { + video_layout_bgcolor = "#000000"; + } - conference->video_canvas_bgcolor = switch_core_strdup(conference->pool, video_canvas_bgcolor); - conference->video_layout_bgcolor = switch_core_strdup(conference->pool, video_layout_bgcolor); + conference->video_canvas_bgcolor = switch_core_strdup(conference->pool, video_canvas_bgcolor); + conference->video_layout_bgcolor = switch_core_strdup(conference->pool, video_layout_bgcolor); - if (fps) { - conference_set_fps(conference, fps); - } + if (fps) { + conference_set_fps(conference, fps); + } - if (!conference->video_fps.ms) { - conference_set_fps(conference, 30); - } - - if (video_canvas_size && video_layout_name) { - int w = 0, h = 0; - char *p; + if (!conference->video_fps.ms) { + conference_set_fps(conference, 30); + } - if ((w = atoi(video_canvas_size))) { - if ((p = strchr(video_canvas_size, 'x'))) { - p++; - if (*p) { - h = atoi(p); + 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; + } + + if (!strncasecmp(video_layout_name, "group:", 6)) { + video_layout_group = video_layout_name + 6; + } + if (video_layout_name) { + conference->video_layout_name = switch_core_strdup(conference->pool, video_layout_name); + } + if (video_layout_group) { + conference->video_layout_group = switch_core_strdup(conference->pool, video_layout_group); + } + + if (!get_layout(conference)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid video-layout-name specified, using " CONFERENCE_MUX_DEFAULT_LAYOUT "\n"); + video_layout_name = CONFERENCE_MUX_DEFAULT_LAYOUT; + video_layout_group = video_layout_name + 6; + conference->video_layout_name = switch_core_strdup(conference->pool, video_layout_name); + conference->video_layout_group = switch_core_strdup(conference->pool, video_layout_group); + } + + if (!get_layout(conference)) { + conference->video_layout_name = conference->video_layout_group = video_layout_group = video_layout_name = NULL; + conference->conf_video_mode = CONF_VIDEO_MODE_TRANSCODE; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid conference layout settings, falling back to transcode mode\n"); + } else { + int w = 0, h = 0; + if (video_canvas_size) { + char *p; + + if ((w = atoi(video_canvas_size))) { + if ((p = strchr(video_canvas_size, 'x'))) { + p++; + if (*p) { + h = atoi(p); + } + } } } - } - if (w > 0 && h > 0) { - conference->canvas_width = w; - conference->canvas_height = h; - if (video_layout_name) { - conference->video_layout_name = switch_core_strdup(conference->pool, video_layout_name); + if (w > 0 && h > 0) { + conference->canvas_width = w; + conference->canvas_height = h; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s video-canvas-size, falling back to %ux%u\n", + video_canvas_size ? "Invalid" : "Unspecified", CONFERENCE_CANVAS_DEFAULT_WIDTH, CONFERENCE_CANVAS_DEFAULT_HIGHT); + conference->canvas_width = CONFERENCE_CANVAS_DEFAULT_WIDTH; + conference->canvas_height = CONFERENCE_CANVAS_DEFAULT_HIGHT; } - if (video_layout_group) { - conference->video_layout_group = switch_core_strdup(conference->pool, video_layout_group); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid conference dimensions\n"); } + } - } else if (video_canvas_size || video_layout_name || video_layout_group) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid conference layout settings\n"); + if (conference->conf_video_mode == CONF_VIDEO_MODE_TRANSCODE || conference->conf_video_mode == CONF_VIDEO_MODE_MUX) { + switch_set_flag(conference, CFLAG_TRANSCODE_VIDEO); } if (outcall_templ) { @@ -12663,7 +12704,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c switch_core_hash_insert(globals.conference_hash, conference->name, conference); switch_mutex_unlock(globals.hash_mutex); - if (conference->video_layout_name && !conference->video_muxing_thread) { + if (conference->conf_video_mode == CONF_VIDEO_MODE_MUX && !conference->video_muxing_thread) { launch_conference_video_muxing_thread(conference); }