提交 60a5ff16 authored 作者: Anthony Minessale's avatar Anthony Minessale

FS-10472: [mod_conference] Crash due to hangup race in conference personal…

FS-10472: [mod_conference] Crash due to hangup race in conference personal canvas mode -- manual cherry pick
上级 7a77e0bb
...@@ -351,14 +351,20 @@ void conference_video_reset_layer(mcu_layer_t *layer) ...@@ -351,14 +351,20 @@ void conference_video_reset_layer(mcu_layer_t *layer)
layer->canvas->refresh = 1; layer->canvas->refresh = 1;
} }
switch_img_free(&layer->img); switch_mutex_lock(layer->overlay_mutex);
if (layer->screen_w && layer->screen_h) { if (layer->img && (layer->img->d_w != layer->screen_w || layer->img->d_h != layer->screen_h)) {
switch_img_free(&layer->img);
}
if (!layer->img && layer->screen_w && layer->screen_h) {
layer->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, layer->screen_w, layer->screen_h, 1); layer->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, layer->screen_w, layer->screen_h, 1);
switch_assert(layer->img); switch_assert(layer->img);
} }
conference_video_clear_layer(layer); conference_video_clear_layer(layer);
switch_img_free(&layer->cur_img); switch_img_free(&layer->cur_img);
switch_mutex_unlock(layer->overlay_mutex);
} }
void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze) void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze)
...@@ -433,7 +439,9 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, ...@@ -433,7 +439,9 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
} }
if (freeze) { if (freeze) {
switch_mutex_lock(layer->overlay_mutex);
switch_img_free(&layer->img); switch_img_free(&layer->img);
switch_mutex_unlock(layer->overlay_mutex);
} }
if (screen_aspect > img_aspect) { if (screen_aspect > img_aspect) {
...@@ -450,10 +458,12 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, ...@@ -450,10 +458,12 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
conference_video_clear_layer(layer); conference_video_clear_layer(layer);
} }
switch_mutex_lock(layer->overlay_mutex);
if (!layer->img) { if (!layer->img) {
layer->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, img_w, img_h, 1); layer->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, img_w, img_h, 1);
} }
switch_mutex_unlock(layer->overlay_mutex);
if (layer->banner_img && !layer->banner_patched) { if (layer->banner_img && !layer->banner_patched) {
switch_img_fill(layer->canvas->img, layer->x_pos + layer->geometry.border, layer->y_pos + layer->geometry.border, layer->screen_w, layer->screen_h, &layer->canvas->letterbox_bgcolor); switch_img_fill(layer->canvas->img, layer->x_pos + layer->geometry.border, layer->y_pos + layer->geometry.border, layer->screen_w, layer->screen_h, &layer->canvas->letterbox_bgcolor);
switch_img_fit(&layer->banner_img, layer->screen_w, layer->screen_h, SWITCH_FIT_SIZE); switch_img_fit(&layer->banner_img, layer->screen_w, layer->screen_h, SWITCH_FIT_SIZE);
...@@ -1032,7 +1042,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member, ...@@ -1032,7 +1042,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member,
return status; return status;
} }
void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout) void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout, switch_bool_t force)
{ {
int i = 0; int i = 0;
...@@ -1042,11 +1052,24 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva ...@@ -1042,11 +1052,24 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
switch_mutex_lock(canvas->mutex); switch_mutex_lock(canvas->mutex);
canvas->layout_floor_id = -1; canvas->layout_floor_id = -1;
for (i = 0; i < MCU_MAX_LAYERS; i++) {
mcu_layer_t *layer = &canvas->layers[i];
if (!layer->overlay_mutex) {
switch_mutex_init(&layer->overlay_mutex, SWITCH_MUTEX_NESTED, canvas->pool);
}
}
if (!vlayout) { if (!vlayout) {
vlayout = canvas->new_vlayout; vlayout = canvas->new_vlayout;
canvas->new_vlayout = NULL; canvas->new_vlayout = NULL;
} }
if (vlayout && canvas->vlayout == vlayout && !force) {
switch_mutex_unlock(canvas->mutex);
switch_thread_rwlock_unlock(canvas->video_rwlock);
return;
}
if (!vlayout) { if (!vlayout) {
switch_mutex_unlock(canvas->mutex); switch_mutex_unlock(canvas->mutex);
switch_thread_rwlock_unlock(canvas->video_rwlock); switch_thread_rwlock_unlock(canvas->video_rwlock);
...@@ -1213,7 +1236,7 @@ switch_status_t conference_video_init_canvas(conference_obj_t *conference, video ...@@ -1213,7 +1236,7 @@ switch_status_t conference_video_init_canvas(conference_obj_t *conference, video
conference_video_set_canvas_bgcolor(canvas, conference->video_canvas_bgcolor); conference_video_set_canvas_bgcolor(canvas, conference->video_canvas_bgcolor);
conference_video_set_canvas_letterbox_bgcolor(canvas, conference->video_letterbox_bgcolor); conference_video_set_canvas_letterbox_bgcolor(canvas, conference->video_letterbox_bgcolor);
conference_video_set_canvas_border_color(canvas, conference->video_border_color); conference_video_set_canvas_border_color(canvas, conference->video_border_color);
conference_video_init_canvas_layers(conference, canvas, vlayout); conference_video_init_canvas_layers(conference, canvas, vlayout, SWITCH_TRUE);
switch_mutex_unlock(canvas->mutex); switch_mutex_unlock(canvas->mutex);
canvas->canvas_id = -1; canvas->canvas_id = -1;
...@@ -1246,14 +1269,19 @@ void conference_video_destroy_canvas(mcu_canvas_t **canvasP) { ...@@ -1246,14 +1269,19 @@ void conference_video_destroy_canvas(mcu_canvas_t **canvasP) {
int i; int i;
mcu_canvas_t *canvas = *canvasP; mcu_canvas_t *canvas = *canvasP;
switch_mutex_lock(canvas->mutex);
switch_img_free(&canvas->img); switch_img_free(&canvas->img);
switch_img_free(&canvas->bgimg); switch_img_free(&canvas->bgimg);
conference_video_flush_queue(canvas->video_queue, 0); conference_video_flush_queue(canvas->video_queue, 0);
for (i = 0; i < MCU_MAX_LAYERS; i++) { for (i = 0; i < MCU_MAX_LAYERS; i++) {
switch_img_free(&canvas->layers[i].img); mcu_layer_t *layer = &canvas->layers[i];
switch_mutex_lock(layer->overlay_mutex);
switch_img_free(&layer->img);
switch_mutex_unlock(layer->overlay_mutex);
} }
switch_mutex_unlock(canvas->mutex);
*canvasP = NULL; *canvasP = NULL;
} }
...@@ -2335,7 +2363,7 @@ switch_status_t conference_video_change_res(conference_obj_t *conference, int w, ...@@ -2335,7 +2363,7 @@ switch_status_t conference_video_change_res(conference_obj_t *conference, int w,
canvas->height = h; canvas->height = h;
switch_img_free(&canvas->img); switch_img_free(&canvas->img);
canvas->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, canvas->width, canvas->height, 0); canvas->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, canvas->width, canvas->height, 0);
conference_video_init_canvas_layers(conference, canvas, canvas->vlayout); conference_video_init_canvas_layers(conference, canvas, canvas->vlayout, SWITCH_TRUE);
switch_mutex_unlock(canvas->mutex); switch_mutex_unlock(canvas->mutex);
switch_mutex_unlock(conference->canvas_mutex); switch_mutex_unlock(conference->canvas_mutex);
...@@ -2387,7 +2415,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr ...@@ -2387,7 +2415,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
if (!personal) { if (!personal) {
if (canvas->new_vlayout && switch_mutex_trylock(conference->canvas_mutex) == SWITCH_STATUS_SUCCESS) { if (canvas->new_vlayout && switch_mutex_trylock(conference->canvas_mutex) == SWITCH_STATUS_SUCCESS) {
conference_video_init_canvas_layers(conference, canvas, NULL); conference_video_init_canvas_layers(conference, canvas, NULL, SWITCH_TRUE);
switch_mutex_unlock(conference->canvas_mutex); switch_mutex_unlock(conference->canvas_mutex);
} }
} }
...@@ -2797,14 +2825,14 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr ...@@ -2797,14 +2825,14 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
if (!imember->canvas) { if (!imember->canvas) {
if ((vlayout = conference_video_get_layout(conference, conference->video_layout_name, canvas->video_layout_group))) { if ((vlayout = conference_video_get_layout(conference, conference->video_layout_name, canvas->video_layout_group))) {
conference_video_init_canvas(conference, vlayout, &imember->canvas); conference_video_init_canvas(conference, vlayout, &imember->canvas);
conference_video_init_canvas_layers(conference, imember->canvas, vlayout); //conference_video_init_canvas_layers(conference, imember->canvas, vlayout, SWITCH_TRUE);
} else { } else {
continue; continue;
} }
} }
if (conference->new_personal_vlayout) { if (conference->new_personal_vlayout) {
conference_video_init_canvas_layers(conference, imember->canvas, conference->new_personal_vlayout); conference_video_init_canvas_layers(conference, imember->canvas, conference->new_personal_vlayout, SWITCH_FALSE);
layout_applied++; layout_applied++;
} }
...@@ -2839,7 +2867,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr ...@@ -2839,7 +2867,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
if (conference->video_layout_group && (lg = switch_core_hash_find(conference->layout_group_hash, conference->video_layout_group))) { if (conference->video_layout_group && (lg = switch_core_hash_find(conference->layout_group_hash, conference->video_layout_group))) {
if ((vlayout = conference_video_find_best_layout(conference, lg, total, 0))) { if ((vlayout = conference_video_find_best_layout(conference, lg, total, 0))) {
conference_video_init_canvas_layers(conference, imember->canvas, vlayout); conference_video_init_canvas_layers(conference, imember->canvas, vlayout, SWITCH_FALSE);
} }
} }
...@@ -3311,6 +3339,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr ...@@ -3311,6 +3339,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
layer = &canvas->layers[i]; layer = &canvas->layers[i];
switch_mutex_lock(canvas->mutex); switch_mutex_lock(canvas->mutex);
switch_mutex_lock(layer->overlay_mutex);
switch_img_free(&layer->cur_img); switch_img_free(&layer->cur_img);
switch_img_free(&layer->img); switch_img_free(&layer->img);
layer->banner_patched = 0; layer->banner_patched = 0;
...@@ -3318,6 +3347,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr ...@@ -3318,6 +3347,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
switch_img_free(&layer->logo_img); switch_img_free(&layer->logo_img);
switch_img_free(&layer->logo_text_img); switch_img_free(&layer->logo_text_img);
switch_img_free(&layer->mute_img); switch_img_free(&layer->mute_img);
switch_mutex_unlock(layer->overlay_mutex);
switch_mutex_unlock(canvas->mutex); switch_mutex_unlock(canvas->mutex);
if (layer->txthandle) { if (layer->txthandle) {
...@@ -3396,7 +3426,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ ...@@ -3396,7 +3426,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_
switch_mutex_lock(canvas->mutex); switch_mutex_lock(canvas->mutex);
if (canvas->new_vlayout) { if (canvas->new_vlayout) {
conference_video_init_canvas_layers(conference, canvas, NULL); conference_video_init_canvas_layers(conference, canvas, NULL, SWITCH_TRUE);
} }
switch_mutex_unlock(canvas->mutex); switch_mutex_unlock(canvas->mutex);
...@@ -3451,7 +3481,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ ...@@ -3451,7 +3481,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_
if ((lg = switch_core_hash_find(conference->layout_group_hash, CONFERENCE_MUX_DEFAULT_SUPER_LAYOUT))) { if ((lg = switch_core_hash_find(conference->layout_group_hash, CONFERENCE_MUX_DEFAULT_SUPER_LAYOUT))) {
if ((vlayout = conference_video_find_best_layout(conference, lg, total, 0))) { if ((vlayout = conference_video_find_best_layout(conference, lg, total, 0))) {
conference_video_init_canvas_layers(conference, canvas, vlayout); conference_video_init_canvas_layers(conference, canvas, vlayout, SWITCH_TRUE);
} }
} }
} }
...@@ -3659,6 +3689,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ ...@@ -3659,6 +3689,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_
layer = &canvas->layers[i]; layer = &canvas->layers[i];
switch_mutex_lock(canvas->mutex); switch_mutex_lock(canvas->mutex);
switch_mutex_lock(layer->overlay_mutex);
switch_img_free(&layer->cur_img); switch_img_free(&layer->cur_img);
switch_img_free(&layer->img); switch_img_free(&layer->img);
layer->banner_patched = 0; layer->banner_patched = 0;
...@@ -3666,6 +3697,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ ...@@ -3666,6 +3697,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_
switch_img_free(&layer->logo_img); switch_img_free(&layer->logo_img);
switch_img_free(&layer->logo_text_img); switch_img_free(&layer->logo_text_img);
switch_img_free(&layer->mute_img); switch_img_free(&layer->mute_img);
switch_mutex_unlock(layer->overlay_mutex);
switch_mutex_unlock(canvas->mutex); switch_mutex_unlock(canvas->mutex);
if (layer->txthandle) { if (layer->txthandle) {
......
...@@ -465,6 +465,7 @@ typedef struct mcu_layer_s { ...@@ -465,6 +465,7 @@ typedef struct mcu_layer_s {
struct mcu_canvas_s *canvas; struct mcu_canvas_s *canvas;
int need_patch; int need_patch;
conference_member_t *member; conference_member_t *member;
switch_mutex_t *overlay_mutex;
} mcu_layer_t; } mcu_layer_t;
typedef struct video_layout_s { typedef struct video_layout_s {
...@@ -961,7 +962,7 @@ void conference_event_la_command_handler(switch_live_array_t *la, const char *cm ...@@ -961,7 +962,7 @@ void conference_event_la_command_handler(switch_live_array_t *la, const char *cm
void conference_event_adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join); void conference_event_adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join);
switch_status_t conference_video_init_canvas(conference_obj_t *conference, video_layout_t *vlayout, mcu_canvas_t **canvasP); switch_status_t conference_video_init_canvas(conference_obj_t *conference, video_layout_t *vlayout, mcu_canvas_t **canvasP);
switch_status_t conference_video_attach_canvas(conference_obj_t *conference, mcu_canvas_t *canvas, int super); switch_status_t conference_video_attach_canvas(conference_obj_t *conference, mcu_canvas_t *canvas, int super);
void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout); void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout, switch_bool_t force);
switch_status_t conference_video_attach_video_layer(conference_member_t *member, mcu_canvas_t *canvas, int idx); switch_status_t conference_video_attach_video_layer(conference_member_t *member, mcu_canvas_t *canvas, int idx);
void conference_video_reset_video_bitrate_counters(conference_member_t *member); void conference_video_reset_video_bitrate_counters(conference_member_t *member);
void conference_video_layer_set_banner(conference_member_t *member, mcu_layer_t *layer, const char *text); void conference_video_layer_set_banner(conference_member_t *member, mcu_layer_t *layer, const char *text);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论