FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/itut35.c
Date: 2026-09-27 02:02:56
Exec Total Coverage
Lines: 114 260 43.8%
Functions: 3 4 75.0%
Branches: 41 146 28.1%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "libavutil/buffer.h"
20 #include "libavutil/frame.h"
21 #include "libavutil/hdr_dynamic_metadata.h"
22 #include "libavutil/internal.h"
23 #include "libavutil/mem.h"
24
25 #include "avcodec.h"
26 #include "atsc_a53.h"
27 #include "bytestream.h"
28 #include "decode.h"
29 #include "dynamic_hdr_vivid.h"
30 #include "dovi_rpu.h"
31 #include "itut35.h"
32 #include "version.h"
33
34 1589 int ff_itut_t35_parse_buffer(FFITUTT35 *const itut_t35, const uint8_t *buf,
35 size_t buf_size, int flags) {
36 GetByteContext gb;
37 int provider_code, country_code;
38 1589 unsigned int provider_oriented_code = 0;
39
40 1589 bytestream2_init(&gb, buf, buf_size);
41
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1589 times.
1589 if (flags & FF_ITUT_T35_FLAG_COUNTRY_CODE)
43 ✗ country_code = itut_t35->country_code;
44 else {
45 1589 country_code = bytestream2_get_byte(&gb);
46
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1589 times.
1589 if (country_code == 0xFF) {
47 ✗ if (bytestream2_get_bytes_left(&gb) < 1)
48 ✗ return AVERROR_INVALIDDATA;
49
50 ✗ bytestream2_skipu(&gb, 1); // itu_t_t35_country_code_extension_byte
51 }
52 }
53
54
3/4
✓ Branch 0 taken 1250 times.
✓ Branch 1 taken 336 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
1589 switch (country_code) {
55 1250 case ITU_T_T35_COUNTRY_CODE_US:
56
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1250 times.
1250 if (bytestream2_get_bytes_left(&gb) < 2)
57 ✗ return AVERROR_INVALIDDATA;
58 1250 provider_code = bytestream2_get_be16u(&gb);
59
60
2/6
✓ Branch 0 taken 1239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1250 switch (provider_code) {
61 1239 case ITU_T_T35_PROVIDER_CODE_ATSC:
62
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1239 times.
1239 if (bytestream2_get_bytes_left(&gb) < 4)
63 ✗ return AVERROR_INVALIDDATA;
64 1239 provider_oriented_code = bytestream2_get_be32u(&gb);
65
2/3
✓ Branch 0 taken 1233 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
1239 switch (provider_oriented_code) {
66 1233 case MKBETAG('D', 'T', 'G', '1'): // afd_data
67
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1233 times.
1233 if (bytestream2_get_bytes_left(&gb) < 2)
68 ✗ return AVERROR_INVALIDDATA;
69
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1233 times.
1233 if (!(bytestream2_get_byteu(&gb) & 0x40)) // active_format_flag
70 ✗ return 0; //ignore
71 1233 break;
72 6 case MKBETAG('G', 'A', '9', '4'): // closed captions
73 6 break;
74 ✗ default: // ignore unsupported identifiers
75 ✗ return 0;
76 }
77 1239 break;
78 ✗ case ITU_T_T35_PROVIDER_CODE_AOM:
79 ✗ if (bytestream2_get_bytes_left(&gb) < 1)
80 ✗ return AVERROR_INVALIDDATA;
81
82 ✗ provider_oriented_code = bytestream2_get_byteu(&gb);
83 ✗ if (provider_oriented_code != 0x0001)
84 ✗ return 0; // ignore
85 ✗ break;
86 11 case ITU_T_T35_PROVIDER_CODE_SAMSUNG:
87
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if (bytestream2_get_bytes_left(&gb) < 3)
88 ✗ return AVERROR_INVALIDDATA;
89 11 provider_oriented_code = bytestream2_get_be16u(&gb);
90 11 int application_identifier = bytestream2_get_byteu(&gb);
91
92
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if (provider_oriented_code != 1 || application_identifier != 4)
93 ✗ return 0; // ignore
94 11 break;
95 ✗ case ITU_T_T35_PROVIDER_CODE_DOLBY:
96 ✗ if (bytestream2_get_bytes_left(&gb) < 4)
97 ✗ return AVERROR_INVALIDDATA;
98 ✗ provider_oriented_code = bytestream2_get_be32u(&gb);
99 ✗ if (provider_oriented_code != 0x800)
100 ✗ return 0; // ignore
101 ✗ break;
102 ✗ case ITU_T_T35_PROVIDER_CODE_SMPTE:
103 ✗ if (bytestream2_get_bytes_left(&gb) < 2)
104 ✗ return AVERROR_INVALIDDATA;
105 ✗ provider_oriented_code = bytestream2_get_be16u(&gb);
106 ✗ if (provider_oriented_code != 1)
107 ✗ return 0; // ignore
108 ✗ break;
109 ✗ default: // ignore unsupported provider codes
110 ✗ return 0;
111 }
112 1250 break;
113 336 case ITU_T_T35_COUNTRY_CODE_UK:
114
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 336 times.
336 if (bytestream2_get_bytes_left(&gb) < 3)
115 ✗ return AVERROR_INVALIDDATA;
116
117 336 bytestream2_skipu(&gb, 1); // t35_uk_country_code_second_octet
118 336 provider_code = bytestream2_get_be16u(&gb);
119
120
1/2
✓ Branch 0 taken 336 times.
✗ Branch 1 not taken.
336 switch (provider_code) {
121 336 case ITU_T_T35_PROVIDER_CODE_VNOVA:
122 336 break;
123 ✗ default: // ignore unsupported provider codes
124 ✗ return 0;
125 }
126 336 break;
127 3 case ITU_T_T35_COUNTRY_CODE_CN:
128
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (bytestream2_get_bytes_left(&gb) < 2)
129 ✗ return AVERROR_INVALIDDATA;
130 3 provider_code = bytestream2_get_be16u(&gb);
131
132
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 switch (provider_code) {
133 3 case ITU_T_T35_PROVIDER_CODE_HDR_VIVID:
134
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (bytestream2_get_bytes_left(&gb) < 2)
135 ✗ return AVERROR_INVALIDDATA;
136
137 3 provider_oriented_code = bytestream2_get_be16u(&gb);
138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (provider_oriented_code != 0x0005)
139 ✗ return 0; //ignore
140 3 break;
141 ✗ default: // ignore unsupported provider codes
142 ✗ return 0;
143 }
144 3 break;
145
146 ✗ default: // ignore unsupported country codes
147 ✗ return 0;
148 }
149
150
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1589 times.
1589 if (!bytestream2_get_bytes_left(&gb))
151 ✗ return AVERROR_INVALIDDATA;
152
153 1589 itut_t35->payload = gb.buffer;
154 1589 itut_t35->payload_size = bytestream2_get_bytes_left(&gb);
155
156 1589 itut_t35->country_code = country_code;
157 1589 itut_t35->provider_code = provider_code;
158 1589 itut_t35->provider_oriented_code = provider_oriented_code;
159
160 1589 return 1;
161 }
162
163 1589 int ff_itut_t35_parse_payload_to_struct(FFITUTT35 *const itut_t35, FFITUTT35Aux *const aux,
164 FFITUTT35Meta *metadata, int err_recognition)
165 {
166 int ret;
167
168
3/4
✓ Branch 0 taken 1250 times.
✓ Branch 1 taken 336 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
1589 switch (itut_t35->country_code) {
169 1250 case ITU_T_T35_COUNTRY_CODE_US:
170
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1239 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1250 switch (itut_t35->provider_code) {
171 ✗ case ITU_T_T35_PROVIDER_CODE_AOM:
172 ✗ ff_aom_uninit_film_grain_params(&metadata->aom_film_grain);
173 ✗ ret = ff_aom_parse_film_grain_sets(&metadata->aom_film_grain,
174 ✗ itut_t35->payload, itut_t35->payload_size);
175 ✗ if (ret < 0)
176 ✗ return ret;
177 ✗ break;
178 1239 case ITU_T_T35_PROVIDER_CODE_ATSC:
179
2/3
✓ Branch 0 taken 1233 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
1239 switch (itut_t35->provider_oriented_code) {
180 1233 case MKBETAG('D', 'T', 'G', '1'): // afd_data
181 1233 av_buffer_unref(&metadata->afd);
182 1233 metadata->afd = av_buffer_alloc(1);
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1233 times.
1233 if (!metadata->afd)
184 ✗ return AVERROR(ENOMEM);
185
186 1233 *metadata->afd->data = *itut_t35->payload & 0xf;
187
188 1233 break;
189 6 case MKBETAG('G', 'A', '9', '4'): // closed captions
190 6 ret = ff_parse_a53_cc(&metadata->a53_cc, itut_t35->payload, itut_t35->payload_size);
191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
192 ✗ return ret;
193
194 6 break;
195 ✗ default: // ignore unsupported identifiers
196 ✗ break;
197 }
198 1239 break;
199 11 case ITU_T_T35_PROVIDER_CODE_SAMSUNG: {
200 size_t size;
201 11 AVDynamicHDRPlus *hdr_plus = av_dynamic_hdr_plus_alloc(&size);
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (!hdr_plus)
203 ✗ return AVERROR(ENOMEM);
204
205 11 ret = av_dynamic_hdr_plus_from_t35(hdr_plus, itut_t35->payload,
206 itut_t35->payload_size);
207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ret < 0) {
208 ✗ av_free(hdr_plus);
209 ✗ return ret;
210 }
211
212 11 av_buffer_unref(&metadata->hdr_plus);
213 11 metadata->hdr_plus = av_buffer_create((uint8_t *)hdr_plus, size, NULL, NULL, 0);
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (!metadata->hdr_plus) {
215 ✗ av_free(hdr_plus);
216 ✗ return AVERROR(ENOMEM);
217 }
218
219 11 break;
220 }
221 ✗ case ITU_T_T35_PROVIDER_CODE_DOLBY: {
222 AVDOVIMetadata *dovi;
223
224 ✗ if (!aux || !aux->dovi)
225 ✗ return 0; // ignore
226
227 ✗ ret = ff_dovi_rpu_parse(aux->dovi, itut_t35->payload, itut_t35->payload_size,
228 err_recognition);
229 ✗ if (ret < 0)
230 ✗ return 0; // ignore
231
232 ✗ ret = ff_dovi_get_metadata(aux->dovi, &dovi);
233 ✗ if (ret <= 0)
234 ✗ return ret;
235
236 ✗ av_buffer_unref(&metadata->dovi);
237 ✗ metadata->dovi = av_buffer_create((uint8_t *)dovi, ret, NULL, NULL, 0);
238 ✗ if (!metadata->dovi) {
239 ✗ av_free(dovi);
240 ✗ return AVERROR(ENOMEM);
241 }
242
243 ✗ break;
244 }
245 ✗ case ITU_T_T35_PROVIDER_CODE_SMPTE: {
246 size_t size;
247 ✗ AVDynamicHDRSmpte2094App5 *hdr_smpte2094_app5 = av_dynamic_hdr_smpte2094_app5_alloc(&size);
248 ✗ if (!hdr_smpte2094_app5)
249 ✗ return AVERROR(ENOMEM);
250
251 ✗ ret = av_dynamic_hdr_smpte2094_app5_from_t35(hdr_smpte2094_app5, itut_t35->payload,
252 itut_t35->payload_size);
253 ✗ if (ret < 0) {
254 ✗ av_free(hdr_smpte2094_app5);
255 ✗ return ret;
256 }
257
258 ✗ av_buffer_unref(&metadata->hdr_smpte2094_app5);
259 ✗ metadata->hdr_smpte2094_app5 = av_buffer_create((uint8_t *)hdr_smpte2094_app5, size, NULL, NULL, 0);
260 ✗ if (!metadata->hdr_smpte2094_app5) {
261 ✗ av_free(hdr_smpte2094_app5);
262 ✗ return AVERROR(ENOMEM);
263 }
264
265 ✗ break;
266 }
267 ✗ default:
268 ✗ break;
269 }
270 1250 break;
271 336 case ITU_T_T35_COUNTRY_CODE_UK:
272
1/2
✓ Branch 0 taken 336 times.
✗ Branch 1 not taken.
336 switch (itut_t35->provider_code) {
273 336 case ITU_T_T35_PROVIDER_CODE_VNOVA:
274 336 av_buffer_unref(&metadata->lcevc);
275 336 metadata->lcevc = av_buffer_alloc(itut_t35->payload_size);
276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 336 times.
336 if (!metadata->lcevc)
277 ✗ return AVERROR(ENOMEM);
278
279 336 memcpy(metadata->lcevc->data, itut_t35->payload, itut_t35->payload_size);
280
281 336 break;
282 ✗ default:
283 ✗ break;
284 }
285 336 break;
286 3 case ITU_T_T35_COUNTRY_CODE_CN:
287
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 switch (itut_t35->provider_code) {
288 3 case ITU_T_T35_PROVIDER_CODE_HDR_VIVID: {
289 size_t size;
290 3 AVDynamicHDRVivid *hdr_vivid = av_dynamic_hdr_vivid_alloc(&size);
291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!hdr_vivid)
292 ✗ return AVERROR(ENOMEM);
293
294 3 ret = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(hdr_vivid, itut_t35->payload,
295 3 itut_t35->payload_size);
296
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
297 ✗ av_free(hdr_vivid);
298 ✗ return ret;
299 }
300
301 3 av_buffer_unref(&metadata->hdr_vivid);
302 3 metadata->hdr_vivid = av_buffer_create((uint8_t *)hdr_vivid, size, NULL, NULL, 0);
303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!metadata->hdr_vivid) {
304 ✗ av_free(hdr_vivid);
305 ✗ return AVERROR(ENOMEM);
306 }
307 3 break;
308 }
309 ✗ default:
310 ✗ break;
311 }
312 3 break;
313
314 ✗ default:
315 // ignore unsupported provider codes
316 ✗ break;
317 }
318
319 1589 return 0;
320 }
321
322 ✗ int ff_itut_t35_parse_payload_to_frame(FFITUTT35 *const itut_t35, FFITUTT35Aux *const aux,
323 AVCodecContext *const avctx, AVFrame *const frame)
324 {
325 ✗ FFITUTT35Meta metadata = { 0 };
326 int ret;
327
328 ✗ ret = ff_itut_t35_parse_payload_to_struct(itut_t35, aux, &metadata, avctx->err_recognition);
329 ✗ if (ret < 0)
330 ✗ return ret;
331
332 ✗ if (metadata.afd) {
333 ✗ if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_AFD, metadata.afd))
334 ✗ av_buffer_unref(&metadata.afd);
335 ✗ metadata.afd = NULL;
336 }
337
338 ✗ if (metadata.a53_cc) {
339 ✗ ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_A53_CC, &metadata.a53_cc);
340 ✗ if (ret < 0)
341 ✗ return ret;
342 }
343
344 ✗ if (metadata.aom_film_grain.enable) {
345 ✗ ret = ff_aom_attach_film_grain_sets(&metadata.aom_film_grain, frame);
346 ✗ if (ret < 0)
347 ✗ return ret;
348 }
349
350 ✗ if (metadata.hdr_plus) {
351 ✗ ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS,
352 &metadata.hdr_plus);
353 ✗ if (ret < 0)
354 ✗ return ret;
355 }
356
357 ✗ if (metadata.dovi) {
358 ✗ AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_DOVI_METADATA,
359 metadata.dovi);
360 ✗ if (!sd) {
361 ✗ av_buffer_unref(&metadata.dovi);
362 ✗ return AVERROR(ENOMEM);
363 }
364 ✗ metadata.dovi = NULL;
365 }
366
367 ✗ if (metadata.hdr_smpte2094_app5) {
368 ✗ ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_DYNAMIC_HDR_SMPTE_2094_APP5,
369 &metadata.hdr_smpte2094_app5);
370 ✗ if (ret < 0)
371 ✗ return ret;
372 }
373
374 ✗ if (metadata.lcevc) {
375 ✗ ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_LCEVC,
376 &metadata.lcevc);
377 ✗ if (ret < 0)
378 ✗ return ret;
379 }
380
381 ✗ if (metadata.hdr_vivid) {
382 ✗ ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_DYNAMIC_HDR_VIVID,
383 &metadata.hdr_vivid);
384 ✗ if (ret < 0)
385 ✗ return ret;
386 }
387
388 ✗ ff_itut_t35_unref(&metadata);
389
390 ✗ return 0;
391 }
392
393 78651 void ff_itut_t35_unref(FFITUTT35Meta *metadata)
394 {
395 78651 ff_aom_uninit_film_grain_params(&metadata->aom_film_grain);
396 78651 av_buffer_unref(&metadata->afd);
397 78651 av_buffer_unref(&metadata->a53_cc);
398 78651 av_buffer_unref(&metadata->hdr_plus);
399 78651 av_buffer_unref(&metadata->hdr_smpte2094_app5);
400 78651 av_buffer_unref(&metadata->lcevc);
401 78651 av_buffer_unref(&metadata->dovi);
402 78651 av_buffer_unref(&metadata->hdr_vivid);
403 78651 }
404