Matthieu Bouron | 27 May 2012 14:21
Picon

[PATCH 1/4] avutil: support 50 and 60 frame rates in timecode api

---
Hi there,

This patch introduce support for 50/60 frame rates and a new function
av_timecode_adjust_ntsc_framenum2 to handle both 29.97 and 59.94 cases.

Note: the original formula comes from:
http://www.andrewduncan.ws/Timecodes/Timecodes.html

Regards,
Matthieu
---
 libavcodec/mpeg12enc.c |    2 +-
 libavutil/avutil.h     |    3 +++
 libavutil/timecode.c   |   28 +++++++++++++++++++++++++---
 libavutil/timecode.h   |   13 ++++++++++++-
 4 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 169f155..b045c74 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
 <at>  <at>  -300,7 +300,7  <at>  <at>  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/avutil.h b/libavutil/avutil.h
index acef213..c1c228c 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
 <at>  <at>  -193,6 +193,9  <at>  <at> 
 #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

 /**
  *  <at> }
diff --git a/libavutil/timecode.c b/libavutil/timecode.c
index ad3f7fa..dcb93cb 100644
--- a/libavutil/timecode.c
+++ b/libavutil/timecode.c
 <at>  <at>  -31,6 +31,7  <at>  <at> 
 #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 */
 <at>  <at>  -39,6 +40,25  <at>  <at>  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)
 {
 <at>  <at>  -48,7 +68,7  <at>  <at>  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;
 <at>  <at>  -77,7 +97,7  <at>  <at>  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;
 <at>  <at>  -139,7 +159,9  <at>  <at>  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 41e56d6..525f2a9 100644
--- a/libavutil/timecode.h
+++ b/libavutil/timecode.h
 <at>  <at>  -57,8 +57,19  <at>  <at>  typedef struct {
  *  <at> param framenum frame number to adjust
  *  <at> return         adjusted frame number
  *  <at> warning        adjustment is only valid in NTSC 29.97
+ *  <at> 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.
+ *
+ *  <at> param framenum frame number to adjust
+ *  <at> param fps      frame per second, 30 or 60
+ *  <at> return         adjusted frame number
+ *  <at> 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.
--

-- 
1.7.10

Gmane