diff mbox series

[FFmpeg-devel,4/8] avutil/timecode: add av_timecode_make_smpte_tc_string2

Message ID 20200905182217.28037-4-cus@passwd.hu
State Accepted
Headers show
Series [FFmpeg-devel,1/8] avutil/timecode: fix av_timecode_get_smpte_from_framenum with 50/60 fps | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Marton Balint Sept. 5, 2020, 6:22 p.m. UTC
Signed-off-by: Marton Balint <cus@passwd.hu>
---
 doc/APIchanges       |  3 +++
 libavutil/timecode.c | 19 ++++++++++++++++++-
 libavutil/timecode.h | 17 +++++++++++++++++
 libavutil/version.h  |  2 +-
 4 files changed, 39 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/doc/APIchanges b/doc/APIchanges
index 0054908e1e..e2d7369c83 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@  libavutil:     2017-10-21
 
 API changes, most recent first:
 
+2020-09-xx - xxxxxxxxxx - lavu 56.59.100 - timecode.h
+  Add av_timecode_make_smpte_tc_string2.
+
 2020-08-21 - xxxxxxxxxx - lavu 56.58.100 - avstring.h
   Deprecate av_d2str(). Use av_asprintf() instead.
 
diff --git a/libavutil/timecode.c b/libavutil/timecode.c
index 806638ddfc..f2db21c52c 100644
--- a/libavutil/timecode.c
+++ b/libavutil/timecode.c
@@ -136,16 +136,33 @@  static unsigned bcd2uint(uint8_t bcd)
    return low + 10*high;
 }
 
-char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df)
+char *av_timecode_make_smpte_tc_string2(char *buf, AVRational rate, uint32_t tcsmpte, int prevent_df, int skip_field)
 {
     unsigned hh   = bcd2uint(tcsmpte     & 0x3f);    // 6-bit hours
     unsigned mm   = bcd2uint(tcsmpte>>8  & 0x7f);    // 7-bit minutes
     unsigned ss   = bcd2uint(tcsmpte>>16 & 0x7f);    // 7-bit seconds
     unsigned ff   = bcd2uint(tcsmpte>>24 & 0x3f);    // 6-bit frames
     unsigned drop = tcsmpte & 1<<30 && !prevent_df;  // 1-bit drop if not arbitrary bit
+
+    if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) {
+        ff <<= 1;
+        if (!skip_field) {
+            if (av_cmp_q(rate, (AVRational) {50, 1}) == 0)
+                ff += !!(tcsmpte & 1 << 7);
+            else
+                ff += !!(tcsmpte & 1 << 23);
+        }
+    }
+
     snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u",
              hh, mm, ss, drop ? ';' : ':', ff);
     return buf;
+
+}
+
+char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df)
+{
+    return av_timecode_make_smpte_tc_string2(buf, (AVRational){30, 1}, tcsmpte, prevent_df, 1);
 }
 
 char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit)
diff --git a/libavutil/timecode.h b/libavutil/timecode.h
index e54b116e93..f9471a6e38 100644
--- a/libavutil/timecode.h
+++ b/libavutil/timecode.h
@@ -109,6 +109,23 @@  uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss
  */
 char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum);
 
+/**
+ * Get the timecode string from the SMPTE timecode format.
+ *
+ * In contrast to av_timecode_make_smpte_tc_string this function supports 50/60
+ * fps timecodes by using the field bit.
+ *
+ * @param buf        destination buffer, must be at least AV_TIMECODE_STR_SIZE long
+ * @param rate       frame rate of the timecode
+ * @param tcsmpte    the 32-bit SMPTE timecode
+ * @param prevent_df prevent the use of a drop flag when it is known the DF bit
+ *                   is arbitrary
+ * @param skip_field prevent the use of a field flag when it is known the field
+ *                   bit is arbitrary (e.g. because it is used as PC flag)
+ * @return           the buf parameter
+ */
+char *av_timecode_make_smpte_tc_string2(char *buf, AVRational rate, uint32_t tcsmpte, int prevent_df, int skip_field);
+
 /**
  * Get the timecode string from the SMPTE timecode format.
  *
diff --git a/libavutil/version.h b/libavutil/version.h
index 3f0a4a8402..7028bd2c88 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@ 
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  56
-#define LIBAVUTIL_VERSION_MINOR  58
+#define LIBAVUTIL_VERSION_MINOR  59
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \