Resubmitting with [PATCH] tag and unified diff. Adds functionality to pause transcoding with 'p' key and upause with 'u' key over stdin. Pauses in the main transcode loop as well as the input_thread loop.
----------------- diff --git a/ffmpeg.c b/ffmpeg.c index 6604ff0..37b351a 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -120,6 +120,9 @@ const char *const forced_keyframes_const_names[] = { static void do_video_stats(OutputStream *ost, int frame_size); static int64_t getutime(void); static int64_t getmaxrss(void); +static int64_t gettime_relative_minus_pause(void); +static void pause_transcoding(void); +static void unpause_transcoding(void); static int run_as_daemon = 0; static int nb_frames_dup = 0; @@ -146,6 +149,9 @@ int nb_output_files = 0; FilterGraph **filtergraphs; int nb_filtergraphs; +int64_t paused_start = 0; +int64_t paused_time = 0; + #if HAVE_TERMIOS_H /* init terminal so that we can grab keys */ @@ -1447,7 +1453,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti last_time = cur_time; } - oc = output_files[0]->ctx; total_size = avio_size(oc->pb); @@ -3256,18 +3261,38 @@ static OutputStream *choose_output(void) return ost_min; } +static void pause_transcoding(void) +{ + if (!paused_start) + paused_start = av_gettime_relative(); +} + +static void unpause_transcoding(void) +{ + if (paused_start) { + paused_time += av_gettime_relative() - paused_start; + paused_start = 0; + } +} + static int check_keyboard_interaction(int64_t cur_time) { int i, ret, key; static int64_t last_time; - if (received_nb_signals) + if (received_nb_signals) { + unpause_transcoding(); return AVERROR_EXIT; + } /* read_key() returns 0 on EOF */ if(cur_time - last_time >= 100000 && !run_as_daemon){ key = read_key(); last_time = cur_time; }else key = -1; + // Reserve 'u' for unpausing a paused transcode, but allow any key to + // unpause for backward compatibility + if (key == 'u' || key != -1) unpause_transcoding(); + if (key == 'p') pause_transcoding(); if (key == 'q') return AVERROR_EXIT; if (key == '+') av_log_set_level(av_log_get_level()+10); @@ -3346,7 +3371,9 @@ static int check_keyboard_interaction(int64_t cur_time) "C Send/Que command to all matching filters\n" "D cycle through available debug modes\n" "h dump packets/hex press to cycle through the 3 states\n" + "p pause transcoding\n" "q quit\n" + "u unpause transcoding\n" "s Show QP histogram\n" ); } @@ -3361,6 +3388,10 @@ static void *input_thread(void *arg) int ret = 0; while (1) { + if (paused_start) { + av_usleep(1000); // Be more responsive to unpausing than main thread + continue; + } AVPacket pkt; ret = av_read_frame(f->ctx, &pkt); @@ -3778,6 +3809,11 @@ static int transcode_step(void) InputStream *ist; int ret; + if (paused_start) { + av_usleep(10000); + return 0; + } + ost = choose_output(); if (!ost) { if (got_eagain()) { @@ -3838,11 +3874,11 @@ static int transcode(void) #endif while (!received_sigterm) { - int64_t cur_time= av_gettime_relative(); + int64_t cur_time = gettime_relative_minus_pause(); /* if 'q' pressed, exits */ if (stdin_interaction) - if (check_keyboard_interaction(cur_time) < 0) + if (check_keyboard_interaction(av_gettime_relative()) < 0) break; /* check if there's any stream where output is still needed */ @@ -3885,7 +3921,7 @@ static int transcode(void) } /* dump report by using the first video and audio streams */ - print_report(1, timer_start, av_gettime_relative()); + print_report(1, timer_start, gettime_relative_minus_pause()); /* close each encoder */ for (i = 0; i < nb_output_streams; i++) { @@ -3934,6 +3970,11 @@ static int transcode(void) return ret; } +static int64_t gettime_relative_minus_pause(void) +{ + return av_gettime_relative() - paused_time - + (paused_start ? av_gettime_relative() - paused_start : 0); +} static int64_t getutime(void) { _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel