FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/atsc_a53.c
Date: 2026-08-27 17:28:56
Exec Total Coverage
Lines: 16 45 35.6%
Functions: 1 2 50.0%
Branches: 8 22 36.4%

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 <stddef.h>
20 #include <stdint.h>
21
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/mem.h"
24 #include "atsc_a53.h"
25
26 int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len,
27 void **data, size_t *sei_size)
28 {
29 AVFrameSideData *side_data = NULL;
30 uint8_t *sei_data;
31
32 if (frame)
33 side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC);
34
35 if (!side_data) {
36 *data = NULL;
37 return 0;
38 }
39
40 *sei_size = side_data->size + 11;
41 *data = av_mallocz(*sei_size + prefix_len);
42 if (!*data)
43 return AVERROR(ENOMEM);
44 sei_data = (uint8_t*)*data + prefix_len;
45
46 // country code
47 sei_data[0] = 181;
48 sei_data[1] = 0;
49 sei_data[2] = 49;
50
51 /**
52 * 'GA94' is standard in North America for ATSC, but hard coding
53 * this style may not be the right thing to do -- other formats
54 * do exist. This information is not available in the side_data
55 * so we are going with this right now.
56 */
57 AV_WL32(sei_data + 3, MKTAG('G', 'A', '9', '4'));
58 sei_data[7] = 3;
59 sei_data[8] = ((side_data->size/3) & 0x1f) | 0x40;
60 sei_data[9] = 0;
61
62 memcpy(sei_data + 10, side_data->data, side_data->size);
63
64 sei_data[side_data->size+10] = 255;
65
66 return 0;
67 }
68
69 6 int ff_parse_a53_cc(AVBufferRef **pbuf, const uint8_t *data, int size)
70 {
71 6 AVBufferRef *buf = *pbuf;
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 size_t new_size, old_size = buf ? buf->size : 0;
73 int ret, cc_count;
74
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (size < 3)
76 return AVERROR_INVALIDDATA;
77
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (data[0] != 0x3) // user_data_type_code
79 return 0;
80
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!(data[1] & 0x40)) // process_cc_data_flag
82 return 0;
83
84 6 cc_count = data[1] & 0x1F;
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!cc_count)
86 return 0;
87
88 // content of data[2] is reserved
89 /* 3 bytes per CC plus one byte marker_bits at the end */
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (cc_count * 3 >= size - 3)
91 return AVERROR_INVALIDDATA;
92
93 6 new_size = (old_size + cc_count * 3);
94
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (new_size > INT_MAX)
96 return AVERROR_INVALIDDATA;
97
98 /* Allow merging of the cc data from two fields. */
99 6 ret = av_buffer_realloc(pbuf, new_size);
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
101 return ret;
102
103 6 buf = *pbuf;
104 /* Use of av_buffer_realloc assumes buffer is writeable */
105 6 memcpy(buf->data + old_size, data + 3, cc_count * 3);
106
107 6 return cc_count;
108 }
109