[FFmpeg-devel] [PATCH 2/5] avformat/movenc: fix tfra including non-sync entries

Zhao Zhili quinkblack at foxmail.com
Fri Dec 3 07:06:54 EET 2021


---
 libavformat/movenc.c  | 17 ++++++++++++++++-
 libavformat/movenc.h  |  1 +
 tests/ref/fate/movenc |  4 ++--
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 634a829f28..06d3819591 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -4650,6 +4650,7 @@ static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
         info->time     = track->cluster[0].dts + track->cluster[0].cts;
         info->duration = track->end_pts -
                          (track->cluster[0].dts + track->cluster[0].cts);
+        info->first_sample_flags = track->cluster[0].flags;
         // If the pts is less than zero, we will have trimmed
         // away parts of the media track using an edit list,
         // and the corresponding start presentation time is zero.
@@ -4932,8 +4933,20 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
+    int number_of_entry = 0;
     int i;
 
+    /* We can't write and then update number_of_entry, because we cannot fix
+     * the case when number_of_entry is zero, since zero indicates that every
+     * sample is a sync sample. So get number_of_entry first.
+     */
+    for (i = 0; i < track->nb_frag_info; i++) {
+        if (track->frag_info[i].first_sample_flags & MOV_SYNC_SAMPLE)
+            number_of_entry++;
+    }
+    if (!number_of_entry)
+        return 0;
+
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "tfra");
     avio_w8(pb, 1); /* version */
@@ -4941,8 +4954,10 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
 
     avio_wb32(pb, track->track_id);
     avio_wb32(pb, 0); /* length of traf/trun/sample num */
-    avio_wb32(pb, track->nb_frag_info);
+    avio_wb32(pb, number_of_entry);
     for (i = 0; i < track->nb_frag_info; i++) {
+        if (!(track->frag_info[i].first_sample_flags & MOV_SYNC_SAMPLE))
+            continue;
         avio_wb64(pb, track->frag_info[i].time);
         avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
         avio_w8(pb, 1); /* traf number */
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 40077b1afe..f73604d6f3 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -80,6 +80,7 @@ typedef struct MOVFragmentInfo {
     int64_t duration;
     int64_t tfrf_offset;
     int size;
+    uint32_t first_sample_flags;
 } MOVFragmentInfo;
 
 typedef struct MOVTrack {
diff --git a/tests/ref/fate/movenc b/tests/ref/fate/movenc
index 81ea75f372..70c66b7fd7 100644
--- a/tests/ref/fate/movenc
+++ b/tests/ref/fate/movenc
@@ -138,8 +138,8 @@ write_data len 504, time 800000, type boundary atom moof
 write_data len 420, time 1266667, type boundary atom moof
 write_data len 668, time 1566667, type sync atom moof
 write_data len 440, time 2233333, type boundary atom moof
-write_data len 262, time nopts, type trailer atom -
-a5d087611a9229ba91eb0964cf2f17d9 4209 vfr-noduration-interleave
+write_data len 205, time nopts, type trailer atom -
+2dd052ab30624c1a415184c5bf973670 4152 vfr-noduration-interleave
 write_data len 1231, time nopts, type header atom ftyp
 write_data len 916, time 0, type sync atom moof
 write_data len 908, time 1000000, type sync atom moof
-- 
2.31.1



More information about the ffmpeg-devel mailing list