FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/smpte_436m.c
Date: 2025-08-19 23:55:23
Exec Total Coverage
Lines: 184 256 71.9%
Functions: 15 15 100.0%
Branches: 67 121 55.4%

Line Branch Exec Source
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 378 static int validate_smpte_436m_anc_wrapping_type(AVSmpte436mWrappingType wrapping_type)
30 {
31
1/2
✓ Branch 0 taken 378 times.
✗ Branch 1 not taken.
378 switch (wrapping_type) {
32 378 case AV_SMPTE_436M_WRAPPING_TYPE_VANC_FRAME:
33 case AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_1:
34 case AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_2:
35 case AV_SMPTE_436M_WRAPPING_TYPE_VANC_PROGRESSIVE_FRAME:
36 case AV_SMPTE_436M_WRAPPING_TYPE_HANC_FRAME:
37 case AV_SMPTE_436M_WRAPPING_TYPE_HANC_FIELD_1:
38 case AV_SMPTE_436M_WRAPPING_TYPE_HANC_FIELD_2:
39 case AV_SMPTE_436M_WRAPPING_TYPE_HANC_PROGRESSIVE_FRAME:
40 378 return 0;
41 default:
42 return AVERROR_INVALIDDATA;
43 }
44 }
45
46 378 static int validate_smpte_436m_anc_payload_sample_coding(AVSmpte436mPayloadSampleCoding payload_sample_coding)
47 {
48
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
✗ Branch 2 not taken.
378 switch (payload_sample_coding) {
49 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA:
50 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF:
51 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF:
52 // not allowed for ANC packets
53 return AVERROR_INVALIDDATA;
54 378 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA:
55 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF:
56 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF:
57 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA:
58 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF:
59 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF:
60 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR:
61 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR:
62 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR:
63 378 return 0;
64 default:
65 return AVERROR_INVALIDDATA;
66 }
67 }
68
69 378 int av_smpte_436m_coded_anc_validate(const AVSmpte436mCodedAnc *anc)
70 {
71 378 int ret = validate_smpte_436m_anc_wrapping_type(anc->wrapping_type);
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (ret < 0)
73 return ret;
74 378 ret = validate_smpte_436m_anc_payload_sample_coding(anc->payload_sample_coding);
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (ret < 0)
76 return ret;
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY)
78 return AVERROR_INVALIDDATA;
79 378 ret = av_smpte_436m_coded_anc_payload_size(anc->payload_sample_coding, anc->payload_sample_count);
80
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (ret < 0)
81 return ret;
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (anc->payload_array_length < ret)
83 return AVERROR_INVALIDDATA;
84 378 return 0;
85 }
86
87 // Based off Table 7 (page 13) of:
88 // https://pub.smpte.org/latest/st436/s436m-2006.pdf
89 #define SMPTE_436M_ANC_ENTRY_HEADER_SIZE ( \
90 2 /* line_number */ \
91 + 1 /* wrapping_type */ \
92 + 1 /* payload_sample_coding */ \
93 + 2 /* payload_sample_count */ \
94 + 4 /* payload_array_length */ \
95 + 4 /* payload_array_element_size */ \
96 )
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 378 static int smpte_436m_anc_decode_entry(const uint8_t *in, int size, AVSmpte436mCodedAnc *anc)
106 {
107 // Based off Table 7 (page 13) of:
108 // https://pub.smpte.org/latest/st436/s436m-2006.pdf
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (SMPTE_436M_ANC_ENTRY_HEADER_SIZE > size)
110 return AVERROR_INVALIDDATA;
111 378 int needed_size = SMPTE_436M_ANC_ENTRY_HEADER_SIZE;
112 378 anc->line_number = AV_RB16(in);
113 378 in += 2;
114 378 anc->wrapping_type = AV_RB8(in);
115 378 in++;
116 378 anc->payload_sample_coding = AV_RB8(in);
117 378 in++;
118 378 anc->payload_sample_count = AV_RB16(in);
119 378 in += 2;
120 378 anc->payload_array_length = AV_RB32(in);
121 378 in += 4;
122 378 uint32_t payload_array_element_size = AV_RB32(in);
123 378 in += 4;
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (payload_array_element_size != 1)
125 return AVERROR_INVALIDDATA;
126 378 needed_size += anc->payload_array_length;
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (needed_size > size)
128 return AVERROR_INVALIDDATA;
129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY)
130 return AVERROR_INVALIDDATA;
131 378 memcpy(anc->payload, in, anc->payload_array_length);
132 378 int ret = av_smpte_436m_coded_anc_validate(anc);
133
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (ret < 0)
134 return ret;
135 378 return needed_size;
136 }
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 788 static int smpte_436m_anc_encode_entry(uint8_t *out, int size, const AVSmpte436mCodedAnc *anc)
147 {
148 // Based off Table 7 (page 13) of:
149 // https://pub.smpte.org/latest/st436/s436m-2006.pdf
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 788 times.
788 if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY)
151 return AVERROR_INVALIDDATA;
152 788 int needed_size = SMPTE_436M_ANC_ENTRY_HEADER_SIZE + (int)anc->payload_array_length;
153
2/2
✓ Branch 0 taken 394 times.
✓ Branch 1 taken 394 times.
788 if (!out)
154 394 return needed_size;
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 394 times.
394 if (needed_size > size)
156 return AVERROR_BUFFER_TOO_SMALL;
157 394 AV_WB16(out, anc->line_number);
158 394 out += 2;
159 394 AV_WB8(out, anc->wrapping_type);
160 394 out++;
161 394 AV_WB8(out, anc->payload_sample_coding);
162 394 out++;
163 394 AV_WB16(out, anc->payload_sample_count);
164 394 out += 2;
165 394 AV_WB32(out, anc->payload_array_length);
166 394 out += 4;
167 394 AV_WB32(out, 1); // payload_array_element_size
168 394 out += 4;
169 394 memcpy(out, anc->payload, anc->payload_array_length);
170 394 return needed_size;
171 }
172
173 596 int av_smpte_436m_anc_encode(uint8_t *out, int size, int anc_packet_count, const AVSmpte436mCodedAnc *anc_packets)
174 {
175 // Based off Table 7 (page 13) of:
176 // https://pub.smpte.org/latest/st436/s436m-2006.pdf
177
3/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 596 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 596 times.
596 if (anc_packet_count < 0 || anc_packet_count >= (1L << 16) || size < 0)
178 return AVERROR_INVALIDDATA;
179
180 596 int needed_size = 2;
181
2/2
✓ Branch 0 taken 298 times.
✓ Branch 1 taken 298 times.
596 if (out) {
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 298 times.
298 if (size < needed_size)
183 return AVERROR_BUFFER_TOO_SMALL;
184 298 AV_WB16(out, anc_packet_count);
185 298 out += 2;
186 298 size -= 2;
187 }
188
2/2
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 596 times.
1192 for (int i = 0; i < anc_packet_count; i++) {
189 596 int ret = smpte_436m_anc_encode_entry(out, size, &anc_packets[i]);
190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 596 times.
596 if (ret < 0)
191 return ret;
192 596 needed_size += ret;
193
2/2
✓ Branch 0 taken 298 times.
✓ Branch 1 taken 298 times.
596 if (out) {
194 298 size -= ret;
195 298 out += ret;
196 }
197 }
198 596 return needed_size;
199 }
200
201 96 int av_smpte_436m_anc_append(AVPacket *pkt, int anc_packet_count, const AVSmpte436mCodedAnc *anc_packets)
202 {
203 96 int final_packet_count = 0;
204 96 int write_start = 2;
205
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 64 times.
96 if (pkt->size >= 2) {
206 32 final_packet_count = AV_RB16(pkt->data);
207 32 write_start = pkt->size;
208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 } else if (pkt->size != 0) // if packet isn't empty
209 return AVERROR_INVALIDDATA;
210
2/4
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
96 if (anc_packet_count < 0 || anc_packet_count >= (1L << 16))
211 return AVERROR_INVALIDDATA;
212 96 final_packet_count += anc_packet_count;
213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (final_packet_count >= (1L << 16))
214 return AVERROR_INVALIDDATA;
215 96 int ret, additional_size = write_start - pkt->size;
216
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 96 times.
192 for (int i = 0; i < anc_packet_count; i++) {
217 96 ret = smpte_436m_anc_encode_entry(NULL, 0, &anc_packets[i]);
218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (ret < 0)
219 return ret;
220 96 additional_size += ret;
221 }
222 96 ret = av_grow_packet(pkt, additional_size);
223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (ret < 0)
224 return ret;
225
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 96 times.
192 for (int i = 0; i < anc_packet_count; i++) {
226 96 ret = smpte_436m_anc_encode_entry(pkt->data + write_start, pkt->size - write_start, &anc_packets[i]);
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 av_assert0(ret >= 0);
228 96 write_start += ret;
229 }
230 96 AV_WB16(pkt->data, final_packet_count);
231 96 return 0;
232 }
233
234 362 int av_smpte_436m_anc_iter_init(AVSmpte436mAncIterator *iter, const uint8_t *buf, int buf_size)
235 {
236 // Based off Table 7 (page 13) of:
237 // https://pub.smpte.org/latest/st436/s436m-2006.pdf
238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 362 times.
362 if (buf_size < 2)
239 return AVERROR_INVALIDDATA;
240 362 *iter = (AVSmpte436mAncIterator){
241 362 .anc_packets_left = AV_RB16(buf),
242 362 .size_left = buf_size - 2,
243 362 .data_left = buf + 2,
244 };
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 362 times.
362 if (iter->anc_packets_left > iter->size_left)
246 return AVERROR_INVALIDDATA;
247 362 return 0;
248 }
249
250 708 int av_smpte_436m_anc_iter_next(AVSmpte436mAncIterator *iter, AVSmpte436mCodedAnc *anc)
251 {
252
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 378 times.
708 if (iter->anc_packets_left <= 0)
253 330 return AVERROR_EOF;
254 378 iter->anc_packets_left--;
255 378 int ret = smpte_436m_anc_decode_entry(iter->data_left, iter->size_left, anc);
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
378 if (ret < 0) {
257 iter->anc_packets_left = 0;
258 return ret;
259 }
260 378 iter->data_left += ret;
261 378 iter->size_left -= ret;
262 378 return 0;
263 }
264
265 680 int av_smpte_436m_coded_anc_payload_size(AVSmpte436mPayloadSampleCoding sample_coding, uint16_t sample_count)
266 {
267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 680 times.
680 if (sample_count > AV_SMPTE_436M_CODED_ANC_SAMPLE_CAPACITY)
268 return AVERROR_INVALIDDATA;
269
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 680 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
680 switch (sample_coding) {
270 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA:
271 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF:
272 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF:
273 return AVERROR_INVALIDDATA;
274 680 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA:
275 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF:
276 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF:
277 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR:
278 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR:
279 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 680 return (sample_count + 3) & -4;
283 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA:
284 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF:
285 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 return 4 * ((sample_count + 2) / 3);
290 default:
291 return AVERROR_INVALIDDATA;
292 }
293 }
294
295 474 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 {
301
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 474 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
474 switch (sample_coding) {
302 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA:
303 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF:
304 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF:
305 return AVERROR_INVALIDDATA;
306 474 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA:
307 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF:
308 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF:
309 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR:
310 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR:
311 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR:
312 {
313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 474 times.
474 if (sample_count < 3)
314 return AVERROR_INVALIDDATA;
315 474 out->did = *payload++;
316 474 out->sdid_or_dbn = *payload++;
317 474 out->data_count = *payload++;
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 474 times.
474 if (sample_count < out->data_count + 3)
319 return AVERROR_INVALIDDATA;
320 474 memcpy(out->payload, payload, out->data_count);
321 // the checksum isn't stored in 8-bit mode, so calculate it.
322 474 av_smpte_291m_anc_8bit_fill_checksum(out);
323 474 return 0;
324 }
325 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA:
326 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF:
327 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF:
328 av_log(log_ctx,
329 AV_LOG_ERROR,
330 "decoding an ANC packet using the 10-bit SMPTE 436M sample coding isn't implemented.\n");
331 return AVERROR_PATCHWELCOME;
332 default:
333 return AVERROR_INVALIDDATA;
334 }
335 }
336
337 772 void av_smpte_291m_anc_8bit_fill_checksum(AVSmpte291mAnc8bit *anc)
338 {
339 772 uint8_t checksum = anc->did + anc->sdid_or_dbn + anc->data_count;
340
2/2
✓ Branch 0 taken 31252 times.
✓ Branch 1 taken 772 times.
32024 for (unsigned i = 0; i < anc->data_count; i++) {
341 31252 checksum += anc->payload[i];
342 }
343 772 anc->checksum = checksum;
344 772 }
345
346 302 int av_smpte_291m_anc_8bit_get_sample_count(const AVSmpte291mAnc8bit *anc,
347 AVSmpte436mPayloadSampleCoding sample_coding,
348 void *log_ctx)
349 {
350
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 302 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
302 switch (sample_coding) {
351 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA:
352 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF:
353 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF:
354 return AVERROR_INVALIDDATA;
355 302 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA:
356 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF:
357 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF:
358 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR:
359 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR:
360 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 302 return 3 + anc->data_count;
363 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA:
364 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF:
365 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF:
366 av_log(log_ctx,
367 AV_LOG_ERROR,
368 "encoding an ANC packet using the 10-bit SMPTE 436M sample coding isn't implemented.\n");
369 return AVERROR_PATCHWELCOME;
370 default:
371 return AVERROR_INVALIDDATA;
372 }
373 }
374
375 302 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 {
382 302 out->line_number = line_number;
383 302 out->wrapping_type = wrapping_type;
384 302 out->payload_sample_coding = sample_coding;
385
386 302 int ret = av_smpte_291m_anc_8bit_get_sample_count(payload, sample_coding, log_ctx);
387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 302 times.
302 if (ret < 0)
388 return ret;
389
390 302 out->payload_sample_count = ret;
391
392 302 ret = av_smpte_436m_coded_anc_payload_size(sample_coding, out->payload_sample_count);
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 302 times.
302 if (ret < 0)
394 return ret;
395
396 302 out->payload_array_length = ret;
397
398
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 302 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
302 switch (sample_coding) {
399 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA:
400 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF:
401 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF:
402 return AVERROR_INVALIDDATA;
403 302 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA:
404 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF:
405 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF:
406 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR:
407 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR:
408 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR:
409 {
410 // fill trailing padding with zeros
411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 302 times.
302 av_assert0(out->payload_array_length >= 4);
412 302 memset(out->payload + out->payload_array_length - 4, 0, 4);
413
414 302 out->payload[0] = payload->did;
415 302 out->payload[1] = payload->sdid_or_dbn;
416 302 out->payload[2] = payload->data_count;
417
418 302 memcpy(out->payload + 3, payload->payload, payload->data_count);
419 302 return 0;
420 }
421 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA:
422 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF:
423 case AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF:
424 av_log(log_ctx,
425 AV_LOG_ERROR,
426 "encoding an ANC packet using the 10-bit SMPTE 436M sample coding isn't implemented.\n");
427 return AVERROR_PATCHWELCOME;
428 default:
429 return AVERROR_INVALIDDATA;
430 }
431 }
432
433 160 int av_smpte_291m_anc_8bit_extract_cta_708(const AVSmpte291mAnc8bit *anc, uint8_t *cc_data, void *log_ctx)
434 {
435
3/4
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 128 times.
160 if (anc->did != AV_SMPTE_291M_ANC_DID_CTA_708 || anc->sdid_or_dbn != AV_SMPTE_291M_ANC_SDID_CTA_708)
436 32 return AVERROR(EAGAIN);
437 GetByteContext gb;
438 128 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 128 uint16_t cdp_identifier = bytestream2_get_be16(&gb);
442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (cdp_identifier != 0x9669) { // CDPs always have this value
443 av_log(log_ctx, AV_LOG_ERROR, "wrong cdp identifier %x\n", cdp_identifier);
444 return AVERROR_INVALIDDATA;
445 }
446 128 bytestream2_get_byte(&gb); // cdp_length
447 128 bytestream2_get_byte(&gb); // cdp_frame_rate and reserved
448 128 bytestream2_get_byte(&gb); // flags
449 128 bytestream2_get_be16(&gb); // cdp_hdr_sequence_cntr
450 128 unsigned section_id = bytestream2_get_byte(&gb);
451
452 128 const unsigned TIME_CODE_SECTION_ID = 0x71;
453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (section_id == TIME_CODE_SECTION_ID) {
454 bytestream2_skip(&gb, 4); // skip time code section
455 section_id = bytestream2_get_byte(&gb);
456 }
457 128 const unsigned CC_DATA_SECTION_ID = 0x72;
458
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 if (section_id == CC_DATA_SECTION_ID) {
459
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 128 times.
128 if (bytestream2_get_bytes_left(&gb) < 1)
460 goto too_short;
461 // 0x1F for lower 5 bits, upper 3 bits are marker bits
462 128 unsigned cc_count = bytestream2_get_byte(&gb) & 0x1F;
463 128 unsigned data_length = cc_count * 3; // EIA-608/CTA-708 triples are 3 bytes long
464
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 128 times.
128 if (bytestream2_get_bytes_left(&gb) < data_length)
465 goto too_short;
466
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 32 times.
128 if (cc_data)
467 96 bytestream2_get_bufferu(&gb, cc_data, data_length);
468 128 return cc_count;
469 }
470 return AVERROR(EAGAIN);
471
472 too_short:
473 av_log(log_ctx, AV_LOG_ERROR, "not enough bytes in cdp\n");
474 return AVERROR_INVALIDDATA;
475 }
476