avdevice/decklink: add option to drop frames till timecode is seen
authorGyan Doshi <ffmpeg@gyani.pro>
Mon, 9 Sep 2019 13:03:09 +0000 (18:33 +0530)
committerGyan Doshi <ffmpeg@gyani.pro>
Mon, 18 Nov 2019 04:31:03 +0000 (10:01 +0530)
Option wait_for_tc only takes effect if tc_format is set

doc/indevs.texi
libavdevice/decklink_common.h
libavdevice/decklink_common_c.h
libavdevice/decklink_dec.cpp
libavdevice/decklink_dec_c.c
libavdevice/version.h

index 1459577..92bc65b 100644 (file)
@@ -395,6 +395,14 @@ Either sync could go wrong by 1 frame or in a rarer case
 @option{timestamp_align} seconds.
 Defaults to @samp{0}.
 
+@item wait_for_tc (@emph{bool})
+Drop frames till a frame with timecode is received. Sometimes serial timecode
+isn't received with the first input frame. If that happens, the stored stream
+timecode will be inaccurate. If this option is set to @option{true}, input frames
+are dropped till a frame with timecode is received.
+Option @var{timecode_format} must be specified.
+Defaults to @option{false}.
+
 @end table
 
 @subsection Examples
index 921818b..35422a3 100644 (file)
@@ -149,6 +149,7 @@ struct decklink_ctx {
 
     int channels;
     int audio_depth;
+    unsigned long tc_seen;    // used with option wait_for_tc
 };
 
 typedef enum { DIRECTION_IN, DIRECTION_OUT} decklink_direction_t;
index ca85ec2..b78630b 100644 (file)
@@ -58,6 +58,7 @@ struct decklink_cctx {
     int copyts;
     int64_t timestamp_align;
     int timing_offset;
+    int wait_for_tc;
 };
 
 #endif /* AVDEVICE_DECKLINK_COMMON_C_H */
index 4da9122..ab7f281 100644 (file)
@@ -784,6 +784,8 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
                             if (packed_metadata) {
                                 if (av_packet_add_side_data(&pkt, AV_PKT_DATA_STRINGS_METADATA, packed_metadata, metadata_len) < 0)
                                     av_freep(&packed_metadata);
+                                else if (!ctx->tc_seen)
+                                    ctx->tc_seen = ctx->frameCount;
                             }
                         }
                     }
@@ -793,6 +795,14 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
             }
         }
 
+        if (ctx->tc_format && cctx->wait_for_tc && !ctx->tc_seen) {
+
+            av_log(avctx, AV_LOG_WARNING, "No TC detected yet. wait_for_tc set. Dropping. \n");
+            av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - "
+                        "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
+            return S_OK;
+        }
+
         pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, abs_wallclock, ctx->video_pts_source, ctx->video_st->time_base, &initial_video_pts, cctx->copyts);
         pkt.dts = pkt.pts;
 
index 7aceaf9..99439f9 100644 (file)
@@ -85,6 +85,7 @@ static const AVOption options[] = {
     { "audio_depth",   "audio bitdepth (16 or 32)", OFFSET(audio_depth),  AV_OPT_TYPE_INT,   { .i64 = 16}, 16, 32, DEC },
     { "decklink_copyts", "copy timestamps, do not remove the initial offset", OFFSET(copyts), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC },
     { "timestamp_align", "capture start time alignment (in seconds)", OFFSET(timestamp_align), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, DEC },
+    { "wait_for_tc",     "drop frames till a frame with timecode is received. TC format must be set", OFFSET(wait_for_tc), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC },
     { NULL },
 };
 
index e3a583d..6830290 100644 (file)
@@ -29,7 +29,7 @@
 
 #define LIBAVDEVICE_VERSION_MAJOR  58
 #define LIBAVDEVICE_VERSION_MINOR   9
-#define LIBAVDEVICE_VERSION_MICRO 100
+#define LIBAVDEVICE_VERSION_MICRO 101
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
                                                LIBAVDEVICE_VERSION_MINOR, \