|
|
|
@@ -93,6 +93,7 @@ typedef struct mkv_cues { |
|
|
|
typedef struct mkv_track { |
|
|
|
int write_dts; |
|
|
|
int has_cue; |
|
|
|
uint64_t uid; |
|
|
|
int sample_rate; |
|
|
|
int64_t sample_rate_offset; |
|
|
|
int64_t last_timestamp; |
|
|
|
@@ -1115,8 +1116,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, |
|
|
|
track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0); |
|
|
|
put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER, |
|
|
|
mkv->is_dash ? mkv->dash_track_number : i + 1); |
|
|
|
put_ebml_uint (pb, MATROSKA_ID_TRACKUID, |
|
|
|
mkv->is_dash ? mkv->dash_track_number : i + 1); |
|
|
|
put_ebml_uint (pb, MATROSKA_ID_TRACKUID, mkv->tracks[i].uid); |
|
|
|
put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet) |
|
|
|
|
|
|
|
if ((tag = av_dict_get(st->metadata, "title", NULL, 0))) |
|
|
|
@@ -1569,6 +1569,7 @@ static int mkv_write_tags(AVFormatContext *s) |
|
|
|
tagp = (s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live ? &tag : NULL; |
|
|
|
for (i = 0; i < s->nb_streams; i++) { |
|
|
|
AVStream *st = s->streams[i]; |
|
|
|
mkv_track *track = &mkv->tracks[i]; |
|
|
|
|
|
|
|
if (st->codecpar->codec_type == AVMEDIA_TYPE_ATTACHMENT) |
|
|
|
continue; |
|
|
|
@@ -1577,7 +1578,7 @@ static int mkv_write_tags(AVFormatContext *s) |
|
|
|
continue; |
|
|
|
|
|
|
|
ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, |
|
|
|
i + 1, tagp); |
|
|
|
track->uid, tagp); |
|
|
|
if (ret < 0) return ret; |
|
|
|
|
|
|
|
if (tagp) { |
|
|
|
@@ -1783,10 +1784,6 @@ static int mkv_write_header(AVFormatContext *s) |
|
|
|
version = 4; |
|
|
|
} |
|
|
|
|
|
|
|
mkv->tracks = av_mallocz_array(s->nb_streams, sizeof(*mkv->tracks)); |
|
|
|
if (!mkv->tracks) { |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
ebml_header = start_ebml_master(pb, EBML_ID_HEADER, MAX_EBML_HEADER_SIZE); |
|
|
|
put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); |
|
|
|
put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); |
|
|
|
@@ -2607,8 +2604,28 @@ static int webm_query_codec(enum AVCodecID codec_id, int std_compliance) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static uint64_t mkv_get_uid(const mkv_track *tracks, int i, AVLFG *c) |
|
|
|
{ |
|
|
|
while (1) { |
|
|
|
uint64_t uid; |
|
|
|
int k; |
|
|
|
uid = (uint64_t)av_lfg_get(c) << 32; |
|
|
|
uid |= av_lfg_get(c); |
|
|
|
if (!uid) |
|
|
|
continue; |
|
|
|
for (k = 0; k < i; k++) { |
|
|
|
if (tracks[k].uid == uid) |
|
|
|
break; |
|
|
|
} |
|
|
|
if (k == i) |
|
|
|
return uid; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static int mkv_init(struct AVFormatContext *s) |
|
|
|
{ |
|
|
|
MatroskaMuxContext *mkv = s->priv_data; |
|
|
|
AVLFG c; |
|
|
|
int i; |
|
|
|
|
|
|
|
if (s->nb_streams > MAX_TRACKS) { |
|
|
|
@@ -2637,7 +2654,23 @@ static int mkv_init(struct AVFormatContext *s) |
|
|
|
s->internal->avoid_negative_ts_use_pts = 1; |
|
|
|
} |
|
|
|
|
|
|
|
mkv->tracks = av_mallocz_array(s->nb_streams, sizeof(*mkv->tracks)); |
|
|
|
if (!mkv->tracks) { |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
|
|
|
|
if (!(s->flags & AVFMT_FLAG_BITEXACT)) |
|
|
|
av_lfg_init(&c, av_get_random_seed()); |
|
|
|
|
|
|
|
for (i = 0; i < s->nb_streams; i++) { |
|
|
|
mkv_track *track = &mkv->tracks[i]; |
|
|
|
|
|
|
|
if (s->flags & AVFMT_FLAG_BITEXACT) { |
|
|
|
track->uid = i + 1; |
|
|
|
} else { |
|
|
|
track->uid = mkv_get_uid(mkv->tracks, i, &c); |
|
|
|
} |
|
|
|
|
|
|
|
// ms precision is the de-facto standard timescale for mkv files |
|
|
|
avpriv_set_pts_info(s->streams[i], 64, 1, 1000); |
|
|
|
} |
|
|
|
|