[FFmpeg-devel] [PATCH] Fix segment muxer

Marton Balint cus at passwd.hu
Sun Oct 27 18:03:33 EET 2019



On Mon, 7 Oct 2019, just.one.man at yandex.ru wrote:

Please use a proper commit title: e.g:

avformat/segment: fix non-zero start pts

Also make sure you provide the author name you want when you send the 
patch email. (you only provided an email address in the From field, not a 
full name, I guess this is not intentional).

> 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) {

What happens if the first packet is not from a reference stream? As far as 
I see in that case the output packet timestamp will be 0 based until we 
get a packet from the refence stream... Maybe you should accept a packet 
from any stream here?

> +                // 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);
> +            }
>         }
>     }

Regards,
Marton


More information about the ffmpeg-devel mailing list