[FFmpeg-cvslog] avformat/movenc: added ability to use original stream ids as track ids instead of regenerating them

Erkki Seppälä git at videolan.org
Thu Sep 1 16:29:51 EEST 2016


ffmpeg | branch: master | Erkki Seppälä <erkki.seppala.ext at nokia.com> | Wed Aug 31 14:35:44 2016 +0300| [499e8b0952b2888e2defda7a2c9914dcdf1cfa8d] | committer: Michael Niedermayer

avformat/movenc: added ability to use original stream ids as track ids instead of regenerating them

Sometimes it's useful to be able to define the exact track numbers in
the generated track, instead of always beginning at track id 1. Using
the option use_stream_ids_as_track_ids now copies the use stream ids
to track ids. Dynamically generated tracks (ie. tmcd) have their track
numbers defined as continuing from the highest numbered stream id.

Signed-off-by: Erkki Seppälä <erkki.seppala.ext at nokia.com>
Signed-off-by: OZOPlayer <OZOPL at nokia.com>
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

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

 libavformat/movenc.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++------
 libavformat/movenc.h |  2 ++
 2 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 9bf3a04..b82bfea 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -89,6 +89,7 @@ static const AVOption options[] = {
     { "encryption_scheme",    "Configures the encryption scheme, allowed values are none, cenc-aes-ctr", offsetof(MOVMuxContext, encryption_scheme_str),   AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
     { "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
     { "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
+    { "use_stream_ids_as_track_ids", "use stream ids as track ids", offsetof(MOVMuxContext, use_stream_ids_as_track_ids), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -3435,6 +3436,52 @@ static void build_chunks(MOVTrack *trk)
     }
 }
 
+/**
+ * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
+ * the stream ids are used as track ids.
+ *
+ * This assumes mov->tracks and s->streams are in the same order and
+ * there are no gaps in either of them (so mov->tracks[n] refers to
+ * s->streams[n]).
+ *
+ * As an exception, there can be more entries in
+ * s->streams than in mov->tracks, in which case new track ids are
+ * generated (starting after the largest found stream id).
+ */
+static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
+{
+    int i;
+
+    if (mov->track_ids_ok)
+        return 0;
+
+    if (mov->use_stream_ids_as_track_ids) {
+        int next_generated_track_id = 0;
+        for (i = 0; i < s->nb_streams; i++) {
+            if (s->streams[i]->id > next_generated_track_id)
+                next_generated_track_id = s->streams[i]->id;
+        }
+
+        for (i = 0; i < mov->nb_streams; i++) {
+            if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
+                continue;
+
+            mov->tracks[i].track_id = i >= s->nb_streams ? ++next_generated_track_id : s->streams[i]->id;
+        }
+    } else {
+        for (i = 0; i < mov->nb_streams; i++) {
+            if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
+                continue;
+
+            mov->tracks[i].track_id = i + 1;
+        }
+    }
+
+    mov->track_ids_ok = 1;
+
+    return 0;
+}
+
 static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
                               AVFormatContext *s)
 {
@@ -3443,12 +3490,13 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
     avio_wb32(pb, 0); /* size placeholder*/
     ffio_wfourcc(pb, "moov");
 
+    mov_setup_track_ids(mov, s);
+
     for (i = 0; i < mov->nb_streams; i++) {
         if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
             continue;
 
         mov->tracks[i].time     = mov->time;
-        mov->tracks[i].track_id = i + 1;
 
         if (mov->tracks[i].entry)
             build_chunks(&mov->tracks[i]);
@@ -3529,7 +3577,7 @@ static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *va
     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
 }
 
-static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
+static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
 {
     int64_t pos = avio_tell(pb);
     int i;
@@ -3552,12 +3600,13 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
     avio_printf(pb, "</head>\n");
     avio_printf(pb, "<body>\n");
     avio_printf(pb, "<switch>\n");
+
+    mov_setup_track_ids(mov, s);
+
     for (i = 0; i < mov->nb_streams; i++) {
         MOVTrack *track = &mov->tracks[i];
         const char *type;
-        /* track->track_id is initialized in write_moov, and thus isn't known
-         * here yet */
-        int track_id = i + 1;
+        int track_id = track->track_id;
 
         if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
             type = "video";
@@ -5773,7 +5822,7 @@ static int mov_write_header(AVFormatContext *s)
     avio_flush(pb);
 
     if (mov->flags & FF_MOV_FLAG_ISML)
-        mov_write_isml_manifest(pb, mov);
+        mov_write_isml_manifest(pb, mov, s);
 
     if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
         !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 894a1b0..ea76e39 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -217,6 +217,8 @@ typedef struct MOVMuxContext {
 
     int need_rewrite_extradata;
 
+    int use_stream_ids_as_track_ids;
+    int track_ids_ok;
 } MOVMuxContext;
 
 #define FF_MOV_FLAG_RTP_HINT              (1 <<  0)



More information about the ffmpeg-cvslog mailing list