summaryrefslogtreecommitdiff
path: root/libavformat/movenc.c
diff options
context:
space:
mode:
authorErkki Seppälä <erkki.seppala.ext@nokia.com>2016-08-31 14:35:44 +0300
committerMichael Niedermayer <michael@niedermayer.cc>2016-09-01 14:56:10 +0200
commit499e8b0952b2888e2defda7a2c9914dcdf1cfa8d (patch)
tree56c2dc48b8fa47c99a590966970b7caae5a1429e /libavformat/movenc.c
parentaabe12eba3758d6f393ba754a54307d5c705084c (diff)
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@nokia.com> Signed-off-by: OZOPlayer <OZOPL@nokia.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r--libavformat/movenc.c61
1 files changed, 55 insertions, 6 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 9bf3a04c6b..b82bfea2b6 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)) {