diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 6ca2c8430d..9536d64a41 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -300,7 +300,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number; av_assert0(s->drop_frame_timecode == !!(s->tc.flags & AV_TIMECODE_FLAG_DROPFRAME)); if (s->drop_frame_timecode) - time_code = av_timecode_adjust_ntsc_framenum(time_code); + time_code = av_timecode_adjust_ntsc_framenum2(time_code, fps); put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); put_bits(&s->pb, 1, 1); diff --git a/libavutil/timecode.c b/libavutil/timecode.c index ad3f7faa5c..dcb93cb12e 100644 --- a/libavutil/timecode.c +++ b/libavutil/timecode.c @@ -31,6 +31,7 @@ #include "log.h" #include "error.h" +#ifdef FF_API_OLD_TC_ADJUST_FRAMENUM int av_timecode_adjust_ntsc_framenum(int framenum) { /* only works for NTSC 29.97 */ @@ -39,6 +40,25 @@ int av_timecode_adjust_ntsc_framenum(int framenum) //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */ return framenum + 18 * d + 2 * ((m - 2) / 1798); } +#endif + +int av_timecode_adjust_ntsc_framenum2(int framenum, int fps) +{ + /* only works for NTSC 29.97 and 59.94 */ + int drop_frames = 0; + int d = framenum / 17982; + int m = framenum % 17982; + + if (fps == 30) + drop_frames = 2; + else if (fps == 60) + drop_frames = 4; + else + return framenum; + + //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */ + return framenum + 9 * drop_frames * d + drop_frames * ((m - 2) / 1798); +} uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) { @@ -48,7 +68,7 @@ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) framenum += tc->start; if (drop) - framenum = av_timecode_adjust_ntsc_framenum(framenum); + framenum = av_timecode_adjust_ntsc_framenum2(framenum, tc->fps); ff = framenum % fps; ss = framenum / fps % 60; mm = framenum / (fps*60) % 60; @@ -77,7 +97,7 @@ char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum) framenum += tc->start; if (drop) - framenum = av_timecode_adjust_ntsc_framenum(framenum); + framenum = av_timecode_adjust_ntsc_framenum2(framenum, fps); if (framenum < 0) { framenum = -framenum; neg = tc->flags & AV_TIMECODE_FLAG_ALLOWNEGATIVE; @@ -139,7 +159,9 @@ static int check_timecode(void *log_ctx, AVTimecode *tc) switch (tc->fps) { case 24: case 25: - case 30: return 0; + case 30: + case 50: + case 60: return 0; default: av_log(log_ctx, AV_LOG_ERROR, "Timecode frame rate not supported\n"); diff --git a/libavutil/timecode.h b/libavutil/timecode.h index da252c1c17..be4102e577 100644 --- a/libavutil/timecode.h +++ b/libavutil/timecode.h @@ -51,8 +51,19 @@ typedef struct { * @param framenum frame number to adjust * @return adjusted frame number * @warning adjustment is only valid in NTSC 29.97 + * @deprecated use av_timecode_adjust_ntsc_framenum2 instead */ -int av_timecode_adjust_ntsc_framenum(int framenum); +attribute_deprecated int av_timecode_adjust_ntsc_framenum(int framenum); + +/** + * Adjust frame number for NTSC drop frame time code. + * + * @param framenum frame number to adjust + * @param fps frame per second, 30 or 60 + * @return adjusted frame number + * @warning adjustment is only valid in NTSC 29.97 and 59.94 + */ +int av_timecode_adjust_ntsc_framenum2(int framenum, int fps); /** * Convert frame number to SMPTE 12M binary representation. diff --git a/libavutil/version.h b/libavutil/version.h index 5ae7367d4d..a06fbc71ef 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -78,6 +78,9 @@ #ifndef FF_API_OLD_AVOPTIONS #define FF_API_OLD_AVOPTIONS (LIBAVUTIL_VERSION_MAJOR < 52) #endif +#ifndef FF_API_OLD_TC_ADJUST_FRAMENUM +#define FF_API_OLD_TC_ADJUST_FRAMENUM (LIBAVUTIL_VERSION_MAJOR < 52) +#endif /** * @}