diff mbox

[FFmpeg-devel,03/21] libavformat/movenc: added ability to use original stream ids as track i ds instead of regenerating them

Message ID 1471943019-14136-4-git-send-email-erkki.seppala.ext@nokia.com
State Superseded
Headers show

Commit Message

erkki.seppala.ext@nokia.com Aug. 23, 2016, 9:03 a.m. UTC
From: Erkki Seppälä <erkki.seppala.ext@nokia.com>

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@nokia.com>
Signed-off-by: OZOPlayer <OZOPL@nokia.com>
---
 libavformat/movenc.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++------
 libavformat/movenc.h |  2 ++
 2 files changed, 50 insertions(+), 6 deletions(-)

Comments

Carl Eugen Hoyos Aug. 23, 2016, 7:21 p.m. UTC | #1
2016-08-23 11:03 GMT+02:00  <erkki.seppala.ext@nokia.com>:
> +/** Assign track ids. If use_stream_ids_as_track_ids is set, the
> +    stream ids are used as track ids special case is taken to generate
> +    track ids for generated tracks, which don't have a 1:1 stream to
> +    copy the stream id from. This the order of tracks is the same in
> +    both mov->tracks and s->streams (and no holes). */

The last sentence is missing an important word, I think.

Carl Eugen
erkki.seppala.ext@nokia.com Aug. 24, 2016, 7:41 a.m. UTC | #2
On 08/23/2016 10:21 PM, Carl Eugen Hoyos wrote:
> 2016-08-23 11:03 GMT+02:00  <erkki.seppala.ext@nokia.com>:
>> +/** Assign track ids. If use_stream_ids_as_track_ids is set, the
>> +    stream ids are used as track ids special case is taken to generate
>> +    track ids for generated tracks, which don't have a 1:1 stream to
>> +    copy the stream id from. This the order of tracks is the same in
>> +    both mov->tracks and s->streams (and no holes). */
>
> The last sentence is missing an important word, I think.

In fact probably the whole paragraph needs some rewriting :). Thanks for 
review!
diff mbox

Patch

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 1f55333..8c4252d 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,45 @@  static void build_chunks(MOVTrack *trk)
     }
 }
 
+/** Assign track ids. If use_stream_ids_as_track_ids is set, the
+    stream ids are used as track ids special case is taken to generate
+    track ids for generated tracks, which don't have a 1:1 stream to
+    copy the stream id from. This the order of tracks is the same in
+    both mov->tracks and s->streams (and no holes). */
+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 +3483,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 +3570,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 +3593,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 +5815,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)