diff options
author | Clément Bœsch <clement.boesch@smartjog.com> | 2012-01-02 11:56:06 +0100 |
---|---|---|
committer | Clément Bœsch <ubitux@gmail.com> | 2012-01-05 20:59:52 +0100 |
commit | 35da85562d2f731855b28d4ab3b9b0679730ebf7 (patch) | |
tree | 4d043324a5c368b97b3f81d8efee2ef1ae865db0 /libavformat | |
parent | adc278788bf14b59c7a1c8ced1a00348cbe2ded9 (diff) | |
download | ffmpeg-35da85562d2f731855b28d4ab3b9b0679730ebf7.tar.gz |
mov: support timecode extraction.
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/mov.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 5923fb7f82..6698b6a3a4 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -36,6 +36,7 @@ #include "riff.h" #include "isom.h" #include "libavcodec/get_bits.h" +#include "libavcodec/timecode.h" #include "id3v1.h" #include "mov_chan.h" @@ -2615,6 +2616,46 @@ finish: avio_seek(sc->pb, cur_pos, SEEK_SET); } +static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, + uint32_t value) +{ + char buf[16]; + struct ff_timecode tc = { + .drop = st->codec->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE, + .rate = (AVRational){st->codec->time_base.den, + st->codec->time_base.num}, + }; + + if (avpriv_check_timecode_rate(s, tc.rate, tc.drop) < 0) + return AVERROR(EINVAL); + av_dict_set(&st->metadata, "timecode", + avpriv_timecode_to_string(buf, &tc, value), 0); + return 0; +} + +static int mov_read_timecode_track(AVFormatContext *s, AVStream *st) +{ + MOVStreamContext *sc = st->priv_data; + int64_t cur_pos = avio_tell(sc->pb); + uint32_t value; + + if (!st->nb_index_entries) + return -1; + + avio_seek(sc->pb, st->index_entries->pos, SEEK_SET); + value = avio_rb32(s->pb); + + /* Assume Counter flag is set to 1 in tmcd track (even though it is likely + * not the case) and thus assume "frame number format" instead of QT one. + * No sample with tmcd track can be found with a QT timecode at the moment, + * despite what the tmcd track "suggests" (Counter flag set to 0 means QT + * format). */ + parse_timecode_in_framenum_format(s, st, value); + + avio_seek(sc->pb, cur_pos, SEEK_SET); + return 0; +} + static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap) { MOVContext *mov = s->priv_data; @@ -2640,8 +2681,14 @@ static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap) } av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb)); - if (pb->seekable && mov->chapter_track > 0) - mov_read_chapters(s); + if (pb->seekable) { + int i; + if (mov->chapter_track > 0) + mov_read_chapters(s); + for (i = 0; i < s->nb_streams; i++) + if (s->streams[i]->codec->codec_tag == AV_RL32("tmcd")) + mov_read_timecode_track(s, s->streams[i]); + } return 0; } |