From 1ec23d9c02079bae2ee02a3efe7da6f628781f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Mon, 4 Jun 2012 11:10:09 +0200 Subject: [PATCH] mov: copy timecode metadata from tmcd track to the related video stream. Apple softwares seem not to add a tref for the timecode (the next commit fixes this issue), but at least FFmpeg does. This can be used to generate a sample that demonstrates the feature: ./ffmpeg -f lavfi -i testsrc \ -f lavfi -i mptestsrc \ -f lavfi -i rgbtestsrc \ -map 0 -map 1 -map 2 \ -metadata:s:0 timecode=00:00:00:12 \ -metadata:s:2 timecode=01:02:12:20 \ -t 10 -y out.mov ./ffprobe out.mov The timecode metadata being transmitted to the video streams, it can be kept while transmuxed/transcoded. --- libavformat/mov.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 85fb255610..3ac1230b23 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2876,7 +2876,7 @@ static int mov_read_header(AVFormatContext *s) { MOVContext *mov = s->priv_data; AVIOContext *pb = s->pb; - int err; + int i, err; MOVAtom atom = { AV_RL32("root") }; mov->fc = s; @@ -2900,7 +2900,6 @@ static int mov_read_header(AVFormatContext *s) av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb)); if (pb->seekable) { - int i; if (mov->chapter_track > 0) mov_read_chapters(s); for (i = 0; i < s->nb_streams; i++) @@ -2908,8 +2907,23 @@ static int mov_read_header(AVFormatContext *s) mov_read_timecode_track(s, s->streams[i]); } + /* copy timecode metadata from tmcd tracks to the related video streams */ + for (i = 0; i < s->nb_streams; i++) { + AVStream *st = s->streams[i]; + MOVStreamContext *sc = st->priv_data; + if (sc->tref_type == AV_RL32("tmcd") && sc->trefs_count) { + AVDictionaryEntry *tcr; + int tmcd_st_id = sc->trefs[0] - 1; + + if (tmcd_st_id < 0 || tmcd_st_id >= s->nb_streams) + continue; + tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0); + if (tcr) + av_dict_set(&st->metadata, "timecode", tcr->value, 0); + } + } + if (mov->trex_data) { - int i; for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; MOVStreamContext *sc = st->priv_data;