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

This commit is contained in:
Anthony Minessale 2015-05-06 14:02:44 -05:00 committed by Michael Jerris
parent 02cac73d37
commit 772665e0fa
4 changed files with 42 additions and 28 deletions

View 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;
}

View 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);
}

View 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) {

View 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) {