Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/itut35.c
Line
Count
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
int ff_itut_t35_parse_buffer(FFITUTT35 *const itut_t35, const uint8_t *buf,
35
2.24M
                             size_t buf_size, int flags) {
36
2.24M
    GetByteContext gb;
37
2.24M
    int provider_code, country_code;
38
2.24M
    unsigned int provider_oriented_code = 0;
39
40
2.24M
    bytestream2_init(&gb, buf, buf_size);
41
42
2.24M
    if (flags & FF_ITUT_T35_FLAG_COUNTRY_CODE)
43
0
        country_code = itut_t35->country_code;
44
2.24M
    else {
45
2.24M
        country_code = bytestream2_get_byte(&gb);
46
2.24M
        if (country_code == 0xFF) {
47
32.1k
            if (bytestream2_get_bytes_left(&gb) < 1)
48
4.03k
                return AVERROR_INVALIDDATA;
49
50
28.1k
            bytestream2_skipu(&gb, 1); // itu_t_t35_country_code_extension_byte
51
28.1k
        }
52
2.24M
    }
53
54
2.24M
    switch (country_code) {
55
965k
    case ITU_T_T35_COUNTRY_CODE_US:
56
965k
        if (bytestream2_get_bytes_left(&gb) < 2)
57
3.61k
            return AVERROR_INVALIDDATA;
58
961k
        provider_code = bytestream2_get_be16u(&gb);
59
60
961k
        switch (provider_code) {
61
72.5k
        case ITU_T_T35_PROVIDER_CODE_ATSC:
62
72.5k
            if (bytestream2_get_bytes_left(&gb) < 4)
63
4.36k
                return AVERROR_INVALIDDATA;
64
68.2k
            provider_oriented_code = bytestream2_get_be32u(&gb);
65
68.2k
            switch (provider_oriented_code) {
66
9.58k
            case MKBETAG('D', 'T', 'G', '1'): // afd_data
67
9.58k
                if (bytestream2_get_bytes_left(&gb) < 2)
68
1.20k
                    return AVERROR_INVALIDDATA;
69
8.37k
                if (!(bytestream2_get_byteu(&gb) & 0x40)) // active_format_flag
70
3.22k
                    return 0; //ignore
71
5.15k
                break;
72
44.1k
            case MKBETAG('G', 'A', '9', '4'): // closed captions
73
44.1k
                break;
74
14.5k
            default: // ignore unsupported identifiers
75
14.5k
                return 0;
76
68.2k
            }
77
49.2k
            break;
78
261k
        case ITU_T_T35_PROVIDER_CODE_AOM:
79
261k
            if (bytestream2_get_bytes_left(&gb) < 1)
80
2.58k
                return AVERROR_INVALIDDATA;
81
82
258k
            provider_oriented_code = bytestream2_get_byteu(&gb);
83
258k
            if (provider_oriented_code != 0x0001)
84
15.3k
                return 0; // ignore
85
243k
            break;
86
385k
        case ITU_T_T35_PROVIDER_CODE_SAMSUNG:
87
385k
            if (bytestream2_get_bytes_left(&gb) < 3)
88
38.1k
                return AVERROR_INVALIDDATA;
89
347k
            provider_oriented_code = bytestream2_get_be16u(&gb);
90
347k
            int application_identifier = bytestream2_get_byteu(&gb);
91
92
347k
            if (provider_oriented_code != 1 || application_identifier != 4)
93
35.5k
                return 0; // ignore
94
311k
            break;
95
311k
        case ITU_T_T35_PROVIDER_CODE_DOLBY:
96
11.2k
            if (bytestream2_get_bytes_left(&gb) < 4)
97
2.81k
                return AVERROR_INVALIDDATA;
98
8.45k
            provider_oriented_code = bytestream2_get_be32u(&gb);
99
8.45k
            if (provider_oriented_code != 0x800)
100
6.23k
                return 0; // ignore
101
2.21k
            break;
102
173k
        case ITU_T_T35_PROVIDER_CODE_SMPTE:
103
173k
            if (bytestream2_get_bytes_left(&gb) < 2)
104
6.15k
                return AVERROR_INVALIDDATA;
105
167k
            provider_oriented_code = bytestream2_get_be16u(&gb);
106
167k
            if (provider_oriented_code != 1)
107
8.51k
                return 0; // ignore
108
158k
            break;
109
158k
        default: // ignore unsupported provider codes
110
57.7k
            return 0;
111
961k
        }
112
765k
        break;
113
765k
    case ITU_T_T35_COUNTRY_CODE_UK:
114
23.5k
        if (bytestream2_get_bytes_left(&gb) < 3)
115
6.28k
            return AVERROR_INVALIDDATA;
116
117
17.2k
        bytestream2_skipu(&gb, 1); // t35_uk_country_code_second_octet
118
17.2k
        provider_code = bytestream2_get_be16u(&gb);
119
120
17.2k
        switch (provider_code) {
121
4.60k
        case ITU_T_T35_PROVIDER_CODE_VNOVA:
122
4.60k
            break;
123
12.6k
        default: // ignore unsupported provider codes
124
12.6k
            return 0;
125
17.2k
        }
126
4.60k
        break;
127
137k
    case ITU_T_T35_COUNTRY_CODE_CN:
128
137k
        if (bytestream2_get_bytes_left(&gb) < 2)
129
4.22k
            return AVERROR_INVALIDDATA;
130
133k
        provider_code = bytestream2_get_be16u(&gb);
131
132
133k
        switch (provider_code) {
133
115k
        case ITU_T_T35_PROVIDER_CODE_HDR_VIVID:
134
115k
            if (bytestream2_get_bytes_left(&gb) < 2)
135
8.39k
                return AVERROR_INVALIDDATA;
136
137
106k
            provider_oriented_code = bytestream2_get_be16u(&gb);
138
106k
            if (provider_oriented_code != 0x0005)
139
13.7k
                return 0; //ignore
140
92.8k
            break;
141
92.8k
        default: // ignore unsupported provider codes
142
18.4k
            return 0;
143
133k
        }
144
92.8k
        break;
145
146
1.11M
    default: // ignore unsupported country codes
147
1.11M
        return 0;
148
2.24M
    }
149
150
862k
    if (!bytestream2_get_bytes_left(&gb))
151
4.86k
        return AVERROR_INVALIDDATA;
152
153
857k
    itut_t35->payload = gb.buffer;
154
857k
    itut_t35->payload_size = bytestream2_get_bytes_left(&gb);
155
156
857k
    itut_t35->country_code  = country_code;
157
857k
    itut_t35->provider_code = provider_code;
158
857k
    itut_t35->provider_oriented_code = provider_oriented_code;
159
160
857k
    return 1;
161
862k
}
162
163
int ff_itut_t35_parse_payload_to_struct(FFITUTT35 *const itut_t35, FFITUTT35Aux *const aux,
164
                                        FFITUTT35Meta *metadata, int err_recognition)
165
857k
{
166
857k
    int ret;
167
168
857k
    switch (itut_t35->country_code) {
169
762k
    case ITU_T_T35_COUNTRY_CODE_US:
170
762k
        switch (itut_t35->provider_code) {
171
242k
        case ITU_T_T35_PROVIDER_CODE_AOM:
172
242k
            ff_aom_uninit_film_grain_params(&metadata->aom_film_grain);
173
242k
            ret = ff_aom_parse_film_grain_sets(&metadata->aom_film_grain,
174
242k
                                               itut_t35->payload, itut_t35->payload_size);
175
242k
            if (ret < 0)
176
172k
                return ret;
177
69.8k
            break;
178
69.8k
        case ITU_T_T35_PROVIDER_CODE_ATSC:
179
48.9k
            switch (itut_t35->provider_oriented_code) {
180
5.15k
            case MKBETAG('D', 'T', 'G', '1'): // afd_data
181
5.15k
                av_buffer_unref(&metadata->afd);
182
5.15k
                metadata->afd = av_buffer_alloc(1);
183
5.15k
                if (!metadata->afd)
184
0
                    return AVERROR(ENOMEM);
185
186
5.15k
                *metadata->afd->data = *itut_t35->payload & 0xf;
187
188
5.15k
                break;
189
43.7k
            case MKBETAG('G', 'A', '9', '4'): // closed captions
190
43.7k
                ret = ff_parse_a53_cc(&metadata->a53_cc, itut_t35->payload, itut_t35->payload_size);
191
43.7k
                if (ret < 0)
192
9.14k
                    return ret;
193
194
34.6k
                break;
195
34.6k
            default: // ignore unsupported identifiers
196
0
                break;
197
48.9k
            }
198
39.7k
            break;
199
310k
        case ITU_T_T35_PROVIDER_CODE_SAMSUNG: {
200
310k
            size_t size;
201
310k
            AVDynamicHDRPlus *hdr_plus = av_dynamic_hdr_plus_alloc(&size);
202
310k
            if (!hdr_plus)
203
0
                return AVERROR(ENOMEM);
204
205
310k
            ret = av_dynamic_hdr_plus_from_t35(hdr_plus, itut_t35->payload,
206
310k
                                               itut_t35->payload_size);
207
310k
            if (ret < 0) {
208
236k
                av_free(hdr_plus);
209
236k
                return ret;
210
236k
            }
211
212
74.3k
            av_buffer_unref(&metadata->hdr_plus);
213
74.3k
            metadata->hdr_plus = av_buffer_create((uint8_t *)hdr_plus, size, NULL, NULL, 0);
214
74.3k
            if (!metadata->hdr_plus) {
215
0
                av_free(hdr_plus);
216
0
                return AVERROR(ENOMEM);
217
0
            }
218
219
74.3k
            break;
220
74.3k
        }
221
74.3k
        case ITU_T_T35_PROVIDER_CODE_DOLBY: {
222
2.08k
            AVDOVIMetadata *dovi;
223
224
2.08k
            if (!aux || !aux->dovi)
225
2.08k
                return 0; // ignore
226
227
0
            ret = ff_dovi_rpu_parse(aux->dovi, itut_t35->payload, itut_t35->payload_size,
228
0
                                    err_recognition);
229
0
            if (ret < 0)
230
0
                return 0; // ignore
231
232
0
            ret = ff_dovi_get_metadata(aux->dovi, &dovi);
233
0
            if (ret <= 0)
234
0
                return ret;
235
236
0
            av_buffer_unref(&metadata->dovi);
237
0
            metadata->dovi = av_buffer_create((uint8_t *)dovi, ret, NULL, NULL, 0);
238
0
            if (!metadata->dovi) {
239
0
                av_free(dovi);
240
0
                return AVERROR(ENOMEM);
241
0
            }
242
243
0
            break;
244
0
        }
245
158k
        case ITU_T_T35_PROVIDER_CODE_SMPTE: {
246
158k
            size_t size;
247
158k
            AVDynamicHDRSmpte2094App5 *hdr_smpte2094_app5 = av_dynamic_hdr_smpte2094_app5_alloc(&size);
248
158k
            if (!hdr_smpte2094_app5)
249
0
                return AVERROR(ENOMEM);
250
251
158k
            ret = av_dynamic_hdr_smpte2094_app5_from_t35(hdr_smpte2094_app5, itut_t35->payload,
252
158k
                                                         itut_t35->payload_size);
253
158k
            if (ret < 0) {
254
119k
                av_free(hdr_smpte2094_app5);
255
119k
                return ret;
256
119k
            }
257
258
38.3k
            av_buffer_unref(&metadata->hdr_smpte2094_app5);
259
38.3k
            metadata->hdr_smpte2094_app5 = av_buffer_create((uint8_t *)hdr_smpte2094_app5, size, NULL, NULL, 0);
260
38.3k
            if (!metadata->hdr_smpte2094_app5) {
261
0
                av_free(hdr_smpte2094_app5);
262
0
                return AVERROR(ENOMEM);
263
0
            }
264
265
38.3k
            break;
266
38.3k
        }
267
38.3k
        default:
268
0
            break;
269
762k
        }
270
222k
        break;
271
222k
    case ITU_T_T35_COUNTRY_CODE_UK:
272
2.89k
        switch (itut_t35->provider_code) {
273
2.89k
        case ITU_T_T35_PROVIDER_CODE_VNOVA:
274
2.89k
            av_buffer_unref(&metadata->lcevc);
275
2.89k
            metadata->lcevc = av_buffer_alloc(itut_t35->payload_size);
276
2.89k
            if (!metadata->lcevc)
277
0
                return AVERROR(ENOMEM);
278
279
2.89k
            memcpy(metadata->lcevc->data, itut_t35->payload, itut_t35->payload_size);
280
281
2.89k
            break;
282
0
        default:
283
0
            break;
284
2.89k
        }
285
2.89k
        break;
286
92.2k
    case ITU_T_T35_COUNTRY_CODE_CN:
287
92.2k
        switch (itut_t35->provider_code) {
288
92.2k
        case ITU_T_T35_PROVIDER_CODE_HDR_VIVID: {
289
92.2k
            size_t size;
290
92.2k
            AVDynamicHDRVivid *hdr_vivid = av_dynamic_hdr_vivid_alloc(&size);
291
92.2k
            if (!hdr_vivid)
292
0
                return AVERROR(ENOMEM);
293
294
92.2k
            ret = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(hdr_vivid, itut_t35->payload,
295
92.2k
                                                          itut_t35->payload_size);
296
92.2k
            if (ret < 0) {
297
48.9k
                av_free(hdr_vivid);
298
48.9k
                return ret;
299
48.9k
            }
300
301
43.3k
            av_buffer_unref(&metadata->hdr_vivid);
302
43.3k
            metadata->hdr_vivid = av_buffer_create((uint8_t *)hdr_vivid, size, NULL, NULL, 0);
303
43.3k
            if (!metadata->hdr_vivid) {
304
0
                av_free(hdr_vivid);
305
0
                return AVERROR(ENOMEM);
306
0
            }
307
43.3k
            break;
308
43.3k
        }
309
43.3k
        default:
310
0
            break;
311
92.2k
        }
312
43.3k
        break;
313
314
43.3k
    default:
315
        // ignore unsupported provider codes
316
0
        break;
317
857k
    }
318
319
268k
    return 0;
320
857k
}
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
0
{
325
0
    FFITUTT35Meta metadata = { 0 };
326
0
    int ret;
327
328
0
    ret = ff_itut_t35_parse_payload_to_struct(itut_t35, aux, &metadata, avctx->err_recognition);
329
0
    if (ret < 0)
330
0
        return ret;
331
332
0
    if (metadata.afd) {
333
0
        if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_AFD, metadata.afd))
334
0
            av_buffer_unref(&metadata.afd);
335
0
        metadata.afd = NULL;
336
0
    }
337
338
0
    if (metadata.a53_cc) {
339
0
        ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_A53_CC, &metadata.a53_cc);
340
0
        if (ret < 0)
341
0
            return ret;
342
0
    }
343
344
0
    if (metadata.aom_film_grain.enable) {
345
0
        ret = ff_aom_attach_film_grain_sets(&metadata.aom_film_grain, frame);
346
0
        if (ret < 0)
347
0
            return ret;
348
0
    }
349
350
0
    if (metadata.hdr_plus) {
351
0
        ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS,
352
0
                                              &metadata.hdr_plus);
353
0
        if (ret < 0)
354
0
            return ret;
355
0
    }
356
357
0
    if (metadata.dovi) {
358
0
        AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_DOVI_METADATA,
359
0
                                                              metadata.dovi);
360
0
        if (!sd) {
361
0
            av_buffer_unref(&metadata.dovi);
362
0
            return AVERROR(ENOMEM);
363
0
        }
364
0
        metadata.dovi = NULL;
365
0
    }
366
367
0
    if (metadata.hdr_smpte2094_app5) {
368
0
        ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_DYNAMIC_HDR_SMPTE_2094_APP5,
369
0
                                              &metadata.hdr_smpte2094_app5);
370
0
        if (ret < 0)
371
0
            return ret;
372
0
    }
373
374
0
    if (metadata.lcevc) {
375
0
        ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_LCEVC,
376
0
                                             &metadata.lcevc);
377
0
        if (ret < 0)
378
0
            return ret;
379
0
    }
380
381
0
    if (metadata.hdr_vivid) {
382
0
        ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_DYNAMIC_HDR_VIVID,
383
0
                                              &metadata.hdr_vivid);
384
0
        if (ret < 0)
385
0
            return ret;
386
0
    }
387
388
0
    ff_itut_t35_unref(&metadata);
389
390
0
    return 0;
391
0
}
392
393
void ff_itut_t35_unref(FFITUTT35Meta *metadata)
394
18.6M
{
395
18.6M
    ff_aom_uninit_film_grain_params(&metadata->aom_film_grain);
396
18.6M
    av_buffer_unref(&metadata->afd);
397
18.6M
    av_buffer_unref(&metadata->a53_cc);
398
18.6M
    av_buffer_unref(&metadata->hdr_plus);
399
18.6M
    av_buffer_unref(&metadata->hdr_smpte2094_app5);
400
18.6M
    av_buffer_unref(&metadata->lcevc);
401
18.6M
    av_buffer_unref(&metadata->dovi);
402
18.6M
    av_buffer_unref(&metadata->hdr_vivid);
403
18.6M
}