]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8864 #resolve [Improve video file playback]
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 24 Feb 2016 04:01:38 +0000 (22:01 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 26 Feb 2016 21:28:03 +0000 (15:28 -0600)
src/include/switch_core_media.h
src/mod/applications/mod_av/avformat.c
src/switch_core_media.c
src/switch_rtp.c
src/switch_vpx.c

index 9df7a7125100ec08811d221ad12db0e2cd818d77..4528da03c8ef1edcf15f47dacaa184227d3a97cf 100644 (file)
@@ -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)
index c0eb72eb418c4cc0747ab8cecf5409f35149f0a0..c00cf9c9edf4d52f58e6fcfc99f96fac85131456 100644 (file)
@@ -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;
+
+               if (context->has_video) {
+                       vid_frames = switch_queue_size(context->eh.video_queue);
+               }
 
-       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 (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;
index 086ec3b9fd03ad5a397269cbe860b2e57e992b0e..c0acf48212f21858f344eb244f36642aa1d57dd4 100644 (file)
@@ -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;
                        } 
index cd718efa6a5bf1e2d46c4353f7721758d6f0a71b..f111b49dcab2344e43b5c7206d1c9df78c88a2ed 100644 (file)
@@ -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;
                                        }
                                }
index e49fa4c7979a479e15070c49efb35916e9986493..c8dfd516b288611f55b8a67cb79a93ff73f218c9 100644 (file)
@@ -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) {