* [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add segment_write_temp option
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
@ 2025-06-13 5:54 ` softworkz
2025-06-13 20:37 ` Marton Balint
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 02/10] doc/muxers: Add documentation for " softworkz
` (9 subsequent siblings)
10 siblings, 1 reply; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Allows to write segments as temp files (.tmp) which
are renamed on completion.
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 65323ec678..04e973a198 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -121,6 +121,7 @@ typedef struct SegmentContext {
int break_non_keyframes;
int write_empty;
+ int segment_write_temp; ///< write segments as temp files and rename on completion
int use_rename;
char temp_list_filename[1024];
@@ -226,6 +227,15 @@ static int set_segment_filename(AVFormatContext *s)
seg->entry_prefix ? seg->entry_prefix : "",
av_basename(oc->url));
+ // Write segment as a temp file and rename on completion
+ if(seg->segment_write_temp) {
+ av_strlcatf(buf, sizeof(buf), ".tmp");
+ char *temp_name = av_strdup(buf);
+ if (!temp_name)
+ return AVERROR(ENOMEM);
+ ff_format_set_url(oc, temp_name);
+ }
+
return 0;
}
@@ -372,7 +382,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
SegmentListEntry *entry = av_mallocz(sizeof(*entry));
if (!entry) {
ret = AVERROR(ENOMEM);
- goto end;
+ goto fail;
}
/* append new element */
@@ -393,7 +403,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
}
if ((ret = segment_list_open(s)) < 0)
- goto end;
+ goto fail;
for (entry = seg->segment_list_entries; entry; entry = entry->next)
segment_list_print_entry(seg->list_pb, seg->list_type, entry, s);
if (seg->list_type == LIST_TYPE_M3U8 && is_last)
@@ -450,7 +460,20 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
}
}
-end:
+ ff_format_io_close(oc, &oc->pb);
+
+ // Now rename the .tmp file to its actual name.
+ if (seg->segment_write_temp) {
+ char *final_filename = av_strndup(oc->url, strlen(oc->url) - 4);
+ if (!final_filename)
+ return AVERROR(ENOMEM);
+ ret = ff_rename(oc->url, final_filename, s);
+ av_free(final_filename);
+ }
+
+ return ret;
+
+fail:
ff_format_io_close(oc, &oc->pb);
return ret;
@@ -1075,6 +1098,7 @@ static const AVOption options[] = {
{ "reset_timestamps", "reset timestamps at the beginning of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
{ "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
{ "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
+ { "segment_write_temp", "write segments as temp files (.tmp) and rename on completion", OFFSET(segment_write_temp), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
{ NULL },
};
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add segment_write_temp option
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add segment_write_temp option softworkz
@ 2025-06-13 20:37 ` Marton Balint
2025-06-13 21:43 ` softworkz .
0 siblings, 1 reply; 33+ messages in thread
From: Marton Balint @ 2025-06-13 20:37 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Fri, 13 Jun 2025, softworkz wrote:
> From: softworkz <softworkz@hotmail.com>
>
> Allows to write segments as temp files (.tmp) which
> are renamed on completion.
>
> Signed-off-by: softworkz <softworkz@hotmail.com>
> ---
> libavformat/segment.c | 30 +++++++++++++++++++++++++++---
> 1 file changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index 65323ec678..04e973a198 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -121,6 +121,7 @@ typedef struct SegmentContext {
> int break_non_keyframes;
> int write_empty;
>
> + int segment_write_temp; ///< write segments as temp files and rename on completion
> int use_rename;
> char temp_list_filename[1024];
>
> @@ -226,6 +227,15 @@ static int set_segment_filename(AVFormatContext *s)
> seg->entry_prefix ? seg->entry_prefix : "",
> av_basename(oc->url));
>
> + // Write segment as a temp file and rename on completion
> + if(seg->segment_write_temp) {
> + av_strlcatf(buf, sizeof(buf), ".tmp");
> + char *temp_name = av_strdup(buf);
> + if (!temp_name)
> + return AVERROR(ENOMEM);
You should use av_asprintf() directly instead of strlcatf() + av_strdup()
> + ff_format_set_url(oc, temp_name);
> + }
> +
> return 0;
> }
>
> @@ -372,7 +382,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
> SegmentListEntry *entry = av_mallocz(sizeof(*entry));
> if (!entry) {
> ret = AVERROR(ENOMEM);
> - goto end;
> + goto fail;
> }
>
> /* append new element */
> @@ -393,7 +403,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
> }
>
> if ((ret = segment_list_open(s)) < 0)
> - goto end;
> + goto fail;
> for (entry = seg->segment_list_entries; entry; entry = entry->next)
> segment_list_print_entry(seg->list_pb, seg->list_type, entry, s);
> if (seg->list_type == LIST_TYPE_M3U8 && is_last)
> @@ -450,7 +460,20 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
> }
> }
>
> -end:
> + ff_format_io_close(oc, &oc->pb);
> +
> + // Now rename the .tmp file to its actual name.
> + if (seg->segment_write_temp) {
> + char *final_filename = av_strndup(oc->url, strlen(oc->url) - 4);
> + if (!final_filename)
> + return AVERROR(ENOMEM);
goto fail?
> + ret = ff_rename(oc->url, final_filename, s);
> + av_free(final_filename);
> + }
> +
> + return ret;
> +
> +fail:
> ff_format_io_close(oc, &oc->pb);
>
> return ret;
> @@ -1075,6 +1098,7 @@ static const AVOption options[] = {
> { "reset_timestamps", "reset timestamps at the beginning of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
> { "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
> { "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
> + { "segment_write_temp", "write segments as temp files (.tmp) and rename on completion", OFFSET(segment_write_temp), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
> { NULL },
> };
Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add segment_write_temp option
2025-06-13 20:37 ` Marton Balint
@ 2025-06-13 21:43 ` softworkz .
2025-06-13 22:07 ` Marton Balint
0 siblings, 1 reply; 33+ messages in thread
From: softworkz . @ 2025-06-13 21:43 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Hi Marton,
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
> Marton Balint
> Sent: Freitag, 13. Juni 2025 22:38
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add
> segment_write_temp option
>
>
>
> On Fri, 13 Jun 2025, softworkz wrote:
>
> > From: softworkz <softworkz@hotmail.com>
> >
> > Allows to write segments as temp files (.tmp) which
> > are renamed on completion.
> >
> > Signed-off-by: softworkz <softworkz@hotmail.com>
> > ---
> > libavformat/segment.c | 30 +++++++++++++++++++++++++++---
> > 1 file changed, 27 insertions(+), 3 deletions(-)
> >
> > diff --git a/libavformat/segment.c b/libavformat/segment.c
> > index 65323ec678..04e973a198 100644
> > --- a/libavformat/segment.c
> > +++ b/libavformat/segment.c
> > @@ -121,6 +121,7 @@ typedef struct SegmentContext {
> > int break_non_keyframes;
> > int write_empty;
> >
> > + int segment_write_temp; ///< write segments as temp files
> and rename on completion
> > int use_rename;
> > char temp_list_filename[1024];
> >
> > @@ -226,6 +227,15 @@ static int
> set_segment_filename(AVFormatContext *s)
> > seg->entry_prefix ? seg->entry_prefix : "",
> > av_basename(oc->url));
> >
> > + // Write segment as a temp file and rename on completion
> > + if(seg->segment_write_temp) {
> > + av_strlcatf(buf, sizeof(buf), ".tmp");
> > + char *temp_name = av_strdup(buf);
> > + if (!temp_name)
> > + return AVERROR(ENOMEM);
>
> You should use av_asprintf() directly instead of strlcatf() +
> av_strdup()
I could be wrong, but I was thinking that this way is more efficient,
because in the av_strdup case, the size of the needed allocation is
already known, while I would suppose that av_asprintf() needs to
allocate a larger size of memory because it cannot predict the eventual
size after applying all the formats. Am I on a wrong track?
> > + ff_format_set_url(oc, temp_name);
> > + }
> > +
> > return 0;
> > }
> >
> > @@ -372,7 +382,7 @@ static int segment_end(AVFormatContext *s,
> int write_trailer, int is_last)
> > SegmentListEntry *entry = av_mallocz(sizeof(*entry));
> > if (!entry) {
> > ret = AVERROR(ENOMEM);
> > - goto end;
> > + goto fail;
> > }
> >
> > /* append new element */
> > @@ -393,7 +403,7 @@ static int segment_end(AVFormatContext *s,
> int write_trailer, int is_last)
> > }
> >
> > if ((ret = segment_list_open(s)) < 0)
> > - goto end;
> > + goto fail;
> > for (entry = seg->segment_list_entries; entry; entry
> = entry->next)
> > segment_list_print_entry(seg->list_pb, seg-
> >list_type, entry, s);
> > if (seg->list_type == LIST_TYPE_M3U8 && is_last)
> > @@ -450,7 +460,20 @@ static int segment_end(AVFormatContext *s,
> int write_trailer, int is_last)
> > }
> > }
> >
> > -end:
> > + ff_format_io_close(oc, &oc->pb);
> > +
> > + // Now rename the .tmp file to its actual name.
> > + if (seg->segment_write_temp) {
> > + char *final_filename = av_strndup(oc->url, strlen(oc-
> >url) - 4);
> > + if (!final_filename)
> > + return AVERROR(ENOMEM);
>
> goto fail?
At that point, ff_format_io_close(oc, &oc->pb) has
already been called.
Here's the full block (after the patch):
ff_format_io_close(oc, &oc->pb);
// Now rename the .tmp file to its actual name.
if (seg->segment_write_temp) {
char *final_filename = av_strndup(oc->url, strlen(oc->url) - 4);
if (!final_filename)
return AVERROR(ENOMEM);
ret = ff_rename(oc->url, final_filename, s);
av_free(final_filename);
}
return ret;
fail:
ff_format_io_close(oc, &oc->pb);
return ret;
}
Thanks,
sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add segment_write_temp option
2025-06-13 21:43 ` softworkz .
@ 2025-06-13 22:07 ` Marton Balint
2025-06-13 22:26 ` softworkz .
0 siblings, 1 reply; 33+ messages in thread
From: Marton Balint @ 2025-06-13 22:07 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Fri, 13 Jun 2025, softworkz . wrote:
> Hi Marton,
>
>
>> -----Original Message-----
>> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
>> Marton Balint
>> Sent: Freitag, 13. Juni 2025 22:38
>> To: FFmpeg development discussions and patches <ffmpeg-
>> devel@ffmpeg.org>
>> Subject: Re: [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add
>> segment_write_temp option
>>
>>
>>
>> On Fri, 13 Jun 2025, softworkz wrote:
>>
>>> From: softworkz <softworkz@hotmail.com>
>>>
>>> Allows to write segments as temp files (.tmp) which
>>> are renamed on completion.
>>>
>>> Signed-off-by: softworkz <softworkz@hotmail.com>
>>> ---
>>> libavformat/segment.c | 30 +++++++++++++++++++++++++++---
>>> 1 file changed, 27 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/libavformat/segment.c b/libavformat/segment.c
>>> index 65323ec678..04e973a198 100644
>>> --- a/libavformat/segment.c
>>> +++ b/libavformat/segment.c
>>> @@ -121,6 +121,7 @@ typedef struct SegmentContext {
>>> int break_non_keyframes;
>>> int write_empty;
>>>
>>> + int segment_write_temp; ///< write segments as temp files
>> and rename on completion
>>> int use_rename;
>>> char temp_list_filename[1024];
>>>
>>> @@ -226,6 +227,15 @@ static int
>> set_segment_filename(AVFormatContext *s)
>>> seg->entry_prefix ? seg->entry_prefix : "",
>>> av_basename(oc->url));
>>>
>>> + // Write segment as a temp file and rename on completion
>>> + if(seg->segment_write_temp) {
>>> + av_strlcatf(buf, sizeof(buf), ".tmp");
>>> + char *temp_name = av_strdup(buf);
>>> + if (!temp_name)
>>> + return AVERROR(ENOMEM);
>>
>> You should use av_asprintf() directly instead of strlcatf() +
>> av_strdup()
>
> I could be wrong, but I was thinking that this way is more efficient,
> because in the av_strdup case, the size of the needed allocation is
> already known, while I would suppose that av_asprintf() needs to
> allocate a larger size of memory because it cannot predict the eventual
> size after applying all the formats. Am I on a wrong track?
I think it does not matter, this is not performance critical code, so
simplicity/readability is more imporant. Also we should avoid hard coded
path length limits if we can, an by using a static buffer you can hit
that.
>
>
>>> + ff_format_set_url(oc, temp_name);
>>> + }
>>> +
>>> return 0;
>>> }
>>>
>>> @@ -372,7 +382,7 @@ static int segment_end(AVFormatContext *s,
>> int write_trailer, int is_last)
>>> SegmentListEntry *entry = av_mallocz(sizeof(*entry));
>>> if (!entry) {
>>> ret = AVERROR(ENOMEM);
>>> - goto end;
>>> + goto fail;
>>> }
>>>
>>> /* append new element */
>>> @@ -393,7 +403,7 @@ static int segment_end(AVFormatContext *s,
>> int write_trailer, int is_last)
>>> }
>>>
>>> if ((ret = segment_list_open(s)) < 0)
>>> - goto end;
>>> + goto fail;
>>> for (entry = seg->segment_list_entries; entry; entry
>> = entry->next)
>>> segment_list_print_entry(seg->list_pb, seg-
>>> list_type, entry, s);
>>> if (seg->list_type == LIST_TYPE_M3U8 && is_last)
>>> @@ -450,7 +460,20 @@ static int segment_end(AVFormatContext *s,
>> int write_trailer, int is_last)
>>> }
>>> }
>>>
>>> -end:
>>> + ff_format_io_close(oc, &oc->pb);
>>> +
>>> + // Now rename the .tmp file to its actual name.
>>> + if (seg->segment_write_temp) {
>>> + char *final_filename = av_strndup(oc->url, strlen(oc-
>>> url) - 4);
>>> + if (!final_filename)
>>> + return AVERROR(ENOMEM);
>>
>> goto fail?
>
> At that point, ff_format_io_close(oc, &oc->pb) has
> already been called.
Ah, I missed that, OK then.
Thanks,
Marton
>
> Here's the full block (after the patch):
>
>
> ff_format_io_close(oc, &oc->pb);
>
> // Now rename the .tmp file to its actual name.
> if (seg->segment_write_temp) {
> char *final_filename = av_strndup(oc->url, strlen(oc->url) - 4);
> if (!final_filename)
> return AVERROR(ENOMEM);
> ret = ff_rename(oc->url, final_filename, s);
> av_free(final_filename);
> }
>
> return ret;
>
> fail:
> ff_format_io_close(oc, &oc->pb);
>
> return ret;
> }
>
>
> Thanks,
> sw
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add segment_write_temp option
2025-06-13 22:07 ` Marton Balint
@ 2025-06-13 22:26 ` softworkz .
0 siblings, 0 replies; 33+ messages in thread
From: softworkz . @ 2025-06-13 22:26 UTC (permalink / raw)
To: FFmpeg development discussions and patches
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
> Marton Balint
> Sent: Samstag, 14. Juni 2025 00:07
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add
> segment_write_temp option
>
>
>
> On Fri, 13 Jun 2025, softworkz . wrote:
>
> > Hi Marton,
> >
> >
> >> -----Original Message-----
> >> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf
> Of
> >> Marton Balint
> >> Sent: Freitag, 13. Juni 2025 22:38
> >> To: FFmpeg development discussions and patches <ffmpeg-
> >> devel@ffmpeg.org>
> >> Subject: Re: [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add
> >> segment_write_temp option
> >>
> >>
> >>
> >> On Fri, 13 Jun 2025, softworkz wrote:
> >>
> >>> From: softworkz <softworkz@hotmail.com>
> >>>
> >>> Allows to write segments as temp files (.tmp) which
> >>> are renamed on completion.
> >>>
> >>> Signed-off-by: softworkz <softworkz@hotmail.com>
> >>> ---
> >>> libavformat/segment.c | 30 +++++++++++++++++++++++++++---
> >>> 1 file changed, 27 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/libavformat/segment.c b/libavformat/segment.c
> >>> index 65323ec678..04e973a198 100644
> >>> --- a/libavformat/segment.c
> >>> +++ b/libavformat/segment.c
> >>> @@ -121,6 +121,7 @@ typedef struct SegmentContext {
> >>> int break_non_keyframes;
> >>> int write_empty;
> >>>
> >>> + int segment_write_temp; ///< write segments as temp files
> >> and rename on completion
> >>> int use_rename;
> >>> char temp_list_filename[1024];
> >>>
> >>> @@ -226,6 +227,15 @@ static int
> >> set_segment_filename(AVFormatContext *s)
> >>> seg->entry_prefix ? seg->entry_prefix : "",
> >>> av_basename(oc->url));
> >>>
> >>> + // Write segment as a temp file and rename on completion
> >>> + if(seg->segment_write_temp) {
> >>> + av_strlcatf(buf, sizeof(buf), ".tmp");
> >>> + char *temp_name = av_strdup(buf);
> >>> + if (!temp_name)
> >>> + return AVERROR(ENOMEM);
> >>
> >> You should use av_asprintf() directly instead of strlcatf() +
> >> av_strdup()
> >
> > I could be wrong, but I was thinking that this way is more
> efficient,
> > because in the av_strdup case, the size of the needed allocation
> is
> > already known, while I would suppose that av_asprintf() needs to
> > allocate a larger size of memory because it cannot predict the
> eventual
> > size after applying all the formats. Am I on a wrong track?
>
> I think it does not matter, this is not performance critical code,
> so
> simplicity/readability is more imporant. Also we should avoid hard
> coded
> path length limits if we can, an by using a static buffer you can
> hit
> that.
I agree. Yet, the buffer was there already and I just added on to
that. I can change it to an AVBPrint, but it should probably be
a separate commit I suppose?
First the buffer substitution and then my change?
Thanks,
sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 02/10] doc/muxers: Add documentation for segment_write_temp option
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add segment_write_temp option softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments softworkz
` (8 subsequent siblings)
10 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
doc/muxers.texi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 30c95c3d34..6d5c17b4cc 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -3505,6 +3505,11 @@ argument must be a time duration specification, and defaults to 0.
If enabled, write an empty segment if there are no packets during the period a
segment would usually span. Otherwise, the segment will be filled with the next
packet written. Defaults to @code{0}.
+
+@item segment_write_temp @var{1|0}
+Write segments to files with a .tmp extension. Each file is renamed to its
+actual name on completion. This can help to prevent segment files from
+being accessed before they are complete. Disabled by default (@code{0}).
@end table
Make sure to require a closed GOP when encoding and to set the GOP
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 01/10] avformat/segment: Add segment_write_temp option softworkz
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 02/10] doc/muxers: Add documentation for " softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-13 13:42 ` Derek Buitenhuis
2025-06-13 20:44 ` Marton Balint
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 04/10] avformat/segment: Add segment_limit option softworkz
` (7 subsequent siblings)
10 siblings, 2 replies; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Also moves point of log writing to after rename of temp files
and changes log level to INFO. The completion of a segment is
important enough to justify logging at INFO level.
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 04e973a198..608cad0ba4 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -417,8 +417,6 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
}
}
- av_log(s, AV_LOG_VERBOSE, "segment:'%s' count:%d ended\n",
- seg->avf->url, seg->segment_count);
seg->segment_count++;
if (seg->increment_tc) {
@@ -471,6 +469,12 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
av_free(final_filename);
}
+ av_log(s, AV_LOG_INFO, "SegmentComplete=%s:%d Index=%d Start=%f End=%f Duration=%f offset_pts=%s start_pts=%s Frames=%d filename=%s\n",
+ av_get_media_type_string(s->streams[seg->reference_stream_index]->codecpar->codec_type),
+ seg->reference_stream_index, seg->segment_idx, seg->cur_entry.start_time, seg->cur_entry.end_time,
+ seg->cur_entry.end_time - seg->cur_entry.start_time, av_ts2str(seg->cur_entry.offset_pts), av_ts2str(seg->cur_entry.start_pts),
+ seg->segment_frame_count, seg->cur_entry.filename);
+
return ret;
fail:
@@ -994,6 +998,8 @@ calc_times:
if (pkt->dts != AV_NOPTS_VALUE)
pkt->dts += offset;
+ seg->cur_entry.offset_pts = av_rescale_q(offset, st->time_base, AV_TIME_BASE_Q);
+
av_log(s, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments softworkz
@ 2025-06-13 13:42 ` Derek Buitenhuis
2025-06-13 14:03 ` softworkz .
2025-06-13 20:44 ` Marton Balint
1 sibling, 1 reply; 33+ messages in thread
From: Derek Buitenhuis @ 2025-06-13 13:42 UTC (permalink / raw)
To: ffmpeg-devel
On 6/13/2025 6:54 AM, softworkz wrote:
> av_log(s, AV_LOG_INFO, "SegmentComplete=%s:%d Index=%d Start=%f End=%f Duration=%f offset_pts=%s start_pts=%s Frames=%d filename=%s\n",
Should be VERBOSE, not INFO.
- Derek
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments
2025-06-13 13:42 ` Derek Buitenhuis
@ 2025-06-13 14:03 ` softworkz .
0 siblings, 0 replies; 33+ messages in thread
From: softworkz . @ 2025-06-13 14:03 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Hi Derek,
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
> Derek Buitenhuis
> Sent: Freitag, 13. Juni 2025 15:43
> To: ffmpeg-devel@ffmpeg.org
> Subject: Re: [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log
> more detailed information about written segments
>
> On 6/13/2025 6:54 AM, softworkz wrote:
> > av_log(s, AV_LOG_INFO, "SegmentComplete=%s:%d Index=%d
> Start=%f End=%f Duration=%f offset_pts=%s start_pts=%s Frames=%d
> filename=%s\n",
>
> Should be VERBOSE, not INFO.
>
> - Derek
> _______________________________________________
Thanks for looking at it.
I had hoped it might be acceptable to make it INFO, but I don't
want to argue about it. If it's got to be VERBOSE, then I'll
make it so.
Thank you,
sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments softworkz
2025-06-13 13:42 ` Derek Buitenhuis
@ 2025-06-13 20:44 ` Marton Balint
2025-06-13 23:53 ` softworkz .
1 sibling, 1 reply; 33+ messages in thread
From: Marton Balint @ 2025-06-13 20:44 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Fri, 13 Jun 2025, softworkz wrote:
> From: softworkz <softworkz@hotmail.com>
>
> Also moves point of log writing to after rename of temp files
> and changes log level to INFO. The completion of a segment is
> important enough to justify logging at INFO level.
>
> Signed-off-by: softworkz <softworkz@hotmail.com>
> ---
> libavformat/segment.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index 04e973a198..608cad0ba4 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -417,8 +417,6 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
> }
> }
>
> - av_log(s, AV_LOG_VERBOSE, "segment:'%s' count:%d ended\n",
> - seg->avf->url, seg->segment_count);
> seg->segment_count++;
>
> if (seg->increment_tc) {
> @@ -471,6 +469,12 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
> av_free(final_filename);
> }
>
> + av_log(s, AV_LOG_INFO, "SegmentComplete=%s:%d Index=%d Start=%f End=%f Duration=%f offset_pts=%s start_pts=%s Frames=%d filename=%s\n",
> + av_get_media_type_string(s->streams[seg->reference_stream_index]->codecpar->codec_type),
> + seg->reference_stream_index, seg->segment_idx, seg->cur_entry.start_time, seg->cur_entry.end_time,
> + seg->cur_entry.end_time - seg->cur_entry.start_time, av_ts2str(seg->cur_entry.offset_pts), av_ts2str(seg->cur_entry.start_pts),
> + seg->segment_frame_count, seg->cur_entry.filename);
No CamelCase please, follow snake_case as the other similar messages. And
yes, VERBOSE is the proper loglevel for this.
> +
> return ret;
>
> fail:
> @@ -994,6 +998,8 @@ calc_times:
> if (pkt->dts != AV_NOPTS_VALUE)
> pkt->dts += offset;
>
> + seg->cur_entry.offset_pts = av_rescale_q(offset, st->time_base, AV_TIME_BASE_Q);
> +
This line does not belong to this patch, or the patch description is
incomplete.
Thanks,
Marton
> av_log(s, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
> av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
> av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
> --
> ffmpeg-codebot
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments
2025-06-13 20:44 ` Marton Balint
@ 2025-06-13 23:53 ` softworkz .
0 siblings, 0 replies; 33+ messages in thread
From: softworkz . @ 2025-06-13 23:53 UTC (permalink / raw)
To: FFmpeg development discussions and patches
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
> Marton Balint
> Sent: Freitag, 13. Juni 2025 22:45
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log
> more detailed information about written segments
>
>
>
> On Fri, 13 Jun 2025, softworkz wrote:
>
> > From: softworkz <softworkz@hotmail.com>
> >
> > Also moves point of log writing to after rename of temp files
> > and changes log level to INFO. The completion of a segment is
> > important enough to justify logging at INFO level.
> >
> > Signed-off-by: softworkz <softworkz@hotmail.com>
> > ---
> > libavformat/segment.c | 10 ++++++++--
> > 1 file changed, 8 insertions(+), 2 deletions(-)
> >
> > diff --git a/libavformat/segment.c b/libavformat/segment.c
> > index 04e973a198..608cad0ba4 100644
> > --- a/libavformat/segment.c
> > +++ b/libavformat/segment.c
> > @@ -417,8 +417,6 @@ static int segment_end(AVFormatContext *s,
> int write_trailer, int is_last)
> > }
> > }
> >
> > - av_log(s, AV_LOG_VERBOSE, "segment:'%s' count:%d ended\n",
> > - seg->avf->url, seg->segment_count);
> > seg->segment_count++;
> >
> > if (seg->increment_tc) {
> > @@ -471,6 +469,12 @@ static int segment_end(AVFormatContext *s,
> int write_trailer, int is_last)
> > av_free(final_filename);
> > }
> >
> > + av_log(s, AV_LOG_INFO, "SegmentComplete=%s:%d Index=%d
> Start=%f End=%f Duration=%f offset_pts=%s start_pts=%s Frames=%d
> filename=%s\n",
> > + av_get_media_type_string(s->streams[seg-
> >reference_stream_index]->codecpar->codec_type),
> > + seg->reference_stream_index, seg->segment_idx, seg-
> >cur_entry.start_time, seg->cur_entry.end_time,
> > + seg->cur_entry.end_time - seg->cur_entry.start_time,
> av_ts2str(seg->cur_entry.offset_pts), av_ts2str(seg-
> >cur_entry.start_pts),
> > + seg->segment_frame_count, seg->cur_entry.filename);
>
> No CamelCase please, follow snake_case as the other similar
> messages. And
> yes, VERBOSE is the proper loglevel for this.
>
> > +
> > return ret;
> >
> > fail:
> > @@ -994,6 +998,8 @@ calc_times:
> > if (pkt->dts != AV_NOPTS_VALUE)
> > pkt->dts += offset;
> >
> > + seg->cur_entry.offset_pts = av_rescale_q(offset, st-
> >time_base, AV_TIME_BASE_Q);
> > +
>
> This line does not belong to this patch, or the patch description
> is
> incomplete.
The line does belong there. The field it sets (offset_pts) is used
for logging only.
(it had been unused for years and exactly the name that was needed,
a really funny coincidence)
But I'm withdrawing this one anyway.
Thanks a lot,
sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 04/10] avformat/segment: Add segment_limit option
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
` (2 preceding siblings ...)
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 03/10] avformat/segment: Log more detailed information about written segments softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for " softworkz
` (6 subsequent siblings)
10 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Example use case:
Existing segments 0-30 and 70-99, 31-69 need to be created.
This option allows to stop precisely after 69. Otherwise it would
start overwriting segment 70 before stopping via 'q' or break signal.
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 608cad0ba4..15196b6970 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -121,6 +121,8 @@ typedef struct SegmentContext {
int break_non_keyframes;
int write_empty;
+ int segment_limit; ///< max number of segments to create
+
int segment_write_temp; ///< write segments as temp files and rename on completion
int use_rename;
char temp_list_filename[1024];
@@ -366,6 +368,9 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
int i;
int err;
+ if (seg->segment_limit && seg->segment_count >= seg->segment_limit)
+ return 0;
+
if (!oc || !oc->pb)
return AVERROR(EINVAL);
@@ -884,6 +889,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
int64_t usecs;
int64_t wrapped_val;
+ if (seg->segment_limit && seg->segment_count >= seg->segment_limit)
+ return 0;
+
if (!seg->avf || !seg->avf->pb)
return AVERROR(EINVAL);
@@ -958,6 +966,9 @@ calc_times:
if ((ret = segment_end(s, seg->individual_header_trailer, 0)) < 0)
goto fail;
+ if (seg->segment_limit && seg->segment_count >= seg->segment_limit)
+ return 0;
+
if ((ret = segment_start(s, seg->individual_header_trailer)) < 0)
goto fail;
@@ -1105,6 +1116,7 @@ static const AVOption options[] = {
{ "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
{ "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
{ "segment_write_temp", "write segments as temp files (.tmp) and rename on completion", OFFSET(segment_write_temp), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
+ { "segment_limit", "stop output once the specified number of segments has been written", OFFSET(segment_limit), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
{ NULL },
};
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for segment_limit option
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
` (3 preceding siblings ...)
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 04/10] avformat/segment: Add segment_limit option softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-13 20:25 ` Marton Balint
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 06/10] avformat/segment: Fix invalid codecpar extradata_size after copying softworkz
` (5 subsequent siblings)
10 siblings, 1 reply; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
doc/muxers.texi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 6d5c17b4cc..1cca8da1fb 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -3510,6 +3510,13 @@ packet written. Defaults to @code{0}.
Write segments to files with a .tmp extension. Each file is renamed to its
actual name on completion. This can help to prevent segment files from
being accessed before they are complete. Disabled by default (@code{0}).
+
+@item segment_limit @var{number}
+Stops after the specified number of segments has been generated.
+This can be helpful to fill gaps in a range of already generated segments,
+which is difficult to achieve otherwise as it would either cause the last
+segment to be incomplete or to overwrite an existing segment with a partial
+data. Default is @code{0} - no limit.
@end table
Make sure to require a closed GOP when encoding and to set the GOP
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for segment_limit option
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for " softworkz
@ 2025-06-13 20:25 ` Marton Balint
2025-06-13 21:33 ` softworkz .
0 siblings, 1 reply; 33+ messages in thread
From: Marton Balint @ 2025-06-13 20:25 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Fri, 13 Jun 2025, softworkz wrote:
> From: softworkz <softworkz@hotmail.com>
>
> Signed-off-by: softworkz <softworkz@hotmail.com>
> ---
> doc/muxers.texi | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index 6d5c17b4cc..1cca8da1fb 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -3510,6 +3510,13 @@ packet written. Defaults to @code{0}.
> Write segments to files with a .tmp extension. Each file is renamed to its
> actual name on completion. This can help to prevent segment files from
> being accessed before they are complete. Disabled by default (@code{0}).
> +
> +@item segment_limit @var{number}
> +Stops after the specified number of segments has been generated.
> +This can be helpful to fill gaps in a range of already generated segments,
> +which is difficult to achieve otherwise as it would either cause the last
> +segment to be incomplete or to overwrite an existing segment with a partial
> +data. Default is @code{0} - no limit.
You can merge the documentation patch with the feature patch, there is no
need to split.
What is not quite clear is that what is going to happen to the surplus
data at after the last segment? Is it silently dropped? Because that would
be unacceptable IMHO.
Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for segment_limit option
2025-06-13 20:25 ` Marton Balint
@ 2025-06-13 21:33 ` softworkz .
2025-06-13 21:59 ` Marton Balint
0 siblings, 1 reply; 33+ messages in thread
From: softworkz . @ 2025-06-13 21:33 UTC (permalink / raw)
To: FFmpeg development discussions and patches
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
> Marton Balint
> Sent: Freitag, 13. Juni 2025 22:26
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add
> documentation for segment_limit option
>
>
>
> On Fri, 13 Jun 2025, softworkz wrote:
>
> > From: softworkz <softworkz@hotmail.com>
> >
> > Signed-off-by: softworkz <softworkz@hotmail.com>
> > ---
> > doc/muxers.texi | 7 +++++++
> > 1 file changed, 7 insertions(+)
> >
> > diff --git a/doc/muxers.texi b/doc/muxers.texi
> > index 6d5c17b4cc..1cca8da1fb 100644
> > --- a/doc/muxers.texi
> > +++ b/doc/muxers.texi
> > @@ -3510,6 +3510,13 @@ packet written. Defaults to @code{0}.
> > Write segments to files with a .tmp extension. Each file is
> renamed to its
> > actual name on completion. This can help to prevent segment files
> from
> > being accessed before they are complete. Disabled by default
> (@code{0}).
> > +
> > +@item segment_limit @var{number}
> > +Stops after the specified number of segments has been generated.
> > +This can be helpful to fill gaps in a range of already generated
> segments,
> > +which is difficult to achieve otherwise as it would either cause
> the last
> > +segment to be incomplete or to overwrite an existing segment
> with a partial
> > +data. Default is @code{0} - no limit.
Hi Marton,
thanks a lot for reviewing.
> You can merge the documentation patch with the feature patch, there
> is no
> need to split.
Sure, will do that - I just never know which way is right.
> What is not quite clear is that what is going to happen to the
> surplus
> data at after the last segment? Is it silently dropped? Because
> that would be unacceptable IMHO.
Well, that's the whole point of the feature. FFmpeg will stop as
soon as the specified number of segments has been generated.
(Please note, that the default is 0, which means that nothing is
dropped and there's no change in behavior when it's 0).
Probably it's best to look at an example. Let's say we have:
- a 300s video
- that we want to stream via HLS
- Segment-Duration: 3s - makes 100 segments
- Now we want to create the segments on-demand only,
so we deliver a synthetic playlist with 100 3s segments,
even though we don't have any segment yet
- Once specific segments are needed, we create them on-the-fly
That's a situation that the commit message is about:
Existing segments 0-30 and 70-99 => we already have them on disk
31-69 need to be created
This option allows to stop precisely after 69.
Otherwise, it would start overwriting segment 70 before stopping
via 'q' or break signal.
So, in order to generate segments 31-69, you will set
segment_start_number to 31 and the segment_limit to 38.
This causes the muxer to write and complete segment 69
in the exact same way like when it would be creating segment
70, but without starting to write segment 70 - which would destroy
the existing segment 70 (which is good already).
Thanks and best regards,
sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for segment_limit option
2025-06-13 21:33 ` softworkz .
@ 2025-06-13 21:59 ` Marton Balint
2025-06-13 22:49 ` softworkz .
0 siblings, 1 reply; 33+ messages in thread
From: Marton Balint @ 2025-06-13 21:59 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Fri, 13 Jun 2025, softworkz . wrote:
>
>> -----Original Message-----
>> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
>> Marton Balint
>> Sent: Freitag, 13. Juni 2025 22:26
>> To: FFmpeg development discussions and patches <ffmpeg-
>> devel@ffmpeg.org>
>> Subject: Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add
>> documentation for segment_limit option
>>
>>
>>
>> On Fri, 13 Jun 2025, softworkz wrote:
>>
>>> From: softworkz <softworkz@hotmail.com>
>>>
>>> Signed-off-by: softworkz <softworkz@hotmail.com>
>>> ---
>>> doc/muxers.texi | 7 +++++++
>>> 1 file changed, 7 insertions(+)
>>>
>>> diff --git a/doc/muxers.texi b/doc/muxers.texi
>>> index 6d5c17b4cc..1cca8da1fb 100644
>>> --- a/doc/muxers.texi
>>> +++ b/doc/muxers.texi
>>> @@ -3510,6 +3510,13 @@ packet written. Defaults to @code{0}.
>>> Write segments to files with a .tmp extension. Each file is
>> renamed to its
>>> actual name on completion. This can help to prevent segment files
>> from
>>> being accessed before they are complete. Disabled by default
>> (@code{0}).
>>> +
>>> +@item segment_limit @var{number}
>>> +Stops after the specified number of segments has been generated.
>>> +This can be helpful to fill gaps in a range of already generated
>> segments,
>>> +which is difficult to achieve otherwise as it would either cause
>> the last
>>> +segment to be incomplete or to overwrite an existing segment
>> with a partial
>>> +data. Default is @code{0} - no limit.
>
> Hi Marton,
>
> thanks a lot for reviewing.
>
>> You can merge the documentation patch with the feature patch, there
>> is no
>> need to split.
>
> Sure, will do that - I just never know which way is right.
>
>
>> What is not quite clear is that what is going to happen to the
>> surplus
>> data at after the last segment? Is it silently dropped? Because
>> that would be unacceptable IMHO.
>
> Well, that's the whole point of the feature. FFmpeg will stop as
> soon as the specified number of segments has been generated.
As far as I understand ffmpeg will not stop, but will keep reading on the
input till the end of the source file, gigabytes worst case. Or am I
missing something?
>
> (Please note, that the default is 0, which means that nothing is
> dropped and there's no change in behavior when it's 0).
>
> Probably it's best to look at an example. Let's say we have:
>
> - a 300s video
> - that we want to stream via HLS
> - Segment-Duration: 3s - makes 100 segments
> - Now we want to create the segments on-demand only,
> so we deliver a synthetic playlist with 100 3s segments,
> even though we don't have any segment yet
> - Once specific segments are needed, we create them on-the-fly
>
> That's a situation that the commit message is about:
>
> Existing segments 0-30 and 70-99 => we already have them on disk
>
> 31-69 need to be created
>
> This option allows to stop precisely after 69.
> Otherwise, it would start overwriting segment 70 before stopping
> via 'q' or break signal.
>
> So, in order to generate segments 31-69, you will set
> segment_start_number to 31 and the segment_limit to 38.
> This causes the muxer to write and complete segment 69
> in the exact same way like when it would be creating segment
> 70, but without starting to write segment 70 - which would destroy
> the existing segment 70 (which is good already).
Buy you have to seek in the input to achieve that, don't you? And you can
just as easily specify the input duration to not overwrite segment 70...
If you want to implement the segment limit, you have to make sure the
ffmpeg encoding process stops after the last segment. One idea is to
return an error if the segment limit is reached.
Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for segment_limit option
2025-06-13 21:59 ` Marton Balint
@ 2025-06-13 22:49 ` softworkz .
2025-06-14 15:59 ` Marton Balint
0 siblings, 1 reply; 33+ messages in thread
From: softworkz . @ 2025-06-13 22:49 UTC (permalink / raw)
To: FFmpeg development discussions and patches
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
> Marton Balint
> Sent: Samstag, 14. Juni 2025 00:00
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add
> documentation for segment_limit option
>
>
>
> On Fri, 13 Jun 2025, softworkz . wrote:
>
> >
> >> -----Original Message-----
> >> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf
> Of
> >> Marton Balint
> >> Sent: Freitag, 13. Juni 2025 22:26
> >> To: FFmpeg development discussions and patches <ffmpeg-
> >> devel@ffmpeg.org>
> >> Subject: Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add
> >> documentation for segment_limit option
> >>
> >>
> >>
> >> On Fri, 13 Jun 2025, softworkz wrote:
> >>
> >>> From: softworkz <softworkz@hotmail.com>
> >>>
> >>> Signed-off-by: softworkz <softworkz@hotmail.com>
> >>> ---
> >>> doc/muxers.texi | 7 +++++++
> >>> 1 file changed, 7 insertions(+)
> >>>
> >>> diff --git a/doc/muxers.texi b/doc/muxers.texi
> >>> index 6d5c17b4cc..1cca8da1fb 100644
> >>> --- a/doc/muxers.texi
> >>> +++ b/doc/muxers.texi
> >>> @@ -3510,6 +3510,13 @@ packet written. Defaults to @code{0}.
> >>> Write segments to files with a .tmp extension. Each file is
> >> renamed to its
> >>> actual name on completion. This can help to prevent segment
> files
> >> from
> >>> being accessed before they are complete. Disabled by default
> >> (@code{0}).
> >>> +
> >>> +@item segment_limit @var{number}
> >>> +Stops after the specified number of segments has been
> generated.
> >>> +This can be helpful to fill gaps in a range of already
> generated
> >> segments,
> >>> +which is difficult to achieve otherwise as it would either
> cause
> >> the last
> >>> +segment to be incomplete or to overwrite an existing segment
> >> with a partial
> >>> +data. Default is @code{0} - no limit.
> >
> > Hi Marton,
> >
> > thanks a lot for reviewing.
> >
> >> You can merge the documentation patch with the feature patch,
> there
> >> is no
> >> need to split.
> >
> > Sure, will do that - I just never know which way is right.
> >
> >
> >> What is not quite clear is that what is going to happen to the
> >> surplus
> >> data at after the last segment? Is it silently dropped? Because
> >> that would be unacceptable IMHO.
> >
> > Well, that's the whole point of the feature. FFmpeg will stop as
> > soon as the specified number of segments has been generated.
>
> As far as I understand ffmpeg will not stop, but will keep reading
> on the
> input till the end of the source file, gigabytes worst case. Or am
> I
> missing something?
Ah you are right! It's been a while since I had been dealing with the
use cases. The reason why I said that "it stops" is because we're
additionally setting an end time ('-to') which is slightly after the
end of the last segment to generate.
> > (Please note, that the default is 0, which means that nothing is
> > dropped and there's no change in behavior when it's 0).
> >
> > Probably it's best to look at an example. Let's say we have:
> >
> > - a 300s video
> > - that we want to stream via HLS
> > - Segment-Duration: 3s - makes 100 segments
> > - Now we want to create the segments on-demand only,
> > so we deliver a synthetic playlist with 100 3s segments,
> > even though we don't have any segment yet
> > - Once specific segments are needed, we create them on-the-fly
> >
> > That's a situation that the commit message is about:
> >
> > Existing segments 0-30 and 70-99 => we already have them on disk
> >
> > 31-69 need to be created
> >
> > This option allows to stop precisely after 69.
> > Otherwise, it would start overwriting segment 70 before stopping
> > via 'q' or break signal.
> >
> > So, in order to generate segments 31-69, you will set
> > segment_start_number to 31 and the segment_limit to 38.
> > This causes the muxer to write and complete segment 69
> > in the exact same way like when it would be creating segment
> > 70, but without starting to write segment 70 - which would
> destroy
> > the existing segment 70 (which is good already).
>
> Buy you have to seek in the input to achieve that, don't you? And
> you can
> just as easily specify the input duration to not overwrite segment
> 70...
Here we're getting at the core of the problem: When specifying -to or
a duration, you cannot achieve the exact same "cut" like the segment
muxer does it. It usually cuts by video key frames. And when it does
the cut it also cuts all other streams at that moment. Timestamp
offsets between video and audio are common, often the audio is
somewhat ahead of the video (specifically in case of TV broadcast
streams), but it varies. Also, when transcoding before segmenting,
it's not easy to predict the exact video key frame times.
For each segment n to segment n+1 the cut must be done in a way
that for each stream, there is neither a duplicate nor a missing
frame. That is what makes it non-trivial.
In the end, it always comes down to the same conclusion: the only
way to get the exact same cut point through all streams like the
segment muxer does it - is to let the segment muxer do it.
At least that was my conclusion from intensive work on this, some
years ago.
> If you want to implement the segment limit, you have to make sure
> the
> ffmpeg encoding process stops after the last segment. One idea is
> to
> return an error if the segment limit is reached.
Maybe an EOF/EOS error?
Thanks,
sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for segment_limit option
2025-06-13 22:49 ` softworkz .
@ 2025-06-14 15:59 ` Marton Balint
0 siblings, 0 replies; 33+ messages in thread
From: Marton Balint @ 2025-06-14 15:59 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Fri, 13 Jun 2025, softworkz . wrote:
[...]
>>> (Please note, that the default is 0, which means that nothing is
>>> dropped and there's no change in behavior when it's 0).
>>>
>>> Probably it's best to look at an example. Let's say we have:
>>>
>>> - a 300s video
>>> - that we want to stream via HLS
>>> - Segment-Duration: 3s - makes 100 segments
>>> - Now we want to create the segments on-demand only,
>>> so we deliver a synthetic playlist with 100 3s segments,
>>> even though we don't have any segment yet
>>> - Once specific segments are needed, we create them on-the-fly
>>>
>>> That's a situation that the commit message is about:
>>>
>>> Existing segments 0-30 and 70-99 => we already have them on disk
>>>
>>> 31-69 need to be created
>>>
>>> This option allows to stop precisely after 69.
>>> Otherwise, it would start overwriting segment 70 before stopping
>>> via 'q' or break signal.
>>>
>>> So, in order to generate segments 31-69, you will set
>>> segment_start_number to 31 and the segment_limit to 38.
>>> This causes the muxer to write and complete segment 69
>>> in the exact same way like when it would be creating segment
>>> 70, but without starting to write segment 70 - which would
>> destroy
>>> the existing segment 70 (which is good already).
>>
>> Buy you have to seek in the input to achieve that, don't you? And
>> you can
>> just as easily specify the input duration to not overwrite segment
>> 70...
>
> Here we're getting at the core of the problem: When specifying -to or
> a duration, you cannot achieve the exact same "cut" like the segment
> muxer does it. It usually cuts by video key frames. And when it does
> the cut it also cuts all other streams at that moment. Timestamp
> offsets between video and audio are common, often the audio is
> somewhat ahead of the video (specifically in case of TV broadcast
> streams), but it varies. Also, when transcoding before segmenting,
> it's not easy to predict the exact video key frame times.
>
> For each segment n to segment n+1 the cut must be done in a way
> that for each stream, there is neither a duplicate nor a missing
> frame. That is what makes it non-trivial.
>
> In the end, it always comes down to the same conclusion: the only
> way to get the exact same cut point through all streams like the
> segment muxer does it - is to let the segment muxer do it.
>
> At least that was my conclusion from intensive work on this, some
> years ago.
But this is also a problem for the first segment. You can set
segment_start_number to 31, but you still have to know where to seek
exactly, because setting segment_start_number alone won't make the segment
muxer "ignore" data for the first 30 segments...
So what does not make sense to me is that you want to rely on segment
muxer behaviour for ending the segments, but not for starting them. The
way I see it you either know exactly where the segments supposed to start
and end, in which case you don't really need this option, because you
can set -ss and -to as you need. Or you don't, in which case this option
alone won't help you.
>
>
>
>> If you want to implement the segment limit, you have to make sure
>> the
>> ffmpeg encoding process stops after the last segment. One idea is
>> to
>> return an error if the segment limit is reached.
>
> Maybe an EOF/EOS error?
I am not sure if it is legal for a muxer to return AVERROR_EOF... Maybe
I'd simply return AVERROR_INVALIDDATA.
Another possibility is that if you limit the number of segments, then you
make all remaining data go to the last segment. I don't know if that
helps or hurts any actual use case :)
Regards,
Marton
>
>
> Thanks,
> sw
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 06/10] avformat/segment: Fix invalid codecpar extradata_size after copying
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
` (4 preceding siblings ...)
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 05/10] doc/muxers: Add documentation for " softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-13 6:03 ` softworkz .
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 07/10] avformat/segment: Remove non-negative constraint from segment_time_delta softworkz
` (4 subsequent siblings)
10 siblings, 1 reply; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 15196b6970..70ff01b353 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -905,6 +905,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
goto calc_times;
}
memcpy(st->codecpar->extradata, pkt_extradata, pkt_extradata_size);
+ st->codecpar->extradata_size = pkt_extradata_size;
}
}
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH 06/10] avformat/segment: Fix invalid codecpar extradata_size after copying
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 06/10] avformat/segment: Fix invalid codecpar extradata_size after copying softworkz
@ 2025-06-13 6:03 ` softworkz .
0 siblings, 0 replies; 33+ messages in thread
From: softworkz . @ 2025-06-13 6:03 UTC (permalink / raw)
To: softworkz, ffmpeg-devel
> -----Original Message-----
> From: softworkz <ffmpegagent@gmail.com>
> Sent: Freitag, 13. Juni 2025 07:54
> To: ffmpeg-devel@ffmpeg.org
> Cc: softworkz <softworkz@hotmail.com>; softworkz
> <softworkz@hotmail.com>
> Subject: [PATCH 06/10] avformat/segment: Fix invalid codecpar
> extradata_size after copying
>
> From: softworkz <softworkz@hotmail.com>
>
> Signed-off-by: softworkz <softworkz@hotmail.com>
> ---
> libavformat/segment.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index 15196b6970..70ff01b353 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -905,6 +905,7 @@ static int seg_write_packet(AVFormatContext *s,
> AVPacket *pkt)
> goto calc_times;
> }
> memcpy(st->codecpar->extradata, pkt_extradata,
> pkt_extradata_size);
> + st->codecpar->extradata_size = pkt_extradata_size;
> }
> }
>
> --
> ffmpeg-codebot
Please ignore this one. It slipped in accidentally. The size is
already set in ff_alloc_extradata().
Thanks
sw
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 07/10] avformat/segment: Remove non-negative constraint from segment_time_delta
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
` (5 preceding siblings ...)
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 06/10] avformat/segment: Fix invalid codecpar extradata_size after copying softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 08/10] avformat/segment: Don't allow negative segment duration softworkz
` (3 subsequent siblings)
10 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Use case is to keep early content out of the first segment when
not starting from zero.
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 70ff01b353..83b7ff269b 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -1099,7 +1099,7 @@ static const AVOption options[] = {
{ "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E},
{ "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E},
{ "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, INT64_MIN, INT64_MAX, E },
- { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
+ { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, INT64_MIN, INT64_MAX, E },
{ "min_seg_duration", "set minimum segment duration", OFFSET(min_seg_duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
{ "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
{ "segment_frames", "set segment split frame numbers", OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 08/10] avformat/segment: Don't allow negative segment duration
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
` (6 preceding siblings ...)
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 07/10] avformat/segment: Remove non-negative constraint from segment_time_delta softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 09/10] avformat/segment: Fix typo softworkz
` (2 subsequent siblings)
10 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 83b7ff269b..c2b09b08aa 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -1098,7 +1098,7 @@ static const AVOption options[] = {
{ "segment_atclocktime", "set segment to be cut at clocktime", OFFSET(use_clocktime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
{ "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E},
{ "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E},
- { "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, INT64_MIN, INT64_MAX, E },
+ { "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, 0, INT64_MAX, E },
{ "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, INT64_MIN, INT64_MAX, E },
{ "min_seg_duration", "set minimum segment duration", OFFSET(min_seg_duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
{ "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 09/10] avformat/segment: Fix typo
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
` (7 preceding siblings ...)
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 08/10] avformat/segment: Don't allow negative segment duration softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 10/10] avformat/segment: Indent and whitespace fixes softworkz
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements ffmpegagent
10 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index c2b09b08aa..3cd9e313f4 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -20,7 +20,7 @@
/**
* @file generic segmenter
- * M3U8 specification can be find here:
+ * M3U8 specification can be found here:
* @url{http://tools.ietf.org/id/draft-pantos-http-live-streaming}
*/
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH 10/10] avformat/segment: Indent and whitespace fixes
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
` (8 preceding siblings ...)
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 09/10] avformat/segment: Fix typo softworkz
@ 2025-06-13 5:54 ` softworkz
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements ffmpegagent
10 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-13 5:54 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 48 +++++++++++++++++++++----------------------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 3cd9e313f4..8e1e4a9c0c 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -177,7 +177,7 @@ static int segment_mux_init(AVFormatContext *s)
return AVERROR(ENOMEM);
opar = st->codecpar;
if (!oc->oformat->codec_tag ||
- av_codec_get_id (oc->oformat->codec_tag, ipar->codec_tag) == opar->codec_id ||
+ av_codec_get_id(oc->oformat->codec_tag, ipar->codec_tag) == opar->codec_id ||
av_codec_get_tag(oc->oformat->codec_tag, ipar->codec_id) <= 0) {
opar->codec_tag = ipar->codec_tag;
} else {
@@ -340,17 +340,17 @@ static void segment_list_print_entry(AVIOContext *list_ioctx,
list_entry->end_time - list_entry->start_time, list_entry->filename);
break;
case LIST_TYPE_FFCONCAT:
- {
- char *buf;
- if (av_escape(&buf, list_entry->filename, NULL, AV_ESCAPE_MODE_AUTO, AV_ESCAPE_FLAG_WHITESPACE) < 0) {
- av_log(log_ctx, AV_LOG_WARNING,
- "Error writing list entry '%s' in list file\n", list_entry->filename);
- return;
+ {
+ char *buf;
+ if (av_escape(&buf, list_entry->filename, NULL, AV_ESCAPE_MODE_AUTO, AV_ESCAPE_FLAG_WHITESPACE) < 0) {
+ av_log(log_ctx, AV_LOG_WARNING,
+ "Error writing list entry '%s' in list file\n", list_entry->filename);
+ return;
+ }
+ avio_printf(list_ioctx, "file %s\n", buf);
+ av_free(buf);
+ break;
}
- avio_printf(list_ioctx, "file %s\n", buf);
- av_free(buf);
- break;
- }
default:
av_assert0(!"Invalid list type");
}
@@ -456,8 +456,8 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
av_log(s, AV_LOG_WARNING, "Could not increment stream %d timecode, error occurred during timecode creation.\n", i);
continue;
}
- st_tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(st_rate)); // increment timecode
- av_dict_set(&s->streams[i]->metadata, "timecode", av_timecode_make_string(&st_tc, st_buf, 0), 0);
+ st_tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(st_rate)); // increment timecode
+ av_dict_set(&s->streams[i]->metadata, "timecode", av_timecode_make_string(&st_tc, st_buf, 0), 0);
}
}
}
@@ -755,8 +755,8 @@ static int seg_init(AVFormatContext *s)
if (seg->list) {
if (seg->list_type == LIST_TYPE_UNDEFINED) {
- if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
- else if (av_match_ext(seg->list, "ext" )) seg->list_type = LIST_TYPE_EXT;
+ if (av_match_ext(seg->list, "csv")) seg->list_type = LIST_TYPE_CSV;
+ else if (av_match_ext(seg->list, "ext")) seg->list_type = LIST_TYPE_EXT;
else if (av_match_ext(seg->list, "m3u8")) seg->list_type = LIST_TYPE_M3U8;
else if (av_match_ext(seg->list, "ffcat,ffconcat")) seg->list_type = LIST_TYPE_FFCONCAT;
else seg->list_type = LIST_TYPE_FLAT;
@@ -911,11 +911,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
calc_times:
if (seg->times) {
- end_pts = seg->segment_count < seg->nb_times ?
- seg->times[seg->segment_count] : INT64_MAX;
+ end_pts = seg->segment_count < seg->nb_times ? seg->times[seg->segment_count] : INT64_MAX;
} else if (seg->frames) {
- start_frame = seg->segment_count < seg->nb_frames ?
- seg->frames[seg->segment_count] : INT_MAX;
+ start_frame = seg->segment_count < seg->nb_frames ? seg->frames[seg->segment_count] : INT_MAX;
} else {
if (seg->use_clocktime) {
int64_t avgt = av_gettime();
@@ -956,10 +954,10 @@ calc_times:
(pkt->flags & AV_PKT_FLAG_KEY || seg->break_non_keyframes) &&
(seg->segment_frame_count > 0 || seg->write_empty) &&
(seg->cut_pending || seg->frame_count >= start_frame ||
- (pkt->pts != AV_NOPTS_VALUE &&
- pkt_pts_avtb - seg->cur_entry.start_pts >= seg->min_seg_duration &&
- av_compare_ts(pkt->pts, st->time_base,
- end_pts - seg->time_delta, AV_TIME_BASE_Q) >= 0))) {
+ (pkt->pts != AV_NOPTS_VALUE &&
+ pkt_pts_avtb - seg->cur_entry.start_pts >= seg->min_seg_duration &&
+ av_compare_ts(pkt->pts, st->time_base,
+ end_pts - seg->time_delta, AV_TIME_BASE_Q) >= 0))) {
/* sanitize end time in case last packet didn't have a defined duration */
if (seg->cur_entry.last_duration == 0)
seg->cur_entry.end_time = (double)pkt->pts * av_q2d(st->time_base);
@@ -1064,8 +1062,8 @@ static int seg_check_bitstream(AVFormatContext *s, AVStream *st,
if (ret == 1) {
FFStream *const sti = ffstream(st);
FFStream *const osti = ffstream(ost);
- sti->bsfc = osti->bsfc;
- osti->bsfc = NULL;
+ sti->bsfc = osti->bsfc;
+ osti->bsfc = NULL;
}
return ret;
}
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements
2025-06-13 5:54 [FFmpeg-devel] [PATCH 00/10] avformat/segment: Various segment muxer improvements ffmpegagent
` (9 preceding siblings ...)
2025-06-13 5:54 ` [FFmpeg-devel] [PATCH 10/10] avformat/segment: Indent and whitespace fixes softworkz
@ 2025-06-14 0:59 ` ffmpegagent
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 1/6] avformat/segment: Add segment_write_temp option softworkz
` (5 more replies)
10 siblings, 6 replies; 33+ messages in thread
From: ffmpegagent @ 2025-06-14 0:59 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
Includes
* Two new options
* segment_write_temp
Allows to write segments as temp files (.tmp) which are renamed on
completion
* segment_limit Stop after n segments have been written
* some minor changes (option contraints and formatting fixes)
Versions
========
V2
==
* merge the documentation patch with the feature patch
* segment_write_temp: use av_asprintf() directly instead of strlcatf() +
av_strdup()
(as per review by Marton - thanks!)
* removed logging patch
.
softworkz (6):
avformat/segment: Add segment_write_temp option
avformat/segment: Add segment_limit option
avformat/segment: Remove non-negative constraint from
segment_time_delta
avformat/segment: Don't allow negative segment duration
avformat/segment: Fix typo
avformat/segment: Indent and whitespace fixes
doc/muxers.texi | 12 ++++++
libavformat/segment.c | 95 +++++++++++++++++++++++++++++--------------
2 files changed, 76 insertions(+), 31 deletions(-)
base-commit: f3bf5356966b4ad9334034e720fa224c2d9464a6
Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-96%2Fsoftworkz%2Fsubmit_segment_muxer-v2
Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-96/softworkz/submit_segment_muxer-v2
Pull-Request: https://github.com/ffstaging/FFmpeg/pull/96
Range-diff vs v1:
1: 0132f3f933 ! 1: 79b4f63573 avformat/segment: Add segment_write_temp option
@@ Commit message
Signed-off-by: softworkz <softworkz@hotmail.com>
+ ## doc/muxers.texi ##
+@@ doc/muxers.texi: argument must be a time duration specification, and defaults to 0.
+ If enabled, write an empty segment if there are no packets during the period a
+ segment would usually span. Otherwise, the segment will be filled with the next
+ packet written. Defaults to @code{0}.
++
++@item segment_write_temp @var{1|0}
++Write segments to files with a .tmp extension. Each file is renamed to its
++actual name on completion. This can help to prevent segment files from
++being accessed before they are complete. Disabled by default (@code{0}).
+ @end table
+
+ Make sure to require a closed GOP when encoding and to set the GOP
+
## libavformat/segment.c ##
@@ libavformat/segment.c: typedef struct SegmentContext {
int break_non_keyframes;
@@ libavformat/segment.c: static int set_segment_filename(AVFormatContext *s)
+ // Write segment as a temp file and rename on completion
+ if(seg->segment_write_temp) {
-+ av_strlcatf(buf, sizeof(buf), ".tmp");
-+ char *temp_name = av_strdup(buf);
++ char *temp_name = av_asprintf("%s%s", buf, ".tmp");
+ if (!temp_name)
+ return AVERROR(ENOMEM);
+ ff_format_set_url(oc, temp_name);
2: 2bad7a3acc < -: ---------- doc/muxers: Add documentation for segment_write_temp option
3: 6a76e43900 < -: ---------- avformat/segment: Log more detailed information about written segments
4: 4f05a7d2e9 ! 2: 10b1c22439 avformat/segment: Add segment_limit option
@@ Commit message
Signed-off-by: softworkz <softworkz@hotmail.com>
+ ## doc/muxers.texi ##
+@@ doc/muxers.texi: packet written. Defaults to @code{0}.
+ Write segments to files with a .tmp extension. Each file is renamed to its
+ actual name on completion. This can help to prevent segment files from
+ being accessed before they are complete. Disabled by default (@code{0}).
++
++@item segment_limit @var{number}
++Stops after the specified number of segments has been generated.
++This can be helpful to fill gaps in a range of already generated segments,
++which is difficult to achieve otherwise as it would either cause the last
++segment to be incomplete or to overwrite an existing segment with a partial
++data. Default is @code{0} - no limit.
+ @end table
+
+ Make sure to require a closed GOP when encoding and to set the GOP
+
## libavformat/segment.c ##
@@ libavformat/segment.c: typedef struct SegmentContext {
int break_non_keyframes;
5: 53b693320f < -: ---------- doc/muxers: Add documentation for segment_limit option
6: ddf37a882b < -: ---------- avformat/segment: Fix invalid codecpar extradata_size after copying
7: d5def15604 = 3: a855134dc7 avformat/segment: Remove non-negative constraint from segment_time_delta
8: 16cb8ea92b = 4: 33139f28c8 avformat/segment: Don't allow negative segment duration
9: 1348b1b42c = 5: 64451d004a avformat/segment: Fix typo
10: 88a8dc7875 = 6: cb3267591d avformat/segment: Indent and whitespace fixes
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH v2 1/6] avformat/segment: Add segment_write_temp option
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements ffmpegagent
@ 2025-06-14 0:59 ` softworkz
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 2/6] avformat/segment: Add segment_limit option softworkz
` (4 subsequent siblings)
5 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-14 0:59 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Allows to write segments as temp files (.tmp) which
are renamed on completion.
Signed-off-by: softworkz <softworkz@hotmail.com>
---
doc/muxers.texi | 5 +++++
libavformat/segment.c | 29 ++++++++++++++++++++++++++---
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 30c95c3d34..6d5c17b4cc 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -3505,6 +3505,11 @@ argument must be a time duration specification, and defaults to 0.
If enabled, write an empty segment if there are no packets during the period a
segment would usually span. Otherwise, the segment will be filled with the next
packet written. Defaults to @code{0}.
+
+@item segment_write_temp @var{1|0}
+Write segments to files with a .tmp extension. Each file is renamed to its
+actual name on completion. This can help to prevent segment files from
+being accessed before they are complete. Disabled by default (@code{0}).
@end table
Make sure to require a closed GOP when encoding and to set the GOP
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 65323ec678..14eba90292 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -121,6 +121,7 @@ typedef struct SegmentContext {
int break_non_keyframes;
int write_empty;
+ int segment_write_temp; ///< write segments as temp files and rename on completion
int use_rename;
char temp_list_filename[1024];
@@ -226,6 +227,14 @@ static int set_segment_filename(AVFormatContext *s)
seg->entry_prefix ? seg->entry_prefix : "",
av_basename(oc->url));
+ // Write segment as a temp file and rename on completion
+ if(seg->segment_write_temp) {
+ char *temp_name = av_asprintf("%s%s", buf, ".tmp");
+ if (!temp_name)
+ return AVERROR(ENOMEM);
+ ff_format_set_url(oc, temp_name);
+ }
+
return 0;
}
@@ -372,7 +381,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
SegmentListEntry *entry = av_mallocz(sizeof(*entry));
if (!entry) {
ret = AVERROR(ENOMEM);
- goto end;
+ goto fail;
}
/* append new element */
@@ -393,7 +402,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
}
if ((ret = segment_list_open(s)) < 0)
- goto end;
+ goto fail;
for (entry = seg->segment_list_entries; entry; entry = entry->next)
segment_list_print_entry(seg->list_pb, seg->list_type, entry, s);
if (seg->list_type == LIST_TYPE_M3U8 && is_last)
@@ -450,7 +459,20 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
}
}
-end:
+ ff_format_io_close(oc, &oc->pb);
+
+ // Now rename the .tmp file to its actual name.
+ if (seg->segment_write_temp) {
+ char *final_filename = av_strndup(oc->url, strlen(oc->url) - 4);
+ if (!final_filename)
+ return AVERROR(ENOMEM);
+ ret = ff_rename(oc->url, final_filename, s);
+ av_free(final_filename);
+ }
+
+ return ret;
+
+fail:
ff_format_io_close(oc, &oc->pb);
return ret;
@@ -1075,6 +1097,7 @@ static const AVOption options[] = {
{ "reset_timestamps", "reset timestamps at the beginning of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
{ "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
{ "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
+ { "segment_write_temp", "write segments as temp files (.tmp) and rename on completion", OFFSET(segment_write_temp), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
{ NULL },
};
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH v2 2/6] avformat/segment: Add segment_limit option
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements ffmpegagent
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 1/6] avformat/segment: Add segment_write_temp option softworkz
@ 2025-06-14 0:59 ` softworkz
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 3/6] avformat/segment: Remove non-negative constraint from segment_time_delta softworkz
` (3 subsequent siblings)
5 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-14 0:59 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Example use case:
Existing segments 0-30 and 70-99, 31-69 need to be created.
This option allows to stop precisely after 69. Otherwise it would
start overwriting segment 70 before stopping via 'q' or break signal.
Signed-off-by: softworkz <softworkz@hotmail.com>
---
doc/muxers.texi | 7 +++++++
libavformat/segment.c | 12 ++++++++++++
2 files changed, 19 insertions(+)
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 6d5c17b4cc..1cca8da1fb 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -3510,6 +3510,13 @@ packet written. Defaults to @code{0}.
Write segments to files with a .tmp extension. Each file is renamed to its
actual name on completion. This can help to prevent segment files from
being accessed before they are complete. Disabled by default (@code{0}).
+
+@item segment_limit @var{number}
+Stops after the specified number of segments has been generated.
+This can be helpful to fill gaps in a range of already generated segments,
+which is difficult to achieve otherwise as it would either cause the last
+segment to be incomplete or to overwrite an existing segment with a partial
+data. Default is @code{0} - no limit.
@end table
Make sure to require a closed GOP when encoding and to set the GOP
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 14eba90292..e8b1582e7d 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -121,6 +121,8 @@ typedef struct SegmentContext {
int break_non_keyframes;
int write_empty;
+ int segment_limit; ///< max number of segments to create
+
int segment_write_temp; ///< write segments as temp files and rename on completion
int use_rename;
char temp_list_filename[1024];
@@ -365,6 +367,9 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
int i;
int err;
+ if (seg->segment_limit && seg->segment_count >= seg->segment_limit)
+ return 0;
+
if (!oc || !oc->pb)
return AVERROR(EINVAL);
@@ -879,6 +884,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
int64_t usecs;
int64_t wrapped_val;
+ if (seg->segment_limit && seg->segment_count >= seg->segment_limit)
+ return 0;
+
if (!seg->avf || !seg->avf->pb)
return AVERROR(EINVAL);
@@ -953,6 +961,9 @@ calc_times:
if ((ret = segment_end(s, seg->individual_header_trailer, 0)) < 0)
goto fail;
+ if (seg->segment_limit && seg->segment_count >= seg->segment_limit)
+ return 0;
+
if ((ret = segment_start(s, seg->individual_header_trailer)) < 0)
goto fail;
@@ -1098,6 +1109,7 @@ static const AVOption options[] = {
{ "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E },
{ "write_empty_segments", "allow writing empty 'filler' segments", OFFSET(write_empty), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
{ "segment_write_temp", "write segments as temp files (.tmp) and rename on completion", OFFSET(segment_write_temp), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
+ { "segment_limit", "stop output once the specified number of segments has been written", OFFSET(segment_limit), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
{ NULL },
};
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH v2 3/6] avformat/segment: Remove non-negative constraint from segment_time_delta
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements ffmpegagent
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 1/6] avformat/segment: Add segment_write_temp option softworkz
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 2/6] avformat/segment: Add segment_limit option softworkz
@ 2025-06-14 0:59 ` softworkz
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 4/6] avformat/segment: Don't allow negative segment duration softworkz
` (2 subsequent siblings)
5 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-14 0:59 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Use case is to keep early content out of the first segment when
not starting from zero.
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index e8b1582e7d..1e99acdddb 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -1091,7 +1091,7 @@ static const AVOption options[] = {
{ "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E},
{ "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E},
{ "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, INT64_MIN, INT64_MAX, E },
- { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
+ { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, INT64_MIN, INT64_MAX, E },
{ "min_seg_duration", "set minimum segment duration", OFFSET(min_seg_duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
{ "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
{ "segment_frames", "set segment split frame numbers", OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH v2 4/6] avformat/segment: Don't allow negative segment duration
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements ffmpegagent
` (2 preceding siblings ...)
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 3/6] avformat/segment: Remove non-negative constraint from segment_time_delta softworkz
@ 2025-06-14 0:59 ` softworkz
2025-06-14 20:40 ` Michael Niedermayer
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 5/6] avformat/segment: Fix typo softworkz
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 6/6] avformat/segment: Indent and whitespace fixes softworkz
5 siblings, 1 reply; 33+ messages in thread
From: softworkz @ 2025-06-14 0:59 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 1e99acdddb..daff385c2c 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -1090,7 +1090,7 @@ static const AVOption options[] = {
{ "segment_atclocktime", "set segment to be cut at clocktime", OFFSET(use_clocktime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
{ "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E},
{ "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E},
- { "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, INT64_MIN, INT64_MAX, E },
+ { "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, 0, INT64_MAX, E },
{ "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, INT64_MIN, INT64_MAX, E },
{ "min_seg_duration", "set minimum segment duration", OFFSET(min_seg_duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
{ "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 4/6] avformat/segment: Don't allow negative segment duration
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 4/6] avformat/segment: Don't allow negative segment duration softworkz
@ 2025-06-14 20:40 ` Michael Niedermayer
0 siblings, 0 replies; 33+ messages in thread
From: Michael Niedermayer @ 2025-06-14 20:40 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 595 bytes --]
On Sat, Jun 14, 2025 at 12:59:10AM +0000, softworkz wrote:
> From: softworkz <softworkz@hotmail.com>
>
> Signed-off-by: softworkz <softworkz@hotmail.com>
> ---
> libavformat/segment.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
should be ok
thx
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Frequently ignored answer#1 FFmpeg bugs should be sent to our bugtracker. User
questions about the command line tools should be sent to the ffmpeg-user ML.
And questions about how to use libav* should be sent to the libav-user ML.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH v2 5/6] avformat/segment: Fix typo
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements ffmpegagent
` (3 preceding siblings ...)
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 4/6] avformat/segment: Don't allow negative segment duration softworkz
@ 2025-06-14 0:59 ` softworkz
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 6/6] avformat/segment: Indent and whitespace fixes softworkz
5 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-14 0:59 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index daff385c2c..ec084483d4 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -20,7 +20,7 @@
/**
* @file generic segmenter
- * M3U8 specification can be find here:
+ * M3U8 specification can be found here:
* @url{http://tools.ietf.org/id/draft-pantos-http-live-streaming}
*/
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread
* [FFmpeg-devel] [PATCH v2 6/6] avformat/segment: Indent and whitespace fixes
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 0/6] avformat/segment: Various segment muxer improvements ffmpegagent
` (4 preceding siblings ...)
2025-06-14 0:59 ` [FFmpeg-devel] [PATCH v2 5/6] avformat/segment: Fix typo softworkz
@ 2025-06-14 0:59 ` softworkz
5 siblings, 0 replies; 33+ messages in thread
From: softworkz @ 2025-06-14 0:59 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: softworkz
From: softworkz <softworkz@hotmail.com>
Signed-off-by: softworkz <softworkz@hotmail.com>
---
libavformat/segment.c | 48 +++++++++++++++++++++----------------------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index ec084483d4..57ea54b00a 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -177,7 +177,7 @@ static int segment_mux_init(AVFormatContext *s)
return AVERROR(ENOMEM);
opar = st->codecpar;
if (!oc->oformat->codec_tag ||
- av_codec_get_id (oc->oformat->codec_tag, ipar->codec_tag) == opar->codec_id ||
+ av_codec_get_id(oc->oformat->codec_tag, ipar->codec_tag) == opar->codec_id ||
av_codec_get_tag(oc->oformat->codec_tag, ipar->codec_id) <= 0) {
opar->codec_tag = ipar->codec_tag;
} else {
@@ -339,17 +339,17 @@ static void segment_list_print_entry(AVIOContext *list_ioctx,
list_entry->end_time - list_entry->start_time, list_entry->filename);
break;
case LIST_TYPE_FFCONCAT:
- {
- char *buf;
- if (av_escape(&buf, list_entry->filename, NULL, AV_ESCAPE_MODE_AUTO, AV_ESCAPE_FLAG_WHITESPACE) < 0) {
- av_log(log_ctx, AV_LOG_WARNING,
- "Error writing list entry '%s' in list file\n", list_entry->filename);
- return;
+ {
+ char *buf;
+ if (av_escape(&buf, list_entry->filename, NULL, AV_ESCAPE_MODE_AUTO, AV_ESCAPE_FLAG_WHITESPACE) < 0) {
+ av_log(log_ctx, AV_LOG_WARNING,
+ "Error writing list entry '%s' in list file\n", list_entry->filename);
+ return;
+ }
+ avio_printf(list_ioctx, "file %s\n", buf);
+ av_free(buf);
+ break;
}
- avio_printf(list_ioctx, "file %s\n", buf);
- av_free(buf);
- break;
- }
default:
av_assert0(!"Invalid list type");
}
@@ -457,8 +457,8 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
av_log(s, AV_LOG_WARNING, "Could not increment stream %d timecode, error occurred during timecode creation.\n", i);
continue;
}
- st_tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(st_rate)); // increment timecode
- av_dict_set(&s->streams[i]->metadata, "timecode", av_timecode_make_string(&st_tc, st_buf, 0), 0);
+ st_tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(st_rate)); // increment timecode
+ av_dict_set(&s->streams[i]->metadata, "timecode", av_timecode_make_string(&st_tc, st_buf, 0), 0);
}
}
}
@@ -750,8 +750,8 @@ static int seg_init(AVFormatContext *s)
if (seg->list) {
if (seg->list_type == LIST_TYPE_UNDEFINED) {
- if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
- else if (av_match_ext(seg->list, "ext" )) seg->list_type = LIST_TYPE_EXT;
+ if (av_match_ext(seg->list, "csv")) seg->list_type = LIST_TYPE_CSV;
+ else if (av_match_ext(seg->list, "ext")) seg->list_type = LIST_TYPE_EXT;
else if (av_match_ext(seg->list, "m3u8")) seg->list_type = LIST_TYPE_M3U8;
else if (av_match_ext(seg->list, "ffcat,ffconcat")) seg->list_type = LIST_TYPE_FFCONCAT;
else seg->list_type = LIST_TYPE_FLAT;
@@ -905,11 +905,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
calc_times:
if (seg->times) {
- end_pts = seg->segment_count < seg->nb_times ?
- seg->times[seg->segment_count] : INT64_MAX;
+ end_pts = seg->segment_count < seg->nb_times ? seg->times[seg->segment_count] : INT64_MAX;
} else if (seg->frames) {
- start_frame = seg->segment_count < seg->nb_frames ?
- seg->frames[seg->segment_count] : INT_MAX;
+ start_frame = seg->segment_count < seg->nb_frames ? seg->frames[seg->segment_count] : INT_MAX;
} else {
if (seg->use_clocktime) {
int64_t avgt = av_gettime();
@@ -950,10 +948,10 @@ calc_times:
(pkt->flags & AV_PKT_FLAG_KEY || seg->break_non_keyframes) &&
(seg->segment_frame_count > 0 || seg->write_empty) &&
(seg->cut_pending || seg->frame_count >= start_frame ||
- (pkt->pts != AV_NOPTS_VALUE &&
- pkt_pts_avtb - seg->cur_entry.start_pts >= seg->min_seg_duration &&
- av_compare_ts(pkt->pts, st->time_base,
- end_pts - seg->time_delta, AV_TIME_BASE_Q) >= 0))) {
+ (pkt->pts != AV_NOPTS_VALUE &&
+ pkt_pts_avtb - seg->cur_entry.start_pts >= seg->min_seg_duration &&
+ av_compare_ts(pkt->pts, st->time_base,
+ end_pts - seg->time_delta, AV_TIME_BASE_Q) >= 0))) {
/* sanitize end time in case last packet didn't have a defined duration */
if (seg->cur_entry.last_duration == 0)
seg->cur_entry.end_time = (double)pkt->pts * av_q2d(st->time_base);
@@ -1056,8 +1054,8 @@ static int seg_check_bitstream(AVFormatContext *s, AVStream *st,
if (ret == 1) {
FFStream *const sti = ffstream(st);
FFStream *const osti = ffstream(ost);
- sti->bsfc = osti->bsfc;
- osti->bsfc = NULL;
+ sti->bsfc = osti->bsfc;
+ osti->bsfc = NULL;
}
return ret;
}
--
ffmpeg-codebot
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 33+ messages in thread