]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7499 FS-7500: combat black screen disease
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 1 May 2015 20:40:50 +0000 (15:40 -0500)
committerMichael Jerris <mike@jerris.com>
Thu, 28 May 2015 17:47:28 +0000 (12:47 -0500)
src/include/switch_channel.h
src/include/switch_types.h
src/mod/applications/mod_commands/mod_commands.c
src/mod/applications/mod_conference/mod_conference.c
src/mod/codecs/mod_vpx/mod_vpx.c
src/switch_channel.c
src/switch_core_media.c
src/switch_rtp.c

index 3c08d6a22d204949dd29d226491528bc4bf95908..d3267ae122f8072f2907ba7455e0d1e9d15cda21 100644 (file)
@@ -624,6 +624,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(_In_ switch_channe
 
 SWITCH_DECLARE(void) switch_channel_perform_audio_sync(switch_channel_t *channel, const char *file, const char *func, int line);
 #define switch_channel_audio_sync(_c)  switch_channel_perform_audio_sync(_c, __FILE__, __SWITCH_FUNC__, __LINE__)
+SWITCH_DECLARE(void) switch_channel_perform_video_sync(switch_channel_t *channel, const char *file, const char *func, int line);
+#define switch_channel_video_sync(_c)  switch_channel_perform_video_sync(_c, __FILE__, __SWITCH_FUNC__, __LINE__)
 
 SWITCH_DECLARE(void) switch_channel_set_private_flag(switch_channel_t *channel, uint32_t flags);
 SWITCH_DECLARE(void) switch_channel_clear_private_flag(switch_channel_t *channel, uint32_t flags);
index 917638bede214ae1e24238289466b405448b65b8..cec2f605bcf7386cb22964bb6edbbab25f4aea1d 100644 (file)
@@ -1046,6 +1046,7 @@ typedef enum {
        SWITCH_MESSAGE_INDICATE_DISPLAY,
        SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY,
        SWITCH_MESSAGE_INDICATE_AUDIO_SYNC,
+       SWITCH_MESSAGE_INDICATE_VIDEO_SYNC,
        SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA,
        SWITCH_MESSAGE_INDICATE_UUID_CHANGE,
        SWITCH_MESSAGE_INDICATE_SIMPLIFY,
index 53cf75111410360fc5bc0a4ef98262dedd6f1dfb..cae64d20a7f3f9ed686504bb7ca294e591839b2f 100644 (file)
@@ -3935,6 +3935,7 @@ SWITCH_STANDARD_API(uuid_video_refresh_function)
 
                if ((lsession = switch_core_session_locate(argv[0]))) {
                        switch_core_session_video_reinit(lsession);
+                       switch_channel_video_sync(switch_core_session_get_channel(lsession));
                        status = SWITCH_STATUS_SUCCESS;
                        switch_core_session_rwunlock(lsession);
                }
index b262b794f5976408ca1a0e34d83545ef3fb9f960..dcb6580b547a418e10ac00a1a6173396dbbf67b3 100644 (file)
@@ -1806,6 +1806,8 @@ static int flush_video_queue(switch_queue_t *q)
        void *pop;
        int r = 0;
 
+       if (!q) return 0;
+
        while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
                img = (switch_image_t *)pop;
                switch_img_free(&img);
@@ -2000,8 +2002,13 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
                                        }
                                        size = switch_queue_size(imember->video_queue);
                                } while(size > 0);
-                               if (!img) {
+                               if (!img && switch_test_flag(imember, MFLAG_CAN_BE_SEEN)) {
                                        imember->blanks++;
+
+                                       if (imember->blanks == conference->video_fps.fps || (imember->blanks % (int)(conference->video_fps.fps * 10)) == 0) {
+                                               switch_core_session_request_video_refresh(imember->session);
+                                       }
+
                                        if (imember->blanks == conference->video_fps.fps * 2) {
                                                check_avatar(imember, SWITCH_TRUE);
                                                if (layer && imember->avatar_png_img) {
@@ -2015,6 +2022,8 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
                                if (flushed && imember->blanks) {
                                        switch_img_free(&imember->avatar_png_img);
                                        imember->blanks = 0;
+                                       switch_core_session_request_video_refresh(imember->session);
+                                       switch_channel_video_sync(imember->channel);
                                }
                                                
                                img = imember->avatar_png_img;
@@ -4775,7 +4784,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
        if (switch_test_flag(member->conference, CFLAG_VIDEO_MUXING)) {
                switch_image_t *img_copy = NULL;
 
-               if (frame->img && !member->conference->playing_video_file) {
+               if (frame->img && !member->conference->playing_video_file && switch_queue_size(member->video_queue) < 3) {
                        switch_img_copy(frame->img, &img_copy);
                        switch_queue_push(member->video_queue, img_copy);
                }
@@ -8302,6 +8311,8 @@ static switch_status_t conf_api_sub_vmute(conference_member_t *member, switch_st
 
        if (member->channel) {
                switch_channel_set_flag(member->channel, CF_VIDEO_PAUSE_READ);
+               switch_core_session_request_video_refresh(member->session);
+               switch_channel_video_sync(member->channel);
        }
 
        if (!(data) || !strstr((char *) data, "quiet")) {
@@ -8358,6 +8369,8 @@ static switch_status_t conf_api_sub_unvmute(conference_member_t *member, switch_
 
        if (member->channel) {
                switch_channel_clear_flag(member->channel, CF_VIDEO_PAUSE_READ);
+               switch_core_session_request_video_refresh(member->session);
+               switch_channel_video_sync(member->channel);
        }
 
        if (!(data) || !strstr((char *) data, "quiet")) {
index f3eb3034d30bc1341a5abb0bf088c5a029a78d56..1d25acd45e22cd1b59be57ac305f57381172a856 100644 (file)
@@ -772,7 +772,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
        if (context->is_vp9) {
                is_keyframe = IS_VP9_KEY_FRAME(*(unsigned char *)frame->data);
        } else { // vp8
-               is_keyframe = IS_VP8_KEY_FRAME((uint8_t *)frame->data);
+               is_keyframe = (*(unsigned char *)frame->data & 0x10) || IS_VP8_KEY_FRAME((uint8_t *)frame->data);
        }
 
        // if (is_keyframe) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got key %d\n", is_keyframe);
@@ -843,7 +843,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
                err = vpx_codec_decode(decoder, data, (unsigned int)len, NULL, 0);
 
                if (err != VPX_CODEC_OK) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n",
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n",
                                                          len, err, vpx_codec_error(decoder), vpx_codec_error_detail(decoder));
                        switch_goto_status(SWITCH_STATUS_RESTART, end);
                }
@@ -869,9 +869,9 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
 
 end:
 
-       if (status == SWITCH_STATUS_RESTART) {
-               context->need_decoder_reset = 1;
-       }
+       //if (status == SWITCH_STATUS_RESTART) {
+       //      context->need_decoder_reset = 1;
+       //}
 
        if (!frame->img || status == SWITCH_STATUS_RESTART) {
                status = SWITCH_STATUS_MORE_DATA;
index 0c271468dd9b40979466f76bafd3d76e9b67fade..60b3b62b350be4cd00aaa91518a2d001d0e9b903 100644 (file)
@@ -361,6 +361,20 @@ SWITCH_DECLARE(void) switch_channel_perform_audio_sync(switch_channel_t *channel
 }
 
 
+SWITCH_DECLARE(void) switch_channel_perform_video_sync(switch_channel_t *channel, const char *file, const char *func, int line)
+{
+       if (switch_channel_media_up(channel)) {
+               switch_core_session_message_t msg = { 0 };
+               msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_SYNC;
+               msg.from = channel->name;
+               msg._file = file;
+               msg._func = func;
+               msg._line = line;
+               switch_core_session_receive_message(channel->session, &msg);
+       }
+}
+
+
 
 SWITCH_DECLARE(switch_call_cause_t) switch_channel_cause_q850(switch_call_cause_t cause)
 {
index 1cb54a1c06c858f317f78406a9b245e43009da65..87ad91810834b6b28428ea4dc27961895d51fa86 100644 (file)
@@ -8748,6 +8748,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
                }
                goto end;
 
+       case SWITCH_MESSAGE_INDICATE_VIDEO_SYNC:
+               if (switch_rtp_ready(v_engine->rtp_session)) {
+                       switch_rtp_flush(v_engine->rtp_session);
+               }
+               goto end;
+
        case SWITCH_MESSAGE_INDICATE_MEDIA:
                {
 
index 2aadb0323ff00cb73f9244f6ae0dba5fe2ad3e48..6ddeee6c7538dfb9a3d0540fc6f129f8e85648a3 100644 (file)
@@ -4069,9 +4069,7 @@ SWITCH_DECLARE(void) switch_rtp_flush(switch_rtp_t *rtp_session)
                return;
        }
 
-       if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
-               switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH);
-       }
+       switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH);
 }
 
 SWITCH_DECLARE(void) switch_rtp_video_refresh(switch_rtp_t *rtp_session)
@@ -4396,10 +4394,6 @@ SWITCH_DECLARE(void) switch_rtp_clear_flags(switch_rtp_t *rtp_session, switch_rt
 SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag)
 {
 
-       if (flag == SWITCH_RTP_FLAG_FLUSH && rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
-               return;
-       }
-
        switch_mutex_lock(rtp_session->flag_mutex);
        rtp_session->flags[flag] = 1;
        switch_mutex_unlock(rtp_session->flag_mutex);
@@ -4423,7 +4417,11 @@ SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_f
                                }
                        }
                }
+
+
                rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
+
+
                if (rtp_session->jb) {
                        stfu_n_reset(rtp_session->jb);
                }
@@ -4635,7 +4633,6 @@ SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp
 {
 
        if (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] ||
-               rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ||
                rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) {
                return;
        }
@@ -4684,11 +4681,11 @@ static void do_flush(switch_rtp_t *rtp_session, int force)
        if (!switch_rtp_ready(rtp_session)) {
                return;
        }
+
        reset_jitter_seq(rtp_session);
 
        if (!force) {
                if (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || 
-                       rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ||
                        rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] ||
                        rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON]
                        ) {
@@ -4701,14 +4698,22 @@ static void do_flush(switch_rtp_t *rtp_session, int force)
        if (switch_rtp_ready(rtp_session) ) {
 
                if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) {
-                       goto end;
+                       stfu_n_reset(rtp_session->jb);
+               }
+
+               if (rtp_session->vb) {
+                       switch_vb_reset(rtp_session->vb);
+               }
+
+               if (rtp_session->vbw) {
+                       switch_vb_reset(rtp_session->vbw);
                }
 
                if (rtp_session->flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session),
-                                 SWITCH_LOG_CONSOLE, "%s FLUSH\n",
-                                 rtp_session->session ? switch_channel_get_name(switch_core_session_get_channel(rtp_session->session)) : "NoName"
-                                 );
+                                                         SWITCH_LOG_CONSOLE, "%s FLUSH\n",
+                                                         rtp_session->session ? switch_channel_get_name(switch_core_session_get_channel(rtp_session->session)) : "NoName"
+                                                         );
                }
 
                if (!rtp_session->flags[SWITCH_RTP_FLAG_NOBLOCK]) {
@@ -4757,8 +4762,6 @@ static void do_flush(switch_rtp_t *rtp_session, int force)
                }
        }
 
- end:
-
        READ_DEC(rtp_session);
 }
 
@@ -6076,10 +6079,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                check = !bytes;
 
                if (rtp_session->flags[SWITCH_RTP_FLAG_FLUSH]) {
-                       if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
-                               do_flush(rtp_session, SWITCH_FALSE);
-                               bytes = 0;
-                       }
+                       do_flush(rtp_session, SWITCH_FALSE);
+                       bytes = 0;
                        switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH);
                }
                
@@ -6104,7 +6105,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                }
 
                if (bytes && rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->recv_te && 
-                       !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) {
+                       !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] &&
+                       !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) {
                        rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
                }