PR #25620 opened by Kilian (lusoris) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25620 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25620.patch
Smooth Streaming publishes a fragment even when its header copy fails. `copy_moof` ignores output write and close errors, and `ism_flush` ignores its result, so the fragment is renamed and listed in the manifest with an incomplete `FragmentInfo` file. `copy_moof` now returns the output error after flushing, or the close error if nothing failed earlier. `ism_flush` stops before publishing a fragment whose header could not be copied. Read error handling is unchanged. **Tests** - A sample-free sine/AAC reproducer with `FragmentInfo(audio=0)` symlinked to `/dev/full`: base exited 0, published the fragment and listed it in the manifest. It now exits 228 (ENOSPC), and the fragment is neither published nor listed. A healthy control run still succeeds. - `fate-lavf-ismv` and `fate-api-movenc` pass. FATE has no direct target for this muxer, so the reproducer is the test of the change. This merges cleanly with PR 25475, which adds the same check in `ism_flush`, and with PR 25312. It addresses part of a pre-existing limitation listed in the automated review of PR 25475; it does not change that PR. >From 26f43c140947d9305e7a058fbfa5646a3a93d577 Mon Sep 17 00:00:00 2001 From: lusoris <[email protected]> Date: Fri, 30 Oct 2026 15:28:48 +0100 Subject: [PATCH] avformat/smoothstreamingenc: propagate fragment header errors Failed fragment header writes were ignored, allowing the fragment to be renamed and recorded despite an incomplete header. Preserve read errors, check the output error after flushing, and propagate close errors when no earlier error occurred. Stop flushing before publishing a fragment whose header could not be copied. A sample-free sine/AAC reproducer with FragmentInfo(audio=0) symlinked to /dev/full exited 0 before the fix and published the failed fragment. With the fix it exits nonzero with ENOSPC and leaves that fragment unpublished and absent from the manifest. The healthy control and sample-free fate-lavf-ismv and fate-api-movenc tests pass. Signed-off-by: lusoris <[email protected]> --- libavformat/smoothstreamingenc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 118761bfc0b..62506f3da52 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -468,7 +468,7 @@ static int add_fragment(OutputStream *os, const char *file, const char *infofile static int copy_moof(AVFormatContext *s, const char* infile, const char *outfile, int64_t size) { AVIOContext *in, *out; - int ret = 0; + int ret = 0, err; if ((ret = s->io_open(s, &in, infile, AVIO_FLAG_READ, NULL)) < 0) return ret; if ((ret = s->io_open(s, &out, outfile, AVIO_FLAG_WRITE, NULL)) < 0) { @@ -487,7 +487,11 @@ static int copy_moof(AVFormatContext *s, const char* infile, const char *outfile size -= n; } avio_flush(out); - ff_format_io_close(s, &out); + if (!ret) + ret = out->error; + err = ff_format_io_close(s, &out); + if (!ret) + ret = err; ff_format_io_close(s, &in); return ret; } @@ -542,7 +546,9 @@ static int ism_flush(AVFormatContext *s, int final) snprintf(header_filename, sizeof(header_filename), "%s/FragmentInfo(%s=%"PRIu64")", os->dirname, os->stream_type_tag, start_ts); snprintf(target_filename, sizeof(target_filename), "%s/Fragments(%s=%"PRIu64")", os->dirname, os->stream_type_tag, start_ts); - copy_moof(s, filename, header_filename, moof_size); + ret = copy_moof(s, filename, header_filename, moof_size); + if (ret < 0) + break; ret = ff_rename(filename, target_filename, s); if (ret < 0) break; -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
