[FFmpeg-devel] [PATCH] libavformat/movenc: Adds use_absolute_dts option

Chris Hiszpanski chris.hiszpanski at verkada.com
Fri Mar 31 20:49:57 EEST 2023


When transcoding from one mp4 segment to another, copying the
input base media decode time to the output is desired so that
segments can be transcoded independently in parallel, since
base media decode time must be sequential between segments.

Specifying -copyts and -movflags use_tfdt should copy the base
media decode time, but does not as its computation is relative.

The use_absolute_dts option indicates to use the absolute DTS
for the base media decode time.
---
 libavformat/movenc.c | 13 +++++++++----
 libavformat/movenc.h |  1 +
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 6b61a9ed1c..ee2b469f77 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -120,6 +120,7 @@ static const AVOption options[] = {
     { "pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_PTS}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, "prft"},
     { "empty_hdlr_name", "write zero-length name string in hdlr atoms within mdia and minf atoms", offsetof(MOVMuxContext, empty_hdlr_name), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+    { "use_absolute_dts", "use absolute decode timestamp", offsetof(MOVMuxContext, use_absolute_dts), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -5021,7 +5022,7 @@ static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
     }
 }
 
-static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
+static int mov_write_tfdt_tag(AVIOContext *pb, int64_t bmdt)
 {
     int64_t pos = avio_tell(pb);
 
@@ -5029,7 +5030,7 @@ static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
     ffio_wfourcc(pb, "tfdt");
     avio_w8(pb, 1); /* version */
     avio_wb24(pb, 0);
-    avio_wb64(pb, track->cluster[0].dts - track->start_dts);
+    avio_wb64(pb, bmdt);
     return update_size(pb, pos);
 }
 
@@ -5037,14 +5038,18 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
                               MOVTrack *track, int64_t moof_offset,
                               int moof_size)
 {
+    int64_t bmdt = track->cluster[0].dts;
     int64_t pos = avio_tell(pb);
     int i, start = 0;
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "traf");
 
     mov_write_tfhd_tag(pb, mov, track, moof_offset);
-    if (mov->mode != MODE_ISM)
-        mov_write_tfdt_tag(pb, track);
+    if (mov->mode != MODE_ISM) {
+        if (!mov->use_absolute_dts)
+            bmdt -= track->start_dts;
+        mov_write_tfdt_tag(pb, bmdt);
+    }
     for (i = 1; i < track->entry; i++) {
         if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
             mov_write_trun_tag(pb, mov, track, moof_size, start, i);
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 267ec6f8f2..7f2fcc17d6 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -246,6 +246,7 @@ typedef struct MOVMuxContext {
     MOVPrftBox write_prft;
     int empty_hdlr_name;
     int movie_timescale;
+    int use_absolute_dts;
 
     int64_t avif_extent_pos[2];  // index 0 is YUV and 1 is Alpha.
     int avif_extent_length[2];   // index 0 is YUV and 1 is Alpha.
-- 
2.25.1



More information about the ffmpeg-devel mailing list