From 0fa449d573297ba6d6b3eda9d6c09236a0688943 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sun, 27 Mar 2016 16:08:40 +0800 Subject: [PATCH] FS-8749 #resolve #comment please test --- src/include/switch_types.h | 3 +- src/mod/applications/mod_av/avformat.c | 73 +++++++++++++++++-- .../mod_conference/mod_conference.c | 1 + src/switch_ivr.c | 3 + 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index fda2d20b22..b8da675996 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2600,7 +2600,8 @@ typedef enum { } switch_vid_spy_fmt_t; typedef enum { - SCFC_FLUSH_AUDIO + SCFC_FLUSH_AUDIO, + SCFC_PAUSE_READ } switch_file_command_t; SWITCH_END_EXTERN_C diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 31424cd1c9..e378f7911f 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1265,6 +1265,7 @@ struct av_file_context { int read_fps; switch_time_t last_vid_push; int64_t seek_ts; + switch_bool_t read_paused; }; typedef struct av_file_context av_file_context_t; @@ -1434,7 +1435,7 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo // if (context->has_audio) stream_id = context->audio_st.st->index; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "seeking to %" SWITCH_INT64_T_FMT "\n", context->seek_ts); avformat_seek_file(context->fc, stream_id, 0, context->seek_ts, INT64_MAX, 0); - context->seek_ts = -1; + context->seek_ts = -2; context->video_st.next_pts = 0; context->video_start_time = 0; @@ -1964,6 +1965,15 @@ static switch_status_t av_file_command(switch_file_handle_t *handle, switch_file switch_buffer_zero(context->audio_buffer); switch_mutex_unlock(context->mutex); break; + case SCFC_PAUSE_READ: + if (context->read_paused) { + context->read_paused = SWITCH_FALSE; + context->video_st.next_pts = 0; + context->video_start_time = 0; + } else { + context->read_paused = SWITCH_TRUE; + } + break; default: break; } @@ -2138,6 +2148,63 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f do_fl = 1; } + if (!context->file_read_thread_running && switch_queue_size(context->eh.video_queue) == 0) { + return SWITCH_STATUS_FALSE; + } + + if (context->read_paused) { + int sanity = 10; + + if (context->seek_ts == -2) { // just seeked, try read a new img + again1: + status = switch_queue_trypop(context->eh.video_queue, &pop); + if (pop && status == SWITCH_STATUS_SUCCESS) { + context->seek_ts = -1; + switch_img_free(&context->last_img); + context->last_img = (switch_image_t *)pop; + switch_img_copy(context->last_img, &frame->img); + context->vid_ready = 1; + return SWITCH_STATUS_SUCCESS; + } + + if (context->last_img) { // repeat the last img + switch_img_copy(context->last_img, &frame->img); + context->vid_ready = 1; + context->seek_ts = -1; + return SWITCH_STATUS_SUCCESS; + } + + if ((flags & SVR_BLOCK) && sanity-- > 0) { + switch_yield(10000); + goto again1; + } + + return SWITCH_STATUS_BREAK; + } + + if (context->last_img) { // repeat the last img + if ((flags & SVR_BLOCK)) switch_yield(100000); + switch_img_copy(context->last_img, &frame->img); + context->vid_ready = 1; + return SWITCH_STATUS_SUCCESS; + } + + if ((flags & SVR_BLOCK)) { + status = switch_queue_pop(context->eh.video_queue, &pop); + } else { + status = switch_queue_trypop(context->eh.video_queue, &pop); + } + + if (pop && status == SWITCH_STATUS_SUCCESS) { + context->last_img = (switch_image_t *)pop; + switch_img_copy(context->last_img, &frame->img); + context->vid_ready = 1; + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_BREAK; + } + if (context->last_img) { if (mst->next_pts && (switch_time_now() - mst->next_pts > max_delta)) { switch_img_free(&context->last_img); // too late @@ -2159,10 +2226,6 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f } } - if (!context->file_read_thread_running && switch_queue_size(context->eh.video_queue) == 0) { - return SWITCH_STATUS_FALSE; - } - if (st->codec->time_base.num) { ticks = st->parser ? st->parser->repeat_pict + 1 : st->codec->ticks_per_frame; // mst->next_pts += ((int64_t)AV_TIME_BASE * st->codec->time_base.num * ticks) / st->codec->time_base.den; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 85f749fc78..6c630c2a56 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1254,6 +1254,7 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i void conference_fnode_toggle_pause(conference_file_node_t *fnode, switch_stream_handle_t *stream) { if (fnode) { + switch_core_file_command(&fnode->fh, SCFC_PAUSE_READ); if (switch_test_flag(fnode, NFLAG_PAUSE)) { stream->write_function(stream, "+OK Resume\n"); switch_clear_flag(fnode, NFLAG_PAUSE); diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 712e9e15a0..0c2af8b9d8 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -3878,6 +3878,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_process_fh(switch_core_session_t *ses } else { switch_set_flag_locked(fhp, SWITCH_FILE_PAUSE); } + + switch_core_file_command(fhp, SCFC_PAUSE_READ); + return SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(cmd, "stop")) { switch_set_flag_locked(fhp, SWITCH_FILE_DONE);