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.
Unified · Split
| @@ -371,6 +371,20 @@ If set to @option{true}, timestamps are forwarded as they are without removing · 370 unmodified lines | |||
| 371 | the initial offset. | 371 | the initial offset. |
| 372 | Defaults to @option{false}. | 372 | Defaults to @option{false}. |
| 373 | 373 | ||
| 374 | @item timestamp_align | ||
| 375 | Capture start time alignment in seconds. If set to nonzero, input frames are | ||
| 376 | dropped till the system timestamp aligns with configured value. | ||
| 377 | Alignment difference of upto one frame duration is tolerated. | ||
| 378 | This is useful for maintaining input synchronization across N different | ||
| 379 | hardware devices deployed for 'N-way' redundancy. The system time of different | ||
| 380 | hardware devices should be synchronized with protocols such as NTP or PTP, | ||
| 381 | before using this option. | ||
| 382 | Note that this method is not foolproof. In some border cases input | ||
| 383 | synchronization may not happen due to thread scheduling jitters in the OS. | ||
| 384 | Either sync could go wrong by 1 frame or in a rarer case | ||
| 385 | @option{timestamp_align} seconds. | ||
| 386 | Defaults to @samp{0}. | ||
| 387 | |||
| 374 | @end table | 388 | @end table |
| 375 | 389 | ||
| 376 | @subsection Examples | 390 | @subsection Examples |
| @@ -56,6 +56,7 @@ struct decklink_cctx { · 55 unmodified lines | |||
| 56 | int raw_format; | 56 | int raw_format; |
| 57 | int64_t queue_size; | 57 | int64_t queue_size; |
| 58 | int copyts; | 58 | int copyts; |
| 59 | int64_t timestamp_align; | ||
| 59 | }; | 60 | }; |
| 60 | 61 | ||
| 61 | #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ | 62 | #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ |
| @@ -703,6 +703,16 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( · 702 unmodified lines | |||
| 703 | return S_OK; | 703 | return S_OK; |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | // Drop the frames till system's timestamp aligns with the configured value. | ||
| 707 | if (0 == ctx->frameCount && cctx->timestamp_align) { | ||
| 708 | AVRational remainder = av_make_q(av_gettime() % cctx->timestamp_align, 1000000); | ||
| 709 | AVRational frame_duration = av_inv_q(ctx->video_st->r_frame_rate); | ||
| 710 | if (av_cmp_q(remainder, frame_duration) > 0) { | ||
| 711 | ++ctx->dropped; | ||
| 712 | return S_OK; | ||
| 713 | } | ||
| 714 | } | ||
| 715 | |||
| 706 | ctx->frameCount++; | 716 | ctx->frameCount++; |
| 707 | if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == PTS_SRC_WALLCLOCK) | 717 | if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == PTS_SRC_WALLCLOCK) |
| 708 | wallclock = av_gettime_relative(); | 718 | wallclock = av_gettime_relative(); |
| @@ -84,6 +84,7 @@ static const AVOption options[] = { · 83 unmodified lines | |||
| 84 | { "queue_size", "input queue buffer size", OFFSET(queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC }, | 84 | { "queue_size", "input queue buffer size", OFFSET(queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC }, |
| 85 | { "audio_depth", "audio bitdepth (16 or 32)", OFFSET(audio_depth), AV_OPT_TYPE_INT, { .i64 = 16}, 16, 32, DEC }, | 85 | { "audio_depth", "audio bitdepth (16 or 32)", OFFSET(audio_depth), AV_OPT_TYPE_INT, { .i64 = 16}, 16, 32, DEC }, |
| 86 | { "decklink_copyts", "copy timestamps, do not remove the initial offset", OFFSET(copyts), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC }, | 86 | { "decklink_copyts", "copy timestamps, do not remove the initial offset", OFFSET(copyts), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC }, |
| 87 | { "timestamp_align", "capture start time alignment (in seconds)", OFFSET(timestamp_align), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, DEC }, | ||
| 87 | { NULL }, | 88 | { NULL }, |
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| @@ -29,7 +29,7 @@ · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #define LIBAVDEVICE_VERSION_MAJOR 58 | 30 | #define LIBAVDEVICE_VERSION_MAJOR 58 |
| 31 | #define LIBAVDEVICE_VERSION_MINOR 4 | 31 | #define LIBAVDEVICE_VERSION_MINOR 4 |
| 32 | #define LIBAVDEVICE_VERSION_MICRO 104 | 32 | #define LIBAVDEVICE_VERSION_MICRO 105 |
| 33 | 33 | ||
| 34 | #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ | 34 | #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ |
| 35 | LIBAVDEVICE_VERSION_MINOR, \ | 35 | LIBAVDEVICE_VERSION_MINOR, \ |