From: Anthony Minessale Date: Wed, 6 May 2015 19:02:44 +0000 (-0500) Subject: FS-7499 FS-7500 FS-7508 FS-7513 trying to improve the video signal decoding under... X-Git-Tag: v1.6.2~614^2~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=772665e0fa2470f95bd225e1dc168fafc336783f;p=thirdparty%2Ffreeswitch.git FS-7499 FS-7500 FS-7508 FS-7513 trying to improve the video signal decoding under stress and get vpx to latch on to a signale sooner --- diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 69c420006f..2664174128 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -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; } diff --git a/src/mod/codecs/mod_vpx/mod_vpx.c b/src/mod/codecs/mod_vpx/mod_vpx.c index e6eeb052f7..3e6deecdbf 100644 --- a/src/mod/codecs/mod_vpx/mod_vpx.c +++ b/src/mod/codecs/mod_vpx/mod_vpx.c @@ -39,7 +39,7 @@ #include #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); } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 0fbda36c1b..f1e31752a7 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -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) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 24cf12ef52..9bb4287a69 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -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) {