[FFmpeg-cvslog] movenc: Write the moof atom in two passes

Martin Storsjö git at videolan.org
Wed Sep 18 12:52:38 CEST 2013


ffmpeg | branch: master | Martin Storsjö <martin at martin.st> | Mon Sep  9 12:05:01 2013 +0300| [a4adabb460ace39783d707a5b3bbe28b4b5b9dc4] | committer: Martin Storsjö

movenc: Write the moof atom in two passes

This is a bit more work, but avoids having to fill in
the data offset field afterwards instead of directly when
the rest of the trun atom is written.

This simplifies future cases where this field needs to be set to
something different.

Signed-off-by: Martin Storsjö <martin at martin.st>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a4adabb460ace39783d707a5b3bbe28b4b5b9dc4
---

 libavformat/movenc.c |   47 +++++++++++++++++++++++++----------------------
 libavformat/movenc.h |    1 -
 2 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 46bc6e1..051d6ac 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2267,7 +2267,7 @@ static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
            (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
 }
 
-static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
+static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track, int moof_size)
 {
     int64_t pos = avio_tell(pb);
     uint32_t flags = MOV_TRUN_DATA_OFFSET;
@@ -2292,8 +2292,8 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb24(pb, flags);
 
     avio_wb32(pb, track->entry); /* sample count */
-    track->moof_size_offset = avio_tell(pb);
-    avio_wb32(pb, 0); /* data offset */
+    avio_wb32(pb, moof_size + 8 + track->data_offset +
+                  track->cluster[0].pos); /* data offset */
     if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
         avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
 
@@ -2382,14 +2382,15 @@ static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov,
 }
 
 static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
-                              MOVTrack *track, int64_t moof_offset)
+                              MOVTrack *track, int64_t moof_offset,
+                              int moof_size)
 {
     int64_t pos = avio_tell(pb);
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "traf");
 
     mov_write_tfhd_tag(pb, track, moof_offset);
-    mov_write_trun_tag(pb, track);
+    mov_write_trun_tag(pb, track, moof_size);
     if (mov->mode == MODE_ISM) {
         mov_write_tfxd_tag(pb, track);
 
@@ -2407,10 +2408,11 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
     return update_size(pb, pos);
 }
 
-static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
+static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov,
+                                       int tracks, int moof_size)
 {
-    int64_t pos = avio_tell(pb), end;
-    int i, moof_size;
+    int64_t pos = avio_tell(pb);
+    int i;
 
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "moof");
@@ -2422,25 +2424,26 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
             continue;
         if (!track->entry)
             continue;
-        mov_write_traf_tag(pb, mov, track, pos);
+        mov_write_traf_tag(pb, mov, track, pos, moof_size);
     }
 
-    end = avio_tell(pb);
-    moof_size = end - pos;
-    for (i = 0; i < mov->nb_streams; i++) {
-        MOVTrack *track = &mov->tracks[i];
-        if (tracks >= 0 && i != tracks)
-            continue;
-        if (!track->entry)
-            continue;
-        avio_seek(pb, mov->tracks[i].moof_size_offset, SEEK_SET);
-        avio_wb32(pb, moof_size + 8 + mov->tracks[i].data_offset);
-    }
-    avio_seek(pb, end, SEEK_SET);
-
     return update_size(pb, pos);
 }
 
+static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
+{
+    AVIOContext *avio_buf;
+    int ret, moof_size;
+    uint8_t *buf;
+
+    if ((ret = avio_open_dyn_buf(&avio_buf)) < 0)
+        return ret;
+    mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
+    moof_size = avio_close_dyn_buf(avio_buf, &buf);
+    av_free(buf);
+    return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
+}
+
 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 78001cc..bcb87e1 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -116,7 +116,6 @@ typedef struct MOVTrack {
     HintSampleQueue sample_queue;
 
     AVIOContext *mdat_buf;
-    int64_t     moof_size_offset;
     int64_t     data_offset;
     int64_t     frag_start;
     int64_t     tfrf_offset;



More information about the ffmpeg-cvslog mailing list