[FFmpeg-devel] [PATCH 1/3] ffmpeg: use avformat_init_output to initialize output files

James Almer jamrial at gmail.com
Sun Nov 26 22:51:02 EET 2017


Postpone writing the header until the first output packet is ready to be
written.
This makes sure any stream parameter change that could take place while
processing an input frame will be taken into account when writing the
output file header.

Signed-off-by: James Almer <jamrial at gmail.com>
---
 fftools/ffmpeg.c | 31 ++++++++++++++++++++++++++-----
 fftools/ffmpeg.h |  3 +++
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 0c16e75ab0..07476e88e7 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -700,7 +700,7 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int u
         ost->frame_number++;
     }
 
-    if (!of->header_written) {
+    if (!of->initialized) {
         AVPacket tmp_pkt = {0};
         /* the muxer is not initialized yet, buffer the packet */
         if (!av_fifo_space(ost->muxing_queue)) {
@@ -804,6 +804,17 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int u
               );
     }
 
+    if (!of->header_written) {
+        ret = avformat_write_header(s, &of->opts);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR,
+                   "Could not write header for output file #%d: %s\n",
+                   ost->file_index, av_err2str(ret));
+            exit_program(1);
+        }
+        of->header_written = 1;
+    }
+
     ret = av_interleaved_write_frame(s, pkt);
     if (ret < 0) {
         print_error("av_interleaved_write_frame()", ret);
@@ -2756,7 +2767,7 @@ static void print_sdp(void)
     AVFormatContext **avc;
 
     for (i = 0; i < nb_output_files; i++) {
-        if (!output_files[i]->header_written)
+        if (!output_files[i]->initialized)
             return;
     }
 
@@ -2947,16 +2958,26 @@ static int check_init_output_file(OutputFile *of, int file_index)
 
     of->ctx->interrupt_callback = int_cb;
 
-    ret = avformat_write_header(of->ctx, &of->opts);
+    ret = avformat_init_output(of->ctx, &of->opts);
     if (ret < 0) {
         av_log(NULL, AV_LOG_ERROR,
-               "Could not write header for output file #%d "
+               "Could not initialize output file #%d "
                "(incorrect codec parameters ?): %s\n",
                file_index, av_err2str(ret));
         return ret;
     }
     //assert_avoptions(of->opts);
-    of->header_written = 1;
+    of->initialized = ret;
+    if (!ret) {
+        ret = avformat_write_header(of->ctx, &of->opts);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR,
+                   "Could not write header for output file #%d: %s\n",
+                   file_index, av_err2str(ret));
+            return ret;
+        }
+        of->initialized = of->header_written = 1;
+    }
 
     av_dump_format(of->ctx, file_index, of->ctx->filename, 1);
 
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index e0977e1bf1..c46ffd8b03 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -571,6 +571,9 @@ typedef struct OutputFile {
 
     int shortest;
 
+    // avformat_init_output() has been called for this file
+    int initialized;
+    // avformat_write_header() has been called for this file
     int header_written;
 } OutputFile;
 
-- 
2.15.0



More information about the ffmpeg-devel mailing list