Commit 1ec23d9c authored by Clément Bœsch's avatar Clément Bœsch Committed by Clément Bœsch

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.
parent 0d96ec19
...@@ -2876,7 +2876,7 @@ static int mov_read_header(AVFormatContext *s) ...@@ -2876,7 +2876,7 @@ static int mov_read_header(AVFormatContext *s)
{ {
MOVContext *mov = s->priv_data; MOVContext *mov = s->priv_data;
AVIOContext *pb = s->pb; AVIOContext *pb = s->pb;
int err; int i, err;
MOVAtom atom = { AV_RL32("root") }; MOVAtom atom = { AV_RL32("root") };
mov->fc = s; mov->fc = s;
...@@ -2900,7 +2900,6 @@ static int mov_read_header(AVFormatContext *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)); av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
if (pb->seekable) { if (pb->seekable) {
int i;
if (mov->chapter_track > 0) if (mov->chapter_track > 0)
mov_read_chapters(s); mov_read_chapters(s);
for (i = 0; i < s->nb_streams; i++) for (i = 0; i < s->nb_streams; i++)
...@@ -2908,8 +2907,23 @@ static int mov_read_header(AVFormatContext *s) ...@@ -2908,8 +2907,23 @@ static int mov_read_header(AVFormatContext *s)
mov_read_timecode_track(s, s->streams[i]); 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) { if (mov->trex_data) {
int i;
for (i = 0; i < s->nb_streams; i++) { for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i]; AVStream *st = s->streams[i];
MOVStreamContext *sc = st->priv_data; MOVStreamContext *sc = st->priv_data;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment