/src/ffmpeg/libavcodec/smpte_436m.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * MXF SMPTE-436M VBI/ANC parsing functions |
3 | | * Copyright (c) 2025 Jacob Lifshay |
4 | | * |
5 | | * This file is part of FFmpeg. |
6 | | * |
7 | | * FFmpeg is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2.1 of the License, or (at your option) any later version. |
11 | | * |
12 | | * FFmpeg is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with FFmpeg; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | #include "libavcodec/smpte_436m.h" |
23 | | #include "bytestream.h" |
24 | | #include "libavcodec/packet.h" |
25 | | #include "libavutil/avassert.h" |
26 | | #include "libavutil/error.h" |
27 | | #include "libavutil/intreadwrite.h" |
28 | | |
29 | | static int validate_smpte_436m_anc_wrapping_type(AVSmpte436mWrappingType wrapping_type) |
30 | 6.11k | { |
31 | 6.11k | switch (wrapping_type) { |
32 | 5.70k | case AV_SMPTE_436M_WRAPPING_TYPE_VANC_FRAME: |
33 | 5.70k | case AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_1: |
34 | 5.71k | case AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_2: |
35 | 5.71k | case AV_SMPTE_436M_WRAPPING_TYPE_VANC_PROGRESSIVE_FRAME: |
36 | 5.72k | case AV_SMPTE_436M_WRAPPING_TYPE_HANC_FRAME: |
37 | 5.72k | case AV_SMPTE_436M_WRAPPING_TYPE_HANC_FIELD_1: |
38 | 5.72k | case AV_SMPTE_436M_WRAPPING_TYPE_HANC_FIELD_2: |
39 | 5.72k | case AV_SMPTE_436M_WRAPPING_TYPE_HANC_PROGRESSIVE_FRAME: |
40 | 5.72k | return 0; |
41 | 398 | default: |
42 | 398 | return AVERROR_INVALIDDATA; |
43 | 6.11k | } |
44 | 6.11k | } |
45 | | |
46 | | static int validate_smpte_436m_anc_payload_sample_coding(AVSmpte436mPayloadSampleCoding payload_sample_coding) |
47 | 5.72k | { |
48 | 5.72k | switch (payload_sample_coding) { |
49 | 1 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA: |
50 | 1 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF: |
51 | 4 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF: |
52 | | // not allowed for ANC packets |
53 | 4 | return AVERROR_INVALIDDATA; |
54 | 547 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA: |
55 | 759 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF: |
56 | 1.01k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF: |
57 | 1.24k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA: |
58 | 1.46k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF: |
59 | 1.66k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF: |
60 | 2.11k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR: |
61 | 5.11k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR: |
62 | 5.48k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR: |
63 | 5.48k | return 0; |
64 | 229 | default: |
65 | 229 | return AVERROR_INVALIDDATA; |
66 | 5.72k | } |
67 | 5.72k | } |
68 | | |
69 | | int av_smpte_436m_coded_anc_validate(const AVSmpte436mCodedAnc *anc) |
70 | 6.11k | { |
71 | 6.11k | int ret = validate_smpte_436m_anc_wrapping_type(anc->wrapping_type); |
72 | 6.11k | if (ret < 0) |
73 | 398 | return ret; |
74 | 5.72k | ret = validate_smpte_436m_anc_payload_sample_coding(anc->payload_sample_coding); |
75 | 5.72k | if (ret < 0) |
76 | 233 | return ret; |
77 | 5.48k | if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY) |
78 | 0 | return AVERROR_INVALIDDATA; |
79 | 5.48k | ret = av_smpte_436m_coded_anc_payload_size(anc->payload_sample_coding, anc->payload_sample_count); |
80 | 5.48k | if (ret < 0) |
81 | 248 | return ret; |
82 | 5.23k | if (anc->payload_array_length < ret) |
83 | 393 | return AVERROR_INVALIDDATA; |
84 | 4.84k | return 0; |
85 | 5.23k | } |
86 | | |
87 | | // Based off Table 7 (page 13) of: |
88 | | // https://pub.smpte.org/latest/st436/s436m-2006.pdf |
89 | 33.3k | #define SMPTE_436M_ANC_ENTRY_HEADER_SIZE ( \ |
90 | 33.3k | 2 /* line_number */ \ |
91 | 33.3k | + 1 /* wrapping_type */ \ |
92 | 33.3k | + 1 /* payload_sample_coding */ \ |
93 | 33.3k | + 2 /* payload_sample_count */ \ |
94 | 33.3k | + 4 /* payload_array_length */ \ |
95 | 33.3k | + 4 /* payload_array_element_size */ \ |
96 | 33.3k | ) |
97 | | |
98 | | /** |
99 | | * Decode an ANC packet. |
100 | | * @param[in] in Input bytes. |
101 | | * @param[in] size the size of in. |
102 | | * @param[out] anc the decoded ANC packet |
103 | | * @return The number of read bytes on success, AVERROR_INVALIDDATA otherwise. |
104 | | */ |
105 | | static int smpte_436m_anc_decode_entry(const uint8_t *in, int size, AVSmpte436mCodedAnc *anc) |
106 | 9.70k | { |
107 | | // Based off Table 7 (page 13) of: |
108 | | // https://pub.smpte.org/latest/st436/s436m-2006.pdf |
109 | 9.70k | if (SMPTE_436M_ANC_ENTRY_HEADER_SIZE > size) |
110 | 594 | return AVERROR_INVALIDDATA; |
111 | 9.11k | int needed_size = SMPTE_436M_ANC_ENTRY_HEADER_SIZE; |
112 | 9.11k | anc->line_number = AV_RB16(in); |
113 | 9.11k | in += 2; |
114 | 9.11k | anc->wrapping_type = AV_RB8(in); |
115 | 9.11k | in++; |
116 | 9.11k | anc->payload_sample_coding = AV_RB8(in); |
117 | 9.11k | in++; |
118 | 9.11k | anc->payload_sample_count = AV_RB16(in); |
119 | 9.11k | in += 2; |
120 | 9.11k | anc->payload_array_length = AV_RB32(in); |
121 | 9.11k | in += 4; |
122 | 9.11k | uint32_t payload_array_element_size = AV_RB32(in); |
123 | 9.11k | in += 4; |
124 | 9.11k | if (payload_array_element_size != 1) |
125 | 2.23k | return AVERROR_INVALIDDATA; |
126 | 6.87k | needed_size += anc->payload_array_length; |
127 | 6.87k | if (needed_size > size) |
128 | 348 | return AVERROR_INVALIDDATA; |
129 | 6.52k | if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY) |
130 | 410 | return AVERROR_INVALIDDATA; |
131 | 6.11k | memcpy(anc->payload, in, anc->payload_array_length); |
132 | 6.11k | int ret = av_smpte_436m_coded_anc_validate(anc); |
133 | 6.11k | if (ret < 0) |
134 | 1.27k | return ret; |
135 | 4.84k | return needed_size; |
136 | 6.11k | } |
137 | | |
138 | | /** |
139 | | * Encode an ANC packet. |
140 | | * @param[in] anc the ANC packet to encode |
141 | | * @param[in] size the size of out. ignored if out is NULL. |
142 | | * @param[out] out Output bytes. Doesn't write anything if out is NULL. |
143 | | * @return the number of bytes written on success, AVERROR codes otherwise. |
144 | | * If out is NULL, returns the number of bytes it would have written. |
145 | | */ |
146 | | static int smpte_436m_anc_encode_entry(uint8_t *out, int size, const AVSmpte436mCodedAnc *anc) |
147 | 14.5k | { |
148 | | // Based off Table 7 (page 13) of: |
149 | | // https://pub.smpte.org/latest/st436/s436m-2006.pdf |
150 | 14.5k | if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY) |
151 | 0 | return AVERROR_INVALIDDATA; |
152 | 14.5k | int needed_size = SMPTE_436M_ANC_ENTRY_HEADER_SIZE + (int)anc->payload_array_length; |
153 | 14.5k | if (!out) |
154 | 7.28k | return needed_size; |
155 | 7.28k | if (needed_size > size) |
156 | 0 | return AVERROR_BUFFER_TOO_SMALL; |
157 | 7.28k | AV_WB16(out, anc->line_number); |
158 | 7.28k | out += 2; |
159 | 7.28k | AV_WB8(out, anc->wrapping_type); |
160 | 7.28k | out++; |
161 | 7.28k | AV_WB8(out, anc->payload_sample_coding); |
162 | 7.28k | out++; |
163 | 7.28k | AV_WB16(out, anc->payload_sample_count); |
164 | 7.28k | out += 2; |
165 | 7.28k | AV_WB32(out, anc->payload_array_length); |
166 | 7.28k | out += 4; |
167 | 7.28k | AV_WB32(out, 1); // payload_array_element_size |
168 | 7.28k | out += 4; |
169 | 7.28k | memcpy(out, anc->payload, anc->payload_array_length); |
170 | 7.28k | return needed_size; |
171 | 7.28k | } |
172 | | |
173 | | int av_smpte_436m_anc_encode(uint8_t *out, int size, int anc_packet_count, const AVSmpte436mCodedAnc *anc_packets) |
174 | 14.5k | { |
175 | | // Based off Table 7 (page 13) of: |
176 | | // https://pub.smpte.org/latest/st436/s436m-2006.pdf |
177 | 14.5k | if (anc_packet_count < 0 || anc_packet_count >= (1L << 16) || size < 0) |
178 | 0 | return AVERROR_INVALIDDATA; |
179 | | |
180 | 14.5k | int needed_size = 2; |
181 | 14.5k | if (out) { |
182 | 7.28k | if (size < needed_size) |
183 | 0 | return AVERROR_BUFFER_TOO_SMALL; |
184 | 7.28k | AV_WB16(out, anc_packet_count); |
185 | 7.28k | out += 2; |
186 | 7.28k | size -= 2; |
187 | 7.28k | } |
188 | 29.1k | for (int i = 0; i < anc_packet_count; i++) { |
189 | 14.5k | int ret = smpte_436m_anc_encode_entry(out, size, &anc_packets[i]); |
190 | 14.5k | if (ret < 0) |
191 | 0 | return ret; |
192 | 14.5k | needed_size += ret; |
193 | 14.5k | if (out) { |
194 | 7.28k | size -= ret; |
195 | 7.28k | out += ret; |
196 | 7.28k | } |
197 | 14.5k | } |
198 | 14.5k | return needed_size; |
199 | 14.5k | } |
200 | | |
201 | | int av_smpte_436m_anc_append(AVPacket *pkt, int anc_packet_count, const AVSmpte436mCodedAnc *anc_packets) |
202 | 0 | { |
203 | 0 | int final_packet_count = 0; |
204 | 0 | int write_start = 2; |
205 | 0 | if (pkt->size >= 2) { |
206 | 0 | final_packet_count = AV_RB16(pkt->data); |
207 | 0 | write_start = pkt->size; |
208 | 0 | } else if (pkt->size != 0) // if packet isn't empty |
209 | 0 | return AVERROR_INVALIDDATA; |
210 | 0 | if (anc_packet_count < 0 || anc_packet_count >= (1L << 16)) |
211 | 0 | return AVERROR_INVALIDDATA; |
212 | 0 | final_packet_count += anc_packet_count; |
213 | 0 | if (final_packet_count >= (1L << 16)) |
214 | 0 | return AVERROR_INVALIDDATA; |
215 | 0 | int ret, additional_size = write_start - pkt->size; |
216 | 0 | for (int i = 0; i < anc_packet_count; i++) { |
217 | 0 | ret = smpte_436m_anc_encode_entry(NULL, 0, &anc_packets[i]); |
218 | 0 | if (ret < 0) |
219 | 0 | return ret; |
220 | 0 | additional_size += ret; |
221 | 0 | } |
222 | 0 | ret = av_grow_packet(pkt, additional_size); |
223 | 0 | if (ret < 0) |
224 | 0 | return ret; |
225 | 0 | for (int i = 0; i < anc_packet_count; i++) { |
226 | 0 | ret = smpte_436m_anc_encode_entry(pkt->data + write_start, pkt->size - write_start, &anc_packets[i]); |
227 | 0 | av_assert0(ret >= 0); |
228 | 0 | write_start += ret; |
229 | 0 | } |
230 | 0 | AV_WB16(pkt->data, final_packet_count); |
231 | 0 | return 0; |
232 | 0 | } |
233 | | |
234 | | int av_smpte_436m_anc_iter_init(AVSmpte436mAncIterator *iter, const uint8_t *buf, int buf_size) |
235 | 14.4k | { |
236 | | // Based off Table 7 (page 13) of: |
237 | | // https://pub.smpte.org/latest/st436/s436m-2006.pdf |
238 | 14.4k | if (buf_size < 2) |
239 | 1.88k | return AVERROR_INVALIDDATA; |
240 | 12.6k | *iter = (AVSmpte436mAncIterator){ |
241 | 12.6k | .anc_packets_left = AV_RB16(buf), |
242 | 12.6k | .size_left = buf_size - 2, |
243 | 12.6k | .data_left = buf + 2, |
244 | 12.6k | }; |
245 | 12.6k | if (iter->anc_packets_left > iter->size_left) |
246 | 4.20k | return AVERROR_INVALIDDATA; |
247 | 8.40k | return 0; |
248 | 12.6k | } |
249 | | |
250 | | int av_smpte_436m_anc_iter_next(AVSmpte436mAncIterator *iter, AVSmpte436mCodedAnc *anc) |
251 | 10.1k | { |
252 | 10.1k | if (iter->anc_packets_left <= 0) |
253 | 400 | return AVERROR_EOF; |
254 | 9.70k | iter->anc_packets_left--; |
255 | 9.70k | int ret = smpte_436m_anc_decode_entry(iter->data_left, iter->size_left, anc); |
256 | 9.70k | if (ret < 0) { |
257 | 4.86k | iter->anc_packets_left = 0; |
258 | 4.86k | return ret; |
259 | 4.86k | } |
260 | 4.84k | iter->data_left += ret; |
261 | 4.84k | iter->size_left -= ret; |
262 | 4.84k | return 0; |
263 | 9.70k | } |
264 | | |
265 | | int av_smpte_436m_coded_anc_payload_size(AVSmpte436mPayloadSampleCoding sample_coding, uint16_t sample_count) |
266 | 13.0k | { |
267 | 13.0k | if (sample_count > AV_SMPTE_436M_CODED_ANC_SAMPLE_CAPACITY) |
268 | 248 | return AVERROR_INVALIDDATA; |
269 | 12.8k | switch (sample_coding) { |
270 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA: |
271 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF: |
272 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF: |
273 | 0 | return AVERROR_INVALIDDATA; |
274 | 8.11k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA: |
275 | 8.32k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF: |
276 | 8.57k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF: |
277 | 8.79k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR: |
278 | 11.7k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR: |
279 | 12.1k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR: |
280 | | // "The Payload Byte Array shall be padded to achieve UInt32 alignment." |
281 | | // section 4.4 of https://pub.smpte.org/latest/st436/s436m-2006.pdf |
282 | 12.1k | return (sample_count + 3) & -4; |
283 | 231 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA: |
284 | 446 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF: |
285 | 646 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF: |
286 | | // encoded with 3 10-bit samples in a UInt32. |
287 | | // "The Payload Byte Array shall be padded to achieve UInt32 alignment." |
288 | | // section 4.4 of https://pub.smpte.org/latest/st436/s436m-2006.pdf |
289 | 646 | return 4 * ((sample_count + 2) / 3); |
290 | 0 | default: |
291 | 0 | return AVERROR_INVALIDDATA; |
292 | 12.8k | } |
293 | 12.8k | } |
294 | | |
295 | | int av_smpte_291m_anc_8bit_decode(AVSmpte291mAnc8bit *out, |
296 | | AVSmpte436mPayloadSampleCoding sample_coding, |
297 | | uint16_t sample_count, |
298 | | const uint8_t *payload, |
299 | | void *log_ctx) |
300 | 258k | { |
301 | 258k | switch (sample_coding) { |
302 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA: |
303 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF: |
304 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF: |
305 | 0 | return AVERROR_INVALIDDATA; |
306 | 253k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA: |
307 | 253k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF: |
308 | 254k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF: |
309 | 254k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR: |
310 | 257k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR: |
311 | 257k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR: |
312 | 257k | { |
313 | 257k | if (sample_count < 3) |
314 | 4.82k | return AVERROR_INVALIDDATA; |
315 | 252k | out->did = *payload++; |
316 | 252k | out->sdid_or_dbn = *payload++; |
317 | 252k | out->data_count = *payload++; |
318 | 252k | if (sample_count < out->data_count + 3) |
319 | 38.8k | return AVERROR_INVALIDDATA; |
320 | 213k | memcpy(out->payload, payload, out->data_count); |
321 | | // the checksum isn't stored in 8-bit mode, so calculate it. |
322 | 213k | av_smpte_291m_anc_8bit_fill_checksum(out); |
323 | 213k | return 0; |
324 | 252k | } |
325 | 229 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA: |
326 | 442 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF: |
327 | 642 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF: |
328 | 642 | av_log(log_ctx, |
329 | 642 | AV_LOG_ERROR, |
330 | 642 | "decoding an ANC packet using the 10-bit SMPTE 436M sample coding isn't implemented.\n"); |
331 | 642 | return AVERROR_PATCHWELCOME; |
332 | 0 | default: |
333 | 0 | return AVERROR_INVALIDDATA; |
334 | 258k | } |
335 | 258k | } |
336 | | |
337 | | void av_smpte_291m_anc_8bit_fill_checksum(AVSmpte291mAnc8bit *anc) |
338 | 221k | { |
339 | 221k | uint8_t checksum = anc->did + anc->sdid_or_dbn + anc->data_count; |
340 | 6.42M | for (unsigned i = 0; i < anc->data_count; i++) { |
341 | 6.20M | checksum += anc->payload[i]; |
342 | 6.20M | } |
343 | 221k | anc->checksum = checksum; |
344 | 221k | } |
345 | | |
346 | | int av_smpte_291m_anc_8bit_get_sample_count(const AVSmpte291mAnc8bit *anc, |
347 | | AVSmpte436mPayloadSampleCoding sample_coding, |
348 | | void *log_ctx) |
349 | 7.56k | { |
350 | 7.56k | switch (sample_coding) { |
351 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA: |
352 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF: |
353 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF: |
354 | 0 | return AVERROR_INVALIDDATA; |
355 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA: |
356 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF: |
357 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF: |
358 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR: |
359 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR: |
360 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR: |
361 | | // 3 for did, sdid_or_dbn, and data_count; checksum isn't stored in 8-bit modes |
362 | 7.56k | return 3 + anc->data_count; |
363 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA: |
364 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF: |
365 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF: |
366 | 0 | av_log(log_ctx, |
367 | 0 | AV_LOG_ERROR, |
368 | 0 | "encoding an ANC packet using the 10-bit SMPTE 436M sample coding isn't implemented.\n"); |
369 | 0 | return AVERROR_PATCHWELCOME; |
370 | 0 | default: |
371 | 0 | return AVERROR_INVALIDDATA; |
372 | 7.56k | } |
373 | 7.56k | } |
374 | | |
375 | | int av_smpte_291m_anc_8bit_encode(AVSmpte436mCodedAnc *out, |
376 | | uint16_t line_number, |
377 | | AVSmpte436mWrappingType wrapping_type, |
378 | | AVSmpte436mPayloadSampleCoding sample_coding, |
379 | | const AVSmpte291mAnc8bit *payload, |
380 | | void *log_ctx) |
381 | 7.56k | { |
382 | 7.56k | out->line_number = line_number; |
383 | 7.56k | out->wrapping_type = wrapping_type; |
384 | 7.56k | out->payload_sample_coding = sample_coding; |
385 | | |
386 | 7.56k | int ret = av_smpte_291m_anc_8bit_get_sample_count(payload, sample_coding, log_ctx); |
387 | 7.56k | if (ret < 0) |
388 | 0 | return ret; |
389 | | |
390 | 7.56k | out->payload_sample_count = ret; |
391 | | |
392 | 7.56k | ret = av_smpte_436m_coded_anc_payload_size(sample_coding, out->payload_sample_count); |
393 | 7.56k | if (ret < 0) |
394 | 0 | return ret; |
395 | | |
396 | 7.56k | out->payload_array_length = ret; |
397 | | |
398 | 7.56k | switch (sample_coding) { |
399 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA: |
400 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF: |
401 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF: |
402 | 0 | return AVERROR_INVALIDDATA; |
403 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA: |
404 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF: |
405 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF: |
406 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR: |
407 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR: |
408 | 7.56k | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR: |
409 | 7.56k | { |
410 | | // fill trailing padding with zeros |
411 | 7.56k | av_assert0(out->payload_array_length >= 4); |
412 | 7.56k | memset(out->payload + out->payload_array_length - 4, 0, 4); |
413 | | |
414 | 7.56k | out->payload[0] = payload->did; |
415 | 7.56k | out->payload[1] = payload->sdid_or_dbn; |
416 | 7.56k | out->payload[2] = payload->data_count; |
417 | | |
418 | 7.56k | memcpy(out->payload + 3, payload->payload, payload->data_count); |
419 | 7.56k | return 0; |
420 | 7.56k | } |
421 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA: |
422 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF: |
423 | 0 | case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF: |
424 | 0 | av_log(log_ctx, |
425 | 0 | AV_LOG_ERROR, |
426 | 0 | "encoding an ANC packet using the 10-bit SMPTE 436M sample coding isn't implemented.\n"); |
427 | 0 | return AVERROR_PATCHWELCOME; |
428 | 0 | default: |
429 | 0 | return AVERROR_INVALIDDATA; |
430 | 7.56k | } |
431 | 7.56k | } |
432 | | |
433 | | int av_smpte_291m_anc_8bit_extract_cta_708(const AVSmpte291mAnc8bit *anc, uint8_t *cc_data, void *log_ctx) |
434 | 214k | { |
435 | 214k | if (anc->did != AV_SMPTE_291M_ANC_DID_CTA_708 || anc->sdid_or_dbn != AV_SMPTE_291M_ANC_SDID_CTA_708) |
436 | 3.65k | return AVERROR(EAGAIN); |
437 | 210k | GetByteContext gb; |
438 | 210k | bytestream2_init(&gb, anc->payload, anc->data_count); |
439 | | // based on Caption Distribution Packet (CDP) Definition: |
440 | | // https://pub.smpte.org/latest/st334-2/st0334-2-2015.pdf |
441 | 210k | uint16_t cdp_identifier = bytestream2_get_be16(&gb); |
442 | 210k | if (cdp_identifier != 0x9669) { // CDPs always have this value |
443 | 5.38k | av_log(log_ctx, AV_LOG_ERROR, "wrong cdp identifier %x\n", cdp_identifier); |
444 | 5.38k | return AVERROR_INVALIDDATA; |
445 | 5.38k | } |
446 | 205k | bytestream2_get_byte(&gb); // cdp_length |
447 | 205k | bytestream2_get_byte(&gb); // cdp_frame_rate and reserved |
448 | 205k | bytestream2_get_byte(&gb); // flags |
449 | 205k | bytestream2_get_be16(&gb); // cdp_hdr_sequence_cntr |
450 | 205k | unsigned section_id = bytestream2_get_byte(&gb); |
451 | | |
452 | 205k | const unsigned TIME_CODE_SECTION_ID = 0x71; |
453 | 205k | if (section_id == TIME_CODE_SECTION_ID) { |
454 | 858 | bytestream2_skip(&gb, 4); // skip time code section |
455 | 858 | section_id = bytestream2_get_byte(&gb); |
456 | 858 | } |
457 | 205k | const unsigned CC_DATA_SECTION_ID = 0x72; |
458 | 205k | if (section_id == CC_DATA_SECTION_ID) { |
459 | 199k | if (bytestream2_get_bytes_left(&gb) < 1) |
460 | 426 | goto too_short; |
461 | | // 0x1F for lower 5 bits, upper 3 bits are marker bits |
462 | 199k | unsigned cc_count = bytestream2_get_byte(&gb) & 0x1F; |
463 | 199k | unsigned data_length = cc_count * 3; // EIA-608/CTA-708 triples are 3 bytes long |
464 | 199k | if (bytestream2_get_bytes_left(&gb) < data_length) |
465 | 2.57k | goto too_short; |
466 | 196k | if (cc_data) |
467 | 196k | bytestream2_get_bufferu(&gb, cc_data, data_length); |
468 | 196k | return cc_count; |
469 | 199k | } |
470 | 5.66k | return AVERROR(EAGAIN); |
471 | | |
472 | 3.00k | too_short: |
473 | 3.00k | av_log(log_ctx, AV_LOG_ERROR, "not enough bytes in cdp\n"); |
474 | 3.00k | return AVERROR_INVALIDDATA; |
475 | 205k | } |