[FFmpeg-devel] [PATCH] Fix segment muxer
just.one.man at yandex.ru
just.one.man at yandex.ru
Mon Oct 7 15:12:46 EEST 2019
Updated patch
---
When incoming media has non-zero start PTS,
segment muxer would fail to correctly calculate
the point where to chunk segments, as it always
assumed that media starts with PTS==0.
This change removes this assumption by remembering
the PTS of the very first frame passed through the muxer.
Also fix starting points of first segment
---
libavformat/segment.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index e308206..8b985df 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -87,6 +87,7 @@ typedef struct SegmentContext {
int64_t last_val; ///< remember last time for wrap around detection
int cut_pending;
int header_written; ///< whether we've already called avformat_write_header
+ int64_t start_pts; ///< pts of the very first packet processed, used to compute correct segment length
char *entry_prefix; ///< prefix to add to list entry filenames
int list_type; ///< set the list type
@@ -702,6 +703,7 @@ static int seg_init(AVFormatContext *s)
if ((ret = parse_frames(s, &seg->frames, &seg->nb_frames, seg->frames_str)) < 0)
return ret;
} else {
+ seg->start_pts = AV_NOPTS_VALUE;
/* set default value if not specified */
if (!seg->time_str)
seg->time_str = av_strdup("2");
@@ -914,7 +916,15 @@ calc_times:
seg->cut_pending = 1;
seg->last_val = wrapped_val;
} else {
- end_pts = seg->time * (seg->segment_count + 1);
+ if (seg->start_pts != AV_NOPTS_VALUE) {
+ end_pts = seg->start_pts + seg->time * (seg->segment_count + 1);
+ } else if (pkt->stream_index == seg->reference_stream_index && pkt->pts != AV_NOPTS_VALUE) {
+ // this is the first packet of the reference stream we see, initialize start point
+ seg->start_pts = av_rescale_q(pkt->pts, st->time_base, AV_TIME_BASE_Q);
+ seg->cur_entry.start_time = (double)pkt->pts * av_q2d(st->time_base);
+ seg->cur_entry.start_pts = seg->start_pts;
+ end_pts = seg->start_pts + seg->time * (seg->segment_count + 1);
+ }
}
}
--
1.7.9.5
06.10.2019, 14:38, "Vasily" <just.one.man at yandex.ru>:
> I used that value somewhere during patch development, but I eventually
> settled on -1, because that "start_pts" and "end_pts" are using some other
> units, not the unit used by pkt->pts.
>
> So I wanted to make a distinction. Though a possibility of negative
> timestamps didn't come to me, so I probably have to change it back to
> AV_NOPTS_VALUE.
>
> P.S. Thanks for reviewing my patch!
>
> вс, 6 окт. 2019 г., 13:56 Marton Balint <cus at passwd.hu>:
>
>> On Thu, 3 Oct 2019, just.one.man at yandex.ru wrote:
>>
>> > It seems that my first attempt to send the patch failed (probably
>> because my box where I executed "git send-email" failed reverse smtp
>> check), so I'm going to re-send it to this same thread.
>> >
>> > ---
>> >
>> > When incoming media has non-zero start PTS,
>> > segment muxer would fail to correctly calculate
>> > the point where to chunk segments, as it always
>> > assumed that media starts with PTS==0.
>> >
>> > This change removes this assumption by remembering
>> > the PTS of the very first frame passed through the muxer.
>> >
>> > Also fix starting points of first segment
>> > ---
>> > libavformat/segment.c | 12 +++++++++++-
>> > 1 file changed, 11 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/libavformat/segment.c b/libavformat/segment.c
>> > index e308206..2478d8f 100644
>> > --- a/libavformat/segment.c
>> > +++ b/libavformat/segment.c
>> > @@ -87,6 +87,7 @@ typedef struct SegmentContext {
>> > int64_t last_val; ///< remember last time for wrap around
>> detection
>> > int cut_pending;
>> > int header_written; ///< whether we've already called
>> avformat_write_header
>> > + int64_t start_pts; ///< pts of the very first packet processed,
>> used to compute correct segment length
>> >
>> > char *entry_prefix; ///< prefix to add to list entry filenames
>> > int list_type; ///< set the list type
>> > @@ -702,6 +703,7 @@ static int seg_init(AVFormatContext *s)
>> > if ((ret = parse_frames(s, &seg->frames, &seg->nb_frames,
>> seg->frames_str)) < 0)
>> > return ret;
>> > } else {
>> > + seg->start_pts = -1;
>>
>> AV_NOPTS_VALUE would be probably better for this purpose, even if the
>> muxer won't get negative timestamps unless allowed by the
>> AVFMT_TS_NEGATIVE flag.
>>
>> Regards,
>> Marton
>>
>> > /* set default value if not specified */
>> > if (!seg->time_str)
>> > seg->time_str = av_strdup("2");
>> > @@ -914,7 +916,15 @@ calc_times:
>> > seg->cut_pending = 1;
>> > seg->last_val = wrapped_val;
>> > } else {
>> > - end_pts = seg->time * (seg->segment_count + 1);
>> > + if (seg->start_pts != -1) {
>> > + end_pts = seg->start_pts + seg->time *
>> (seg->segment_count + 1);
>> > + } else if (pkt->stream_index == seg->reference_stream_index
>> && pkt->pts != AV_NOPTS_VALUE) {
>> > + // this is the first packet of the reference stream we
>> see, initialize start point
>> > + seg->start_pts = av_rescale_q(pkt->pts, st->time_base,
>> AV_TIME_BASE_Q);
>> > + seg->cur_entry.start_time = (double)pkt->pts *
>> av_q2d(st->time_base);
>> > + seg->cur_entry.start_pts = seg->start_pts;
>> > + end_pts = seg->start_pts + seg->time *
>> (seg->segment_count + 1);
>> > + }
>> > }
>> > }
>> >
>> > --
>> > 1.7.9.5
>> > _______________________________________________
>> > ffmpeg-devel mailing list
>> > ffmpeg-devel at ffmpeg.org
>> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> >
>> > To unsubscribe, visit link above, or email
>> > ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel at ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list