From a56e65bacee30ab3328586d6da9ca9645c4432ab Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 5 Feb 2015 15:03:54 -0600 Subject: [PATCH] FS-7513: add flag to choose between encoding each frame and using central encoder per codec, add parsing for floor fields and reservation fields in layouts, add param to control bandwidth for consolidated codecs, add audio-position attr to images in layout to sync with virtual HRTF --- .../autoload_configs/conference.conf.xml | 3 + .../conference_layouts.conf.xml | 16 +- src/include/switch_utils.h | 21 ++ .../mod_conference/mod_conference.c | 290 +++++++++++++----- src/switch_core_media.c | 33 +- src/switch_vidderbuffer.c | 17 +- 6 files changed, 261 insertions(+), 119 deletions(-) diff --git a/conf/vanilla/autoload_configs/conference.conf.xml b/conf/vanilla/autoload_configs/conference.conf.xml index a51d568337..30664e286f 100644 --- a/conf/vanilla/autoload_configs/conference.conf.xml +++ b/conf/vanilla/autoload_configs/conference.conf.xml @@ -175,9 +175,12 @@ + + + diff --git a/conf/vanilla/autoload_configs/conference_layouts.conf.xml b/conf/vanilla/autoload_configs/conference_layouts.conf.xml index 0c97ac1e01..26f149deb2 100644 --- a/conf/vanilla/autoload_configs/conference_layouts.conf.xml +++ b/conf/vanilla/autoload_configs/conference_layouts.conf.xml @@ -105,7 +105,7 @@ - + @@ -113,7 +113,7 @@ - + @@ -123,7 +123,7 @@ - + @@ -135,7 +135,7 @@ - + @@ -147,7 +147,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -171,7 +171,7 @@ - + @@ -180,7 +180,7 @@ - + diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index e922ff262a..4604e620b8 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -976,6 +976,27 @@ SWITCH_DECLARE(char *) switch_util_quote_shell_arg_pool(const char *string, swit #define SWITCH_READ_ACCEPTABLE(status) (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE) +static inline uint32_t switch_parse_bandwidth_string(const char *bwv) +{ + uint32_t bw = 0; + + if (!bwv) return 0; + + if (bwv && (bw = (uint32_t) atol(bwv))) { + if (bw < 0) return 0; + + if (switch_stristr("KB", bwv)) { + bw *= 8; + } else if (switch_stristr("mb", bwv)) { + bw *= 1024; + } else if (switch_stristr("MB", bwv)) { + bw *= 8192; + } + } + + return bw; +} + static inline int switch_needs_url_encode(const char *s) { const char hex[] = "0123456789ABCDEF"; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 80ddd0886c..42e9a446a6 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -231,8 +231,9 @@ typedef enum { CFLAG_LIVEARRAY_SYNC = (1 << 21), CFLAG_CONF_RESTART_AUTO_RECORD = (1 << 22), CFLAG_POSITIONAL = (1 << 23), - CFLAG_DECODE_VIDEO = (1 << 24), - CFLAG_VIDEO_MUXING = (1 << 25) + CFLAG_TRANSCODE_VIDEO = (1 << 24), + CFLAG_VIDEO_MUXING = (1 << 25), + CFLAG_MINIMIZE_VIDEO_ENCODING = (1 << 26) } conf_flag_t; typedef enum { @@ -342,6 +343,7 @@ typedef struct mcu_layer_geometry_s { int scale; int floor; char *res_id; + char *audio_position; } mcu_layer_geometry_t; typedef struct mcu_layer_def_s { @@ -352,6 +354,7 @@ typedef struct mcu_layer_def_s { typedef struct mcu_layer_s { mcu_layer_geometry_t geometry; int member_id; + int idx; switch_image_t *img; switch_image_t *cur_img; } mcu_layer_t; @@ -370,6 +373,7 @@ typedef struct mcu_canvas_s { mcu_layer_t layers[MCU_MAX_LAYERS]; int total_layers; int layers_used; + int layout_floor_id; bgcolor_yuv_t bgcolor; switch_mutex_t *mutex; switch_mutex_t *cond_mutex; @@ -423,6 +427,7 @@ typedef struct conference_obj { char *outcall_templ; char *video_layout_name; char *video_canvas_bgcolor; + uint32_t video_codec_bandwidth; uint32_t canvas_width; uint32_t canvas_height; uint32_t terminate_on_silence; @@ -674,7 +679,7 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem static switch_status_t conf_api_sub_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data); static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data); static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference, switch_stream_handle_t *stream, void *data); - +static switch_status_t conf_api_sub_position(conference_member_t *member, switch_stream_handle_t *stream, void *data); #define lock_member(_member) switch_mutex_lock(_member->write_mutex); switch_mutex_lock(_member->read_mutex) #define unlock_member(_member) switch_mutex_unlock(_member->read_mutex); switch_mutex_unlock(_member->write_mutex) @@ -684,6 +689,7 @@ static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference typedef struct layout_node_s { char *name; + char *audio_position; mcu_layer_geometry_t images[MCU_MAX_LAYERS]; struct layout_node_s *next; int layers; @@ -718,14 +724,13 @@ static void conference_parse_layouts(conference_obj_t *conference) if ((x_layout_settings = switch_xml_child(cfg, "layout-settings"))) { if ((x_layouts = switch_xml_child(x_layout_settings, "layouts"))) { for (x_layout = switch_xml_child(x_layouts, "layout"); x_layout; x_layout = x_layout->next) { - layout_node_t *lnode; - int x = -1, y = -1, scale = -1, floor = 0; - const char *val, *res_id = NULL, *name = NULL; + layout_node_t *lnode; + const char *val = NULL, *name = NULL; if ((val = switch_xml_attr(x_layout, "name"))) { name = val; } - + if (!name) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid layout\n"); continue; @@ -735,7 +740,9 @@ static void conference_parse_layouts(conference_obj_t *conference) lnode->name = switch_core_strdup(conference->pool, name); for (x_image = switch_xml_child(x_layout, "image"); x_image; x_image = x_image->next) { - + const char *res_id = NULL, *audio_position = NULL; + int x = -1, y = -1, scale = -1, floor = 0; + if ((val = switch_xml_attr(x_image, "x"))) { x = atoi(val); } @@ -755,7 +762,13 @@ static void conference_parse_layouts(conference_obj_t *conference) if ((val = switch_xml_attr(x_image, "reservation_id"))) { res_id = val; } - + + if ((val = switch_xml_attr(x_image, "audio-position"))) { + audio_position = val; + } + + + if (x < 0 || y < 0 || scale < 0 || !name) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid image\n"); continue; @@ -770,7 +783,11 @@ static void conference_parse_layouts(conference_obj_t *conference) if (res_id) { lnode->images[lnode->layers].res_id = switch_core_strdup(conference->pool, res_id); } - + + if (audio_position) { + lnode->images[lnode->layers].audio_position = switch_core_strdup(conference->pool, audio_position); + } + lnode->layers++; } @@ -1005,15 +1022,99 @@ static void set_canvas_bgcolor(mcu_canvas_t *canvas, char *color) reset_image(canvas->img, &canvas->bgcolor); } +static void detach_video_layer(conference_member_t *member) +{ + mcu_layer_t *layer = NULL; + + if (!member->conference->canvas || member->video_layer_id < 0) { + return; + } + + layer = &member->conference->canvas->layers[member->video_layer_id]; + + if (layer->geometry.audio_position) { + conf_api_sub_position(member, NULL, "0:0:0"); + } + + switch_mutex_lock(member->conference->canvas->mutex); + reset_layer(member->conference->canvas, layer); + member->conference->canvas->layers_used--; + layer->member_id = 0; + member->video_layer_id = -1; + switch_mutex_unlock(member->conference->canvas->mutex); +} + +static switch_status_t attach_video_layer(conference_member_t *member, int idx) +{ + mcu_layer_t *layer = NULL; + conference_member_t *imember = NULL; + switch_channel_t *channel = NULL; + const char *res_id = NULL; + if (!member->session) abort(); + + channel = switch_core_session_get_channel(member->session); + res_id = switch_channel_get_variable(channel, "video_reservation_id"); + + + layer = &member->conference->canvas->layers[idx]; + + if (layer->member_id && layer->member_id == member->id) return SWITCH_STATUS_BREAK; /* no op */ + + if (layer->geometry.res_id || res_id) { + if (!layer->geometry.res_id || !res_id || strcmp(layer->geometry.res_id, res_id)) { + return SWITCH_STATUS_FALSE; + } + } + + switch_mutex_lock(member->conference->canvas->mutex); + + if (layer->member_id && (imember = conference_member_get(member->conference, layer->member_id))) { + detach_video_layer(imember); + switch_thread_rwlock_unlock(imember->rwlock); + } + + layer->member_id = member->id; + member->conference->canvas->layers_used++; + member->video_layer_id = idx; + switch_mutex_unlock(member->conference->canvas->mutex); + + if (layer->geometry.audio_position) { + conf_api_sub_position(member, NULL, layer->geometry.audio_position); + } + + return SWITCH_STATUS_SUCCESS; +} static void init_canvas_layers(conference_obj_t *conference, layout_node_t *lnode) { int i = 0; + conference_member_t *member = NULL; + conference->canvas->layout_floor_id = -1; + for (i = 0; i < lnode->layers; i++) { - conference->canvas->layers[i].geometry.x = lnode->images[i].x; - conference->canvas->layers[i].geometry.y = lnode->images[i].y; - conference->canvas->layers[i].geometry.scale = lnode->images[i].scale; + mcu_layer_t *layer = &conference->canvas->layers[i]; + + layer->geometry.x = lnode->images[i].x; + layer->geometry.y = lnode->images[i].y; + layer->geometry.scale = lnode->images[i].scale; + layer->geometry.floor = lnode->images[i].floor; + layer->idx = i; + + if (layer->geometry.floor) { + conference->canvas->layout_floor_id = i; + } + + /* if we ever decided to reload layers config on demand the pointer assignment below will lead to segs but we + only load them once forever per conference so these pointers are valid for the life of the conference */ + layer->geometry.res_id = lnode->images[i].res_id; + layer->geometry.audio_position = lnode->images[i].audio_position; + } + + if (conference->canvas->layout_floor_id > -1 && + conference->video_floor_holder && (member = conference_member_get(conference, conference->video_floor_holder))) { + attach_video_layer(member, conference->canvas->layout_floor_id); + switch_thread_rwlock_unlock(member->rwlock); } conference->canvas->total_layers = lnode->layers; @@ -1028,6 +1129,7 @@ static void init_canvas(conference_obj_t *conference, layout_node_t *lnode) switch_mutex_init(&conference->canvas->mutex, SWITCH_MUTEX_NESTED, conference->pool); switch_mutex_init(&conference->canvas->cond_mutex, SWITCH_MUTEX_NESTED, conference->pool); switch_mutex_init(&conference->canvas->cond2_mutex, SWITCH_MUTEX_NESTED, conference->pool); + conference->canvas->layout_floor_id = -1; } switch_img_free(&conference->canvas->img); @@ -1036,9 +1138,10 @@ static void init_canvas(conference_obj_t *conference, layout_node_t *lnode) switch_assert(conference->canvas->img); + switch_mutex_lock(conference->canvas->mutex); set_canvas_bgcolor(conference->canvas, conference->video_canvas_bgcolor); - init_canvas_layers(conference, lnode); + switch_mutex_unlock(conference->canvas->mutex); } static void destroy_canvas(mcu_canvas_t **canvasP) { @@ -1136,9 +1239,11 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread switch_timer_t timer = { 0 }; int i = 0; int used = 0, remaining = 0; - uint32_t video_key_freq = 10000000; + uint32_t video_key_freq = 30000000; switch_time_t last_key_time = 0; mcu_layer_t *layer = NULL; + switch_frame_t write_frame = { 0 }; + uint8_t *packet = switch_core_alloc(conference->pool, SWITCH_RECOMMENDED_BUFFER_SIZE); #ifdef TRACK_FPS uint64_t frames = 0; switch_time_t started = switch_micro_time_now(); @@ -1172,46 +1277,48 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread continue; } + if (switch_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING)) { - if (switch_channel_test_flag(ichannel, CF_VIDEO_REFRESH_REQ)) { - switch_channel_clear_flag(ichannel, CF_VIDEO_REFRESH_REQ); - need_refresh = SWITCH_TRUE; - } + if (switch_channel_test_flag(ichannel, CF_VIDEO_REFRESH_REQ)) { + switch_channel_clear_flag(ichannel, CF_VIDEO_REFRESH_REQ); + need_refresh = SWITCH_TRUE; + } - 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) { - imember->video_codec_index = i; - imember->video_codec_id = check_codec->implementation->codec_id; - break; + 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) { + imember->video_codec_index = i; + imember->video_codec_id = check_codec->implementation->codec_id; + break; + } + } + + 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, 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); + + imember->video_codec_index = i; + imember->video_codec_id = check_codec->implementation->codec_id; + + write_codecs[i]->frame.packet = switch_core_alloc(conference->pool, buflen); + write_codecs[i]->frame.data = ((uint8_t *)write_codecs[i]->frame.packet) + 12; + write_codecs[i]->frame.packetlen = 0; + write_codecs[i]->frame.buflen = buflen - 12; + switch_set_flag((&write_codecs[i]->frame), SFF_RAW_RTP); + + } } } 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, 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); - - imember->video_codec_index = i; - imember->video_codec_id = check_codec->implementation->codec_id; - - write_codecs[i]->frame.packet = switch_core_alloc(conference->pool, buflen); - write_codecs[i]->frame.data = ((uint8_t *)write_codecs[i]->frame.packet) + 12; - write_codecs[i]->frame.packetlen = 0; - write_codecs[i]->frame.buflen = buflen - 12; - switch_set_flag((&write_codecs[i]->frame), SFF_RAW_RTP); - - } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Codec Error\n"); + continue; } } - if (imember->video_codec_index < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Codec Error\n"); - continue; - } - img = NULL; size = 0; @@ -1234,13 +1341,9 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread used++; switch_mutex_lock(conference->canvas->mutex); - if (imember->video_layer_id > -1) { if (imember->video_layer_id >= conference->canvas->total_layers) { - conference->canvas->layers[imember->video_layer_id].member_id = 0; - reset_layer(conference->canvas, &conference->canvas->layers[imember->video_layer_id]); - imember->video_layer_id = -1; - conference->canvas->layers_used--; + detach_video_layer(imember); } else { layer = &conference->canvas->layers[imember->video_layer_id]; } @@ -1251,10 +1354,10 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread for (i = 0; i < conference->canvas->total_layers; i++) { layer = &conference->canvas->layers[i]; if (!layer->member_id) { - conference->canvas->layers[i].member_id = imember->id; - conference->canvas->layers_used++; - imember->video_layer_id = i; - break; + switch_status_t lstatus = attach_video_layer(imember, i); + if (lstatus == SWITCH_STATUS_SUCCESS || lstatus == SWITCH_STATUS_BREAK) { + break; + } } } } @@ -1266,8 +1369,6 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread layer->cur_img = img; scale_and_patch(conference, layer); } - - } if (imember->session) { @@ -1298,9 +1399,36 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread switch_core_timer_sync(&timer); - for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) { - write_codecs[i]->frame.img = conference->canvas->img; - write_canvas_image_to_codec_group(conference, write_codecs[i], i, timer.samplecount, need_refresh, need_keyframe); + if (switch_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 = conference->canvas->img; + write_canvas_image_to_codec_group(conference, write_codecs[i], i, timer.samplecount, need_refresh, need_keyframe); + } + } else { + switch_mutex_lock(conference->member_mutex); + for (imember = conference->members; imember; imember = imember->next) { + switch_channel_t *ichannel = switch_core_session_get_channel(imember->session); + + if (!imember->session || !switch_channel_test_flag(ichannel, CF_VIDEO) || + switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { + continue; + } + + switch_set_flag(&write_frame, SFF_RAW_RTP); + write_frame.img = conference->canvas->img; + write_frame.packet = packet; + write_frame.data = packet + 12; + write_frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE - 12; + write_frame.buflen = write_frame.datalen; + write_frame.packetlen = SWITCH_RECOMMENDED_BUFFER_SIZE; + + switch_core_session_write_video_frame(imember->session, &write_frame, SWITCH_IO_FLAG_NONE, 0); + + if (imember->session) { + switch_core_session_rwunlock(imember->session); + } + } + switch_mutex_unlock(conference->member_mutex); } } @@ -3023,7 +3151,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe switch_set_flag_locked(member, MFLAG_ACK_VIDEO); } - if (switch_test_flag(conference, CFLAG_DECODE_VIDEO)) { + if (switch_test_flag(conference, CFLAG_TRANSCODE_VIDEO)) { switch_channel_set_flag(channel, CF_VIDEO_DECODED_READ); } @@ -3240,6 +3368,15 @@ static void conference_set_video_floor_holder(conference_obj_t *conference, conf 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))) { + + if (member->conference->canvas) { + switch_mutex_lock(member->conference->canvas->mutex); + detach_video_layer(member); + detach_video_layer(imember); + attach_video_layer(member, conference->canvas->layout_floor_id); + switch_mutex_unlock(member->conference->canvas->mutex); + } + switch_core_session_request_video_refresh(imember->session); if (switch_test_flag(imember, MFLAG_VIDEO_BRIDGE)) { @@ -3247,7 +3384,7 @@ static void conference_set_video_floor_holder(conference_obj_t *conference, conf } 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); @@ -3265,6 +3402,10 @@ static void conference_set_video_floor_holder(conference_obj_t *conference, conf } } + if (member && conference->canvas && conference->canvas->layout_floor_id > -1) { + attach_video_layer(member, conference->canvas->layout_floor_id); + } + if (member) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Adding video floor %s\n", switch_channel_get_name(member->channel)); @@ -3485,13 +3626,7 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe lock_member(member); - if (member->video_layer_id > -1 && member->conference->canvas) { - reset_layer(conference->canvas, &conference->canvas->layers[member->video_layer_id]); - switch_mutex_lock(conference->canvas->mutex); - conference->canvas->layers_used--; - conference->canvas->layers[member->video_layer_id].member_id = 0; - switch_mutex_unlock(conference->canvas->mutex); - } + detach_video_layer(member); member_del_relationship(member, 0); @@ -7278,7 +7413,7 @@ static switch_status_t conf_api_sub_auto_position(conference_obj_t *conference, static switch_status_t conf_api_sub_position(conference_member_t *member, switch_stream_handle_t *stream, void *data) { #ifndef OPENAL_POSITIONING - stream->write_function(stream, "-ERR not supported\n"); + if (stream) stream->write_function(stream, "-ERR not supported\n"); #else switch_event_t *event; @@ -9685,8 +9820,12 @@ 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")) { - *f |= CFLAG_DECODE_VIDEO; + } 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; } @@ -10780,6 +10919,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c char *video_layout_name = NULL; char *video_canvas_size = NULL; char *video_canvas_bgcolor = NULL; + char *video_codec_bandwidth = NULL; uint32_t max_members = 0; uint32_t announce_count = 0; char *maxmember_sound = NULL; @@ -10933,6 +11073,8 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c video_canvas_bgcolor= val; } else if (!strcasecmp(var, "video-canvas-size") && !zstr(val)) { video_canvas_size = val; + } else if (!strcasecmp(var, "video-codec-bandwidth") && !zstr(val)) { + video_codec_bandwidth = val; } else if (!strcasecmp(var, "exit-sound") && !zstr(val)) { exit_sound = val; } else if (!strcasecmp(var, "alone-sound") && !zstr(val)) { @@ -11116,6 +11258,10 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c conference->broadcast_chat_messages = broadcast_chat_messages; conference_parse_layouts(conference); + if (video_codec_bandwidth) { + conference->video_codec_bandwidth = switch_parse_bandwidth_string(video_codec_bandwidth); + } + if (video_layout_name && !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"); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index a807c4c777..ce10085cf4 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2367,23 +2367,12 @@ static void switch_core_session_parse_codec_settings(switch_core_session_t *sess case SWITCH_MEDIA_TYPE_VIDEO: { const char *bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth"); - uint32_t bw = 0; - + if (!bwv) { bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth_out"); } - - - if (bwv && (bw = (uint32_t) atol(bwv))) { - if (switch_stristr("KB", bwv)) { - bw *= 8; - } else if (switch_stristr("mb", bwv)) { - bw *= 1024; - } else if (switch_stristr("MB", bwv)) { - bw *= 8192; - } - engine->codec_settings.video.bandwidth = bw; - } + + engine->codec_settings.video.bandwidth = switch_parse_bandwidth_string(bwv); } break; default: @@ -7291,26 +7280,12 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth_in"); } - - if (vbw) { - int v = atoi(vbw); - bw = v; - - if (switch_stristr("KB", vbw)) { - bw *= 8; - } else if (switch_stristr("mb", vbw)) { - bw *= 1024; - } else if (switch_stristr("MB", vbw)) { - bw *= 8192; - } - - } + bw = switch_parse_bandwidth_string(vbw); if (bw > 0) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\n", bw); //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=TIAS:%d\n", bw); } - if (sdp_type == SDP_TYPE_REQUEST) { fir++; diff --git a/src/switch_vidderbuffer.c b/src/switch_vidderbuffer.c index 9553ded9ab..07c83d1933 100644 --- a/src/switch_vidderbuffer.c +++ b/src/switch_vidderbuffer.c @@ -191,8 +191,8 @@ static inline void add_node(switch_vb_t *vb, switch_rtp_packet_t *packet, switch - if (vb->write_init && ((abs(htons(packet->header.seq) - htons(vb->highest_wrote_seq)) > 10) || - (abs(ntohl(node->packet.header.ts) - ntohl(vb->highest_wrote_ts)) > 270000))) { + if (vb->write_init && ((abs(htons(packet->header.seq) - htons(vb->highest_wrote_seq)) > 16) || + (abs(ntohl(node->packet.header.ts) - ntohl(vb->highest_wrote_ts)) > 900000))) { vb_debug(vb, 2, "%s", "CHANGE DETECTED, PUNT\n"); switch_vb_reset(vb); } @@ -408,11 +408,9 @@ SWITCH_DECLARE(uint32_t) switch_vb_pop_nack(switch_vb_t *vb) nack = (uint32_t) htons(least); for(i = 0; i < 16; i++) { - if (switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(least + i))) { + if (switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(least + i + 1))) { vb_debug(vb, 3, "Found addtl NACKABLE seq %u\n", least + i + 1); blp |= (1 << i); - } else { - break; } } @@ -443,18 +441,17 @@ SWITCH_DECLARE(switch_status_t) switch_vb_put_packet(switch_vb_t *vb, switch_rtp if (!want) want = got; if (got > want) { + vb_debug(vb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1); + for (i = want; i < got; i++) { - vb_debug(vb, 2, "MARK SEQ MISSING %u\n", i); switch_core_inthash_insert(vb->missing_seq_hash, (uint32_t)htons(i), (void *)SWITCH_TRUE); } } else { - if (switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(got))) { - vb_debug(vb, 2, "MARK SEQ FOUND %u\n", got); - } + switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(got)); } if (got >= want) { - vb->next_seq = htons(ntohs(packet->header.seq) + 1); + vb->next_seq = htons(got + 1); } add_node(vb, packet, len);