]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/utils: calculate frame number of HEVC if the framerate > 30FPS
authorLimin Wang <lance.lmwang@gmail.com>
Sun, 12 Jul 2020 14:19:31 +0000 (22:19 +0800)
committerLimin Wang <lance.lmwang@gmail.com>
Sun, 16 Aug 2020 14:51:11 +0000 (22:51 +0800)
Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
libavcodec/internal.h
libavcodec/nvenc.c
libavcodec/utils.c

index 21486ae9870458b581dcb623384dafeef614b82a..1c25aab6b99f05883d5c7640d041800de9cfb502 100644 (file)
@@ -367,6 +367,7 @@ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx);
  * Check AVFrame for S12M timecode side data and allocate and fill TC SEI message with timecode info
  *
  * @param frame      Raw frame to get S12M timecode side data from
+ * @param rate       The frame rate
  * @param prefix_len Number of bytes to allocate before SEI message
  * @param data       Pointer to a variable to store allocated memory
  *                   Upon return the variable will hold NULL on error or if frame has no S12M timecode info.
@@ -375,7 +376,7 @@ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx);
  * @param sei_size   Pointer to a variable to store generated SEI message length
  * @return           Zero on success, negative error code on failure
  */
-int ff_alloc_timecode_sei(const AVFrame *frame, size_t prefix_len,
+int ff_alloc_timecode_sei(const AVFrame *frame, AVRational rate, size_t prefix_len,
                      void **data, size_t *sei_size);
 
 /**
index ee8ba3cb39d9f2f4a296bf4d1a343619cce1e84e..887e11b1e27cd56d0c86a39e72303c57b8abf2d5 100644 (file)
@@ -2219,7 +2219,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
             void *tc_data = NULL;
             size_t tc_size = 0;
 
-            if (ff_alloc_timecode_sei(frame, 0, (void**)&tc_data, &tc_size) < 0) {
+            if (ff_alloc_timecode_sei(frame, avctx->framerate, 0, (void**)&tc_data, &tc_size) < 0) {
                 av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n");
             }
 
index 1814b417fc0bcb4f4ce2c5630641f0112e0bdd2d..14cb5cf1aad393284a88ab2a55f43d7c2fe11498 100644 (file)
@@ -2213,7 +2213,7 @@ static unsigned bcd2uint(uint8_t bcd)
     return low + 10*high;
 }
 
-int ff_alloc_timecode_sei(const AVFrame *frame, size_t prefix_len,
+int ff_alloc_timecode_sei(const AVFrame *frame, AVRational rate, size_t prefix_len,
                      void **data, size_t *sei_size)
 {
     AVFrameSideData *sd = NULL;
@@ -2249,6 +2249,17 @@ int ff_alloc_timecode_sei(const AVFrame *frame, size_t prefix_len,
         unsigned ff   = bcd2uint(tcsmpte>>24 & 0x3f);    // 6-bit frames
         unsigned drop = tcsmpte & 1<<30 && !0;  // 1-bit drop if not arbitrary bit
 
+        /* Calculate frame number of HEVC by SMPTE ST 12-1:2014 Sec 12.2 if rate > 30FPS */
+        if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) {
+            unsigned pc;
+            ff *= 2;
+            if (av_cmp_q(rate, (AVRational) {50, 1}) == 0)
+                pc = !!(tcsmpte & 1 << 7);
+            else
+                pc = !!(tcsmpte & 1 << 23);
+            ff = (ff + pc) & 0x7f;
+        }
+
         put_bits(&pb, 1, 1); // clock_timestamp_flag
         put_bits(&pb, 1, 1); // units_field_based_flag
         put_bits(&pb, 5, 0); // counting_type