History

lavc: add API for manipulating SMPTE-436M VBI/ANC data

Jacob Lifshay committed 1 year ago

Commit 1c85a381 parent a566fcb7 files · +835 −0Browse files

Unified · Split

7 files
  1. .forgejo/pre-commit/ignored-words.txt +1 −0
  2. configure +1 −0
  3. doc/APIchanges +4 −0
  4. libavcodec/Makefile +2 −0
  5. libavcodec/smpte_436m.c +475 −0
  6. libavcodec/smpte_436m.h +254 −0
  7. libavcodec/smpte_436m_internal.h +98 −0
.forgejo/pre-commit/ignored-words.txt+1−0
@@ -8,6 +8,7 @@ ALOG · 7 unmodified lines
8ALS8ALS
9als9als
10ANC10ANC
11anc
11ANS12ANS
12ans13ans
13anull14anull
configure+1−0
@@ -2651,6 +2651,7 @@ CONFIG_EXTRA=" · 2650 unmodified lines
2651 rv34dsp2651 rv34dsp
2652 scene_sad2652 scene_sad
2653 sinewin2653 sinewin
2654 smpte_436m
2654 snappy2655 snappy
2655 srtp2656 srtp
2656 startcode2657 startcode
doc/APIchanges+4−0
@@ -2,6 +2,10 @@ The last version increases of all libraries were on 2025-03-28 · 1 unmodified line
2 2
3API changes, most recent first:3API changes, most recent first:
4 4
52025-07-29 - xxxxxxxxxx - lavc 62.10.100 - smpte_436m.h
6 Add a new public header smpte_436m.h with API for
7 manipulating AV_CODEC_ID_SMPTE_436M_ANC data.
8
52025-07-10 - xxxxxxxxxx - lavf 62.2.10092025-07-10 - xxxxxxxxxx - lavf 62.2.100
6 mxf [de]muxer now uses AV_CODEC_ID_SMPTE_436M_ANC for10 mxf [de]muxer now uses AV_CODEC_ID_SMPTE_436M_ANC for
7 the vbi_vanc_smpte_436M streams instead of AV_CODEC_ID_NONE.11 the vbi_vanc_smpte_436M streams instead of AV_CODEC_ID_NONE.
libavcodec/Makefile+2−0
@@ -19,6 +19,7 @@ HEADERS = ac3_parser.h \ · 18 unmodified lines
19 mediacodec.h \19 mediacodec.h \
20 packet.h \20 packet.h \
21 qsv.h \21 qsv.h \
22 smpte_436m.h \
22 vdpau.h \23 vdpau.h \
23 version.h \24 version.h \
24 version_major.h \25 version_major.h \
@@ -167,6 +168,7 @@ OBJS-$(CONFIG_QSVENC) += qsvenc.o · 142 unmodified lines
167OBJS-$(CONFIG_RANGECODER) += rangecoder.o168OBJS-$(CONFIG_RANGECODER) += rangecoder.o
168OBJS-$(CONFIG_RV34DSP) += rv34dsp.o169OBJS-$(CONFIG_RV34DSP) += rv34dsp.o
169OBJS-$(CONFIG_SINEWIN) += sinewin.o170OBJS-$(CONFIG_SINEWIN) += sinewin.o
171OBJS-$(CONFIG_SMPTE_436M) += smpte_436m.o
170OBJS-$(CONFIG_SNAPPY) += snappy.o172OBJS-$(CONFIG_SNAPPY) += snappy.o
171OBJS-$(CONFIG_STARTCODE) += startcode.o173OBJS-$(CONFIG_STARTCODE) += startcode.o
172OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o174OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o
libavcodec/smpte_436m.c+475−0
@@ -0,0 +1,475 @@
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
29static int validate_smpte_436m_anc_wrapping_type(AVSmpte436mWrappingType wrapping_type)
30{
31 switch (wrapping_type) {
32 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 return 0;
41 default:
42 return AVERROR_INVALIDDATA;
43 }
44}
45
46static int validate_smpte_436m_anc_payload_sample_coding(AVSmpte436mPayloadSampleCoding payload_sample_coding)
47{
48 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 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 return 0;
64 default:
65 return AVERROR_INVALIDDATA;
66 }
67}
68
69int av_smpte_436m_coded_anc_validate(const AVSmpte436mCodedAnc *anc)
70{
71 int ret = validate_smpte_436m_anc_wrapping_type(anc->wrapping_type);
72 if (ret < 0)
73 return ret;
74 ret = validate_smpte_436m_anc_payload_sample_coding(anc->payload_sample_coding);
75 if (ret < 0)
76 return ret;
77 if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY)
78 return AVERROR_INVALIDDATA;
79 ret = av_smpte_436m_coded_anc_payload_size(anc->payload_sample_coding, anc->payload_sample_count);
80 if (ret < 0)
81 return ret;
82 if (anc->payload_array_length < ret)
83 return AVERROR_INVALIDDATA;
84 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 */
105static 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 if (SMPTE_436M_ANC_ENTRY_HEADER_SIZE > size)
110 return AVERROR_INVALIDDATA;
111 int needed_size = SMPTE_436M_ANC_ENTRY_HEADER_SIZE;
112 anc->line_number = AV_RB16(in);
113 in += 2;
114 anc->wrapping_type = AV_RB8(in);
115 in++;
116 anc->payload_sample_coding = AV_RB8(in);
117 in++;
118 anc->payload_sample_count = AV_RB16(in);
119 in += 2;
120 anc->payload_array_length = AV_RB32(in);
121 in += 4;
122 uint32_t payload_array_element_size = AV_RB32(in);
123 in += 4;
124 if (payload_array_element_size != 1)
125 return AVERROR_INVALIDDATA;
126 needed_size += anc->payload_array_length;
127 if (needed_size > size)
128 return AVERROR_INVALIDDATA;
129 if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY)
130 return AVERROR_INVALIDDATA;
131 memcpy(anc->payload, in, anc->payload_array_length);
132 int ret = av_smpte_436m_coded_anc_validate(anc);
133 if (ret < 0)
134 return ret;
135 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 */
146static 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 if (anc->payload_array_length > AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY)
151 return AVERROR_INVALIDDATA;
152 int needed_size = SMPTE_436M_ANC_ENTRY_HEADER_SIZE + (int)anc->payload_array_length;
153 if (!out)
154 return needed_size;
155 if (needed_size > size)
156 return AVERROR_BUFFER_TOO_SMALL;
157 AV_WB16(out, anc->line_number);
158 out += 2;
159 AV_WB8(out, anc->wrapping_type);
160 out++;
161 AV_WB8(out, anc->payload_sample_coding);
162 out++;
163 AV_WB16(out, anc->payload_sample_count);
164 out += 2;
165 AV_WB32(out, anc->payload_array_length);
166 out += 4;
167 AV_WB32(out, 1); // payload_array_element_size
168 out += 4;
169 memcpy(out, anc->payload, anc->payload_array_length);
170 return needed_size;
171}
172
173int 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 if (anc_packet_count < 0 || anc_packet_count >= (1L << 16) || size < 0)
178 return AVERROR_INVALIDDATA;
179
180 int needed_size = 2;
181 if (out) {
182 if (size < needed_size)
183 return AVERROR_BUFFER_TOO_SMALL;
184 AV_WB16(out, anc_packet_count);
185 out += 2;
186 size -= 2;
187 }
188 for (int i = 0; i < anc_packet_count; i++) {
189 int ret = smpte_436m_anc_encode_entry(out, size, &anc_packets[i]);
190 if (ret < 0)
191 return ret;
192 needed_size += ret;
193 if (out) {
194 size -= ret;
195 out += ret;
196 }
197 }
198 return needed_size;
199}
200
201int av_smpte_436m_anc_append(AVPacket *pkt, int anc_packet_count, const AVSmpte436mCodedAnc *anc_packets)
202{
203 int final_packet_count = 0;
204 int write_start = 2;
205 if (pkt->size >= 2) {
206 final_packet_count = AV_RB16(pkt->data);
207 write_start = pkt->size;
208 } else if (pkt->size != 0) // if packet isn't empty
209 return AVERROR_INVALIDDATA;
210 if (anc_packet_count < 0 || anc_packet_count >= (1L << 16))
211 return AVERROR_INVALIDDATA;
212 final_packet_count += anc_packet_count;
213 if (final_packet_count >= (1L << 16))
214 return AVERROR_INVALIDDATA;
215 int ret, additional_size = write_start - pkt->size;
216 for (int i = 0; i < anc_packet_count; i++) {
217 ret = smpte_436m_anc_encode_entry(NULL, 0, &anc_packets[i]);
218 if (ret < 0)
219 return ret;
220 additional_size += ret;
221 }
222 ret = av_grow_packet(pkt, additional_size);
223 if (ret < 0)
224 return ret;
225 for (int i = 0; i < anc_packet_count; i++) {
226 ret = smpte_436m_anc_encode_entry(pkt->data + write_start, pkt->size - write_start, &anc_packets[i]);
227 av_assert0(ret >= 0);
228 write_start += ret;
229 }
230 AV_WB16(pkt->data, final_packet_count);
231 return 0;
232}
233
234int 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 if (buf_size < 2)
239 return AVERROR_INVALIDDATA;
240 *iter = (AVSmpte436mAncIterator){
241 .anc_packets_left = AV_RB16(buf),
242 .size_left = buf_size - 2,
243 .data_left = buf + 2,
244 };
245 if (iter->anc_packets_left > iter->size_left)
246 return AVERROR_INVALIDDATA;
247 return 0;
248}
249
250int av_smpte_436m_anc_iter_next(AVSmpte436mAncIterator *iter, AVSmpte436mCodedAnc *anc)
251{
252 if (iter->anc_packets_left <= 0)
253 return AVERROR_EOF;
254 iter->anc_packets_left--;
255 int ret = smpte_436m_anc_decode_entry(iter->data_left, iter->size_left, anc);
256 if (ret < 0) {
257 iter->anc_packets_left = 0;
258 return ret;
259 }
260 iter->data_left += ret;
261 iter->size_left -= ret;
262 return 0;
263}
264
265int av_smpte_436m_coded_anc_payload_size(AVSmpte436mPayloadSampleCoding sample_coding, uint16_t sample_count)
266{
267 if (sample_count > AV_SMPTE_436M_CODED_ANC_SAMPLE_CAPACITY)
268 return AVERROR_INVALIDDATA;
269 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 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 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
295int 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 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 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 if (sample_count < 3)
314 return AVERROR_INVALIDDATA;
315 out->did = *payload++;
316 out->sdid_or_dbn = *payload++;
317 out->data_count = *payload++;
318 if (sample_count < out->data_count + 3)
319 return AVERROR_INVALIDDATA;
320 memcpy(out->payload, payload, out->data_count);
321 // the checksum isn't stored in 8-bit mode, so calculate it.
322 av_smpte_291m_anc_8bit_fill_checksum(out);
323 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
337void av_smpte_291m_anc_8bit_fill_checksum(AVSmpte291mAnc8bit *anc)
338{
339 uint8_t checksum = anc->did + anc->sdid_or_dbn + anc->data_count;
340 for (unsigned i = 0; i < anc->data_count; i++) {
341 checksum += anc->payload[i];
342 }
343 anc->checksum = checksum;
344}
345
346int av_smpte_291m_anc_8bit_get_sample_count(const AVSmpte291mAnc8bit *anc,
347 AVSmpte436mPayloadSampleCoding sample_coding,
348 void *log_ctx)
349{
350 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 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 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
375int 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 out->line_number = line_number;
383 out->wrapping_type = wrapping_type;
384 out->payload_sample_coding = sample_coding;
385
386 int ret = av_smpte_291m_anc_8bit_get_sample_count(payload, sample_coding, log_ctx);
387 if (ret < 0)
388 return ret;
389
390 out->payload_sample_count = ret;
391
392 ret = av_smpte_436m_coded_anc_payload_size(sample_coding, out->payload_sample_count);
393 if (ret < 0)
394 return ret;
395
396 out->payload_array_length = ret;
397
398 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 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 av_assert0(out->payload_array_length >= 4);
412 memset(out->payload + out->payload_array_length - 4, 0, 4);
413
414 out->payload[0] = payload->did;
415 out->payload[1] = payload->sdid_or_dbn;
416 out->payload[2] = payload->data_count;
417
418 memcpy(out->payload + 3, payload->payload, payload->data_count);
419 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
433int av_smpte_291m_anc_8bit_extract_cta_708(const AVSmpte291mAnc8bit *anc, uint8_t *cc_data, void *log_ctx)
434{
435 if (anc->did != AV_SMPTE_291M_ANC_DID_CTA_708 || anc->sdid_or_dbn != AV_SMPTE_291M_ANC_SDID_CTA_708)
436 return AVERROR(EAGAIN);
437 GetByteContext gb;
438 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 uint16_t cdp_identifier = bytestream2_get_be16(&gb);
442 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 bytestream2_get_byte(&gb); // cdp_length
447 bytestream2_get_byte(&gb); // cdp_frame_rate and reserved
448 bytestream2_get_byte(&gb); // flags
449 bytestream2_get_be16(&gb); // cdp_hdr_sequence_cntr
450 unsigned section_id = bytestream2_get_byte(&gb);
451
452 const unsigned TIME_CODE_SECTION_ID = 0x71;
453 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 const unsigned CC_DATA_SECTION_ID = 0x72;
458 if (section_id == CC_DATA_SECTION_ID) {
459 if (bytestream2_get_bytes_left(&gb) < 1)
460 goto too_short;
461 // 0x1F for lower 5 bits, upper 3 bits are marker bits
462 unsigned cc_count = bytestream2_get_byte(&gb) & 0x1F;
463 unsigned data_length = cc_count * 3; // EIA-608/CTA-708 triples are 3 bytes long
464 if (bytestream2_get_bytes_left(&gb) < data_length)
465 goto too_short;
466 if (cc_data)
467 bytestream2_get_bufferu(&gb, cc_data, data_length);
468 return cc_count;
469 }
470 return AVERROR(EAGAIN);
471
472too_short:
473 av_log(log_ctx, AV_LOG_ERROR, "not enough bytes in cdp\n");
474 return AVERROR_INVALIDDATA;
475}
libavcodec/smpte_436m.h+254−0
@@ -0,0 +1,254 @@
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#ifndef AVCODEC_SMPTE_436M_H
23#define AVCODEC_SMPTE_436M_H
24
25#include <stdint.h>
26
27/**
28 * Iterator over the ANC packets in a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data
29 */
30typedef struct AVSmpte436mAncIterator {
31 uint16_t anc_packets_left;
32 int size_left;
33 const uint8_t *data_left;
34} AVSmpte436mAncIterator;
35
36/**
37 * Wrapping Type from Table 7 (page 13) of:
38 * https://pub.smpte.org/latest/st436/s436m-2006.pdf
39 */
40typedef enum AVSmpte436mWrappingType
41{
42 AV_SMPTE_436M_WRAPPING_TYPE_VANC_FRAME = 1,
43 AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_1 = 2,
44 AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_2 = 3,
45 AV_SMPTE_436M_WRAPPING_TYPE_VANC_PROGRESSIVE_FRAME = 4,
46 AV_SMPTE_436M_WRAPPING_TYPE_HANC_FRAME = 0x11,
47 AV_SMPTE_436M_WRAPPING_TYPE_HANC_FIELD_1 = 0x12,
48 AV_SMPTE_436M_WRAPPING_TYPE_HANC_FIELD_2 = 0x13,
49 AV_SMPTE_436M_WRAPPING_TYPE_HANC_PROGRESSIVE_FRAME = 0x14,
50 /** not a real wrapping type, just here to guarantee the enum is big enough */
51 AV_SMPTE_436M_WRAPPING_TYPE_MAX = 0xFF,
52} AVSmpte436mWrappingType;
53
54/**
55 * Payload Sample Coding from Table 4 (page 10) and Table 7 (page 13) of:
56 * https://pub.smpte.org/latest/st436/s436m-2006.pdf
57 */
58typedef enum AVSmpte436mPayloadSampleCoding
59{
60 /** only used for VBI */
61 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA = 1,
62 /** only used for VBI */
63 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF = 2,
64 /** only used for VBI */
65 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF = 3,
66 /** used for VBI and ANC */
67 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA = 4,
68 /** used for VBI and ANC */
69 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF = 5,
70 /** used for VBI and ANC */
71 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF = 6,
72 /** used for VBI and ANC */
73 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA = 7,
74 /** used for VBI and ANC */
75 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF = 8,
76 /** used for VBI and ANC */
77 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF = 9,
78 /** only used for ANC */
79 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR = 10,
80 /** only used for ANC */
81 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR = 11,
82 /** only used for ANC */
83 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR = 12,
84 /** not a real sample coding, just here to guarantee the enum is big enough */
85 AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_MAX = 0xFF,
86} AVSmpte436mPayloadSampleCoding;
87
88/** the payload capacity of AVSmpte291mAnc8bit (and of AVSmpte291mAnc10bit when that gets added) */
89#define AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY 0xFF
90
91/**
92 * An ANC packet with an 8-bit payload.
93 * This can be decoded from AVSmpte436mCodedAnc::payload.
94 *
95 * Note: Some ANC packets need a 10-bit payload, if stored in this struct,
96 * the most-significant 2 bits of each sample are discarded.
97 */
98typedef struct AVSmpte291mAnc8bit {
99 uint8_t did;
100 uint8_t sdid_or_dbn;
101 uint8_t data_count;
102 uint8_t payload[AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY];
103 uint8_t checksum;
104} AVSmpte291mAnc8bit;
105
106/** max number of samples that can be stored in the payload of AVSmpte436mCodedAnc */
107#define AV_SMPTE_436M_CODED_ANC_SAMPLE_CAPACITY \
108 (AV_SMPTE_291M_ANC_PAYLOAD_CAPACITY + 4) /* 4 for did, sdid_or_dbn, data_count, and checksum */
109/** max number of bytes that can be stored in the payload of AVSmpte436mCodedAnc */
110#define AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY (((AV_SMPTE_436M_CODED_ANC_SAMPLE_CAPACITY + 2) / 3) * 4)
111
112/**
113 * An encoded ANC packet within a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
114 * The repeated section of Table 7 (page 13) of:
115 * https://pub.smpte.org/latest/st436/s436m-2006.pdf
116 */
117typedef struct AVSmpte436mCodedAnc {
118 uint16_t line_number;
119 AVSmpte436mWrappingType wrapping_type;
120 AVSmpte436mPayloadSampleCoding payload_sample_coding;
121 uint16_t payload_sample_count;
122 uint32_t payload_array_length;
123 /** the payload, has size payload_array_length.
124 * can be decoded into AVSmpte291mAnc8bit
125 */
126 uint8_t payload[AV_SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY];
127} AVSmpte436mCodedAnc;
128
129/**
130 * Validate a AVSmpte436mCodedAnc structure. Doesn't check if the payload is valid.
131 * @param[in] anc ANC packet to validate
132 * @return 0 on success, AVERROR codes otherwise.
133 */
134int av_smpte_436m_coded_anc_validate(const AVSmpte436mCodedAnc *anc);
135
136/**
137 * Encode ANC packets into a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
138 * @param[in] anc_packet_count number of ANC packets to encode
139 * @param[in] anc_packets the ANC packets to encode
140 * @param[in] size the size of out. ignored if out is NULL.
141 * @param[out] out Output bytes. Doesn't write anything if out is NULL.
142 * @return the number of bytes written on success, AVERROR codes otherwise.
143 * If out is NULL, returns the number of bytes it would have written.
144 */
145int av_smpte_436m_anc_encode(uint8_t *out, int size, int anc_packet_count, const AVSmpte436mCodedAnc *anc_packets);
146
147struct AVPacket;
148
149/**
150 * Append more ANC packets to a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
151 * @param[in] anc_packet_count number of ANC packets to encode
152 * @param[in] anc_packets the ANC packets to encode
153 * @param pkt the AVPacket to append to.
154 * it must either be size 0 or contain valid SMPTE_436M_ANC data.
155 * @return 0 on success, AVERROR codes otherwise.
156 */
157int av_smpte_436m_anc_append(struct AVPacket *pkt, int anc_packet_count, const AVSmpte436mCodedAnc *anc_packets);
158
159/**
160 * Set up iteration over the ANC packets in a single AV_CODEC_ID_SMPTE_436M_ANC AVPacket's data.
161 * @param[in] buf Pointer to the data from a AV_CODEC_ID_SMPTE_436M_ANC AVPacket.
162 * @param[in] buf_size Size of the data from a AV_CODEC_ID_SMPTE_436M_ANC AVPacket.
163 * @param[out] iter Pointer to the iterator.
164 * @return 0 on success, AVERROR codes otherwise.
165 */
166int av_smpte_436m_anc_iter_init(AVSmpte436mAncIterator *iter, const uint8_t *buf, int buf_size);
167
168/**
169 * Get the next ANC packet from the iterator, advancing the iterator.
170 * @param[in,out] iter Pointer to the iterator.
171 * @param[out] anc The returned ANC packet.
172 * @return 0 on success, AVERROR_EOF when the iterator has reached the end, AVERROR codes otherwise.
173 */
174int av_smpte_436m_anc_iter_next(AVSmpte436mAncIterator *iter, AVSmpte436mCodedAnc *anc);
175
176/**
177 * Get the minimum number of bytes needed to store a AVSmpte436mCodedAnc payload.
178 * @param sample_coding the payload sample coding
179 * @param sample_count the number of samples stored in the payload
180 * @return returns the minimum number of bytes needed, on error returns < 0.
181 * always <= SMPTE_436M_CODED_ANC_PAYLOAD_CAPACITY
182 */
183int av_smpte_436m_coded_anc_payload_size(AVSmpte436mPayloadSampleCoding sample_coding, uint16_t sample_count);
184
185/**
186 * Decode a AVSmpte436mCodedAnc payload into AVSmpte291mAnc8bit
187 * @param[in] sample_coding the payload sample coding
188 * @param[in] sample_count the number of samples stored in the payload
189 * @param[in] payload the bytes storing the payload,
190 * the needed size can be obtained from
191 avpriv_smpte_436m_coded_anc_payload_size
192 * @param[in] log_ctx context pointer for av_log
193 * @param[out] out The decoded ANC packet.
194 * @return returns 0 on success, otherwise < 0.
195 */
196int av_smpte_291m_anc_8bit_decode(AVSmpte291mAnc8bit *out,
197 AVSmpte436mPayloadSampleCoding sample_coding,
198 uint16_t sample_count,
199 const uint8_t *payload,
200 void *log_ctx);
201
202/**
203 * Fill in the correct checksum for a AVSmpte291mAnc8bit
204 * @param[in,out] anc The ANC packet.
205 */
206void av_smpte_291m_anc_8bit_fill_checksum(AVSmpte291mAnc8bit *anc);
207
208/**
209 * Compute the sample count needed to encode a AVSmpte291mAnc8bit into a AVSmpte436mCodedAnc payload
210 * @param[in] anc The ANC packet.
211 * @param[in] sample_coding The sample coding.
212 * @param[in] log_ctx context pointer for av_log
213 * @return returns the sample count on success, otherwise < 0.
214 */
215int av_smpte_291m_anc_8bit_get_sample_count(const AVSmpte291mAnc8bit *anc,
216 AVSmpte436mPayloadSampleCoding sample_coding,
217 void *log_ctx);
218
219/**
220 * Encode a AVSmpte291mAnc8bit into a AVSmpte436mCodedAnc
221 * @param[in] line_number the line number the ANC packet is on
222 * @param[in] wrapping_type the wrapping type
223 * @param[in] sample_coding the payload sample coding
224 * @param[in] payload the ANC packet to encode.
225 * @param[in] log_ctx context pointer for av_log
226 * @param[out] out The encoded ANC packet.
227 * @return returns 0 on success, otherwise < 0.
228 */
229int av_smpte_291m_anc_8bit_encode(AVSmpte436mCodedAnc *out,
230 uint16_t line_number,
231 AVSmpte436mWrappingType wrapping_type,
232 AVSmpte436mPayloadSampleCoding sample_coding,
233 const AVSmpte291mAnc8bit *payload,
234 void *log_ctx);
235
236/** AVSmpte291mAnc8bit::did when carrying CTA-708 data (for AV_CODEC_ID_EIA_608) */
237#define AV_SMPTE_291M_ANC_DID_CTA_708 0x61
238
239/** AVSmpte291mAnc8bit::sdid_or_dbn when carrying CTA-708 data (for AV_CODEC_ID_EIA_608) */
240#define AV_SMPTE_291M_ANC_SDID_CTA_708 0x1
241
242/**
243 * Try to decode an ANC packet into EIA-608/CTA-708 data (AV_CODEC_ID_EIA_608). This
244 * @param[in] anc The ANC packet.
245 * @param[in] log_ctx Context pointer for av_log
246 * @param[out] cc_data the buffer to store the extracted EIA-608/CTA-708 data,
247 * you can pass NULL to not store the data.
248 * the required size is 3 * cc_count bytes.
249 * SMPTE_291M_ANC_PAYLOAD_CAPACITY is always enough size.
250 * @return returns cc_count (>= 0) on success, AVERROR(EAGAIN) if it wasn't a CTA-708 ANC packet, < 0 on error.
251 */
252int av_smpte_291m_anc_8bit_extract_cta_708(const AVSmpte291mAnc8bit *anc, uint8_t *cc_data, void *log_ctx);
253
254#endif /* AVCODEC_SMPTE_436M_H */
libavcodec/smpte_436m_internal.h+98−0
@@ -0,0 +1,98 @@
1/*
2 * MXF SMPTE-436M VBI/ANC internals
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#ifndef AVCODEC_SMPTE_436M_INTERNAL_H
23#define AVCODEC_SMPTE_436M_INTERNAL_H
24
25#include "smpte_436m.h"
26
27// clang-format off
28#define FF_SMPTE_436M_WRAPPING_TYPE_VANC_AVOPTIONS(flags, unit_name) \
29 { "vanc_frame", "VANC frame (interlaced or segmented progressive frame)", 0, AV_OPT_TYPE_CONST, \
30 {.i64 = AV_SMPTE_436M_WRAPPING_TYPE_VANC_FRAME}, 0, 0xFF, flags, .unit = unit_name }, \
31 { "vanc_field_1", "VANC field 1", 0, AV_OPT_TYPE_CONST, \
32 {.i64 = AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_1}, 0, 0xFF, flags, .unit = unit_name }, \
33 { "vanc_field_2", "VANC field 2", 0, AV_OPT_TYPE_CONST, \
34 {.i64 = AV_SMPTE_436M_WRAPPING_TYPE_VANC_FIELD_2}, 0, 0xFF, flags, .unit = unit_name }, \
35 { "vanc_progressive_frame", "VANC progressive frame", 0, AV_OPT_TYPE_CONST, \
36 {.i64 = AV_SMPTE_436M_WRAPPING_TYPE_VANC_PROGRESSIVE_FRAME}, 0, 0xFF, flags, .unit = unit_name }
37
38#define FF_SMPTE_436M_WRAPPING_TYPE_HANC_AVOPTIONS(flags, unit_name) \
39 { "hanc_frame", "HANC frame (interlaced or segmented progressive frame)", 0, AV_OPT_TYPE_CONST, \
40 {.i64 = AV_SMPTE_436M_WRAPPING_TYPE_HANC_FRAME}, 0, 0xFF, flags, .unit = unit_name }, \
41 { "hanc_field_1", "HANC field 1", 0, AV_OPT_TYPE_CONST, \
42 {.i64 = AV_SMPTE_436M_WRAPPING_TYPE_HANC_FIELD_1}, 0, 0xFF, flags, .unit = unit_name }, \
43 { "hanc_field_2", "HANC field 2", 0, AV_OPT_TYPE_CONST, \
44 {.i64 = AV_SMPTE_436M_WRAPPING_TYPE_HANC_FIELD_2}, 0, 0xFF, flags, .unit = unit_name }, \
45 { "hanc_progressive_frame", "HANC progressive frame", 0, AV_OPT_TYPE_CONST, \
46 {.i64 = AV_SMPTE_436M_WRAPPING_TYPE_HANC_PROGRESSIVE_FRAME}, 0, 0xFF, flags, .unit = unit_name }
47
48#define FF_SMPTE_436M_WRAPPING_TYPE_AVOPTIONS(flags, unit_name) \
49 FF_SMPTE_436M_WRAPPING_TYPE_VANC_AVOPTIONS(flags, unit_name), \
50 FF_SMPTE_436M_WRAPPING_TYPE_HANC_AVOPTIONS(flags, unit_name)
51// clang-format on
52
53// clang-format off
54#define FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_ONLY_IN_VBI_AVOPTIONS(flags, unit_name) \
55 { "1bit_luma", "1-bit component luma samples", 0, AV_OPT_TYPE_CONST, \
56 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA}, 0, 0xFF, flags, .unit = unit_name }, \
57 { "1bit_color_diff", "1-bit component color difference samples", 0, AV_OPT_TYPE_CONST, \
58 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_COLOR_DIFF}, 0, 0xFF, flags, .unit = unit_name }, \
59 { "1bit_luma_and_color_diff", "1-bit component luma and color difference samples", 0, AV_OPT_TYPE_CONST, \
60 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_1BIT_LUMA_AND_COLOR_DIFF}, 0, 0xFF, flags, .unit = unit_name }
61
62#define FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_SHARED_AVOPTIONS(flags, unit_name) \
63 { "8bit_luma", "8-bit component luma samples", 0, AV_OPT_TYPE_CONST, \
64 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA}, 0, 0xFF, flags, .unit = unit_name }, \
65 { "8bit_color_diff", "8-bit component color difference samples", 0, AV_OPT_TYPE_CONST, \
66 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF}, 0, 0xFF, flags, .unit = unit_name }, \
67 { "8bit_luma_and_color_diff", "8-bit component luma and color difference samples", 0, AV_OPT_TYPE_CONST, \
68 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF}, 0, 0xFF, flags, .unit = unit_name }, \
69 { "10bit_luma", "10-bit component luma samples", 0, AV_OPT_TYPE_CONST, \
70 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA}, 0, 0xFF, flags, .unit = unit_name }, \
71 { "10bit_color_diff", "10-bit component color difference samples", 0, AV_OPT_TYPE_CONST, \
72 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_COLOR_DIFF}, 0, 0xFF, flags, .unit = unit_name }, \
73 { "10bit_luma_and_color_diff", "10-bit component luma and color difference samples", 0, AV_OPT_TYPE_CONST, \
74 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_10BIT_LUMA_AND_COLOR_DIFF}, 0, 0xFF, flags, .unit = unit_name }
75
76#define FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_ONLY_IN_ANC_AVOPTIONS(flags, unit_name) \
77 { "8bit_luma_parity_error", "8-bit component luma samples with parity error", 0, AV_OPT_TYPE_CONST, \
78 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_WITH_PARITY_ERROR}, 0, 0xFF, flags, .unit = unit_name }, \
79 { "8bit_color_diff_parity_error", "8-bit component color difference samples with parity error", 0, AV_OPT_TYPE_CONST, \
80 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_COLOR_DIFF_WITH_PARITY_ERROR}, 0, 0xFF, flags, .unit = unit_name }, \
81 { "8bit_luma_and_color_diff_parity_error", "8-bit component luma and color difference samples with parity error", 0, AV_OPT_TYPE_CONST, \
82 {.i64 = AV_SMPTE_436M_PAYLOAD_SAMPLE_CODING_8BIT_LUMA_AND_COLOR_DIFF_WITH_PARITY_ERROR}, 0, 0xFF, flags, .unit = unit_name }
83
84#define FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_VBI_AVOPTIONS(flags, unit_name) \
85 FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_ONLY_IN_VBI_AVOPTIONS(flags, unit_name), \
86 FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_SHARED_AVOPTIONS(flags, unit_name)
87
88#define FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_ANC_AVOPTIONS(flags, unit_name) \
89 FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_SHARED_AVOPTIONS(flags, unit_name), \
90 FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_ONLY_IN_ANC_AVOPTIONS(flags, unit_name)
91
92#define FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_AVOPTIONS(flags, unit_name) \
93 FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_ONLY_IN_VBI_AVOPTIONS(flags, unit_name), \
94 FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_SHARED_AVOPTIONS(flags, unit_name), \
95 FF_SMPTE_436M_PAYLOAD_SAMPLE_CODING_ONLY_IN_ANC_AVOPTIONS(flags, unit_name)
96// clang-format on
97
98#endif /* AVCODEC_SMPTE_436M_INTERNAL_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t