[FFmpeg-devel] [PATCH] Fix segment muxer

just.one.man at yandex.ru just.one.man at yandex.ru
Thu Oct 3 14:26:37 EEST 2019


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;
         /* 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


More information about the ffmpeg-devel mailing list