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:
parent
449b1dcd7d
commit
c0ee4e0ac2
@ -371,6 +371,20 @@ If set to @option{true}, timestamps are forwarded as they are without removing
|
|||||||
the initial offset.
|
the initial offset.
|
||||||
Defaults to @option{false}.
|
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
|
@end table
|
||||||
|
|
||||||
@subsection Examples
|
@subsection Examples
|
||||||
|
@ -56,6 +56,7 @@ struct decklink_cctx {
|
|||||||
int raw_format;
|
int raw_format;
|
||||||
int64_t queue_size;
|
int64_t queue_size;
|
||||||
int copyts;
|
int copyts;
|
||||||
|
int64_t timestamp_align;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* AVDEVICE_DECKLINK_COMMON_C_H */
|
#endif /* AVDEVICE_DECKLINK_COMMON_C_H */
|
||||||
|
@ -703,6 +703,16 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
|
|||||||
return S_OK;
|
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++;
|
ctx->frameCount++;
|
||||||
if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == PTS_SRC_WALLCLOCK)
|
if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == PTS_SRC_WALLCLOCK)
|
||||||
wallclock = av_gettime_relative();
|
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 },
|
{ "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 },
|
{ "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 },
|
{ "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 },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#define LIBAVDEVICE_VERSION_MAJOR 58
|
#define LIBAVDEVICE_VERSION_MAJOR 58
|
||||||
#define LIBAVDEVICE_VERSION_MINOR 4
|
#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, \
|
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
|
||||||
LIBAVDEVICE_VERSION_MINOR, \
|
LIBAVDEVICE_VERSION_MINOR, \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user