diff mbox series

[FFmpeg-devel] avformat/movenc: fix assert failure in get_cluster_duration()

Message ID tencent_D91A5A063485805A35D13FE957519CD2E009@qq.com
State New
Headers show
Series [FFmpeg-devel] avformat/movenc: fix assert failure in get_cluster_duration() | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Zhao Zhili Dec. 17, 2021, 10:24 a.m. UTC
When editlist is disabled, the workaournd method of shift dts to
zero and increase the first sample duration doesn't work if the
timestamp is larger than mp4 spec restriction (e.g., sample_delta
in stts entry). Further more, it triggers get_cluster_duration()
assert failure. This patch will drop large offsets between
multiple tracks.
---
 libavformat/movenc.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 0f912dd012..dd92c0f26d 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -5917,7 +5917,18 @@  int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
          * to signal the difference in starting time without an edit list.
          * Thus move the timestamp for this first sample to 0, increasing
          * its duration instead. */
-        trk->cluster[trk->entry].dts = trk->start_dts = 0;
+        if (pkt->dts < INT32_MAX) {
+            trk->cluster[trk->entry].dts = trk->start_dts = 0;
+        } else {
+            /* Impossible to write a sample duration >= UINT32_MAX.
+             * Use INT32_MAX as a tight restriction.
+             */
+            trk->start_dts = pkt->dts;
+            av_log(s, AV_LOG_WARNING,
+                   "Track %d starts with a nonzero dts %" PRId64
+                   " which will be shifted to zero\n",
+                   pkt->stream_index, pkt->dts);
+        }
     }
     if (trk->start_dts == AV_NOPTS_VALUE) {
         trk->start_dts = pkt->dts;