diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 9df7a71251..4528da03c8 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -168,6 +168,8 @@ typedef struct switch_core_media_params_s { uint32_t video_key_freq; uint32_t video_key_first; + switch_thread_t *video_write_thread; + } switch_core_media_params_t; static inline const char *switch_media_type2str(switch_media_type_t type) diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index c0eb72eb41..c00cf9c9ed 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1104,6 +1104,7 @@ struct av_file_context { int audio_start; int vid_ready; int audio_ready; + int closed; MediaStream video_st; MediaStream audio_st; @@ -1120,6 +1121,7 @@ struct av_file_context { switch_time_t video_start_time; switch_image_t *last_img; int read_fps; + switch_time_t last_vid_push; }; typedef struct av_file_context av_file_context_t; @@ -1250,6 +1252,9 @@ err: return status; } +//#define ALT_WAY +#define AUDIO_BUF_SEC 5 + static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, void *obj) { av_file_context_t *context = (av_file_context_t *) obj; @@ -1257,36 +1262,51 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo int got_data = 0; int error; int sync = 0; + int eof = 0; context->file_read_thread_running = 1; -#define AUDIO_BUF_SEC 5 + while (context->file_read_thread_running && !context->closed) { + int vid_frames = 0; - while (context->file_read_thread_running) { - if (switch_buffer_inuse(context->audio_buffer) > AUDIO_BUF_SEC * context->audio_st.sample_rate * context->audio_st.channels * 2) { - switch_yield(10000); + if (context->has_video) { + vid_frames = switch_queue_size(context->eh.video_queue); + } + + if (switch_buffer_inuse(context->audio_buffer) > AUDIO_BUF_SEC * context->audio_st.sample_rate * context->audio_st.channels * 2 && + (!context->has_video || vid_frames > 5)) { + switch_yield(context->has_video ? 1000 : 10000); continue; } - + av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; if ((error = av_read_frame(context->fc, &pkt)) < 0) { - if (error == AVERROR_EOF) break; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not read frame (error '%s')\n", get_error_text(error)); - break; + if (error == AVERROR_EOF) { + eof = 1; + /* just make sure*/ + pkt.data = NULL; + pkt.size = 0; + pkt.stream_index = context->video_st.st->index; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not read frame (error '%s')\n", get_error_text(error)); + break; + } } // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "stream: %d, pkt size %d\n", pkt.stream_index, pkt.size); if (context->has_video && pkt.stream_index == context->video_st.st->index) { - AVFrame *vframe = av_frame_alloc(); + AVFrame *vframe; switch_image_t *img; if (!sync) { switch_buffer_zero(context->audio_buffer); sync = 1; } + +again: + vframe = av_frame_alloc(); switch_assert(vframe); if ((error = avcodec_decode_video2(context->video_st.st->codec, vframe, &got_data, &pkt)) < 0) { @@ -1305,7 +1325,7 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo // continue; //} - if (got_data && error > 0) { + if (got_data && error >= 0) { // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got picture %dx%d fmt: %d pktpts:%lld pktdts:%lld\n", vframe->width, vframe->height, vframe->format, vframe->pkt_pts, vframe->pkt_dts); if (vframe->format != AV_PIX_FMT_YUV420P) { @@ -1355,14 +1375,38 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo uint64_t *pts = malloc(sizeof(uint64_t)); if (pts) { +#ifdef ALT_WAY + int diff; + int sleep = 66000; +#endif *pts = vframe->pkt_pts; avframe2img(vframe, img); img->user_priv = pts; + +#ifdef ALT_WAY + diff = sleep - (switch_time_now() - context->last_vid_push); + + if (diff > 0 && diff <= sleep) { + switch_core_timer_next(&context->video_timer); + } else { + switch_core_timer_sync(&context->video_timer); + } +#endif + switch_queue_push(context->eh.video_queue, img); + context->last_vid_push = switch_time_now(); } } } av_frame_free(&vframe); + + if (eof) { + if (got_data) { + goto again; // to get all delayed video frames in decoder + } else { + break; + } + } continue; } else if (context->has_audio && pkt.stream_index == context->audio_st.st->index) { AVFrame in_frame = { { 0 } }; @@ -1457,6 +1501,8 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa handle->private_info = context; context->pool = handle->memory_pool; + switch_core_timer_init(&context->video_timer, "soft", 66, 1, context->pool); + context->offset = DFT_RECORD_OFFSET; if (handle->params && (tmp = switch_event_get_header(handle->params, "av_video_offset"))) { context->offset = atoi(tmp); @@ -1634,6 +1680,10 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s uint32_t bytes; int inuse; + if (!switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { + return SWITCH_STATUS_FALSE; + } + if (!context->vid_ready) { return status; } @@ -1726,6 +1776,8 @@ static switch_status_t av_file_close(switch_file_handle_t *handle) av_file_context_t *context = (av_file_context_t *)handle->private_info; switch_status_t status; + context->closed = 1; + if (context->eh.video_queue) { switch_queue_push(context->eh.video_queue, NULL); } @@ -1784,6 +1836,10 @@ static switch_status_t av_file_read(switch_file_handle_t *handle, void *data, si return SWITCH_STATUS_FALSE; } + while (context->has_video && !context->vid_ready && !context->closed) { + switch_yield(1000); + } + switch_mutex_lock(context->mutex); size = switch_buffer_inuse(context->audio_buffer); if (size > *len * context->audio_st.channels * 2) size = *len * context->audio_st.channels * 2; @@ -1808,6 +1864,46 @@ static switch_status_t av_file_read(switch_file_handle_t *handle, void *data, si return *len == 0 ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS; } + +#ifdef ALT_WAY +static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags) +{ + void *pop; + av_file_context_t *context = (av_file_context_t *)handle->private_info; + switch_status_t status; + + + if (!context->has_video || context->closed) return SWITCH_STATUS_FALSE; + + if ((flags & SVR_CHECK)) { + return SWITCH_STATUS_BREAK; + } + + if ((flags & SVR_FLUSH)) { + flush_video_queue(context->eh.video_queue, 1); + } + + if ((flags & SVR_BLOCK)) { + status = switch_queue_pop(context->eh.video_queue, &pop); + } else { + status = switch_queue_trypop(context->eh.video_queue, &pop); + } + + if (status == SWITCH_STATUS_SUCCESS) { + if (!pop) { + return SWITCH_STATUS_FALSE; + } + + context->vid_ready = 1; + + frame->img = (switch_image_t *) pop; + return SWITCH_STATUS_SUCCESS; + } + + return (flags & SVR_FLUSH) ? SWITCH_STATUS_BREAK : status; +} +#else + static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags) { av_file_context_t *context = (av_file_context_t *)handle->private_info; @@ -1815,7 +1911,7 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f MediaStream *mst = &context->video_st; AVStream *st = mst->st; int ticks = 0; - int max_delta = 1 * AV_TIME_BASE; // 1 second + int64_t max_delta = 1 * AV_TIME_BASE; // 1 second switch_status_t status = SWITCH_STATUS_SUCCESS; double fl_to = 0.02; int do_fl = 0; @@ -1829,7 +1925,7 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f fl_to = (1000 / context->read_fps) * 1000; //printf("WTF %d (%f)\n",switch_queue_size(context->eh.video_queue), fl_to); if (flags & SVR_FLUSH) { - max_delta = fl_to * AV_TIME_BASE; + max_delta = fl_to; do_fl = 1; } @@ -1839,10 +1935,19 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f } else if (mst->next_pts && (switch_time_now() - mst->next_pts > -10000)) { frame->img = context->last_img; context->last_img = NULL; + context->vid_ready = 1; return SWITCH_STATUS_SUCCESS; } - if (!(flags & SVR_BLOCK) && !do_fl) return SWITCH_STATUS_BREAK; + if (!(flags & SVR_BLOCK) && !do_fl) { + if (!mst->next_pts) { + frame->img = context->last_img; + context->last_img = NULL; + context->vid_ready = 1; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_BREAK; + } } if (!context->file_read_thread_running && switch_queue_size(context->eh.video_queue) == 0) { @@ -1870,48 +1975,52 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f if (pop && status == SWITCH_STATUS_SUCCESS) { switch_image_t *img = (switch_image_t *)pop; - uint64_t pts; - uint64_t now = switch_time_now(); + int64_t pts; + int64_t now = switch_time_now(); pts = av_rescale_q(*((uint64_t *)img->user_priv), st->time_base, AV_TIME_BASE_Q); + // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "pkt_pts: %lld pts: %lld queue size: %u\n", *((uint64_t *)img->user_priv), pts, switch_queue_size(context->eh.video_queue)); if (!context->video_start_time) { context->video_start_time = now - pts; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "set start time: %" SWITCH_INT64_T_FMT " now: %" SWITCH_INT64_T_FMT " pts: %" SWITCH_INT64_T_FMT "\n", context->video_start_time, now, pts); } if (st->time_base.num == 0) { mst->next_pts = 0; } else { - //uint64_t last_pts = mst->next_pts; + // int64_t last_pts = mst->next_pts; mst->next_pts = context->video_start_time + pts; - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "pts: %" SWITCH_INT64_T_FMT " last_pts: %" SWITCH_INT64_T_FMT " delta: %" SWITCH_INT64_T_FMT " frame_pts: %" SWITCH_INT64_T_FMT " nextpts: %" SWITCH_INT64_T_FMT ", num: %d, den:%d num:%d den:%d sleep: %" SWITCH_INT64_T_FMT "\n", - //pts, last_pts, mst->next_pts - last_pts, *((uint64_t *)img->user_priv), mst->next_pts, st->time_base.num, st->time_base.den, st->codec->time_base.num, st->codec->time_base.den, mst->next_pts - now); + // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "pts: %" SWITCH_INT64_T_FMT " last_pts: %" SWITCH_INT64_T_FMT " delta: %" SWITCH_INT64_T_FMT " frame_pts: %" SWITCH_INT64_T_FMT " nextpts: %" SWITCH_INT64_T_FMT ", num: %d, den:%d num:%d den:%d sleep: %" SWITCH_INT64_T_FMT "\n", + // pts, last_pts, mst->next_pts - last_pts, *((uint64_t *)img->user_priv), mst->next_pts, st->time_base.num, st->time_base.den, st->codec->time_base.num, st->codec->time_base.den, mst->next_pts - now); } - if (pts == 0) mst->next_pts = 0; + if (pts == 0 || context->video_start_time == 0) mst->next_pts = 0; - if ((mst->next_pts && switch_time_now() - mst->next_pts > max_delta)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG3, "picture is too late, off: %" SWITCH_INT64_T_FMT " queue size:%u\n", (int64_t)(switch_time_now() - mst->next_pts), switch_queue_size(context->eh.video_queue)); + if ((mst->next_pts && (now - mst->next_pts) > max_delta)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "picture is too late, off: %" SWITCH_INT64_T_FMT " max delta: %" SWITCH_INT64_T_FMT " queue size:%u\n", (int64_t)(now - mst->next_pts), max_delta, switch_queue_size(context->eh.video_queue)); switch_img_free(&img); max_delta = AV_TIME_BASE; if (switch_queue_size(context->eh.video_queue) > 0) { + // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WTF again\n"); goto again; } else if (!(flags & SVR_BLOCK) && !do_fl) { mst->next_pts = 0; + context->video_start_time = 0; return SWITCH_STATUS_BREAK; } } if ((flags & SVR_BLOCK) || do_fl) { - while (switch_micro_time_now() - mst->next_pts < -10000 / 2) { - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "yield\n"); - switch_yield(10000); + while (switch_micro_time_now() - mst->next_pts < -10000) { + // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "yield, delta=%" SWITCH_INT64_T_FMT "\n", switch_micro_time_now() - mst->next_pts); + switch_yield(1000); } frame->img = img; do_fl = 0; } else { - if (switch_micro_time_now() - mst->next_pts > -10000 / 2) { + if (switch_micro_time_now() - mst->next_pts > -10000) { frame->img = img; } else { context->last_img = img; @@ -1923,8 +2032,13 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f return SWITCH_STATUS_BREAK; } + if (frame->img) { + context->vid_ready = 1; + } + return frame->img ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; } +#endif static switch_status_t av_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame) { @@ -1978,7 +2092,7 @@ static switch_status_t av_file_write_video(switch_file_handle_t *handle, switch_ //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&context->eh.video_thread, thd_attr, video_thread_run, &context->eh, handle->memory_pool); - switch_core_timer_init(&context->video_timer, "soft", 1, 1, context->pool); + switch_core_timer_init(&context->video_timer, "soft", 66, 1, context->pool); switch_buffer_zero(context->audio_buffer); context->audio_st.frame->pts = 0; context->audio_st.next_pts = 0; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 086ec3b9fd..c0acf48212 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -71,6 +71,7 @@ typedef struct core_video_globals_s { int cur_cpu; switch_memory_pool_t *pool; switch_mutex_t *mutex; + uint32_t fps; } core_video_globals_t; static core_video_globals_t video_globals = { 0 }; @@ -229,6 +230,7 @@ struct switch_media_handle_s { time_t vid_started; int ready_loops; + switch_thread_t *video_write_thread; }; static switch_srtp_crypto_suite_t SUITES[CRYPTO_INVALID] = { @@ -1964,7 +1966,7 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t static void check_jb_sync(switch_core_session_t *session) { int32_t jb_sync_msec = 0; - uint32_t fps, frames = 0; + uint32_t fps = 0, frames = 0; uint32_t min_frames = 0; uint32_t max_frames = 0; uint32_t cur_frames = 0; @@ -2037,12 +2039,16 @@ static void check_jb_sync(switch_core_session_t *session) sync_video = 1; } + if (fps) { + video_globals.fps = fps; + } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s %s \"%s\" Sync A/V JB to %dms %u VFrames FPS %u a:%s v:%s\n", switch_core_session_get_uuid(session), switch_channel_get_name(session->channel), switch_channel_get_variable_dup(session->channel, "caller_id_name", SWITCH_FALSE, -1), - jb_sync_msec, frames, fps, sync_audio ? "yes" : "no", sync_video ? "yes" : "no"); + jb_sync_msec, frames, video_globals.fps, sync_audio ? "yes" : "no", sync_video ? "yes" : "no"); if (sync_audio) { check_jb(session, NULL, jb_sync_msec, 0, SWITCH_TRUE); @@ -2163,6 +2169,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session goto end; } + if (status == SWITCH_STATUS_BREAK) { + goto end; + } + if (type == SWITCH_MEDIA_TYPE_VIDEO && engine->read_frame.m) { if (!smh->vid_started) { smh->vid_started = switch_epoch_time_now(NULL); @@ -4955,6 +4965,73 @@ SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_c } +static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void *obj) +{ + switch_core_session_t *session = (switch_core_session_t *) obj; + switch_media_handle_t *smh; + unsigned char *buf = NULL; + switch_frame_t fr = { 0 }; + switch_rtp_engine_t *v_engine; + int buflen = SWITCH_RTP_MAX_BUF_LEN; + switch_timer_t timer = { 0 }; + int fps; + + if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { + return NULL; + } + + if (!(smh = session->media_handle)) { + return NULL; + } + + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; + + + buf = switch_core_session_alloc(session, buflen); + fr.packet = buf; + fr.packetlen = buflen; + fr.data = buf + 12; + fr.buflen = buflen - 12; + switch_core_media_gen_key_frame(session); + + + if (smh->video_write_fh->mm.source_fps) { + fps = (int) smh->video_write_fh->mm.source_fps; + } else { + fps = video_globals.fps; + } + + if (!fps) { + fps = 15; + } + + + switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , 1, switch_core_session_get_pool(session)); + + while (switch_channel_up_nosig(session->channel) && smh->video_write_fh && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) { + switch_status_t wstatus; + + switch_core_timer_next(&timer); + switch_mutex_lock(v_engine->mh.file_mutex); + wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, SVR_BLOCK); + + if (wstatus == SWITCH_STATUS_SUCCESS) { + switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, SVR_FLUSH); + switch_img_free(&fr.img); + } else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) { + smh->video_write_fh = NULL; + } + switch_mutex_unlock(v_engine->mh.file_mutex); + + } + + switch_core_timer_destroy(&timer); + + switch_core_session_rwunlock(session); + + return NULL; +} + SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw) { switch_media_handle_t *smh; @@ -5004,7 +5081,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses } switch_core_media_gen_key_frame(session); + + if (fh) { + switch_threadattr_t *thd_attr = NULL; + + switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&smh->video_write_thread, thd_attr, video_write_thread, session, switch_core_session_get_pool(session)); + } + smh->video_write_fh = fh; + + + if (!fh && smh->video_write_thread) { + switch_status_t st; + switch_thread_join(&st, smh->video_write_thread); + } + + } if (!fh) switch_channel_video_sync(session->channel); @@ -5045,9 +5139,9 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi switch_frame_t *read_frame = NULL; switch_media_handle_t *smh; uint32_t loops = 0, xloops = 0, vloops = 0; + switch_image_t *blank_img = NULL; switch_frame_t fr = { 0 }; unsigned char *buf = NULL; - switch_image_t *blank_img = NULL; switch_rgb_color_t bgcolor; switch_rtp_engine_t *v_engine = NULL; @@ -5139,13 +5233,13 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi } //if (!smh->video_write_fh || !switch_channel_test_flag(channel, CF_VIDEO_READY)) { - status = switch_core_session_read_video_frame(session, &read_frame, smh->video_write_fh ? SWITCH_IO_FLAG_NOBLOCK : SWITCH_IO_FLAG_NONE, 0); - + status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { switch_cond_next(); continue; } - + //if (switch_test_flag(read_frame, SFF_CNG)) { // continue; //} @@ -5167,19 +5261,11 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi fr.buflen = buflen - 12; switch_core_media_gen_key_frame(session); } + if (switch_channel_test_flag(channel, CF_VIDEO_READY)) { switch_mutex_lock(mh->file_mutex); - if (smh->video_write_fh && switch_channel_ready(session->channel) && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) { - switch_status_t wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, 0); - if (wstatus == SWITCH_STATUS_SUCCESS) { - switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, SVR_FLUSH); - switch_img_free(&fr.img); - } else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) { - smh->video_write_fh = NULL; - } - send_blank = 0; - } else if (smh->video_read_fh && switch_test_flag(smh->video_read_fh, SWITCH_FILE_OPEN) && read_frame->img) { + if (smh->video_read_fh && switch_test_flag(smh->video_read_fh, SWITCH_FILE_OPEN) && read_frame->img) { switch_core_file_write_video(smh->video_read_fh, read_frame); send_blank = 0; } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index cd718efa6a..f111b49dca 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5159,7 +5159,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (*bytes) { b = (unsigned char *) &rtp_session->recv_msg; - + /* version 2 probably rtp, zrtp cookie present means zrtp */ rtp_session->has_rtp = (rtp_session->recv_msg.header.version == 2 || ntohl(*(int *)(b+4)) == ZRTP_MAGIC_COOKIE); @@ -6276,11 +6276,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ pt = 20000; } - - if ((io_flags & SWITCH_IO_FLAG_NOBLOCK)) { - pt = 0; - } - if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA]) { pt = 200000; } @@ -6290,6 +6285,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ pt = 0; } } + + if ((io_flags & SWITCH_IO_FLAG_NOBLOCK)) { + pt = 0; + } poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt); @@ -6397,8 +6396,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ ret = -1; goto end; } - - + + if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) && (rtp_session->dtmf_data.out_digit_dur == 0) && !rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { return_cng_frame(); @@ -6506,7 +6505,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ switch_core_timer_sync(&rtp_session->timer); reset_jitter_seq(rtp_session); } - goto recvfrom; } } diff --git a/src/switch_vpx.c b/src/switch_vpx.c index e49fa4c797..c8dfd516b2 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -783,7 +783,7 @@ static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t * context->codec_settings.video.height = height; reset_codec_encoder(codec); frame->flags |= SFF_PICTURE_RESET; - context->need_key_frame = 1; + context->need_key_frame = 3; } @@ -803,7 +803,7 @@ static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t * now = switch_time_now(); - if (context->need_key_frame != 0) { + if (context->need_key_frame > 0) { // force generate a key frame if (!context->last_key_frame || (now - context->last_key_frame) > KEY_FRAME_MIN_FREQ) {