[FFmpeg-devel] [PATCH 10/24] ffmpeg: refactor limiting output file size with -fs

Anton Khirnov anton at khirnov.net
Mon Dec 13 17:20:28 EET 2021


Move the file size checking code to ffmpeg_mux. Stop calling
avio_tell(), which is a potentially heavy operation - use the recently
introduced bytes_written instead.
---
 fftools/ffmpeg.c     |  4 +---
 fftools/ffmpeg.h     |  4 ++--
 fftools/ffmpeg_mux.c | 14 +++++++++++++-
 fftools/ffmpeg_opt.c |  3 +--
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 8a7cab3fab..3ed1201fda 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -3505,10 +3505,8 @@ static int need_output(void)
     for (i = 0; i < nb_output_streams; i++) {
         OutputStream *ost    = output_streams[i];
         OutputFile *of       = output_files[ost->file_index];
-        AVFormatContext *os  = output_files[ost->file_index]->ctx;
 
-        if (ost->finished ||
-            (os->pb && avio_tell(os->pb) >= of->limit_filesize))
+        if (ost->finished || of_finished(of))
             continue;
         if (ost->frame_number >= ost->max_frames) {
             int j;
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 279a99cc48..67ff391334 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -586,7 +586,6 @@ typedef struct OutputFile {
     int ost_index;       /* index of the first stream in output_streams */
     int64_t recording_time;  ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
     int64_t start_time;      ///< start time in microseconds == AV_TIME_BASE units
-    uint64_t limit_filesize; /* filesize limit expressed in bytes */
 
     int shortest;
 } OutputFile;
@@ -687,7 +686,7 @@ int hw_device_setup_for_filter(FilterGraph *fg);
 
 int hwaccel_decode_init(AVCodecContext *avctx);
 
-int of_muxer_init(OutputFile *of);
+int of_muxer_init(OutputFile *of, uint64_t limit_filesize);
 /* open the muxer when all the streams are initialized */
 int of_check_init(OutputFile *of);
 int of_write_trailer(OutputFile *of);
@@ -695,5 +694,6 @@ void of_close(OutputFile **pof);
 
 void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
                      int unqueue);
+int of_finished(OutputFile *of);
 
 #endif /* FFTOOLS_FFMPEG_H */
diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c
index cf85db674e..aba4b563a4 100644
--- a/fftools/ffmpeg_mux.c
+++ b/fftools/ffmpeg_mux.c
@@ -33,6 +33,8 @@
 #include "ffmpeg.h"
 
 struct Muxer {
+    /* filesize limit expressed in bytes */
+    uint64_t limit_filesize;
     int header_written;
 };
 
@@ -336,7 +338,7 @@ void of_close(OutputFile **pof)
     av_freep(pof);
 }
 
-int of_muxer_init(OutputFile *of)
+int of_muxer_init(OutputFile *of, uint64_t limit_filesize)
 {
     Muxer *mux = av_mallocz(sizeof(*mux));
 
@@ -345,5 +347,15 @@ int of_muxer_init(OutputFile *of)
 
     of->mux  = mux;
 
+    mux->limit_filesize = limit_filesize;
+
+    return 0;
+}
+
+int of_finished(OutputFile *of)
+{
+    AVIOContext *pb = of->ctx->pb;
+    if (pb && pb->bytes_written >= of->mux->limit_filesize)
+        return 1;
     return 0;
 }
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 5b42b450f3..09301acb03 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -2287,7 +2287,6 @@ static int open_output_file(OptionsContext *o, const char *filename)
     of->ost_index      = nb_output_streams;
     of->recording_time = o->recording_time;
     of->start_time     = o->start_time;
-    of->limit_filesize = o->limit_filesize;
     of->shortest       = o->shortest;
     av_dict_copy(&of->opts, o->g->format_opts, 0);
 
@@ -2886,7 +2885,7 @@ loop_end:
         exit_program(1);
     }
 
-    err = of_muxer_init(of);
+    err = of_muxer_init(of, o->limit_filesize);
     if (err < 0) {
         av_log(NULL, AV_LOG_FATAL, "Error initializing the muxer\n");
         exit_program(1);
-- 
2.33.0



More information about the ffmpeg-devel mailing list