Changed the patch to initialize those variables in mkv_write_header. Also checking if stream_duration_offset > 0 before writing them as tags in write_trailer, so it won't be written for webm.
On Tue, Aug 4, 2015 at 6:54 PM, Michael Niedermayer <mich...@niedermayer.cc> wrote: > On Tue, Aug 04, 2015 at 05:32:51PM -0700, Sasi Inguva wrote: > > Compute individual stream durations in matroska muxer. > > Write them as string tags in the same format as mkvmerge tool does. > > > > Signed-off-by: Sasi Inguva <is...@google.com> > > --- > > libavformat/matroskaenc.c | 75 > +++++++++++++++++++++++++++++++++++++++++--- > > tests/fate/wavpack.mak | 4 +-- > > tests/ref/acodec/tta | 4 +-- > > tests/ref/fate/binsub-mksenc | 2 +- > > tests/ref/lavf/mkv | 8 ++--- > > tests/ref/seek/lavf-mkv | 44 +++++++++++++------------- > > 6 files changed, 101 insertions(+), 36 deletions(-) > > > > diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c > > index 2d0d5f6..0d3ae37 100644 > > --- a/libavformat/matroskaenc.c > > +++ b/libavformat/matroskaenc.c > > @@ -44,6 +44,7 @@ > > #include "libavutil/mathematics.h" > > #include "libavutil/opt.h" > > #include "libavutil/random_seed.h" > > +#include "libavutil/rational.h" > > #include "libavutil/samplefmt.h" > > #include "libavutil/sha.h" > > #include "libavutil/stereo3d.h" > > @@ -131,6 +132,9 @@ typedef struct MatroskaMuxContext { > > > > int64_t last_track_timestamp[MAX_TRACKS]; > > > > + int64_t* stream_durations; > > + int64_t* stream_duration_offsets; > > + > > int allow_raw_vfw; > > } MatroskaMuxContext; > > > > @@ -1151,12 +1155,12 @@ static int mkv_write_simpletag(AVIOContext *pb, > AVDictionaryEntry *t) > > return 0; > > } > > > > -static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned > int elementid, > > - unsigned int uid, ebml_master *tags) > > +static int mkv_write_tag_targets(AVFormatContext *s, > > + unsigned int elementid, unsigned int > uid, > > + ebml_master *tags, ebml_master* tag) > > { > > MatroskaMuxContext *mkv = s->priv_data; > > - ebml_master tag, targets; > > - AVDictionaryEntry *t = NULL; > > + ebml_master targets; > > int ret; > > > > if (!tags->pos) { > > @@ -1166,11 +1170,24 @@ static int mkv_write_tag(AVFormatContext *s, > AVDictionary *m, unsigned int eleme > > *tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0); > > } > > > > - tag = start_ebml_master(s->pb, MATROSKA_ID_TAG, 0); > > + *tag = start_ebml_master(s->pb, MATROSKA_ID_TAG, 0); > > targets = start_ebml_master(s->pb, MATROSKA_ID_TAGTARGETS, 0); > > if (elementid) > > put_ebml_uint(s->pb, elementid, uid); > > end_ebml_master(s->pb, targets); > > + return 0; > > +} > > + > > +static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned > int elementid, > > + unsigned int uid, ebml_master *tags) > > +{ > > + ebml_master tag; > > + int ret; > > + AVDictionaryEntry *t = NULL; > > + > > + ret = mkv_write_tag_targets(s, elementid, uid, tags, &tag); > > + if (ret < 0) > > + return ret; > > > > while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) { > > if (av_strcasecmp(t->key, "title") && > > @@ -1220,6 +1237,29 @@ static int mkv_write_tags(AVFormatContext *s) > > if (ret < 0) return ret; > > } > > > > + > > + mkv->stream_durations = av_mallocz(s->nb_streams * sizeof(int64_t)); > > + mkv->stream_duration_offsets = av_mallocz(s->nb_streams * > sizeof(int64_t)); > > this is not called in all cases, for example its not called for > webm > > > > + > > + if (!mkv->is_live) { > > + for (i = 0; i < s->nb_streams; i++) { > > + ebml_master tag_target; > > + ebml_master tag; > > + > > + mkv_write_tag_targets(s, MATROSKA_ID_TAGTARGETS_TRACKUID, i + > 1, &tags, &tag_target); > > + > > + tag = start_ebml_master(s->pb, MATROSKA_ID_SIMPLETAG, 0); > > + put_ebml_string(s->pb, MATROSKA_ID_TAGNAME, "DURATION"); > > + mkv->stream_duration_offsets[i] = avio_tell(s->pb); > > + > > + // Reserve space to write duration as a 20-byte string. > > + // 2 (ebml id) + 1 (data size) + 20 (data) > > + put_ebml_void(s->pb, 23); > > + end_ebml_master(s->pb, tag); > > + end_ebml_master(s->pb, tag_target); > > + } > > + } > > + > > for (i = 0; i < s->nb_chapters; i++) { > > AVChapter *ch = s->chapters[i]; > > > > @@ -1801,6 +1841,9 @@ static int > mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ > > } > > > > mkv->duration = FFMAX(mkv->duration, ts + duration); > > + mkv->stream_durations[pkt->stream_index] = > > + FFMAX(mkv->stream_durations[pkt->stream_index], ts + duration); > > + > > this is called for webm too though > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Old school: Use the lowest level language in which you can solve the > problem > conveniently. > New school: Use the highest level language in which the latest > supercomputer > can solve the problem without the user falling asleep waiting. > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel