Useful where ffmpeg is used by applications that transcode on the fly and
want to provide some throttling (among other things)
From e2f3aa14979675a373a210bd9a028b01a5a0c7eb Mon Sep 17 00:00:00 2001
From: jluce50 <jeremyl...@gmail.com>
Date: Fri, 6 Mar 2015 17:13:40 -0600
Subject: [PATCH 1/4] Add pause/resume via keyboard interaction

---
 ffmpeg.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index 6604ff0..edfd01d 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -120,6 +120,7 @@ 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 int run_as_daemon  = 0;
 static int nb_frames_dup = 0;
@@ -146,6 +147,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 */
@@ -3268,6 +3272,14 @@ static int check_keyboard_interaction(int64_t cur_time)
         last_time = cur_time;
     }else
         key = -1;
+    // if (key == 'u' && paused_start) {
+    if (key != -1 && paused_start) { // Any valid key unpauses (backward compatibility)
+        paused_time += (av_gettime_relative() - paused_start);
+        paused_start = 0;
+    }
+    if (key == 'p' && !paused_start) {
+        paused_start = av_gettime_relative();
+    }
     if (key == 'q')
         return AVERROR_EXIT;
     if (key == '+') av_log_set_level(av_log_get_level()+10);
@@ -3346,7 +3358,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"
                         "s      Show QP histogram\n"
         );
     }
@@ -3778,6 +3792,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,7 +3857,7 @@ static int transcode(void)
 #endif
 
     while (!received_sigterm) {
-        int64_t cur_time= av_gettime_relative();
+        int64_t cur_time = av_gettime_relative();
 
         /* if 'q' pressed, exits */
         if (stdin_interaction)
@@ -3861,7 +3880,7 @@ static int transcode(void)
         }
 
         /* dump report by using the output first video and audio streams */
-        print_report(0, timer_start, cur_time);
+        print_report(0, timer_start, gettime_relative_minus_pause());
     }
 #if HAVE_PTHREADS
     free_input_threads();
@@ -3885,7 +3904,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 +3953,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)
 {
-- 
1.9.1


From 0fb80c6d3df396119d06049f40d552d0f3a81d3b Mon Sep 17 00:00:00 2001
From: jluce50 <jeremyl...@gmail.com>
Date: Sat, 7 Mar 2015 10:03:39 -0600
Subject: [PATCH 2/4] Cleanup for pause/unpause

---
 ffmpeg.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index edfd01d..a505e46 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -1451,7 +1451,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);
@@ -3360,7 +3359,7 @@ static int check_keyboard_interaction(int64_t cur_time)
                         "h      dump packets/hex press to cycle through the 3 states\n"
                         "p      pause transcoding\n"
                         "q      quit\n"
-                        "u      unpause transcoding"
+                        "u      unpause transcoding\n"
                         "s      Show QP histogram\n"
         );
     }
@@ -3857,11 +3856,9 @@ static int transcode(void)
 #endif
 
     while (!received_sigterm) {
-        int64_t cur_time = av_gettime_relative();
-
         /* 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 */
-- 
1.9.1


From 5763c991ea889107ed6f88bdbd4304936d0b7fc8 Mon Sep 17 00:00:00 2001
From: jluce50 <jeremyl...@gmail.com>
Date: Sat, 7 Mar 2015 15:29:40 -0600
Subject: [PATCH 3/4] Cleanup for pause/unpause

---
 ffmpeg.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index a505e46..7e24e6a 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -3271,8 +3271,9 @@ static int check_keyboard_interaction(int64_t cur_time)
         last_time = cur_time;
     }else
         key = -1;
-    // if (key == 'u' && paused_start) {
-    if (key != -1 && paused_start) { // Any valid key unpauses (backward compatibility)
+    // Reserve 'u' for unpausing a paused transcode, but allow any key to
+    // unpause for backward compatibility
+    if ((key == 'u' || key != -1) && paused_start) {
         paused_time += (av_gettime_relative() - paused_start);
         paused_start = 0;
     }
@@ -3856,6 +3857,8 @@ static int transcode(void)
 #endif
 
     while (!received_sigterm) {
+        int64_t cur_time = gettime_relative_minus_pause();
+
         /* if 'q' pressed, exits */
         if (stdin_interaction)
             if (check_keyboard_interaction(av_gettime_relative()) < 0)
@@ -3877,7 +3880,7 @@ static int transcode(void)
         }
 
         /* dump report by using the output first video and audio streams */
-        print_report(0, timer_start, gettime_relative_minus_pause());
+        print_report(0, timer_start, cur_time);
     }
 #if HAVE_PTHREADS
     free_input_threads();
-- 
1.9.1


From 036fededb42e66f1e45c34faa48519896fb56cc1 Mon Sep 17 00:00:00 2001
From: jluce50 <jeremyl...@gmail.com>
Date: Mon, 9 Mar 2015 15:55:14 -0500
Subject: [PATCH 4/4] Add pausing for input threads and some cleanup

---
 ffmpeg.c | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index 7e24e6a..3498dfe 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -121,6 +121,8 @@ 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 pauseTranscoding(void);
+static void unpauseTranscoding(void);
 
 static int run_as_daemon  = 0;
 static int nb_frames_dup = 0;
@@ -3259,12 +3261,28 @@ static OutputStream *choose_output(void)
     return ost_min;
 }
 
+static void pauseTranscoding(void)
+{
+    if (!paused_start)
+        paused_start = av_gettime_relative();
+}
+
+static void unpauseTranscoding(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) {
+        unpauseTranscoding();
         return AVERROR_EXIT;
+    }
     /* read_key() returns 0 on EOF */
     if(cur_time - last_time >= 100000 && !run_as_daemon){
         key =  read_key();
@@ -3273,13 +3291,8 @@ static int check_keyboard_interaction(int64_t cur_time)
         key = -1;
     // Reserve 'u' for unpausing a paused transcode, but allow any key to
     // unpause for backward compatibility
-    if ((key == 'u' || key != -1) && paused_start) {
-        paused_time += (av_gettime_relative() - paused_start);
-        paused_start = 0;
-    }
-    if (key == 'p' && !paused_start) {
-        paused_start = av_gettime_relative();
-    }
+    if (key == 'u' || key != -1) unpauseTranscoding();
+    if (key == 'p') pauseTranscoding();
     if (key == 'q')
         return AVERROR_EXIT;
     if (key == '+') av_log_set_level(av_log_get_level()+10);
@@ -3375,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);
 
-- 
1.9.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to