From 7c13d0b2143a99d099448f9c2cbd2d32a0c6aa39 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 30 May 2017 16:34:48 -0500 Subject: [PATCH] FS-10269: [mod_conference] conference recording pause doesn't work correctly for video #resolve --- src/include/switch_types.h | 4 +- src/mod/applications/mod_av/avformat.c | 41 +++++++++++++++++-- .../mod_conference/conference_record.c | 2 + src/switch_core_file.c | 8 ++++ 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 7084bc587e..69cde7c752 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2621,7 +2621,9 @@ typedef enum { typedef enum { SCFC_FLUSH_AUDIO, - SCFC_PAUSE_READ + SCFC_PAUSE_READ, + SCFC_PAUSE_WRITE, + SCFC_RESUME_WRITE } switch_file_command_t; typedef enum { diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 7aac41fabb..d1645dba46 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -81,6 +81,10 @@ typedef struct record_helper_s { switch_thread_t *video_thread; switch_mm_t *mm; int finalize; + switch_file_handle_t *fh; + int record_timer_offset; + int record_timer_paused; + int record_timer_resumed; } record_helper_t; @@ -802,7 +806,27 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * uint64_t delta_tmp; switch_core_timer_sync(context->eh.timer); - delta_tmp = context->eh.timer->samplecount - last_ts; + + if (context->eh.record_timer_paused) { + continue; + } else if (context->eh.record_timer_resumed) { + context->eh.record_timer_resumed = 0; + + if (delta_avg) { + delta = delta_avg; + } else if (context->eh.mm->fps) { + delta = 1000 / context->eh.mm->fps; + } else { + delta = 33; + } + + context->eh.video_st->frame->pts += delta; + delta_tmp = delta; + context->eh.record_timer_offset = context->eh.timer->samplecount - context->eh.video_st->frame->pts; + context->eh.record_timer_offset = context->eh.record_timer_offset > 0 ? context->eh.record_timer_offset : 0; + } else { + delta_tmp = context->eh.timer->samplecount - last_ts; + } if (delta_tmp != 0) { delta_sum += delta_tmp; @@ -818,7 +842,7 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * delta_avg = (int)(double)(delta_sum / delta_i); } - context->eh.video_st->frame->pts = context->eh.timer->samplecount; + context->eh.video_st->frame->pts = context->eh.timer->samplecount - context->eh.record_timer_offset; } else { context->eh.video_st->frame->pts = (context->eh.timer->samplecount) + 1; } @@ -826,7 +850,6 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * last_ts = context->eh.video_st->frame->pts; - //context->eh.video_st->frame->pts = switch_time_now() / 1000 - context->eh.video_st->next_pts; //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "pts: %ld\n", context->eh.video_st->frame->pts); /* encode the image */ @@ -2098,7 +2121,7 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error encoding audio frame: %d\n", ret); continue; } - + if (got_packet) { if (context->mutex) switch_mutex_lock(context->mutex); ret = write_frame(context->fc, &context->audio_st.st->codec->time_base, context->audio_st.st, &pkt); @@ -2143,6 +2166,16 @@ static switch_status_t av_file_command(switch_file_handle_t *handle, switch_file context->read_paused = SWITCH_TRUE; } break; + case SCFC_PAUSE_WRITE: + context->vid_ready = 0; + context->eh.record_timer_paused = 1; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s pause write\n", handle->file_path); + break; + case SCFC_RESUME_WRITE: + context->eh.record_timer_paused = 0; + context->eh.record_timer_resumed = 1; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s resume write\n", handle->file_path); + break; default: break; } diff --git a/src/mod/applications/mod_conference/conference_record.c b/src/mod/applications/mod_conference/conference_record.c index f7654aaac9..69e854e6eb 100644 --- a/src/mod/applications/mod_conference/conference_record.c +++ b/src/mod/applications/mod_conference/conference_record.c @@ -133,11 +133,13 @@ switch_status_t conference_record_action(conference_obj_t *conference, char *pat case REC_ACTION_PAUSE: conference_utils_member_set_flag_locked(member, MFLAG_PAUSE_RECORDING); switch_set_flag((&member->rec->fh), SWITCH_FILE_PAUSE); + switch_core_file_command(&member->rec->fh, SCFC_PAUSE_WRITE); count = 1; break; case REC_ACTION_RESUME: conference_utils_member_clear_flag_locked(member, MFLAG_PAUSE_RECORDING); switch_clear_flag((&member->rec->fh), SWITCH_FILE_PAUSE); + switch_core_file_command(&member->rec->fh, SCFC_RESUME_WRITE); count = 1; break; } diff --git a/src/switch_core_file.c b/src/switch_core_file.c index aff9442d78..61bb60cd8a 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -533,6 +533,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, return SWITCH_STATUS_FALSE; } + if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) { + return SWITCH_STATUS_SUCCESS; + } + if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) { if (!fh->resampler) { if (switch_resample_create(&fh->resampler, @@ -612,6 +616,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write_video(switch_file_handle_ return SWITCH_STATUS_FALSE; } + if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) { + return SWITCH_STATUS_SUCCESS; + } + return fh->file_interface->file_write_video(fh, frame); }