]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10561: [freeswitch-core,mod_conference] Video concurrency improvements for 1.8...
authorAnthony Minessale <anthm@freeswitch.org>
Mon, 31 Jul 2017 17:12:32 +0000 (12:12 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 31 Jul 2017 17:12:32 +0000 (12:12 -0500)
src/mod/applications/mod_conference/conference_event.c
src/mod/applications/mod_conference/conference_utils.c
src/mod/applications/mod_conference/conference_video.c
src/mod/applications/mod_conference/mod_conference.h
src/switch_core_media.c
src/switch_rtp.c
src/switch_vpx.c

index 058a56123ace64b3e6c2da684c82f1ab600437af..56343155c477768b2a2c320d559e392336105b15 100644 (file)
@@ -586,7 +586,7 @@ void conference_event_adv_layout(conference_obj_t *conference, mcu_canvas_t *can
        cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(conference->info_event_channel));
        cJSON_AddItemToObject(data, "contentType", cJSON_CreateString("layout-info"));
        
-       switch_thread_rwlock_rdlock(canvas->video_rwlock);
+       switch_mutex_lock(canvas->write_mutex);
        switch_mutex_lock(canvas->mutex);
        
        if ((obj = get_canvas_info(canvas))) {
@@ -621,9 +621,9 @@ void conference_event_adv_layout(conference_obj_t *conference, mcu_canvas_t *can
                cJSON_AddItemToObject(obj, "scale", cJSON_CreateNumber(VIDEO_LAYOUT_SCALE));
                cJSON_AddItemToObject(data, "canvasInfo", obj);
        }
-       
+
+       switch_mutex_unlock(canvas->write_mutex);       
        switch_mutex_unlock(canvas->mutex);
-       switch_thread_rwlock_unlock(canvas->video_rwlock);
 
        switch_event_channel_broadcast(conference->info_event_channel, &msg, "mod_conference", conference_globals.event_channel_id);
 
index 5190f9bb78f182058ac43fffd0b44cf8393ad941..5940c06358d962d6c71bbbc8f10ffd6cce91adaf 100644 (file)
@@ -118,6 +118,8 @@ void conference_utils_set_mflags(const char *flags, member_flag_t *f)
                 f[MFLAG_CAN_BE_SEEN] = 0;
                        } else if (!strcasecmp(argv[i], "deaf")) {
                                f[MFLAG_CAN_HEAR] = 0;
+                       } else if (!strcasecmp(argv[i], "blind")) {
+                               f[MFLAG_CAN_SEE] = 0;
                        } else if (!strcasecmp(argv[i], "mute-detect")) {
                                f[MFLAG_MUTE_DETECT] = 1;
                        } else if (!strcasecmp(argv[i], "dist-dtmf")) {
index 80c648e93e5a79bd3e640b9afe256d1da411f2a7..67b963995ae4cc53938bac784966476fde2dd9b9 100644 (file)
@@ -1033,6 +1033,7 @@ void conference_video_detach_video_layer(conference_member_t *member)
        }
 
        switch_mutex_lock(canvas->mutex);
+       switch_mutex_lock(canvas->write_mutex);
 
        if (member->video_layer_id < 0) {
                goto end;
@@ -1079,6 +1080,7 @@ void conference_video_detach_video_layer(conference_member_t *member)
 
  end:
 
+       switch_mutex_unlock(canvas->write_mutex);
        switch_mutex_unlock(canvas->mutex);
        conference_video_release_canvas(&canvas);
 
@@ -1430,8 +1432,9 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
 
        if (!canvas) return;
 
-       switch_thread_rwlock_wrlock(canvas->video_rwlock);
+
        switch_mutex_lock(canvas->mutex);
+       switch_mutex_lock(canvas->write_mutex);
 
        for (i = 0; i < MCU_MAX_LAYERS; i++) {
                mcu_layer_t *layer = &canvas->layers[i];
@@ -1446,8 +1449,8 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
        }
 
        if (vlayout && canvas->vlayout == vlayout && !force) {
+               switch_mutex_unlock(canvas->write_mutex);
                switch_mutex_unlock(canvas->mutex);
-               switch_thread_rwlock_unlock(canvas->video_rwlock);
                return;
        }
 
@@ -1459,8 +1462,8 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
        }
 
        if (!vlayout) {
+               switch_mutex_unlock(canvas->write_mutex);
                switch_mutex_unlock(canvas->mutex);
-               switch_thread_rwlock_unlock(canvas->video_rwlock);
                return;
        }
 
@@ -1559,8 +1562,8 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
                conference_video_set_canvas_bgimg(canvas, conference->video_canvas_bgimg);
        }
 
+       switch_mutex_unlock(canvas->write_mutex);
        switch_mutex_unlock(canvas->mutex);
-       switch_thread_rwlock_unlock(canvas->video_rwlock);
 
        conference_event_adv_layout(conference, canvas, vlayout);
 
@@ -1662,6 +1665,7 @@ switch_status_t conference_video_init_canvas(conference_obj_t *conference, video
        canvas->conference = conference;
        canvas->pool = conference->pool;
        switch_mutex_init(&canvas->mutex, SWITCH_MUTEX_NESTED, conference->pool);
+       switch_mutex_init(&canvas->write_mutex, SWITCH_MUTEX_NESTED, conference->pool);
        canvas->layout_floor_id = -1;
 
        switch_img_free(&canvas->img);
@@ -1671,7 +1675,6 @@ switch_status_t conference_video_init_canvas(conference_obj_t *conference, video
 
        canvas->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, canvas->width, canvas->height, 0);
        switch_queue_create(&canvas->video_queue, 200, canvas->pool);
-       switch_thread_rwlock_create(&canvas->video_rwlock, canvas->pool);
 
        switch_assert(canvas->img);
 
@@ -2086,20 +2089,18 @@ void *SWITCH_THREAD_FUNC conference_video_layer_thread_run(switch_thread_t *thre
                        break;
                }
 
-               switch_mutex_lock(member->conference->canvas_mutex);
+
                if (member->video_layer_id > -1 && member->canvas_id > -1) {
                        canvas = member->conference->canvases[member->canvas_id];
                        layer = &canvas->layers[member->video_layer_id];
+               }
 
-                       if (layer->need_patch && switch_thread_rwlock_tryrdlock(canvas->video_rwlock) == SWITCH_STATUS_SUCCESS) {
-                               if (layer->need_patch) {
-                                       conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE);
-                                       layer->need_patch = 0;
-                               }
-                               switch_thread_rwlock_unlock(canvas->video_rwlock);
+               if (layer) {
+                       if (layer->need_patch) {
+                               conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE);
+                               layer->need_patch = 0;
                        }
                }
-               switch_mutex_unlock(member->conference->canvas_mutex);
        }
 
        switch_mutex_unlock(member->layer_cond_mutex);
@@ -2474,6 +2475,7 @@ void conference_video_fnode_check(conference_file_node_t *fnode, int canvas_id)
                }
 
                if (full_screen) {
+                       canvas->send_keyframe = 1;
                        if (canvas->play_file == 0) {
                                canvas->play_file = 1;
                        }
@@ -2860,8 +2862,7 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_
 
 static void wait_for_canvas(mcu_canvas_t *canvas)
 {
-       //int q = 0;
-
+       switch_mutex_lock(canvas->write_mutex);
        for (;;) {
                int x = 0;
                int i = 0;
@@ -2872,7 +2873,6 @@ static void wait_for_canvas(mcu_canvas_t *canvas)
                        if (layer->need_patch) {
                                if (layer->member_id && layer->member && conference_utils_member_test_flag(layer->member, MFLAG_RUNNING) && layer->member->fb) {
                                        conference_video_wake_layer_thread(layer->member);
-                                       //printf("BALLZ? %d\n", q++);
                                        x++;
                                } else {
                                        layer->need_patch = 0;
@@ -2882,9 +2882,9 @@ static void wait_for_canvas(mcu_canvas_t *canvas)
 
                if (!x) break;
 
-               switch_thread_rwlock_wrlock(canvas->video_rwlock);
-               switch_thread_rwlock_unlock(canvas->video_rwlock);
+               switch_cond_next();
        }
+       switch_mutex_unlock(canvas->write_mutex);
 }
 
 static void personal_attach(mcu_layer_t *layer, conference_member_t *member)
@@ -3797,7 +3797,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
                                                }
 
                                                if (layer->cur_img) {
-                                                       if (layer->member && switch_core_cpu_count() > 2) {
+                                                       if (layer->member && switch_core_cpu_count() > 200) {
                                                                layer->need_patch = 1;
                                                                conference_video_wake_layer_thread(layer->member);
                                                        } else {
@@ -4767,7 +4767,7 @@ switch_status_t conference_video_thread_callback(switch_core_session_t *session,
 
                if (frame->img && (((member->video_layer_id > -1) && canvas_id > -1) || member->canvas) &&
                        conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) &&
-                       switch_queue_size(member->video_queue) < member->conference->video_fps.fps * 2 &&
+                       switch_queue_size(member->video_queue) < 2 && //member->conference->video_fps.fps * 2 &&
                        !member->conference->canvases[canvas_id]->playing_video_file) {
 
                        if (conference_utils_member_test_flag(member, MFLAG_FLIP_VIDEO) || conference_utils_member_test_flag(member, MFLAG_ROTATE_VIDEO)) {
index 141af9cd31737f3a3e63803c3009555114cc3724..c521e430880c3107dc25e4fe8ca171e3c72b385b 100644 (file)
@@ -554,6 +554,7 @@ typedef struct mcu_canvas_s {
        switch_rgb_color_t border_color;
        switch_rgb_color_t letterbox_bgcolor;
        switch_mutex_t *mutex;
+       switch_mutex_t *write_mutex;
        switch_timer_t timer;
        switch_memory_pool_t *pool;
        video_layout_t *vlayout;
@@ -566,7 +567,6 @@ typedef struct mcu_canvas_s {
        int recording;
        switch_image_t *bgimg;
        switch_image_t *fgimg;
-       switch_thread_rwlock_t *video_rwlock;
        int playing_video_file;
        int overlay_video_file;
        codec_set_t *write_codecs[MAX_MUX_CODECS];
index 6aac0f72a4a255239d63ec6924d1bb4a8abe082d..cb2db9f6b371085e2629a59efe72a97124c81d95 100644 (file)
@@ -6288,7 +6288,7 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
        int buflen = SWITCH_RTP_MAX_BUF_LEN;
        switch_timer_t timer = { 0 };
        int fps;
-       switch_video_read_flag_t read_flags = SVR_FLUSH;
+       switch_video_read_flag_t read_flags = SVR_BLOCK;
        switch_core_session_t *b_session = NULL;
        core_fps_t fps_data = { 0 };
        switch_image_t *last_frame = NULL;
@@ -6344,11 +6344,11 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
                switch_core_timer_next(&timer);
                switch_mutex_lock(v_engine->mh.file_write_mutex);
 
-               if (smh->video_write_fh && smh->video_write_fh->mm.source_fps && smh->video_write_fh->mm.source_fps != fps) {
-                       switch_core_timer_destroy(&timer);
-                       video_get_fps(&fps_data, fps);
-                       switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , fps_data.samples, switch_core_session_get_pool(session));
-               }
+               //if (smh->video_write_fh && smh->video_write_fh->mm.source_fps && smh->video_write_fh->mm.source_fps != fps) {
+               //      switch_core_timer_destroy(&timer);
+               //      video_get_fps(&fps_data, fps);
+               //      switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , fps_data.samples, switch_core_session_get_pool(session));
+               //}
 
                if (smh->video_write_fh && !switch_test_flag(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF)) {
                        wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, read_flags);
index a2cf942af94adac50e47f2c4a91f68d5f2288f72..3aeb5aaaa65ba460aec05690be997f7f7c72d810 100644 (file)
@@ -7512,7 +7512,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
 
        do_continue:
 
-               if (!bytes && !rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER]) {
+               if (!bytes && !rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && !switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
 
                        if (sleep_mss) {
                                switch_yield(sleep_mss);
index db90c1bfa09eae639060dd4b454d3ee80ba9b695..76cc5ad7b1b293823fe8c73c3df9e4b5abc16213 100644 (file)
@@ -329,7 +329,11 @@ static switch_status_t init_decoder(switch_codec_t *codec)
                //      context->decoder_init = 0;
                //}
 
-               cfg.threads = 1;//(switch_core_cpu_count() > 1) ? 2 : 1;
+               //cfg.threads = 1;//(switch_core_cpu_count() > 1) ? 2 : 1;
+
+               cfg.threads = switch_core_cpu_count() / 2;
+               if (cfg.threads > 4) cfg.threads = 4;
+               if (cfg.threads < 1) cfg.threads = 1;
 
                if (!context->is_vp9) { // vp8 only
                        // dec_flags = VPX_CODEC_USE_POSTPROC;
@@ -394,7 +398,7 @@ static switch_status_t init_encoder(switch_codec_t *codec)
 
        }
 
-       sane = switch_calc_bitrate(1920, 1080, 2, 30);
+       sane = switch_calc_bitrate(1920, 1080, 5, 60);
 
        if (context->bandwidth > sane) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_WARNING, "BITRATE TRUNCATED FROM %d TO %d\n", context->bandwidth, sane);
@@ -418,6 +422,7 @@ static switch_status_t init_encoder(switch_codec_t *codec)
        config->g_lag_in_frames = 0;
        config->kf_max_dist = 360;//2000;
        threads = cpus / 2;
+       if (threads > 4) threads = 4;
        if (threads < 1) threads = 1;
        config->g_threads = threads;