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)
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");
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))) {
} 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);
}
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;
}
#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
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;
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);
return SWITCH_STATUS_FALSE;
}
- context->iter = NULL;
+ context->enc_iter = NULL;
context->last_ts = frame->timestamp;
context->last_ms = now;
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);
}
// 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++;
}
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);
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;
//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) {
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;
}
}
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);
}
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) {