[FFmpeg-devel] [PATCH v4] Title:Fix buffer data lost bug.

453647684 453647684 at qq.com
Sun Aug 2 05:22:31 EEST 2020


Description:
	At arm architechture of Linux system, use ffmpeg to record the screen.
	command:
		ffmpeg -video_size 1920x1080 -framerate 30 -thread_queue_size 512 -f x11grab -i :0+0,0 -c:v libx264 -pix_fmt yuv420p -crf 1 -vf 'scale=trunc(iw/2)*2:trunc(ih/2)*2' out.mp4
	The last few seconds of the recorded video to be lost.

RootCause:After quit, the data in the buffer(thread_queue_size) is not processed.

Solution:After Processing the buffer data, the program really exits.
---
 fftools/ffmpeg.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 2e9448ea2b..9e294d3cab 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -138,6 +138,7 @@ static int nb_frames_drop = 0;
 static int64_t decode_error_stat[2];
 
 static int want_sdp = 1;
+static int ready_quit = 0;
 
 static BenchmarkTimeStamps current_time;
 AVIOContext *progress_avio = NULL;
@@ -4615,8 +4616,12 @@ static int transcode_step(void)
         return 0;
     }
 
-    if (ret < 0)
+    if (ret < 0){
+        if(ready_quit){
+            return ret;
+        }
         return ret == AVERROR_EOF ? 0 : ret;
+    }
 
     return reap_filters(0);
 }
@@ -4653,8 +4658,10 @@ static int transcode(void)
 
         /* if 'q' pressed, exits */
         if (stdin_interaction)
-            if (check_keyboard_interaction(cur_time) < 0)
+            if (check_keyboard_interaction(cur_time) < 0){
+                ready_quit = 1;
                 break;
+            }
 
         /* check if there's any stream where output is still needed */
         if (!need_output()) {
@@ -4671,6 +4678,26 @@ static int transcode(void)
         /* dump report by using the output first video and audio streams */
         print_report(0, timer_start, cur_time);
     }
+
+#if HAVE_THREADS
+    if(ready_quit){
+        int flag = 0;
+        for (i = 0; i < nb_input_files; i++){
+            InputFile *f = input_files[i];
+            if (!f || !f->in_thread_queue){
+                continue;
+            }
+            flag = 1;
+            av_thread_message_queue_set_err_send(f->in_thread_queue, AVERROR_EOF);
+        }
+        while(flag){
+            ret = transcode_step();
+            if (ret < 0 && ret == AVERROR_EOF) {
+                break;
+            }
+        }
+    }
+#endif
 #if HAVE_THREADS
     free_input_threads();
 #endif
-- 
2.20.1



More information about the ffmpeg-devel mailing list