[FFmpeg-devel] [PATCH] Add ability to pause transcoding via keyboard interaction
Jeremy Luce
jeremyluce at gmail.com
Wed Mar 11 14:34:39 CET 2015
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)
{
More information about the ffmpeg-devel
mailing list