Message ID | 20171126205104.1064-1-jamrial@gmail.com |
---|---|
State | New |
Headers | show |
On Sun, Nov 26, 2017 at 05:51:02PM -0300, James Almer wrote: > 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@gmail.com> > --- > fftools/ffmpeg.c | 31 ++++++++++++++++++++++++++----- > fftools/ffmpeg.h | 3 +++ > 2 files changed, 29 insertions(+), 5 deletions(-) This changes (generates a file before, does not afterwards) ./ffmpeg -i ~/tickets/5114/test_case.ivf -an -y test.mp4 https://trac.ffmpeg.org/attachment/ticket/5114/test_case.ivf ill see if i can find a failure that is more clear, as this one arguable doesnt produce a very usefull file [...]
On 11/27/2017 6:25 PM, Michael Niedermayer wrote: > On Sun, Nov 26, 2017 at 05:51:02PM -0300, James Almer wrote: >> 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@gmail.com> >> --- >> fftools/ffmpeg.c | 31 ++++++++++++++++++++++++++----- >> fftools/ffmpeg.h | 3 +++ >> 2 files changed, 29 insertions(+), 5 deletions(-) > > This changes (generates a file before, does not afterwards) > ./ffmpeg -i ~/tickets/5114/test_case.ivf -an -y test.mp4 > https://trac.ffmpeg.org/attachment/ticket/5114/test_case.ivf > > ill see if i can find a failure that is more clear, as this one > arguable doesnt produce a very usefull file Note the log message you get after this patch: "Nothing was written into output file 0 (test.mp4), because at least one of its streams received no packets." Before this patch, of->header_written was set to 1 after calling avformat_write_header even if no header was really written (Because of the delayed header code in lavf I'm removing in patch 2), so ffmpeg.c instead of printing the above log would call av_write_trailer() which, again, would trigger the delayed header code in lavf and write the header and the trailer in one go, but no packets in between. After this patch, where we used to call avformat_write_header we're now calling avformat_init_output, so of->header_written is 0 at the time the invalid input data error happens, and as such av_write_trailer is effectively never called.
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;
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@gmail.com> --- fftools/ffmpeg.c | 31 ++++++++++++++++++++++++++----- fftools/ffmpeg.h | 3 +++ 2 files changed, 29 insertions(+), 5 deletions(-)