| 10011 | } |
| 10012 | |
| 10013 | static int mov_read_timecode_track(AVFormatContext *s, AVStream *st) |
| 10014 | { |
| 10015 | MOVStreamContext *sc = st->priv_data; |
| 10016 | FFStream *const sti = ffstream(st); |
| 10017 | int flags = 0; |
| 10018 | int64_t cur_pos = avio_tell(sc->pb); |
| 10019 | int64_t value; |
| 10020 | AVRational tc_rate = st->avg_frame_rate; |
| 10021 | int tmcd_nb_frames = sc->tmcd_nb_frames; |
| 10022 | int rounded_tc_rate; |
| 10023 | |
| 10024 | if (!sti->nb_index_entries) |
| 10025 | return -1; |
| 10026 | |
| 10027 | if (!tc_rate.num || !tc_rate.den || !tmcd_nb_frames) |
| 10028 | return -1; |
| 10029 | |
| 10030 | avio_seek(sc->pb, sti->index_entries->pos, SEEK_SET); |
| 10031 | value = avio_rb32(s->pb); |
| 10032 | |
| 10033 | if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME; |
| 10034 | if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX; |
| 10035 | if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE; |
| 10036 | |
| 10037 | /* Assume Counter flag is set to 1 in tmcd track (even though it is likely |
| 10038 | * not the case) and thus assume "frame number format" instead of QT one. |
| 10039 | * No sample with tmcd track can be found with a QT timecode at the moment, |
| 10040 | * despite what the tmcd track "suggests" (Counter flag set to 0 means QT |
| 10041 | * format). */ |
| 10042 | |
| 10043 | /* 60 fps content have tmcd_nb_frames set to 30 but tc_rate set to 60, so |
| 10044 | * we multiply the frame number with the quotient. |
| 10045 | * See tickets #9492, #9710. */ |
| 10046 | rounded_tc_rate = (tc_rate.num + tc_rate.den / 2LL) / tc_rate.den; |
| 10047 | /* Work around files where tmcd_nb_frames is rounded down from frame rate |
| 10048 | * instead of up. See ticket #5978. */ |
| 10049 | if (tmcd_nb_frames == tc_rate.num / tc_rate.den && |
| 10050 | s->strict_std_compliance < FF_COMPLIANCE_STRICT) |
| 10051 | tmcd_nb_frames = rounded_tc_rate; |
| 10052 | value = av_rescale(value, rounded_tc_rate, tmcd_nb_frames); |
| 10053 | |
| 10054 | parse_timecode_in_framenum_format(s, st, value, flags); |
| 10055 | |
| 10056 | avio_seek(sc->pb, cur_pos, SEEK_SET); |
| 10057 | return 0; |
| 10058 | } |
| 10059 | |
| 10060 | static void mov_free_encryption_index(MOVEncryptionIndex **index) { |
| 10061 | int i; |
no test coverage detected