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: Marton Balint <cus@passwd.hu>
This commit is contained in:
Karthick Jeyapal 2018-09-28 12:55:54 +05:30 committed by Marton Balint
parent 449b1dcd7d
commit c0ee4e0ac2
5 changed files with 27 additions and 1 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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();

View File

@ -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 },
};

View File

@ -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, \