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>
pull/230/head
Erkki Seppälä 8 years ago committed by Michael Niedermayer
parent aabe12eba3
commit 499e8b0952
  1. 61
      libavformat/movenc.c
  2. 2
      libavformat/movenc.h

@ -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_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_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 }, { "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 }, { 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, static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
AVFormatContext *s) AVFormatContext *s)
{ {
@ -3443,12 +3490,13 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
avio_wb32(pb, 0); /* size placeholder*/ avio_wb32(pb, 0); /* size placeholder*/
ffio_wfourcc(pb, "moov"); ffio_wfourcc(pb, "moov");
mov_setup_track_ids(mov, s);
for (i = 0; i < mov->nb_streams; i++) { for (i = 0; i < mov->nb_streams; i++) {
if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
continue; continue;
mov->tracks[i].time = mov->time; mov->tracks[i].time = mov->time;
mov->tracks[i].track_id = i + 1;
if (mov->tracks[i].entry) if (mov->tracks[i].entry)
build_chunks(&mov->tracks[i]); 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); 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); int64_t pos = avio_tell(pb);
int i; int i;
@ -3552,12 +3600,13 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
avio_printf(pb, "</head>\n"); avio_printf(pb, "</head>\n");
avio_printf(pb, "<body>\n"); avio_printf(pb, "<body>\n");
avio_printf(pb, "<switch>\n"); avio_printf(pb, "<switch>\n");
mov_setup_track_ids(mov, s);
for (i = 0; i < mov->nb_streams; i++) { for (i = 0; i < mov->nb_streams; i++) {
MOVTrack *track = &mov->tracks[i]; MOVTrack *track = &mov->tracks[i];
const char *type; const char *type;
/* track->track_id is initialized in write_moov, and thus isn't known int track_id = track->track_id;
* here yet */
int track_id = i + 1;
if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) { if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
type = "video"; type = "video";
@ -5773,7 +5822,7 @@ static int mov_write_header(AVFormatContext *s)
avio_flush(pb); avio_flush(pb);
if (mov->flags & FF_MOV_FLAG_ISML) 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 && if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) { !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {

@ -217,6 +217,8 @@ typedef struct MOVMuxContext {
int need_rewrite_extradata; int need_rewrite_extradata;
int use_stream_ids_as_track_ids;
int track_ids_ok;
} MOVMuxContext; } MOVMuxContext;
#define FF_MOV_FLAG_RTP_HINT (1 << 0) #define FF_MOV_FLAG_RTP_HINT (1 << 0)

Loading…
Cancel
Save