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 <jamr...@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

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

Reply via email to