-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy path0015-decklink_dec-support-readout-of-all-timecodes.patch
More file actions
125 lines (116 loc) · 6.67 KB
/
0015-decklink_dec-support-readout-of-all-timecodes.patch
File metadata and controls
125 lines (116 loc) · 6.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From d9f2162b33f7d1b1122cd0994514596aab3ca8b4 Mon Sep 17 00:00:00 2001
From: Jerome Martinez <jerome@mediaarea.net>
Date: Sun, 23 Nov 2025 17:40:55 +0100
Subject: [PATCH 15/19] decklink_dec: support readout of all timecodes
---
libavdevice/decklink_common.h | 1 +
libavdevice/decklink_dec.cpp | 44 ++++++++++++++++++++++++++++-------
libavdevice/decklink_dec_c.c | 3 ++-
3 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
index 095b438bce..3f67d023b1 100644
--- a/libavdevice/decklink_common.h
+++ b/libavdevice/decklink_common.h
@@ -238,6 +238,7 @@ static const BMDTimecodeFormat decklink_timecode_format_map[] = {
#else
(BMDTimecodeFormat)0,
#endif
+ (BMDTimecodeFormat)1, // All
};
static const BMDLinkConfiguration decklink_link_conf_map[] = {
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 78ec0ee0d2..8727e9d389 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -736,6 +736,33 @@ static int get_frame_timecode(AVFormatContext *avctx, decklink_ctx *ctx, AVTimec
{
AVRational frame_rate = ctx->video_st->r_frame_rate;
int ret;
+ if (ctx->tc_format == (BMDTimecodeFormat)1) {
+ int count = 0;
+ ret = get_bmd_timecode(avctx, tc + count, frame_rate, bmdTimecodeRP188VITC1, videoFrame);
+ if (ret != AVERROR(ENOENT))
+ count++;
+ ret = get_bmd_timecode(avctx, tc + count, frame_rate, bmdTimecodeRP188VITC2, videoFrame);
+ if (ret != AVERROR(ENOENT))
+ count++;
+ ret = get_bmd_timecode(avctx, tc + count, frame_rate, bmdTimecodeRP188LTC, videoFrame);
+ if (ret != AVERROR(ENOENT))
+ count++;
+#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
+ ret = get_bmd_timecode(avctx, tc + count, frame_rate, bmdTimecodeRP188HighFrameRate, videoFrame);
+ if (ret != AVERROR(ENOENT))
+ count++;
+#endif
+ ret = get_bmd_timecode(avctx, tc + count, frame_rate, bmdTimecodeVITC, videoFrame);
+ if (ret != AVERROR(ENOENT))
+ count++;
+ ret = get_bmd_timecode(avctx, tc + count, frame_rate, bmdTimecodeVITCField2, videoFrame);
+ if (ret != AVERROR(ENOENT))
+ count++;
+ ret = get_bmd_timecode(avctx, tc + count, frame_rate, bmdTimecodeSerial, videoFrame);
+ if (ret != AVERROR(ENOENT))
+ count++;
+ return count;
+ }
/* 50/60 fps content has alternating VITC1 and VITC2 timecode (see SMPTE ST
* 12-2, section 7), so the native ordering of RP188Any (HFR, VITC1, LTC,
* VITC2) would not work because LTC might not contain the field flag.
@@ -753,7 +780,7 @@ static int get_frame_timecode(AVFormatContext *avctx, decklink_ctx *ctx, AVTimec
} else {
ret = get_bmd_timecode(avctx, tc, frame_rate, ctx->tc_format, videoFrame);
}
- return ret;
+ return ret >= 0;
}
HRESULT decklink_input_callback::VideoInputFrameArrived(
@@ -848,22 +875,23 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
// Handle Timecode (if requested)
if (ctx->tc_format) {
- AVTimecode tcr;
- if (get_frame_timecode(avctx, ctx, &tcr, videoFrame) >= 0) {
+ AVTimecode tcr[8];
+ int count = get_frame_timecode(avctx, ctx, &tcr[0], videoFrame);
+ if (count > 0) {
char tcstr[AV_TIMECODE_STR_SIZE];
- const char *tc = av_timecode_make_string(&tcr, tcstr, 0);
+ const char *tc = av_timecode_make_string(&tcr[0], tcstr, 0);
if (tc) {
AVDictionary* metadata_dict = NULL;
uint8_t* packed_metadata;
if (av_cmp_q(ctx->video_st->r_frame_rate, av_make_q(60, 1)) < 1) {
- uint64_t tc_data = av_timecode_expand_to_64bit(av_timecode_get_smpte_from_framenum(&tcr, 0));
- int size = sizeof(uint64_t) * 4;
+ int size = sizeof(uint64_t) * (1 + count);
uint64_t *sd = (uint64_t *)av_packet_new_side_data(&pkt, AV_PKT_DATA_S12M_TIMECODE, size);
if (sd) {
- *sd = 1; // one TC
- *(sd + 1) = tc_data; // TC
+ *sd = count;
+ for (int i = 0; i < count; i++)
+ *(sd + 1 + i) = av_timecode_expand_to_64bit(av_timecode_get_smpte_from_framenum(&tcr[i], 0));
}
}
diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
index b8cdb7bd8e..583107e191 100644
--- a/libavdevice/decklink_dec_c.c
+++ b/libavdevice/decklink_dec_c.c
@@ -60,7 +60,7 @@ static const AVOption options[] = {
{ "two_sub_device_full", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0, DEC, .unit = "duplex_mode"},
{ "four_sub_device_half", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0, DEC, .unit = "duplex_mode"},
#endif
- { "timecode_format", "timecode format", OFFSET(tc_format), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 8, DEC, .unit = "tc_format"},
+ { "timecode_format", "timecode format", OFFSET(tc_format), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 9, DEC, .unit = "tc_format"},
{ "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, .unit = "tc_format"},
{ "rp188vitc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, .unit = "tc_format"},
{ "rp188vitc2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, .unit = "tc_format"},
@@ -72,6 +72,7 @@ static const AVOption options[] = {
#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
{ "rp188hfr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 8}, 0, 0, DEC, .unit = "tc_format"},
#endif
+ { "all", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 9}, 0, 0, DEC, .unit = "tc_format"},
{ "video_input", "video input", OFFSET(video_input), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 6, DEC, .unit = "video_input"},
{ "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, .unit = "video_input"},
{ "sdi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, .unit = "video_input"},
--
2.52.0