|
|
|
@@ -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; |
|
|
|
} |
|
|
|
|