mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
libavformat/matroska: Write stream durations in metadata, in the format of mkvmerge.
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 <isasi@google.com>
This commit is contained in:
parent
b1f78632c6
commit
31852540d4
@ -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,25 @@ static int mkv_write_tags(AVFormatContext *s)
|
||||
if (ret < 0) return ret;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
@ -1430,6 +1466,10 @@ static int mkv_write_header(AVFormatContext *s)
|
||||
}
|
||||
end_ebml_master(pb, segment_info);
|
||||
|
||||
// initialize stream_duration fields
|
||||
mkv->stream_durations = av_mallocz(s->nb_streams * sizeof(int64_t));
|
||||
mkv->stream_duration_offsets = av_mallocz(s->nb_streams * sizeof(int64_t));
|
||||
|
||||
ret = mkv_write_tracks(s);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -1801,6 +1841,11 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
|
||||
}
|
||||
|
||||
mkv->duration = FFMAX(mkv->duration, ts + duration);
|
||||
|
||||
if (mkv->stream_durations)
|
||||
mkv->stream_durations[pkt->stream_index] =
|
||||
FFMAX(mkv->stream_durations[pkt->stream_index], ts + duration);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1978,6 +2023,28 @@ static int mkv_write_trailer(AVFormatContext *s)
|
||||
avio_seek(pb, mkv->duration_offset, SEEK_SET);
|
||||
put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration);
|
||||
|
||||
// update stream durations
|
||||
if (mkv->stream_durations) {
|
||||
for (int i = 0; i < s->nb_streams; ++i) {
|
||||
AVStream *st = s->streams[i];
|
||||
double duration_sec = mkv->stream_durations[i] * av_q2d(st->time_base);
|
||||
char duration_string[20] = "";
|
||||
|
||||
av_log(s, AV_LOG_DEBUG, "stream %d end duration = %" PRIu64 "\n", i,
|
||||
mkv->stream_durations[i]);
|
||||
|
||||
if (!mkv->is_live && mkv->stream_duration_offsets[i] > 0) {
|
||||
avio_seek(pb, mkv->stream_duration_offsets[i], SEEK_SET);
|
||||
|
||||
snprintf(duration_string, 20, "%02d:%02d:%012.9f",
|
||||
(int) duration_sec / 3600, ((int) duration_sec / 60) % 60,
|
||||
fmod(duration_sec, 60));
|
||||
|
||||
put_ebml_binary(pb, MATROSKA_ID_TAGSTRING, duration_string, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
avio_seek(pb, currentpos, SEEK_SET);
|
||||
}
|
||||
|
||||
@ -1987,6 +2054,8 @@ static int mkv_write_trailer(AVFormatContext *s)
|
||||
av_freep(&mkv->tracks);
|
||||
av_freep(&mkv->cues->entries);
|
||||
av_freep(&mkv->cues);
|
||||
av_freep(&mkv->stream_durations);
|
||||
av_freep(&mkv->stream_duration_offsets);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -91,12 +91,12 @@ fate-wavpack-matroskamode: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/matros
|
||||
FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-mono
|
||||
fate-wavpack-matroska_mux-mono: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -c copy -fflags +bitexact -f matroska
|
||||
fate-wavpack-matroska_mux-mono: CMP = oneline
|
||||
fate-wavpack-matroska_mux-mono: REF = a2987e2e51e01a35e47e7da13eb47a35
|
||||
fate-wavpack-matroska_mux-mono: REF = 4befcc41dab6c690a15d0c396c324468
|
||||
|
||||
FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-61
|
||||
fate-wavpack-matroska_mux-61: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -c copy -fflags +bitexact -f matroska
|
||||
fate-wavpack-matroska_mux-61: CMP = oneline
|
||||
fate-wavpack-matroska_mux-61: REF = ffba4ddea1ba71f7a5901d9ed1a267be
|
||||
fate-wavpack-matroska_mux-61: REF = 7fedbfc3b9ea7348761db664626c29f4
|
||||
|
||||
FATE_SAMPLES_AVCONV += $(FATE_WAVPACK-yes)
|
||||
fate-wavpack: $(FATE_WAVPACK-yes)
|
||||
|
@ -1,4 +1,4 @@
|
||||
aeeb0f2e75d044dbe2f89b7e70a54c82 *tests/data/fate/acodec-tta.matroska
|
||||
331080 tests/data/fate/acodec-tta.matroska
|
||||
6c260836d7a32e4bd714453a3546c0d5 *tests/data/fate/acodec-tta.matroska
|
||||
331148 tests/data/fate/acodec-tta.matroska
|
||||
95e54b261530a1bcf6de6fe3b21dc5f6 *tests/data/fate/acodec-tta.out.wav
|
||||
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
|
||||
|
@ -1 +1 @@
|
||||
2dad5f63688ec613a04e94c8d4d167db
|
||||
37a212f8d56ad71e7466d5129f88e756
|
||||
|
@ -1,6 +1,6 @@
|
||||
bab98f5a04a9f7991fb960041c996478 *./tests/data/lavf/lavf.mkv
|
||||
472668 ./tests/data/lavf/lavf.mkv
|
||||
7c6509f597fb57bab002cbceec960011 *./tests/data/lavf/lavf.mkv
|
||||
472872 ./tests/data/lavf/lavf.mkv
|
||||
./tests/data/lavf/lavf.mkv CRC=0xec6c3c68
|
||||
c93950920d4ee57eb3ff5ba0cf0c8b19 *./tests/data/lavf/lavf.mkv
|
||||
320412 ./tests/data/lavf/lavf.mkv
|
||||
5f8cb4b7e98610347dd8d0d58a828a0f *./tests/data/lavf/lavf.mkv
|
||||
320548 ./tests/data/lavf/lavf.mkv
|
||||
./tests/data/lavf/lavf.mkv CRC=0xec6c3c68
|
||||
|
@ -1,48 +1,48 @@
|
||||
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 661 size: 208
|
||||
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 797 size: 208
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 877 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1013 size: 27837
|
||||
ret: 0 st:-1 flags:1 ts: 1.894167
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292291 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292427 size: 27834
|
||||
ret: 0 st: 0 flags:0 ts: 0.788000
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292291 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292427 size: 27834
|
||||
ret: 0 st: 0 flags:1 ts:-0.317000
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 877 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1013 size: 27837
|
||||
ret:-1 st: 1 flags:0 ts: 2.577000
|
||||
ret: 0 st: 1 flags:1 ts: 1.471000
|
||||
ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320132 size: 209
|
||||
ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320268 size: 209
|
||||
ret: 0 st:-1 flags:0 ts: 0.365002
|
||||
ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146844 size: 27925
|
||||
ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146980 size: 27925
|
||||
ret: 0 st:-1 flags:1 ts:-0.740831
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 877 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1013 size: 27837
|
||||
ret:-1 st: 0 flags:0 ts: 2.153000
|
||||
ret: 0 st: 0 flags:1 ts: 1.048000
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292291 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292427 size: 27834
|
||||
ret: 0 st: 1 flags:0 ts:-0.058000
|
||||
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 661 size: 208
|
||||
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 797 size: 208
|
||||
ret: 0 st: 1 flags:1 ts: 2.836000
|
||||
ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320132 size: 209
|
||||
ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320268 size: 209
|
||||
ret:-1 st:-1 flags:0 ts: 1.730004
|
||||
ret: 0 st:-1 flags:1 ts: 0.624171
|
||||
ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146844 size: 27925
|
||||
ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146980 size: 27925
|
||||
ret: 0 st: 0 flags:0 ts:-0.482000
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 877 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1013 size: 27837
|
||||
ret: 0 st: 0 flags:1 ts: 2.413000
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292291 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292427 size: 27834
|
||||
ret:-1 st: 1 flags:0 ts: 1.307000
|
||||
ret: 0 st: 1 flags:1 ts: 0.201000
|
||||
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 661 size: 208
|
||||
ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 797 size: 208
|
||||
ret: 0 st:-1 flags:0 ts:-0.904994
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 877 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1013 size: 27837
|
||||
ret: 0 st:-1 flags:1 ts: 1.989173
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292291 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292427 size: 27834
|
||||
ret: 0 st: 0 flags:0 ts: 0.883000
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292291 size: 27834
|
||||
ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292427 size: 27834
|
||||
ret: 0 st: 0 flags:1 ts:-0.222000
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 877 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1013 size: 27837
|
||||
ret:-1 st: 1 flags:0 ts: 2.672000
|
||||
ret: 0 st: 1 flags:1 ts: 1.566000
|
||||
ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320132 size: 209
|
||||
ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320268 size: 209
|
||||
ret: 0 st:-1 flags:0 ts: 0.460008
|
||||
ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146844 size: 27925
|
||||
ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146980 size: 27925
|
||||
ret: 0 st:-1 flags:1 ts:-0.645825
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 877 size: 27837
|
||||
ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1013 size: 27837
|
||||
|
Loading…
Reference in New Issue
Block a user