]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8749 #resolve #comment please test
authorSeven Du <dujinfang@gmail.com>
Sun, 27 Mar 2016 08:08:40 +0000 (16:08 +0800)
committerSeven Du <dujinfang@gmail.com>
Sun, 27 Mar 2016 08:08:40 +0000 (16:08 +0800)
src/include/switch_types.h
src/mod/applications/mod_av/avformat.c
src/mod/applications/mod_conference/mod_conference.c
src/switch_ivr.c

index fda2d20b2256546c0cb3ea75d893c24acd230128..b8da6759964d53936cc702b28647a5acf5a9717a 100644 (file)
@@ -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
index 31424cd1c939f8313d4b93c182de384b41afbac5..e378f7911f98311955e39d1891783c551cdc1261 100644 (file)
@@ -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;
index 85f749fc78b129322f5460647bcfb32d3aea7aa5..6c630c2a569964b8f6bfb78ff26c55ff3f1fe770 100644 (file)
@@ -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);
index 712e9e15a0bf44584fca65cc281ac17cf8484a3f..0c2af8b9d8c0d3589f4c858a00900f76f1e837fa 100644 (file)
@@ -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);