diff options
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/isom.h | 1 | ||||
-rw-r--r-- | libavformat/mov.c | 16 |
2 files changed, 15 insertions, 2 deletions
diff --git a/libavformat/isom.h b/libavformat/isom.h index 5caf42b15d..99408a42d1 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -214,6 +214,7 @@ typedef struct MOVStreamContext { int has_palette; int64_t data_size; uint32_t tmcd_flags; ///< tmcd track flags + uint8_t tmcd_nb_frames; ///< tmcd number of frames per tick / second int64_t track_end; ///< used for dts generation in fragmented movie files int start_pad; ///< amount of samples to skip due to enc-dec delay unsigned int rap_group_count; diff --git a/libavformat/mov.c b/libavformat/mov.c index 6c847de164..4db4ded101 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2364,6 +2364,7 @@ static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, tmcd_ctx->tmcd_flags = val; st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */ st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */ + tmcd_ctx->tmcd_nb_frames = st->codecpar->extradata[16]; /* number of frames */ if (size > 30) { uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */ uint32_t format = AV_RB32(st->codecpar->extradata + 22); @@ -7848,7 +7849,7 @@ finish: } static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, - uint32_t value, int flags) + int64_t value, int flags) { AVTimecode tc; char buf[AV_TIMECODE_STR_SIZE]; @@ -7893,11 +7894,16 @@ static int mov_read_timecode_track(AVFormatContext *s, AVStream *st) FFStream *const sti = ffstream(st); int flags = 0; int64_t cur_pos = avio_tell(sc->pb); - uint32_t value; + int64_t value; + AVRational tc_rate = st->avg_frame_rate; + int rounded_tc_rate; if (!sti->nb_index_entries) return -1; + if (!tc_rate.num || !tc_rate.den || !sc->tmcd_nb_frames) + return -1; + avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET); value = avio_rb32(s->pb); @@ -7910,6 +7916,12 @@ static int mov_read_timecode_track(AVFormatContext *s, AVStream *st) * 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). */ + + /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so + * we multiply the frame number with the quotient. */ + rounded_tc_rate = (tc_rate.num + tc_rate.den / 2) / tc_rate.den; + value = av_rescale(value, rounded_tc_rate, sc->tmcd_nb_frames); + parse_timecode_in_framenum_format(s, st, value, flags); avio_seek(sc->pb, cur_pos, SEEK_SET); |