]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7499 FS-7500 FS-7508 FS-7513 trying to improve the video signal decoding under...
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 6 May 2015 19:02:44 +0000 (14:02 -0500)
committerMichael Jerris <mike@jerris.com>
Thu, 28 May 2015 17:47:29 +0000 (12:47 -0500)
src/mod/applications/mod_conference/mod_conference.c
src/mod/codecs/mod_vpx/mod_vpx.c
src/switch_core_media.c
src/switch_rtp.c

index 69c420006f3049d63d131c2c1bbbcd2660e1e786..266417412851af2d6206fd84f2b78f0b0c00b20a 100644 (file)
@@ -1810,13 +1810,13 @@ static int flush_video_queue(switch_queue_t *q)
 
        if (!q) return 0;
 
-       while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
+       while (switch_queue_size(q) > 1 && switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
                img = (switch_image_t *)pop;
                switch_img_free(&img);
                r++;
        }
 
-       return r;
+       return r + switch_queue_size(q);
 }
 
 static void check_avatar(conference_member_t *member, switch_bool_t force)
@@ -1876,7 +1876,6 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
        switch_image_t *write_img = NULL, *file_img = NULL;
        uint32_t timestamp = 0, avatar_layers = 0;
        video_layout_t *vlayout = get_layout(conference);
-       switch_time_t last_refresh_req = 0;
 
        if (!vlayout) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot find layout\n");
@@ -1951,11 +1950,7 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
                        if (switch_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING) && switch_channel_test_flag(imember->channel, CF_VIDEO)) {
                                if (switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) {
                                        switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ);
-                                       
-                                       if (!last_refresh_req || (now - last_refresh_req) > 1000) {
-                                               need_refresh = SWITCH_TRUE;
-                                               last_refresh_req = now;
-                                       }
+                                       need_refresh = SWITCH_TRUE;
                                }
                                
                                if (imember->video_codec_index < 0 && (check_codec = switch_core_session_get_video_write_codec(imember->session))) {
@@ -2011,7 +2006,7 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
                                } while(size > 0);
                                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);
                                        }
@@ -4796,10 +4791,13 @@ 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 && switch_queue_size(member->video_queue) < 3) {
+               
+
+               if (frame->img && !member->conference->playing_video_file && switch_queue_size(member->video_queue) < member->conference->video_fps.fps) {
                        switch_img_copy(frame->img, &img_copy);
                        switch_queue_push(member->video_queue, img_copy);
                }
+
                switch_thread_rwlock_unlock(member->conference->rwlock);
                return SWITCH_STATUS_SUCCESS;
        }
index e6eeb052f7f2e89da22fbff8e9a3379fd3eaa54f..3e6deecdbf3c7ee4eeabdfb7e3db4697c1102ce0 100644 (file)
@@ -39,7 +39,7 @@
 #include <vpx/vp8.h>
 
 #define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE
-#define KEY_FRAME_MIN_FREQ 1000000
+#define KEY_FRAME_MIN_FREQ 250000
 
 
 /*     http://tools.ietf.org/html/draft-ietf-payload-vp8-10
@@ -219,7 +219,8 @@ struct vpx_context {
        int num;
        int partition_index;
        const vpx_codec_cx_pkt_t *pkt;
-       vpx_codec_iter_t iter;
+       vpx_codec_iter_t enc_iter;
+       vpx_codec_iter_t dec_iter;
        uint32_t last_ts;
        switch_time_t last_ms;
        vpx_codec_ctx_t decoder;
@@ -512,7 +513,7 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t
        switch_size_t remaining_bytes = 0;
 
        if (!context->pkt) {
-               if ((context->pkt = vpx_codec_get_cx_data(&context->encoder, &context->iter))) {
+               if ((context->pkt = vpx_codec_get_cx_data(&context->encoder, &context->enc_iter))) {
                        start = 1;
                        if (!context->pbuffer) {
                                switch_buffer_create_partition(context->pool, &context->pbuffer, context->pkt->data.frame.buf, context->pkt->data.frame.sz);
@@ -668,7 +669,7 @@ static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t *
                return SWITCH_STATUS_FALSE;
        }
 
-       context->iter = NULL;
+       context->enc_iter = NULL;
        context->last_ts = frame->timestamp;
        context->last_ms = now;
                
@@ -767,11 +768,12 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
        switch_size_t len;
        vpx_codec_ctx_t *decoder = NULL;
        switch_status_t status = SWITCH_STATUS_SUCCESS;
-       int is_keyframe = 0;
+       int is_start = 0, is_keyframe = 0, get_refresh = 0;
 
        if (context->is_vp9) {
-               is_keyframe = IS_VP9_KEY_FRAME(*(unsigned char *)frame->data);
+               is_start = is_keyframe = IS_VP9_KEY_FRAME(*(unsigned char *)frame->data);
        } else { // vp8
+               is_start = (*(unsigned char *)frame->data & 0x10);
                is_keyframe = IS_VP8_KEY_FRAME((uint8_t *)frame->data);
        }
 
@@ -800,9 +802,12 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
        // context->last_received_timestamp = frame->timestamp;
        context->last_received_complete_picture = frame->m ? SWITCH_TRUE : SWITCH_FALSE;
 
-       if (is_keyframe) {
+       if (is_keyframe || is_start) {
                if (context->got_key_frame <= 0) {
                        context->got_key_frame = 1;
+                       if (!is_keyframe) {
+                               get_refresh = 1;
+                       }
                } else {
                        context->got_key_frame++;
                }
@@ -816,6 +821,11 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
 
        status = context->is_vp9 ? buffer_vp9_packets(context, frame) : buffer_vp8_packets(context, frame);
 
+
+       if (context->dec_iter && (frame->img = (switch_image_t *) vpx_codec_get_frame(decoder, &context->dec_iter))) {
+               switch_goto_status(SWITCH_STATUS_SUCCESS, end);
+       }
+
        //printf("READ buf:%ld got_key:%d st:%d m:%d\n", switch_buffer_inuse(context->vpx_packet_buffer), context->got_key_frame, status, frame->m);
 
        len = switch_buffer_inuse(context->vpx_packet_buffer);
@@ -827,7 +837,6 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
 
        if (status == SWITCH_STATUS_SUCCESS && frame->m && len) {
                uint8_t *data;
-               vpx_codec_iter_t iter = NULL;
                int corrupted = 0;
                int err;
                //int keyframe = 0;
@@ -839,7 +848,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
 
                //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffered: %" SWITCH_SIZE_T_FMT ", key: %d\n", len, keyframe);
 
-
+               context->dec_iter = NULL;
                err = vpx_codec_decode(decoder, data, (unsigned int)len, NULL, 0);
 
                if (err != VPX_CODEC_OK) {
@@ -856,13 +865,14 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
                if (corrupted) {
                        frame->img = NULL;
                } else {
-                       frame->img = (switch_image_t *) vpx_codec_get_frame(decoder, &iter);
+                       frame->img = (switch_image_t *) vpx_codec_get_frame(decoder, &context->dec_iter);
                }
                
                switch_buffer_zero(context->vpx_packet_buffer);
                
                if (!frame->img) {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "VPX invalid packet\n");
+                       context->need_decoder_reset = 1;
+                       context->got_key_frame = 0;
                        status = SWITCH_STATUS_RESTART;
                }
        }
@@ -877,7 +887,7 @@ end:
                status = SWITCH_STATUS_MORE_DATA;
        }
 
-       if (context->got_key_frame <= 0) {
+       if (context->got_key_frame <= 0 || get_refresh) {
                switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
        }
 
index 0fbda36c1bdcccb1c9b7064bcb03773441ff8a77..f1e31752a7c63d80db07af534ff6f323ba42ca86 100644 (file)
@@ -10455,9 +10455,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
                if (switch_test_flag((*frame), SFF_WAIT_KEY_FRAME)) {
                        switch_core_session_request_video_refresh(session);
                        switch_clear_flag((*frame), SFF_WAIT_KEY_FRAME);
-                       *frame = &runtime.dummy_cng_frame;
-                       switch_yield(20000);
-                       return SWITCH_STATUS_SUCCESS;
+
+                       if (!(*frame)->img) {
+                               *frame = &runtime.dummy_cng_frame;
+                               switch_yield(66000);
+                               return SWITCH_STATUS_SUCCESS;
+                       }
                }
 
                if (decode_status == SWITCH_STATUS_MORE_DATA || !(*frame)->img) {
index 24cf12ef525efd76494b56c440e49666bb82312f..9bb4287a69fb103df4c26de32c7c954acb250a37 100644 (file)
@@ -5421,9 +5421,12 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t
        
        if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && (msg->header.type == RTCP_PT_RTPFB || msg->header.type == RTCP_PT_PSFB)) {
                rtcp_ext_msg_t *extp = (rtcp_ext_msg_t *) msg;                  
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "PICKED UP XRTCP type: %d fmt: %d\n", 
-                                                 msg->header.type, extp->header.fmt);
-               
+
+               if (extp->header.fmt != 15) { /* https://code.google.com/p/webrtc/issues/detail?id=4626 */
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "PICKED UP XRTCP type: %d fmt: %d\n", 
+                                                         msg->header.type, extp->header.fmt);
+               }
+
                if (msg->header.type == RTCP_PT_PSFB && (extp->header.fmt == RTCP_PSFB_FIR || extp->header.fmt == RTCP_PSFB_PLI)) {
                        switch_core_media_gen_key_frame(rtp_session->session);
                        if (rtp_session->vbw) {