Commit c0ee4e0a authored by Karthick Jeyapal's avatar Karthick Jeyapal Committed by Marton Balint

avdevice/decklink_dec: add option to align capture start time

This option is useful for maintaining input synchronization across N
different hardware devices deployed for 'N-way' redundancy.
The system time of different hardware devices should be synchronized
with protocols such as NTP or PTP, before using this option.
Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
parent 449b1dcd
......@@ -371,6 +371,20 @@ If set to @option{true}, timestamps are forwarded as they are without removing
the initial offset.
Defaults to @option{false}.
@item timestamp_align
Capture start time alignment in seconds. If set to nonzero, input frames are
dropped till the system timestamp aligns with configured value.
Alignment difference of upto one frame duration is tolerated.
This is useful for maintaining input synchronization across N different
hardware devices deployed for 'N-way' redundancy. The system time of different
hardware devices should be synchronized with protocols such as NTP or PTP,
before using this option.
Note that this method is not foolproof. In some border cases input
synchronization may not happen due to thread scheduling jitters in the OS.
Either sync could go wrong by 1 frame or in a rarer case
@option{timestamp_align} seconds.
Defaults to @samp{0}.
@end table
@subsection Examples
......
......@@ -56,6 +56,7 @@ struct decklink_cctx {
int raw_format;
int64_t queue_size;
int copyts;
int64_t timestamp_align;
};
#endif /* AVDEVICE_DECKLINK_COMMON_C_H */
......@@ -703,6 +703,16 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
return S_OK;
}
// Drop the frames till system's timestamp aligns with the configured value.
if (0 == ctx->frameCount && cctx->timestamp_align) {
AVRational remainder = av_make_q(av_gettime() % cctx->timestamp_align, 1000000);
AVRational frame_duration = av_inv_q(ctx->video_st->r_frame_rate);
if (av_cmp_q(remainder, frame_duration) > 0) {
++ctx->dropped;
return S_OK;
}
}
ctx->frameCount++;
if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == PTS_SRC_WALLCLOCK)
wallclock = av_gettime_relative();
......
......@@ -84,6 +84,7 @@ static const AVOption options[] = {
{ "queue_size", "input queue buffer size", OFFSET(queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC },
{ "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 },
{ NULL },
};
......
......@@ -29,7 +29,7 @@
#define LIBAVDEVICE_VERSION_MAJOR 58
#define LIBAVDEVICE_VERSION_MINOR 4
#define LIBAVDEVICE_VERSION_MICRO 104
#define LIBAVDEVICE_VERSION_MICRO 105
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment